Jump to content
  • Advertisement
Sign in to follow this  
Darragh

OpenGL Matrices and the pipeline

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

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, Well I'm after making some decent progress since I first took up learning OpenGL a few months ago. I can now use vertex arrays, vertex buffer objects, indexed geometry, texture mapping, fog, mipmapping, vertex/pixel shaders etc. etc.. However I feel as if I've skipped some of the basics, which I should really know inside out at this stage... My first question relates to the two matrices: the 'modelview' matrix and 'projection matrix'. In my 3D engine I only use the projection matrix to translate and rotate the map and all the game objects. This works fine, however I am unsure as why there is a second matrix (modelview) and what its purpose is. I have looked for some good explanations on the differences between the two matrices, but couldn't find anything decent to help explain them. So why do we need two transformation matrices ? What typical scenarios would you use each of the two matrices? Is the modelview matrix a transformation matrix used for transformations local to each object in a game (eg: monster / map item) and the projection matrix used for transforming the world (entire map geometry) ? Or is the modelview matrix simply an additional matrix which can recalled and used if needed ? Why use it? The second question regards the pipeline and viewing transforms. When I render each frame I first setup the projection matrix / rotations etc and then draw the map. I then push this matrix to save its status. The matrix is then transformed again by whatever position/rotation that each monster has, and the monster is then drawn. After drawing each monster I then pop the matrix to reload the previously saved state. Now.. If i remove the pop matrix line the entire world gets translated by whatever I translate the monster by. This brings me to some alarming conclusions.. When I am translating the monster, am I really translating everything else too? I thought once something was sent down the pipeline it stays in whatever position it was when it was first sent? Does this mean everytime I move a monster a whole bunch of unnecessary calculations are being peformed on the rest of the map? If so, how can I avoid such calculations? Thanks in advance for your help. I know this post is a bit of a pain [smile] but these are things I really need to get clear in my head before I go any further.

Share this post


Link to post
Share on other sites
Advertisement
Hi,

Whether you know it or not, you are using the modelview matrix. Search through your code - somewhere I'm sure you'll find the line glMatrixMode(GL_MODELVIEW).

Ok, so on to what the two matrices do. The modelview matrix performs an affine transformation; more practically, it sets the position and orientation of your camera and of objects in the scene in 3d space, and applies other linear transformations such as scale, reflection, and shear.

The projection matrix performs a different function: it converts the 3d world into 2d information that can be displayed on the screen. Variables include field of view, aspect ratio, and near and far clipping planes.

I'm not exactly sure how OpenGL implements this internally, but in any case you don't have to worry about doing 'too much transformation'. That's why matrix concatenation is useful; no matter how many transformations you combine, it still comes down to a single matrix-vector multiplication per vertex.

Share this post


Link to post
Share on other sites
projection matirx for the frustum and ortho things.
modelview matrix for translating/rotatting/scaling for the objects
texture matrix same as modelview matrix but for the textures GL_TEXTURE_1D/2D/3D
for more details read the red book

Share this post


Link to post
Share on other sites
mmm i am not sure about your second question but every push you should pop it or you'll face problem, because the matrix stack has a limit and every loop in your main function you'll push till it gets full .
maybe i am wrong about this ..
bye

Share this post


Link to post
Share on other sites
Ah yes- now it makes more sense.. I can see the relationship between the two more clearly now. Good reply..

Quote:
Original post by jyk
Whether you know it or not, you are using the modelview matrix. Search through your code - somewhere I'm sure you'll find the line glMatrixMode(GL_MODELVIEW).


Nope. All throughout my code the matrix used is GL_PROJECTION - even in my vertex shaders. I can see how it can be used to achieve the same effect though, since ultimately it controls how points are projected from world space onto the screen.

Ok, so that's one issue cleared up I think. Any more ideas on the other question?

Thanks again for your post.

Share this post


Link to post
Share on other sites
The answer to the second question is that, for rigid meshes, every vertex is transformed exactly once, with whatever matrix was loaded at the time the draw function is called. Basically, when you call glBegin() the driver makes a copy of the matrix at the top of the stack and sends that along with the vertices you specify, and whatever happens afterwards it preserves the illusion that the vertices are completely transformed & rendered with the current GL state before you go and muck with it.

So, the transformations are just numerical manipulations on the matrix only, and don't actually *move* anything until you draw something. It looks like a little crash-course in linear algebra would help you out a lot in understanding these concepts.

Tom

Share this post


Link to post
Share on other sites
Also, it is perfectly plausible to use the projection matrix only, as the two matrices are always concatenated prior to transformation. They are only separate because it can be handy to manipulate one and not the other. For instance:

You have a Projection matrix with the following transforms:
1. Frustum transform
2. Viewing (camera) transform

And a Model matrix with the following transforms:
3. World transform
4. Model transform
5. Sub-model transform (objects moving relative to parent objects, etc)

This is more or less the same as one Projection matrix with transforms 1-5, but say you wanted to draw mountains twice, once regularly and once reflected in water. To do the reflection, you want to flip the camera.

If you're using one matrix, you need to pop 5, 4, 3, and 2, specify a new camera transform, and then specify 3-5 again.

If you're using two matrices, you just pop 2 off the Projection and specify your new camera, and the Model matrix stays the same.

Tom

Share this post


Link to post
Share on other sites
Quote:
Original post by ParadigmShift
The answer to the second question is that, for rigid meshes, every vertex is transformed exactly once, with whatever matrix was loaded at the time the draw function is called. Basically, when you call glBegin() the driver makes a copy of the matrix at the top of the stack and sends that along with the vertices you specify, and whatever happens afterwards it preserves the illusion that the vertices are completely transformed & rendered with the current GL state before you go and muck with it.


Excellent. That was just what I needed to know.. At least I can be sure now that everything is being transformed once, and once only.

Quote:
Original post by ParadigmShift
So, the transformations are just numerical manipulations on the matrix only, and don't actually *move* anything until you draw something. It looks like a little crash-course in linear algebra would help you out a lot in understanding these concepts.
Tom


I do a lot of stuff on algebra and matrices in college- just had my final year maths exam today in fact! [smile] Its not that I don't understand the maths involved in the rotations, I'm just unsure exactly what the hell OpenGL / display drivers are doing underneath the API to my geometry. However, you're post has helped clear that up so I am thankful for that.

Well thats great guys, I feel much more enlightened now! [wink] You have been most helpful so I think extra ratings are in order.

Cheers
-Darragh

Share this post


Link to post
Share on other sites
Hm, guess I was wrong about having to use the modelview matrix :-| However, see here (section 8.030) and here for discussion of the way OpenGL intends for the matrices to be used and the reasons for following these guidelines.

Share this post


Link to post
Share on other sites
Thanks for that. Those two articles are very informative- i'll keep them for future reference.

You've also managed to solve another long outstanding problem i had...

In the article about 'GL_PROJECTION' abuse (of which I am guilty [smile]), it also mentions the problems of using the projection matrix with fog. Now cast you're eye back to the thread which I started on that very subject.. I was unable to solve the problem (until now) and subsequently had to resort to learning GLSL and using pixel shaders in order to do my fogging. If only I had known about this back then!... [smile]

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!