It seems that i dont fully comprehend how rotation works. So leys say i have a cube and i do this:

x = 90.0f;
rotatef(x, 1.0f, 0.0f, 0.0f);

Notice that my code here may be not all correct, its like that just to symbolize what i mean.

So by doing that i would be facing the Top of the cube. But in this tutorial: http://nehe.gamedev.net/tutorial/moving_bitmaps_in_3d_space/17001/
it states that by doing something like that, its like rotating the whole room so now X axis goes out or into the screen and Z axis is right or left. So its basically the part i dont get, like the guy in tutorial explains, why does the room rotate to the right side? For better understanding this a part from the tutorial:

int DrawGLScene(GLvoid)                     // Here's Where We Do All The Drawing

{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer
glBindTexture(GL_TEXTURE_2D, texture[0]); // Select Our Texture

for (loop=0; loop<num; loop++)               // Loop Through All The Stars
{
    glLoadIdentity();               // Reset The View Before We Draw Each Star
    glTranslatef(0.0f,0.0f,zoom);           // Zoom Into The Screen (Using The Value In 'zoom')
    glRotatef(tilt,1.0f,0.0f,0.0f);         // Tilt The View (Using The Value In 'tilt')

"Now we move the star. The star starts off in the middle of the screen. The first thing we do is spin the scene on the x axis. If we spin 90 degrees, the x axis will no longer run left to right, it will run into and out of the screen. As an example to help clarify. Imagine you were in the center of a room. Now imagine that the left wall had -x written on it, the front wall had -z written on it, the right wall had +x written on it, and the wall behind you had +z written on it. If the room spun 90 degrees to the right, but you did not move, the wall in front of you would no longer say -z it would say -x. All of the walls would have moved. -z would be on the right, +z would be on the left, -x would be in front, and +x would be behind you. Make sense? By rotating the scene, we change the direction of the x and z planes."

P.S why do even need to shift everything by 90? Since in the tutorial we undo this anyways. I get why we need to undo it but dont know why we need to do it in the first place.

Recommended Answers

All 10 Replies

This link (and the downloadable example) helped me understand rotation in OpenGL far better.

Thanks for the link. But it explains and shows the way i understand it, maybe im missing something or the guy in the tutorial made a mistake.

I think the guy in the tutorial made a mistake. What he is describing does not correspond to a rotation about the x axis. It seems to correspond to a rotation about the y axis (vertical).

If you apply a rotation of -90 degrees about the y axis, you will get, as described, where the x axis is pointing out of the screen and the z axis is pointing towards the left of the screen. And, of course, you have to understand a very important concept, that is, the rotations of world are the inverse of the rotation of the camera, meaning that when you apply a -90 degree rotation (of the world), it appears as if the camera rotated by +90 degrees. This is simply a consequence of rotating the entire world in one direction has the same visible effect as rotating the camera in the opposite direction (usually, in 3D engines, the camera transformations are applied in reverse for that reason).

3D rotation transformations are very special and often counter-intuitive. It is very important to understand it well because it might cause you a lot of problems going further. Take the time to understand the math and play around with rotations and sequences of rotations (in various order) to make sure you know how it works. Seriously, I know graduate students who stumbled on problems involving 3D rotations and had disastrous results because they didn't take that topic seriously.

P.S why do even need to shift everything by 90?

Well, if you're going to want to display anything or do anything useful with OpenGL, you will probably want to be able to move around. Motion of the camera and of objects is achieved through translations and rotations. The idea is that you should get familiar with how all this works.

Thanks for a qucik reply. Yes, i think i might need to try doing different variations and stuff with rotation. Theres one more thing i would like to ask:

for (loop = 0; loop < num; loop++) {
    glLoadIdentity();
    glTranslatef(0.0f, 0.0f, zoom);
    glRotatef(tilt, 1.0f, 0.0f, 0.0f);

    glRotatef(star[loop].angle, 0.0f, 1.0f, 0.0f);
    glTranslatef(star[loop].dist, 0.0f, 0.0f);

    glRotatef(-star[loop].angle, 0.0f, 1.0f, 0.0f);
    glRotatef(-tilt, 1.0f, 0.0f, 0.0f);

The part about "why 90" i meant that i dont get how this works, as in like in the code above. We rotate everything on the x axis by 90 (tilt=90), then we rotate the star[loop].angle ("angle" keeps increasing), but later we just undo it all with the last 2 lines. To my understandment the object should get back to the way it was at the start but it doesnt.

Basically, the star-loop contains values of an angle and a distance. In other words, these are polar coordinates for the object. So, the purpose of this sequence of one rotation and one translation has the effect of rotating such that the x-axis is pointing on a particular direction (given by the angle), and then the object is moved along that x-axis by a certain distance. Once you have done that motion, if you want to restore the original orientation of the axes, you have to undo the rotations (in reverse order that they were applied). So, the whole purpose of the rotations, translation, and inverse rotations is just to realign the axis is some direction and then move in that direction and finally restoring the axis alignment (but the translation remains in effect). Basically, this allows you not to have to compute the resulting translation yourself (i.e. the translation resulting from a displacement in a particular direction). That's all it does.

Put simply, this code just computes a translation given by the distance and angle about the center of a tilted plane.

Try to render a cube right after the last glTranslate() call above. Then, move that cube rendering to after the last rotation. And see the difference it makes.

So, i was reading around how everything works (translate, rotate, scale, matrices etc.) and now i know that if we do this for example:

glRotatef(star[loop].angle, 0.0f, 1.0f, 0.0f);
glTranslatef(star[loop].dist, 0.0f, 0.0f);

The Translation will come first and the Rotation second, in reverse order. But before knowing this i figured that we rotate the object to face a certain direction first and then move it into that direction. But now when i think it actually does everything in reverse order these lines dont make much sense.

Aside from that its still kinda confusing with rotating everything and then rotating everything back but the translations still remaining in effect and a bunch of other stuff, but it is satisfying when one gets a hang of it :)

The Translation will come first and the Rotation second, in reverse order.

All this confusion about things being applied in reverse order or not, is just a matter of perspective. People interpret coordinate transformations differently, one way leads to the conclusion that things are applied in reverse order, the other leads to the conclusion that things are applied in the order they appear. In some sense, both interpretations are correct, but from a different point of view. Most of confusion stems from the fact that people don't know that their interpretation is relative to their point of view, and thus, not universally correct.

Point of view #1: "Transformations are applied in reverse order than they appear."

This interpretation comes from the point of view of starting with a set of vertices (or a polygon, or a mesh) drawn (e.g. with glBegin/glEnd). If one looks at the transformations that this polygon will go through before it gets to be drawn on the screen, then one will have to proceed in reverse order of the transformations. For instance, with the transformations you posted, you take the polygon, tilt and rotate it by a reverse angle, then move it some distance along the x-axis, then rotate it back to the original orientation, and finally move it back some (by "zoom") such that it appears at a reasonable distance. Obviously, this makes sense, the reverse order of transformations makes sense.

Point of view #2: "Transformation are applied in the order that they appear."

This interpretation is usually more grounded in the mathematics and is theoretically more sound (and the reason why the transformations are done the way they are done in OpenGL). Imagine you draw a little coordinate system as so:

glBegin(GL_LINES)
  glColor3f( 1.0f, 0.0f, 0.0f);
  glVertex3f(0.0f, 0.0f, 0.0f); glVertex3f(1.0f, 0.0f, 0.0f);
  glColor3f( 0.0f, 1.0f, 0.0f);
  glVertex3f(0.0f, 0.0f, 0.0f); glVertex3f(0.0f, 1.0f, 0.0f);
  glColor3f( 0.0f, 0.0f, 1.0f);
  glVertex3f(0.0f, 0.0f, 0.0f); glVertex3f(0.0f, 0.0f, 1.0f);
glEnd();

If you first place the above code after the first transformation, then compile and run, and then move the block of code from one transformation to the next, compiling and running each time. This will illustrate the mathematical point-of-view which regards this whole thing as a sequence of transformations of the local coordinate system in which the objects are drawn. In this sense, the sequence of transformations you posted correspond to the coordinate frame being first moved back (by "zoom"), then tilted and rotated, then moved away along its local x-axis, and finally rotated and tilted back such that it aligns with the original coordinate frame.

This is a classic duality in the interpretation of coordinate transformations, they can either be regarded as a sequence of rotations of objects or as a sequence of transformations of the coordinate system in which the objects are represented. The former is somewhat more intuitive for people, but the latter is more sound mathematically and will help you better understand the underlying mathematics (homogeneous coordinate transformation matrices).

Dont want to create a new threat for it so i would like to ask a few a simple question but i think it may help me to understand opengl better:

1.When we do transformations (translate, rotate, scale), we only move the whole scene, but the camera always stays in the same place, right?

2.In the tutorial that we were talking about, i tilted the scene, did everything i needed, reverted everything back and yet when i run the program i increase or decrease Tilt and it looks like we are moving around even though its rotation should be 0. I get why translation remains in effect, but not rotation.

3.If i do this:

glRotatef(star[loop].angle,0.0f,1.0f,0.0f); // Rotate To The Current Stars Angle
glTranslatef(star[loop].dist,0.0f,0.0f);    // Move Forward On The X Plane

do i need to imagine as if the whole scene was tilted along the y axis relative to the current star? Or i have to imagine as if the rotation was only made on that one star? i think the first one would be correct, since we load the identity matrix and do it again and stuff...

So yeah, is it normal that i ask so much since i can see that this is one of the harder opengl concepts and want to grasp it as better as i can, i assume that knowhing the math behind it is the key?

1.When we do transformations (translate, rotate, scale), we only move the whole scene, but the camera always stays in the same place, right?

In the real world, when you walk around, how do you know that you are moving? Couldn't it be that the entire world is moving around you?

This may sound like a philosophical question but it is true. A moving camera is indistinguishable from a moving world (moving in reverse). Usually, renderers for computer games will separate the camera transformations from the world coordinate transformations, but this is merely a conceptual distinction, at the end, they are the same. Often people will accumulate some transformations in a camera object, that is, a transformation from world coordinates to camera coordinates. Then, they will accumulate transformations for each visible object, from world coordinates to local object coordinates (in which the 3D model vertices are expressed). Finally, when it gets to rendering all the scene, they will first apply the inverse of the camera transformation (i.e. transforming the world coordinates in reverse of how the camera is "moved") and then apply the per-object transformations before rendering them.

2.In the tutorial that we were talking about, i tilted the scene, did everything i needed, reverted everything back and yet when i run the program i increase or decrease Tilt and it looks like we are moving around even though its rotation should be 0. I get why translation remains in effect, but not rotation.

Only the transformations up to the point in the code where you render something matters. And also, at the point where the translation is done, the rotations that came before it are in effect, until they are cancelled again. This means that the translation is done in the rotated coordinates (before they are cancelled). So, of course, changing those rotations (increasing / decreasing tilt) will affect the effect that the translation will have.

Have you done as I suggested and rendered this little coordinate system (three lines) by placing the code at different places among the transformations (between the translation and rotations, and so on). Try this:

glLoadIdentity();
glTranslatef(0.0f, 0.0f, zoom);

glRotatef(tilt, 1.0f, 0.0f, 0.0f);

// A

glRotatef(45.0, 0.0f, 1.0f, 0.0f);

// B

glTranslatef(10.0, 0.0f, 0.0f);

// C

glRotatef(-45.0, 0.0f, 1.0f, 0.0f);

// D

glRotatef(-tilt, 1.0f, 0.0f, 0.0f);

// This renders a coordinate system:
glBegin(GL_LINES)
  glColor3f( 1.0f, 0.0f, 0.0f);
  glVertex3f(0.0f, 0.0f, 0.0f); glVertex3f(1.0f, 0.0f, 0.0f);
  glColor3f( 0.0f, 1.0f, 0.0f);
  glVertex3f(0.0f, 0.0f, 0.0f); glVertex3f(0.0f, 1.0f, 0.0f);
  glColor3f( 0.0f, 0.0f, 1.0f);
  glVertex3f(0.0f, 0.0f, 0.0f); glVertex3f(0.0f, 0.0f, 1.0f);
glEnd();

And try moving the rendering of the coordinate system to the locations A, B, C and D, and see the difference it makes.

do i need to imagine as if the whole scene was tilted along the y axis relative to the current star? Or i have to imagine as if the rotation was only made on that one star? i think the first one would be correct, since we load the identity matrix and do it again and stuff...

Each set of transformation is for each star, independently. Basically, everytime you do glLoadIdentity(); you reset all the transformations. So, this star-loop corresponds to a per-star set of transformations.

Normally, people use a pair of functions called glPushMatrix(); and glPopMatrix(); to do this better. Pushing the matrix means that the current transformation matrix is saved on a stack (LIFO list). Popping the matrix means that the transformation matrix currently on top of the stack is loaded back as the current transformation matrix. So, in those terms, that star-loop would normally be implemented as:

glLoadIdentity();
glTranslatef(0.0f, 0.0f, zoom);
glRotatef(tilt, 1.0f, 0.0f, 0.0f);

for (loop = 0; loop < num; loop++) {

    glPushMatrix(); // save the current matrix. 

    // Then apply the star-specific transforms:

    glRotatef(star[loop].angle, 0.0f, 1.0f, 0.0f);
    glTranslatef(star[loop].dist, 0.0f, 0.0f);
    glRotatef(-star[loop].angle, 0.0f, 1.0f, 0.0f);
    glRotatef(-tilt, 1.0f, 0.0f, 0.0f);

    // ... the rendering code ..

    glPopMatrix(); // restore the last saved matrix.

};

So yeah, is it normal that i ask so much since i can see that this is one of the harder opengl concepts and want to grasp it as better as i can, i assume that knowhing the math behind it is the key?

It's not only normal but also very good that you do this. Understanding the transformations involved in OpenGL is a key concept and one of the hardest for many people to grasp. And yeah, the math behind this is important. Most game engines or other 3D renderers do not rely on OpenGL functions like glTranslatef() or glRotatef() to apply transformations, usually they will construct the transformation matrices externally to OpenGL and then load those transformations into OpenGL with the glLoadMatrix() or glMultMatrix() functions. Similarly for the projection matrix (instead of OpenGL's basic projection matrix functions like gluPerspective() or glOrtho()). Producing those matrices with your own code (instead of the basic OpenGL functions) gives you more flexibility (and allows for more advanced techniques like skinning or skeletal animations), but it also requires a pretty solid understanding of the underlying math. So, it is certainly worthwhile to take the time to understand this well before you move on.

Awesome! Thanks to you i finally realized how those stars worked, the little cordinate system helped to understand too. Even though i was very close back then but now i see how the translation remains in effect relative to the Tilt rotation to make an illusion that we are able to move up or down. Thanks man :)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.