Archived

This topic is now archived and is closed to further replies.

mits

Simple Transform question

Recommended Posts

According to "OpenGL Programming Guide" , transformations are applied with inverse order to the vertices, so if I write : glLoadIdentity(); glTranslatef(1.0f,0.0f,0.0f); glRotatef(5.0f,1.0f,0.0f,0.0f); glBegin(); ........... glEnd(); the object will first be rotated and then translated.Correct me if I''m wrong. So, I have loaded to memory the points of an .md2 model.The model has three vectors , the view vector, the up vector and the right vector,similarly to a camera model.When I render the model I do this: void RenderModel() { glPushMatrix(); float m[16]; m[0]=view.x; m[1]=view.y; m[2]=view.z; m[3]=0.0f; m[4]=up.x; m[5]=up.y; m[6]=up.z; m[7]=0.0f; m[8]=right.x; m[9]=right.y; m[10]=right.z; m[11]=0.0f; m[12]=0.0f; m[13]=0.0f; m[14]=0.0f; m[15]=1.0f; glMultMatrixf(m); glBegin(); ........ glEnd(); glPopMatrix(); } Assume that the three vectors are orthonormal so this procedure orients the model however I like.So far everything works well and my job is done.But,if I put glLoadIdentity() after glPushMatrix() nothing is rendered.Also if I use glLoadMatrix(m) in place of glMultMatrix(m) nothing is rendered either. Why? My work is done but I want to understand why the above commands don''t work since they seem right. Isn''t it right to use glLoadIdentity() after glPushMatrix()? Assume that the GL_MODELVIEW matrix is selected with glMatrixMod(GL_MODELVIEW)and that the only thing I render is this model.Any answer would be useful. Thanks in advance.

Share this post


Link to post
Share on other sites
That''s right if there is no camera transform in the MODELVIEW matrix. Basically, if the MODELVIEW matrix is identity before your glLoadIdentity() call, then everything is fine, otherwise you''re stomping the camera transform. Is there a camera transform (gluLookat or similar)?

Share this post


Link to post
Share on other sites
quote:
Original post by mits
According to "OpenGL Programming Guide" , transformations are applied with inverse order to the vertices...


This isn''t quite true. If you think about all your transformations affecting a fixed coordinate system then the effect is as if OpenGL had applied all transformations in the inverse order. In reality OpenGL uses a local coordinate system, so transformations are applied in order. For a better explanation of this see Chapter 3 of the Red Book (especially the section headed ''Viewing and Modeling Transformations'').

However, this only applies to multiplicative transformations (such as Translate, Rotate and Scale). glLoadIdentity replaces the modelview matrix, so calling it will wipe out all multiplicative transforms specified prior to it.

Enigma

Share this post


Link to post
Share on other sites
Ok, I understand what happens with glLoadIdentity(), since before the RenderModel(), I use glLookAt(). But what about glLoadMatrix(m)? Does it stomping the camera transform too? Isn''t the glLoadMatrix() transform applied first to the vertices and then the glLookAt()? I''m a little confused now.

Share this post


Link to post
Share on other sites
I thought I had understood the way OpenGL treats matrices but I am confused now.Suppose I think that I have a fixed coordinate system.Then OpenGL applies tranformations in inverse order. If I do this:

void DrawGL()
{
glLoadIdentity();
glLookAt(.....);
RenderModel();
}

which is the order of the transformations? Please someone answer this question!In redbook it says that viewing transformations (e.g. glLookAt()) must be first so modelling transormations will be applied to vertices (that''s because of the inverse order). What happens to the above example? (RenderModel() is explained at the first message). Thanks in advance.

Share this post


Link to post
Share on other sites
OK, I think you don''t quite understand the matrix maths here.

glLoadIdentity() initialises the current matrix to the identity :
1  0  0  0
0 1 0 0
0 0 1 0
0 0 0 1


glTranslate, glRotate, glScale and gluLookAt multiply the current matrix by a new matrix:
current matrix *= new matrix.

In your code you do:
glLoadIdentity();
gluLookAt(...);
glPushMatrix();
glMultMatrixf(...);
glPopMatrix()


gluLookAt just takes the values you give it, generates a matrix and multiplies the current matrix by that matrix. Lets call the matrix generated by gluLookAt look and the matrix you pass to glMultMatrixf mult .

First you call glLoadIdentity, which initialises the modelview matrix to the identity . Next you call gluLookAt, which multiplies the modelview matrix by look . Hopefully you know that identity * anything = anything * identity = anything. So, after the gluLookAt call the modelview matrix is look .

Now you call pushMatrix(), which copies the current modelview matrix and adds this copy to the top of the modelview matrix stack, so the current modelview matrix is still look , but there are two copies on the stack.

Next you call glMultMatrixf, which multiplies the modelview matrix by mult . Now your modelview matrix is look * mult .

Every time you call glVertex, the vertex is multiplied by the modelview matrix. That is, for every vertex the camera space coordinates of the vertex are calculated as modelview matrix * vertex position. In this example this is (look * mult ) * vertex position.

Matrix multiplication is associative, so (look * mult ) * vertex position = look * (mult * vertex position). This explains why it appears as if the glMultMatrixf transformation occurs before the gluLookAt transformation.

So now, what happens if you add a glLoadIdentity call after the glPushMatrix call. Well, everything is exactly the same upto the glPushMatrix call (no surprise there). However, immediately after this call you hit glLoadIdentity, which reinitialises the modelview matrix to identity . Now the modelview matrix stack contains two matrices. The bottom matrix (which you can''t get at and isn''t used for anything until you pop it back to the top of the stack) equals look but the top matrix (the current modelview matrix) equals identity .

Next you call glMultMatrixf, making the current modelview matrix equal to mult . So now any vertices you specify are multiplied by mult but not my look .

Hopefully that will clear things up for you. Sorry if I underestimated your understanding of this - I just tried to be as clear as possible.

Enigma

Share this post


Link to post
Share on other sites