GL_PROJECTION and GL_MODELVIEW

来源:互联网 发布:网络推广运营 编辑:程序博客网 时间:2024/04/30 03:15
 

Cameras are not the right way to think about OpenGL

Sigh, the tales of an old programmer. I'm teaching myself 3d graphics.My bag of 2d tricks has been used up, 3d has been around for almost 10years in the mainstream, and it's time to move on.

To learn, I set out to make a little 3d representation of themandelbrot set. I thought I could just whip that baby out in no time.But, as it turned out, I can't. I had to overcome some basic hurdleswith Opengl.

A few things went through my head.

A lot of OpenGL tutorials talk about cameras, and yet, OpenGL doesn'thave cameras. Instead, you get a bevy of matrixes and glMatrixModes.Computer science is full of horrific analogies, and I really think that"camera" metaphor people use to describe OpenGL is one of them. I askmyself, in my best Battlestar Galactica parlance, "what the frak goingon!!!!"

As I was smashing my keyboard with my fist, causing my shepherd to hideunder the bed, two things dawned on me. First is, thank God Logitechkeyboards are indestructible. Second, all these matrixes do is movepixels around. There's nothing magic going on. The camera is a lie.

OpenGL is about a set of vertices, or points, in a 3d space. You drawthem into 3d coordinates using any of various primitives, such asTRIANGLE_FAN, TRIANGLE_LIST, etc. OpenGL marches through each of thesepoints and "transforms" them into a set of coordinates that lookthree-dish on screen.

Thus, when you specify various transformations, you are tellingOpenGL how to move your points around. With that perspective, you canunderstand GL_PROJECTION and GL_MODELVIEW this way:

GL_PROJECTION is a matrix transformation that is applied to every point that comes after it, always. GL_MODELVIEW is a matrix transformation that is applied to every point in a particular model.There's a hierarchy of transformations, with GL_PROJECTION at the top,and a set of GL_MODEL branches. You set the matrix transformation with glMatrixMode. By default, the matrix mode is GL_MODELVIEW, which assumes everything you draw will be in one 3d space.

Let's talk about GL_PROJECTION first.



 glMatrixMode(GL_PROJECTION);

 glLoadIdentity();

 glOrtho(-1, 1, -1, 1, -1.0, 1.0);


It's all about matrix math. I basically use the glOrtho to apply someperspective to what I'm doing. Everything in 3d graphics is aboutmatrix math.

Once you set the matrix mode, each subsequent operation is applied to that particular matrix mode and below it.They almost should have called it matrix levels and not matrix modes. Iload identity first to give it a place to start because most of the glmatrix commands work by multiplying themselves against whatever thematrix was for that mode before. For example:



 glMatrixMode(GL_PROJECTION);

 glLoadIdentity();

 glOrtho(-1, 1, -1, 1, -1.0, 1.0);

 glTranslate( 100, 100, 100 );

 glRotateF( 45, 1, 0, 0 );


Really means: GL_PROJECTION_MATRIX = IDENTITY * ORTHOGRAPHIC_MATRIX * TRANSLATION_MATRIX * ROTATION_MATRIX.

The order of these calls seems extremely important.

So what's MODEL_VIEW all about? GL_PROJECTION transformations arealways applied, so, we can use it to define a camera, set theperspective, among other things. What model view lets us to do is setup different measuring systems for vertices of different things. Iselect model view by calling



 glMatrixMode(GL_MODELVIEW);


Then I can apply stuff to the model:



 glLoadIdentity();

 glTranslate( modelx, modely, modelz );


To move it in space somewhere, for example.

GL_MODELVIEW is about having different objects being pushed into a"world space". The biggest reason is that I can draw each object usingcoordinates based around 0, merely specifying the translations orrotations or scaling based on how I want my model to go.

To really appreciate this, let's consider a simple example. I want todraw a world that has two things in it, a car and a battleship. To dothis, I might:



 glMatrixMode(GL_PROJECTION);

 glLoadIdentity();

 glOrtho(-1, 1, -1, 1, -1.0, 1.0);

 glTranslate( camerax, cameray, cameraz );



 glMatrixMode(GL_MODELVIEW);

 glLoadIdentity();

 glTranslate( carx, cary, carz );

 // draw car here, by specifying various gl vertices



 glLoadIdentity();

 glTranslate( battleshipx, battleshipy, battleshipz );

 // draw battleship here, by specifying various gl vertices



In that example, each car vertice I specify is being altered as follows:

car_vertice_matrix = projection_ortho_matrix * projection_translation * car_translation_matrix

and, for the battleship

battleship_vertice_matrix = projection_ortho_matrix * projection_translation * battleship_translation_matrix

So, to actually draw the stuff, OpenGl takes the projection matrixmultiplied by the current model matrix and uses that to translate eachspecific vertice within that model. Wow, 3d graphics is nothard. Hell I should go write my own OpenGL. You know, if there wasn'tthe issue of hardware accelaration, it would be tempting. Well, I stillgot a ways to go.

I'll have my little multithreaded 3d demo up shortly. There's actuallya bug in my thread pool that I will be posting a fix for as well.

I remember reading somewhere in a 3d graphics book that theglProjection matrix should not be used to fake a camera. I think thatwas an evil thing to remember. But, wow, it just seems like it would besuch a good spot to do it. What I have to try is something like this:



 glMatrixMode(GL_PROJECTION);

 glLoadIdentity();

 glOrtho(-1, 1, -1, 1, -1.0, 1.0);

 glTranslate( camerax, cameray, cameraz );

 glRotateF( cameraanglex, 1, 0, 0 );


In that case, the glTranslate would be where the camera is, and glRotateF, where it is facing.

Talking about cameras

Now, I know I said that the camera is a lie. It is, because itspretty obvious that we're really moving the entire world to get ourpicture, and not some "camera".

原文地址:http://www.storkyak.com/2005/11/opengl-glprojection-and-glmodelview.html

原创粉丝点击