Jump to content
  • Advertisement
Sign in to follow this  
CodingFreakss

OpenGL OpenGL Rotation issue

This topic is 1944 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Dear All , I have a peice of code in which i want to add a rotation to , can someone guide me or help inb in code how to do it ?

 

 

First Class

 

ColorCube.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;
s.source = readShaderSource(s.filename);
if ( shaders.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; m_vertices[m_index] = s_vertices; 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;
}
 

ColorCube.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;
}
 

 

 

Share this post


Link to post
Share on other sites
Advertisement

Hi,
if I understand properly, you don't really have an issue, you're asking for a know-how, right? I made my cube example recently and I added rotation to it, so I could see a cube instead of a square. Drawing lines along edges (and tinkering with glPolygonOffset so they didn't collide) made it nice looking too.
Anyway, here's a description of how I added rotation to my example. I cannot guarantee everything is used properly, it's just how I made it.

I did this:
I added globally accessible variables to hold rotation angles and directions for each axis, because Glut cannot pass custom arguments to callback functions. I also defined a step value, which was used to increase or decrease the angle based on the direction.

I defined rotation matrices in my vertex shader. They can be found here: http://en.wikipedia.org/wiki/Rotation_matrix#Basic_rotations I made my vertex shader accept three angles as vec3 uniform variable. (All vertices I had defined would be rendered with same rotation, I hope that's correct usage of uniform variable.)

I made my vertex shader to multiply the matrices together and with the vertex location. I assume you know what a transformation matrix is or can at least look it up. Now I know it's better for performance to prepare one final transformation matrix (by multiplying transformation matrices for all transformations needed) in your application and pass that final matrix to the shader, so it doesn't have to do more matrix multiplications than necessary. But it was a test project and I didn't want to worry about representing matrices and multiplying them, GLSL provided me with relevant data types and operators. It also provides trigonometric functions.

I prepared a key press callback function to use with glutKeyboardFunc, which would set direction for rotations, or clear them.

I prepared a timer callback function to use with glutTimerFunc, which would update rotation angles, schedule itself again and if any value got updated, it would flag window for redraw with glutPostRedisplay().

And that's it - at this point I had a cube which I could rotate.

Few notes:
I kept the angle values in range from 0 to 2*M_PI ,in order to allow the rotation to go on indefinetly.
I had to tinker with step and timer values so the rotation would seem smooth.
This way works because the cube is centered at origin. If it were somewhere else, it would go in circles, rather than rotate in place.

 

My aim is to inspire you how to do what you want, I don't want to type the code for you. All the stuff I learned while trying to figure out how to get it working helped me a lot in the long run.

 

I am willing to help with coding, but in answers to specific questions, this one is too general.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!