Ok, finally I understand your real problem
Sorry for the confusion…
To solve your problem, you have to save the current rotation directly, for example as quaternion.
Quaternions are really easy to use. It’s just a bunch of formulas. Here are some functions:
float QuatX = 0, QuatY = 0, QuatZ = 0, QuatW = 1;
void multQuat(float x, float y, float z, float w)
{
float W = QuatW * w - QuatX * x - QuatY * y - QuatZ * z;
float X = QuatX * w + QuatW * x + QuatZ * y - QuatY * z;
float Y = QuatY * w - QuatZ * x + QuatW * y + QuatX * z;
float Z = QuatZ * w + QuatY * x - QuatX * y + QuatW * z;
QuatW = W; QuatX = X; QuatY = Y; QuatZ = Z;
}
void normalizeQuat()
{
float len = QuatX*QuatX + QuatY*QuatY + QuatZ*QuatZ + QuatW*QuatW;
if (len != 1.0) {
len = sqrt(len);
QuatX /= len;
QuatY /= len;
QuatZ /= len;
QuatW /= len;
}
}
void quatToMatrix(float mat[16])
{
float X = QuatX, Y = QuatY, Z = QuatZ, W = QuatW;
float xx, xy, xz, xw, yy, yz, yw, zz, zw;
xx = X * X;
xy = X * Y;
xz = X * Z;
xw = X * W;
yy = Y * Y;
yz = Y * Z;
yw = Y * W;
zz = Z * Z;
zw = Z * W;
mat[0] = 1 - 2 * ( yy + zz );
mat[1] = 2 * ( xy - zw );
mat[2] = 2 * ( xz + yw );
mat[4] = 2 * ( xy + zw );
mat[5] = 1 - 2 * ( xx + zz );
mat[6] = 2 * ( yz - xw );
mat[8] = 2 * ( xz - yw );
mat[9] = 2 * ( yz + xw );
mat[10] = 1 - 2 * ( xx + yy );
mat[3] = mat[7] = mat[11] = mat[12] = mat[13] = mat[14] = 0;
mat[15] = 1;
}
QuatX, QuatY, QuatZ, QuatW are the variables storing the current rotation in the form of a quaternion.
multQuat multiplies another quaternion onto it. If you want to rotate your object phi radians around the axis (x,y,z), you have to call:
multQuat(xsin(phi/2), ysin(phi/2), z*sin(phi/2), cos(phi/2));
normalizeQuat normalizes the quaternion. Normally it should neven happen that the quaternion gets denormalized, but it will happen because of rounding errors. quatToMatrix converts the quaternion to a matrix that you can load with glMultMatrixf.
So your transformation code should look like this:
glTranslatef (0.0, 0.0, 0.0);
normalizeQuat();
quatToMatrix(rot);
glMultMatrixf(rot);
glScalef (1.0, 2.0, 1.0);
(note I moved the scale after the rotation, too)
And your keyboard function should look like this:
case GLUT_KEY_UP : multQuat(sin(.005), 0, 0, cos(.5));break;
case GLUT_KEY_DOWN : multQuat(sin(-.005), 0, 0, cos(-.005));break;
case GLUT_KEY_LEFT : multQuat(0, 0, sin(-.005), cos(-.005));break;
case GLUT_KEY_RIGHT : multQuat(0, 0, sin(.005), cos(.005));break;
(don’t forget the sin and cos functions take radians as argument)