i have this code of a colored cube in openGL however i want to make it a 3d cube and i want to rotate it , can anyone help me with coding ( AS IN CODE ) to ctually be able to do this , if you run this code it would run perfectly on any paltform , i just need someone to help me with that , a tutorial is not a good idea i would love it if someone actually can help me with the implimentation
First Class
Color Cube .cpp
#include "ColorCube.h"
#include <iostream>
#define _USE_MATH_DEFINES
#include <math.h>
#include "mat.h"
vec4 ColorCube::s_vertices[8] = {
vec4(-0.5, -0.5, 0.5, 1.0),
vec4(-0.5, 0.5, 0.5, 1.0),
vec4( 0.5, 0.5, 0.5, 1.0),
vec4(0.5, -0.5, 0.5, 1.0),
vec4(-0.5, -0.5, -0.5, 1.0),
vec4(-0.5, 0.5, -0.5, 1.0),
vec4(0.5, 0.5, -0.5, 1.0),
vec4(0.5, -0.5, -0.5, 1.0)
};
vec4 ColorCube::s_colors[8] = {
vec4(0.0, 0.0, 0.0, 1.0), // black
vec4(1.0, 0.0, 0.0, 1.0), // red
vec4(1.0, 1.0, 0.0, 1.0), // yellow
vec4(0.0, 1.0, 0.0, 1.0), // green
vec4(0.0, 0.0, 1.0, 1.0), // blue
vec4(1.0, 0.0, 1.0, 1.0), // magenta
vec4(1.0, 1.0, 1.0, 1.0), // white
vec4(0.0, 1.0, 1.0, 1.0) // cyan
};
ColorCube::ColorCube()
: m_index(0), m_numVertices(0), m_aspectRatio(1.0f)
{
m_numVertices = 36; //(6 faces)(2 triangles/face)(3 vertices/triangle)
m_vertices = new vec4[m_numVertices];
m_colors = new vec4[m_numVertices];
}
ColorCube::~ColorCube()
{
delete[] m_vertices;
delete[] m_colors;
}
static char* readShaderSource(const char* shaderFile)
{
FILE* fp;
fopen_s(&fp, shaderFile, "r");
if ( fp == NULL )
{
return NULL;
}
fseek(fp, 0L, SEEK_END);
long size = ftell(fp);
fseek(fp, 0L, SEEK_SET);
char* buf = new char[size + 1];
fread(buf, 1, size, fp);
buf[size] = '\0';
fclose(fp);
return buf;
}
GLuint ColorCube::initShader(const char* vShaderFile, const char* fShaderFile)
{
struct Shader {
const char* filename;
GLenum type;
GLchar* source;
} shaders[2] = {
{ vShaderFile, GL_VERTEX_SHADER, NULL },
{ fShaderFile, GL_FRAGMENT_SHADER, NULL }
};
GLuint program = glCreateProgram();
for ( int i = 0; i < 2; ++i ) {
Shader& s = shaders[i];
s.source = readShaderSource(s.filename);
if ( shaders[i].source == NULL ) {
std::cerr << "Failed to read " << s.filename << std::endl;
exit( EXIT_FAILURE );
}
GLuint shader = glCreateShader( s.type );
glShaderSource( shader, 1, (const GLchar**) &s.source, NULL );
glCompileShader( shader );
GLint compiled;
glGetShaderiv( shader, GL_COMPILE_STATUS, &compiled );
if ( !compiled ) {
std::cerr << s.filename << " failed to compile:" << std::endl;
GLint logSize;
glGetShaderiv( shader, GL_INFO_LOG_LENGTH, &logSize );
char* logMsg = new char[logSize];
glGetShaderInfoLog( shader, logSize, NULL, logMsg );
std::cerr << logMsg << std::endl;
delete [] logMsg;
exit( EXIT_FAILURE );
}
delete [] s.source;
glAttachShader( program, shader );
}
// Link and error check
glLinkProgram(program);
GLint linked;
glGetProgramiv( program, GL_LINK_STATUS, &linked );
if ( !linked ) {
std::cerr << "Shader program failed to link" << std::endl;
GLint logSize;
glGetProgramiv( program, GL_INFO_LOG_LENGTH, &logSize);
char* logMsg = new char[logSize];
glGetProgramInfoLog( program, logSize, NULL, logMsg );
std::cerr << logMsg << std::endl;
delete [] logMsg;
exit( EXIT_FAILURE );
}
// Use program object
glUseProgram(program);
return program;
}
void ColorCube::addQuad(int a, int b, int c, int d)
{
m_colors[m_index] = s_colors[a]; m_vertices[m_index] = s_vertices[a]; m_index++;
m_colors[m_index] = s_colors[b]; m_vertices[m_index] = s_vertices[b]; m_index++;
m_colors[m_index] = s_colors[c]; m_vertices[m_index] = s_vertices[c]; m_index++;
m_colors[m_index] = s_colors[a]; m_vertices[m_index] = s_vertices[a]; m_index++;
m_colors[m_index] = s_colors[c]; m_vertices[m_index] = s_vertices[c]; m_index++;
m_colors[m_index] = s_colors[d]; m_vertices[m_index] = s_vertices[d]; m_index++;
}
void ColorCube::buildCube()
{
addQuad(1, 0, 3, 2);
addQuad(2, 3, 7, 6);
addQuad(3, 0, 4, 7);
addQuad(6, 5, 1, 2);
addQuad(4, 5, 6, 7);
addQuad(5, 4, 0, 1);
}
void ColorCube::initGL()
{
// Initialize geometry
buildCube();
// Create a vertex array object
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
// Create and initialize a buffer object
GLuint buffer;
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(vec4)*m_numVertices+sizeof(vec4)*m_numVertices, NULL, GL_STATIC_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vec4)*m_numVertices, m_vertices);
glBufferSubData(GL_ARRAY_BUFFER, sizeof(vec4)*m_numVertices, sizeof(vec4)*m_numVertices, m_colors);
// Load shaders and use the resulting shader program
GLuint program = initShader("Source/vcolorcube.glsl", "Source/fcolorcube.glsl");
glUseProgram(program);
// Set up vertex arrays
GLuint vPosition = glGetAttribLocation(program, "vPosition");
glEnableVertexAttribArray(vPosition);
glVertexAttribPointer(vPosition, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
GLuint vColor = glGetAttribLocation(program, "vColor");
glEnableVertexAttribArray(vColor);
glVertexAttribPointer(vColor, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(sizeof(vec4)*m_numVertices));
// Viewing
m_modelViewLocation = glGetUniformLocation(program, "model_view");
m_projectionLocation = glGetUniformLocation(program, "projection");
glEnable(GL_DEPTH_TEST);
glClearColor(1.0, 1.0, 1.0, 1.0);
}
void ColorCube::display(void)
{
// Place the camera
const GLfloat radius = 2.0f;
const GLfloat theta = static_cast<GLfloat>(M_PI_4);
const GLfloat phi = static_cast<GLfloat>(M_PI_4);
const GLfloat fovy = static_cast<GLfloat>(45.0/180*M_PI); // Field-of-view in Y direction angle (in degrees)
const GLfloat zNear = 0.1f, zFar = 3.0f;
vec4 eye(radius*sin(theta)*cos(phi), radius*sin(theta)*sin(phi),
radius*cos(theta), 1.0);
vec4 at(0.0, 0.0, 0.0, 1.0);
vec4 up(0.0, 1.0, 0.0, 0.0);
mat4 mv = LookAt(eye, at, up);
glUniformMatrix4fv(m_modelViewLocation, 1, GL_TRUE, mv);
const bool perspectiveProjection = true;
mat4 p;
if ( perspectiveProjection )
p = Perspective(fovy, m_aspectRatio, zNear, zFar);
else
p = Ortho(-2.0, 2.0, -2.0, 2.0, zNear, zFar);
glUniformMatrix4fv(m_projectionLocation, 1, GL_TRUE, p);
// Clear and draw
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDrawArrays(GL_TRIANGLES, 0, m_numVertices);
glutSwapBuffers();
}
void ColorCube::keyboard(unsigned char key, int x, int y)
{
switch(key) {
case 033: // Escape Key
case 'q': case 'Q':
exit(EXIT_SUCCESS);
break;
}
}
void ColorCube::mouse(int button, int state, int x, int y)
{
}
void ColorCube::idle(void)
{
}
void ColorCube::reshape(int width, int height)
{
glViewport(0, 0, width, height);
m_aspectRatio = static_cast<GLfloat>(width)/height;
}
Color Cube .h
#include <GL/glew.h>
#include <GL/freeglut.h>
#include "vec.h"
#define BUFFER_OFFSET(offset) ((GLvoid*) (offset))
/**
Display a color cube
Colors are assigned to each vertex and then the rasterizer interpolates
those colors across the triangles. We us an orthographic projection
as the default projection.
*/
class ColorCube
{
public:
ColorCube();
~ColorCube();
/// OpenGL initialization
void initGL();
/// Main Display callback
void display(void);
/// Main Keyboard event callback
void keyboard(unsigned char key, int x, int y);
/// Main Mouse event callback
void mouse(int button, int state, int x, int y);
/// Main Idle callback
void idle(void);
/// Main reshape callback
void reshape(int width, int height);
protected:
/// Create a GLSL program object from vertex and fragment shader files
GLuint initShader(const char* vShaderFile, const char* fShaderFile);
/// Generates two triangles for each face and assigns colors to the vertices
void addQuad(int a, int b, int c, int d);
/// Generate 12 triangles: 36 vertices and 36 colors
void buildCube();
protected:
int m_index;
int m_numVertices;
vec4* m_vertices;
vec4* m_colors;
GLuint m_modelViewLocation;
GLuint m_projectionLocation;
GLfloat m_aspectRatio;
// Vertices of a unit cube centered at origin, sides aligned with axes
static vec4 s_vertices[8];
// RGBA colors
static vec4 s_colors[8];
};
main.cpp
#include "ColorCube.h"
#include <assert.h>
// Global instance to our cube to solve the issue of GLUT not being able to handle C++ function pointer
ColorCube* g_cube = NULL;
// Wrapper for GLUT functions that can't handle C++ function pointer
extern "C" void fmod_display(void)
{ g_cube->display(); }
// Wrapper for GLUT functions that can't handle C++ function pointer
extern "C" void fmod_keyboard(unsigned char key, int x, int y)
{ g_cube->keyboard(key, x, y); }
// Wrapper for GLUT functions that can't handle C++ function pointer
extern "C" void fmod_mouse(int button, int state, int x, int y)
{ g_cube->mouse(button, state, x, y); }
extern "C" void fmod_reshape(int width, int height)
{ g_cube->reshape(width, height); }
// Wrapper for GLUT functions that can't handle C++ function pointer
extern "C" void fmod_idle(void)
{ g_cube->idle(); }
// Main function
int main(int argc, char **argv)
{
// Glut initialization
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowSize(512, 512);
glutCreateWindow("Color Cube");
// GLEW initialization
GLenum glewInitOk = glewInit();
assert(glewInitOk=!GLEW_OK);
// Create a ColorCube
g_cube = new ColorCube;
// Initialization of our geometry and shaders
g_cube->initGL();
// Linking callbacks
glutDisplayFunc(fmod_display);
glutKeyboardFunc(fmod_keyboard);
glutMouseFunc(fmod_mouse);
glutIdleFunc(fmod_idle);
glutReshapeFunc(fmod_reshape);
// Enter main event loop
glutMainLoop();
delete g_cube;
g_cube = NULL;
return 0;
}