Aha!
I believe I understand what your problem is now. (Code can be so much easier to understand sometimes…)
The problem is that when you do rotations like this…
glRotated(RotX, 1.0, 0.0, 0.0);
glRotated(RotY, 0.0, 1.0, 0.0);
glRotated(RotZ, 0.0, 0.0, 1.0);
You are going to get different results than if you did somthing like
glRotated(RotZ, 0.0, 0.0, 1.0);
glRotated(RotX, 1.0, 0.0, 0.0);
glRotated(RotY, 0.0, 1.0, 0.0);
The order of the rotations makes a big difference.
The easiest way to think about it in my mind is in world coordinates, which means that the rotations are actually done in reverse of what you specify them.
Picture taking a line that is straight up in the y axis.
Now picture rotating that line 45 degrees around the X axis so that the top half of the line goes away from you…
Now picture the line in that position being rotated 45 degrees to the left around the Y axis.
You should be picturing a line that goes from the upper left at a going to the lower right coming towards you.
Ok… now let’s go in the reverse order.
Rotate the line 45 degrees around the y axis. Since the line is on the Y axis initially, there is essentially no change.
Now you do the x axis rotation 45 degrees away from you.
You should now be picturing a line that is straight up and down where the top is further away from you than the bottom.
What I believe you are trying to do is to rotate the line from the position it is currently in to the direction you specify, which can get a bit messy. Trying to do this with 3 separate axis rotations is not going to work and results in something affectionately called gimbal lock.
There are a number of possible solutions, but I will present one for you. Store the view rotations in a matrix rather than as separate angle rotations. Then when you apply a new rotation, PRE multiply the new rotation to the current view matrix. Then in your code you would do a glLoadMatrix() instead of 3 discrete glRotations.
Here’s an example to try and illustrate what I mean. Assume you are storing your view matrix in a matrix called M. And you want to do the following rotations in this order.
- Rotate around the X axis 45 degrees.
(Equivalent to glRotatef(45, 1, 0, 0))
- Rotate around the Y axis 45 degrees.
(Equivalent to glRotatef(45, 0, 1, 0))
- Rotate around the Z axis -30 degrees.
(Equivalent to glRotatef(-30, 0, 0, 1))
Initially set your matrix M to the identity matrix, which we will call I.
M = I
Next, determine the matrix R1 which represents rotation #1. After you calculate matrix R1 do this
M = R1 * M (Now M == R1 * I)
Next Determine the matrix R2 which represents rotation #2. Then you now have
M = R2 * M (Now M == R2 * R1 * I)
Finally determine the matrix R3 which represents rotation #3.
M = R3 * M (Now M == R3 * R2 * R1 * I)
Note: Multiplying a matrix by I gives you that same matrix so you essentially have R3 * R2 * R1, which should give you the results you expect.
So basically what you now have is equivalent to
glRotatef(-30, 0, 0, 1);
glRotatef(45, 0, 1, 0);
glRotatef(45, 1, 0, 0);
The nice thing about this is you can apply as many rotations, and rotations in any order that you want and it should always give you the result you expect. Basically in code you wouldn’t create separate R1, R2, R3 matrices but would do something like,
R = GetNewRotationMatrix();
M = R * M;
Now… if you want to know how to multiply matrices and how to determine rotational matrices, you can probably find several good resources. The formula for rotational matrices are described pretty well in one of the appendices of the Red book. There are probably many resources that describe how to multiply matrices together available on the web, and there are even some code snippets todo that on the forum here somewhere.