# instead of glRotatef build a matrix

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

## Recommended Posts

I'm not very skilled with math, but i'm wondering what does glRotatef do internally?

I have some legacy code which does some math i don't really understand and sends values to glRotatef. I am implementing a physics engine to go with this legacy code and i need a 4x4 matrix instead of that output, i don't really understand how the rotation along a vector glrotatef thing works, but i just need a resulting matrix - which if i multiplied with glMultMatrixf instead of glrotatef would result in same working output.

Thanks.

##### Share on other sites

I'm not very skilled with math, but i'm wondering what does glRotatef do internally?

I have some legacy code which does some math i don't really understand and sends values to glRotatef. I am implementing a physics engine to go with this legacy code and i need a 4x4 matrix instead of that output, i don't really understand how the rotation along a vector glrotatef thing works, but i just need a resulting matrix - which if i multiplied with glMultMatrixf instead of glrotatef would result in same working output.

Thanks.

Try the Euler matrices for x,y,and z axes; glMultMatrixf(euler_y_mat_with_desired_angle); will get you spin around the y axis, and you can also multiply them together for multi-axis transforms taking care to avoid locks.

##### Share on other sites
If you need just a matrix, here it is:

 | x^2*(1-c)+c x*y*(1-c)-z*s x*z*(1-c)+y*s 0 | R = | y*x*(1-c)+z*s y^2*(1-c)+c y*z*(1-c)-x*s 0 | | x*z*(1-c)-y*s y*z*(1-c)+x*s z^2*(1-c)+c 0 | | 0 0 0 1 | 

[x, y, z] - a vector about which the rotation should be done

c - cos(alpha)

s - sin(alpha)

alpha - rotation angle

##### Share on other sites
May be of some use to you:
http://en.wikipedia.org/wiki/Rotation_matrix
Most are 3x3, just add 0, 0, 0, 1 column/row vectors in the 4th colum/row to get it 4x4.
The http://en.wikipedia.org/wiki/Rotation_matrix#General_rotations section shows you euler angles

##### Share on other sites
Ok thanks, based on that i wrote this function (sorry for pascal syntax):

 function CreateGlRotateMatrix(angle, x, y, z: single) : TMatrix; var axis: TVector3f; b, c, ac, s: single; begin result:= IdentityHmgMatrix; c:= cos(angle); s:= sin(angle); result[0,0] := (x*x) * (1-c)+c; result[1,0] := x*y * (1-c)-z*s; result[2,0] := x*z * (1-c)+y*s; result[0,1] := y*x * (1-c)+z*s; result[1,1] := (y*y) * (1-c)+c; result[2,1] := y*z * (1-c)-x*s; result[0,2] := x*z * (1-c)-y*s; result[1,2] := y*z * (1-c)+x*s; result[2,2] := (z*z) * (1-c)+c; end; 

The results aren't what it's supposed to be:

I replaced: glRotatef(Angle * 180 / Pi, Axis[0], Axis[1], Axis[2]);

With:

rotang:= CreateGlRotateMatrix( Angle * 180 / Pi, Axis[0], Axis[1], Axis[2]);
glMultMatrixf(@rotang[0,0]);

The results make a total mess when objects are rendered, none of rotations look correctly, did i get the matrix array addressing right? in delphi the matrix order are row-col based.

##### Share on other sites

[x, y, z] - a vector about which the rotation should be done

A normalized vector. I guess you knew that already, but just making sure everyone knows it as well .

##### Share on other sites

A normalized vector. I guess you knew that already, but just making sure everyone knows it as well .

Yes, I've forgotten to say that. glRotatef auto-normalizes that vector. In our code, we should take care of normalization.

Also, be aware that GL assumes column-major order of matrices. If normalization doesn't help alone, transpose your matrix.

##### Share on other sites
Ok, i tried normalizing the vector & transposing / not transposing but still no luck, here's new function i have:

 function CreateGlRotateMatrix(angle, x, y, z: single) : TMatrix; var axis: TVector3f; b, c, ac, s: single; invLen : Single; begin invLen:= RSqrt(x * x + y * y + z * z); x:= x * invLen; y:= y * invLen; z:= z * invLen; result:= IdentityHmgMatrix; c:= cos(angle); s:= sin(angle); result[0,0] := (x*x) * (1-c)+c; result[1,0] := x*y * (1-c)-z*s; result[2,0] := x*z * (1-c)+y*s; result[0,1] := y*x * (1-c)+z*s; result[1,1] := (y*y) * (1-c)+c; result[2,1] := y*z * (1-c)-x*s; result[0,2] := x*z * (1-c)-y*s; result[1,2] := y*z * (1-c)+x*s; result[2,2] := (z*z) * (1-c)+c; // vectorgeometry.TransposeMatrix(result); end; 

