0

I'm trying to rotate a cube's vertexes with a rotation matrix but whenever I run the program the cube just disappears.

I'm using a rotation matrix that was given to us in a lecture that rotates the cube's x coordinates.

double moveCubeX = 0;
float xRotationMatrix[9] = {1, 0, 0,
                            0, cos(moveCubeX), sin(moveCubeX),
                            0, -sin(moveCubeX), cos(moveCubeX) 
};

I'm adding to the moveCubeX variable with the 't' key on my keyboard

case 't':
    moveCubeX += 5;
    break;

And to do the matrix multiplication I'm using

glMultMatrixf();

However when I add this into my code when running it the cube has just disappeared. This is where I add in the glMultMatrixf() function.

void display(void)
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();

    gluLookAt(pan, 0, -g_fViewDistance, 
              pan, 0, -1,
              0, 1, 0);

    glRotatef(rotate_x, 1.0f, 0.0f, 0.0f);   //Rotate the camera
    glRotatef(rotate_y, 0.0f, 1.0f, 0.0f);   //Rotate the camera

    glMultMatrixf(xRotationMatrix);

I'm struggling to see where it is I have gone wrong.

genpfault
  • 51,148
  • 11
  • 85
  • 139
JaAnTr
  • 896
  • 3
  • 16
  • 28

1 Answers1

3

OpenGL uses matrices of size 4x4. Therefore, your rotation matrix needs to be expanded to 4 rows and 4 columns, for a total of 16 elements:

float xRotationMatrix[16] = {1.0f, 0.0f, 0.0f, 0.0f,
                             0.0f, cos(moveCubeX), sin(moveCubeX), 0.0f,
                             0.0f, -sin(moveCubeX), cos(moveCubeX), 0.0f,
                             0.0f, 0.0f, 0.0f, 1.0f};

You will also need to be careful about the units for your angles. Since you add 5 to your angle every time the user presses a key, it looks like you're thinking in degrees. The standard cos() and sin() functions in C/C++ libraries expect the angle to be in radians.

In addition, it looks like your matrix is defined at a global level. If you do this, the elements will only be evaluated once at program startup. You will either have to make the matrix definition local to the display(), so that the matrix is re-evaluated each time you draw, or update the matrix every time the angle changes.

For the second option, you can update only the matrix elements that depend on the angle every time the angle changes. In the function that modifies moveCubeX, add:

xRotationMatrix[5] = cos(moveCubeX);
xRotationMatrix[6] = sin(moveCubeX);
xRotationMatrix[9] = -sin(moveCubeX);
xRotationMatrix[10] = cos(moveCubeX);
Reto Koradi
  • 53,228
  • 8
  • 93
  • 133
  • I originally had it as a 4x4 by read a wikipedia on rotation matrixes and changed it for some reason. Anyway, the good news is that the cube actually shows up when I run it, however it doesn't move when I press the key. With regards to the degrees/radians I was under the impression that OpenGL used degrees according to this http://stackoverflow.com/questions/2146884/why-does-opengl-use-degrees-instead-of-radians. – JaAnTr Nov 14 '14 at 17:30
  • I just realised what you meant about degrees and radians as it's in C++ not OpenGL. I've just tried it so it add 0.175 radians each time. However, it's still not working as it doesn't actually do anything to the cube. – JaAnTr Nov 14 '14 at 17:37
  • @JaAnTr - you need to recalculate the cells of the matrix each time you change the angle, not just define it once. – Cel Skeggs Nov 14 '14 at 17:44
  • @col6y - I don't think I fully understand what that means. How would I go about doing that? – JaAnTr Nov 14 '14 at 17:55
  • It wasn't entirely clear from the code fragments how the whole thing was structured. Yes, if the matrix is currently a static variable, you'll have to either change that to build it as a local variable in `display()`, or at least update the 4 matrix elements that depend on the angle every time the angle changes. I can add that to my answer later. – Reto Koradi Nov 14 '14 at 18:27
  • I've got it working now. The matrix was declared globally but like you said I moved it so it was declared locally in the display() and now it works. Thanks! – JaAnTr Nov 14 '14 at 18:30
  • @RetoKoradi I was just wondering, is this definitely rotating the cube's vertexes as opposed to rotating the camera like glRotatef() does? It's just that I've drawn the some axes using `glBegin(GL_LINES);` and then `glVertex3f(0.0f, 0.0f, 0.0f); glVertex3f(0.0f, 0.0f, 5.0f);` etc but when rotating the cube those lines are spinning. I thought that they would stay in position. – JaAnTr Nov 14 '14 at 23:52
  • @JaAnTr OpenGL does not really have a camera in that sense. All transformations are applied to vertices. If a transformation is applied to vertices that you don't want transformed, you may have to change the order of transformations/drawing, and possibly use `glPushMatrix/glPopMatrix` to apply the transformation only as long as needed. – Reto Koradi Nov 17 '14 at 02:37