Understanding glOrtho

I’m a new openGL programmer trying to understand why certain things are happening with my glOrtho call, and what is actually happening when I call certain things. Specifically, why my GL_LINES show up sometimes and don’t show up others.

In my init() function for GL, I set up my viewport to be 640x480, disable lighting, and a few other things. In my paint() function, I do a glOrtho call:

glOrtho(0.0f, 640.0f, 0.0f, 480.0f, 0.0f, 1.0f);

Here’s my question: if I do a glBegin(GL_LINES) and draw lines BEFORE my projection, I have to draw them on the ([0,1],[0,1]) scale, e.g.


glColor4f(1.0, 0.0, 0.0, 1.0);
  glLineWidth(5.0);
  glBegin( GL_LINES );
  glVertex2f(0, 0);
  glVertex2f(0, 1);
  glEnd();

BUT, if I call it AFTER I do my ortho projection, I draw them on the full ([0,640],[0,480]) scale, e.g.


 glColor4f(1.0, 0.0, 0.0, 1.0);
  glLineWidth(5.0);
  glBegin( GL_LINES );
  glVertex2f(100, 100);
  glVertex2f(200, 200);
  glEnd();

My question is: I thought that everything was relational, so that if I drew a 2D line from 0,0 to 100,100, it would be drawn in some model frame, so that when I did my glOrtho that set my projection to 640x480, it would appear going from 0,0 to 100,100. However, this is not the case.

Can anybody help me understand why/how this is working?

Thank you!

I don’t know what you mean by “relational”, but OpenGL doesn’t know what functions you will call. It only knows what you have called. When you render something, OpenGL uses the state that you have currently set to render with. Any future changes do not have any effect on the rendering up to that point.

And this makes sense. How could you do things like use different textures for different objects if OpenGL knew you were going to change textures? A texture change is no different than a change of perspective matrix: they’re both state changes.

Thanks for your reply. I’m trying to understand exactly how this works: I understand that openGL doesn’t know what functions I will call, but, for instance, I can use the gluLookAt to set my camera, and if I do a bunch of glVertex3f calls, it will look the same if I do the gluLookAt before vs after the glVertex3f (or am I wrong in saying this?)

This is how I envision it in my head:


_______________
|              |
|              |
|----          |
|   |          |
----------------

If that lower-left corner is the area I specify with glOrtho (suppose it’s 2x2, so from 0,0 to 0,2 to 2,2 to 2,0) and my entire space is 10x10, if I draw a line from 0,0 to 2,2, I would think that it would be represented in this 2D space the same no matter if I call glOrtho before I draw the line, or after.

The opposite (in my case) should also be true.(?) So, if my camera is originally looking at 0,0 and has a viewable size of 1x1, if I draw a line from 0,0 to 100,100, I should see the entire line, whether I call glOrtho before I draw the line or afterwards. My visual example:


_______________
|   /          |
|  /           |
|-/-|          |
|/  |          |
----------------

Imagine the small box being what my screen is displaying originally, and the large box being my display after the glOrtho call. This line should look the same if I call glOrtho before or after I draw it. This is not the case.

Obviously I’m wrong, but I don’t understand why.

I can use the gluLookAt to set my camera, and if I do a bunch of glVertex3f calls, it will look the same if I do the gluLookAt before vs after the glVertex3f (or am I wrong in saying this?)

No it doesn’t. If it does, then it is only because it appears to be the same. And then likely because of the parameters you gave gluLookAt.

If that lower-left corner is the area I specify with glOrtho (suppose it’s 2x2, so from 0,0 to 0,2 to 2,2 to 2,0) and my entire space is 10x10, if I draw a line from 0,0 to 2,2, I would think that it would be represented in this 2D space the same no matter if I call glOrtho before I draw the line, or after.

The reason you have to pass glOrtho the size of your display is because you don’t have to use the size of your display. glOrtho is not a “draw in pixel coordinates” function. It sets up an orthographic projection. One of that kind of projection can “draw in pixel coordinates”, but that’s not the only thing it is used for.

The identity orthographic transform states that the entire viewport is a region of space on the range [-1, 1] in all 3 directions. Your glOrtho call is a way of mapping the space you give the function into the [-1, 1] space.

Ah, that makes more sense. So if I do a glOrtho call before drawing my data, it will set up the transform to change what I’m drawing into the [-1,1] space, and thus if I draw in the 640x480 space it will be transformed into this view?

Also, this may be outside of the original question, but why then do I need to specify a viewport, if the projection describes the transformation from [x,y] to [-1, 1] space? What’s the difference between using it to clip this space and using a different glOrtho projection?

Thanks again for your help–this is much clearer now!

but why then do I need to specify a viewport, if the projection describes the transformation from [x,y] to [-1, 1] space?

Becuase the next stage of the transformation goes from clip space to Normalised Device Coordinate (NDC) space. The viewport dimensions specify how that mapping takes place.