I can show some screenshots of the working (glrotatef) & non-working results (CreateGlRotateMatrix) if that would help in any way clear the situation on what's wrong with it.

##### Share on other sites

 c:= cos(angle); s:= sin(angle); 

The results aren't what it's supposed to be:

I replaced: glRotatef(Angle * 180 / Pi, Axis[0], Axis[1], Axis[2]);

With:

rotang:= CreateGlRotateMatrix( Angle * 180 / Pi, Axis[0], Axis[1], Axis[2]);
glMultMatrixf(@rotang[0,0]);

The results make a total mess when objects are rendered, none of rotations look correctly, did i get the matrix array addressing right? in delphi the matrix order are row-col based.

cos/sin take radians while glRotatef takes degrees. So you don't need the radians to degrees conversion (* 180 / PI) when calling your own function.

##### Share on other sites

The results aren't what it's supposed to be:
I replaced: glRotatef(Angle * 180 / Pi, Axis[0], Axis[1], Axis[2]);

With:
rotang:= CreateGlRotateMatrix( Angle * 180 / Pi, Axis[0], Axis[1], Axis[2]);

Hey, I just noticed the way you pass angles... glRotatef() takes angle in degrees not in radians!!!

Previous two lines are not identical, because the angles are not the same.

##### Share on other sites
Ok, thanks to everyone, here's the final working version:

 function CreateGlRotateMatrix(angle, x, y, z: single) : TMatrix; var axis: TVector3f; b, c, ac, s: single; invLen : Single; begin angle:= vectorgeometry.degtorad(angle); invLen:= RSqrt(x * x + y * y + z * z); x:= x * invLen; y:= y * invLen; z:= z * invLen; result:= IdentityHmgMatrix; c:= cos(angle); s:= sin(angle); result[0,0] := (x*x) * (1-c)+c; result[1,0] := x*y * (1-c)-z*s; result[2,0] := x*z * (1-c)+y*s; result[0,1] := y*x * (1-c)+z*s; result[1,1] := (y*y) * (1-c)+c; result[2,1] := y*z * (1-c)-x*s; result[0,2] := x*z * (1-c)-y*s; result[1,2] := y*z * (1-c)+x*s; result[2,2] := (z*z) * (1-c)+c; end; 

This finally matches the game's map files to build a proper matrix, it uses this with some "odd" quaternion conversion routine, which i couldn't reproduce with any other quaternion to matrix algorythm on the internet:

 // preprocess quarternion rotations X := rx; Y := ry; Z := rz; W := -rw; S := Sqrt(1.0 - W * W); // divide by zero if not (S = 0) then begin Axis[0] := X / S; Axis[1] := Y / S; Axis[2] := Z / S; Angle := 2 * geometry.ArcCos(W); if not (Angle = 0) then begin rotang:= CreateGlRotateMatrix( Angle * 180 / Pi, Axis[0], Axis[1], Axis[2]); glMultMatrixf(@rotang[0,0]); //glRotatef(Angle * 180 / Pi, Axis[0], Axis[1], Axis[2]); end; end; 

But this only works on game file quaternions. If i use this on the game's quaternions from the memory i get some strange results, i'll post that as another question if i can't figure it out soon :S Edited by Delfi

##### Share on other sites
Hidden

I'm not very skilled with math, but i'm wondering what does glRotatef do internally?

I have some legacy code which does some math i don't really understand and sends values to glRotatef. I am implementing a physics engine to go with this legacy code and i need a 4x4 matrix instead of that output, i don't really understand how the rotation along a vector glrotatef thing works, but i just need a resulting matrix - which if i multiplied with glMultMatrixf instead of glrotatef would result in same working output.

Thanks.

It multiplies the internal modelview matrix by a rotation matrix that was constructed with your parameters.
You can see how OpenGL constructs the rotation matrix in the respective page http://www.opengl.org/sdk/docs/man/xhtml/glRotate.xml