Explain viewport, object, glOrtho relationship

I’ve been thrashing at this for days and am obviously misunderstanding something extremely basic at the heart of OpenGL. Hopefully someone here can help.

I’m trying to write a simple OpenGL gadget that displays user options on the sides of a rotating cube. Doesn’t get much more trivial than that, right? And I can make it work, more or less, but getting the cube to be the size I want requires tweaking of glOrtho params, the results of which don’t seem to make much sense.

The cube is drawn using the traditional beginner co-ordinate system: center at (0,0,0), which each of the corners 1 unit away, so that each side of the cube is 2 units long.

Say I want to display this cube in a viewport of 500 by 500 pixels, where the cube precisely fills the viewport (let’s not worry about the fact that the cube’s sides will extend off the edges of the viewport when it’s rotated).

By tedious experimentation, I’ve determined that the proper values for the ortho X and Y params are about 0.37. The value of the Z params in the glortho call don’t seem to matter, except if the absolute values drop below 10, the cube vanishes.

glViewport( 0, 0, 500, 500 );
glMatrixMode( GL_PROJECTION );
glOrtho( -0.37, +0.37, +0.37, -0.37, -10, 10 );
glMatrixMode( GL_MODELVIEW );

I have two basic questions:

  1. How does 0.37 make sense to scale the 2-unit wide cube to fill a 500 pixel square viewport? What conceivable calculation could I make to find this magic number automatically?

  2. Some of the images I want to put on the sides of the cube are detailed and I’d prefer to render them at their native size with no scaling to screw things up. The idea was that if the image was (say) 500 by 500 pixels, I’d simply create a viewport that size and make sure the cube precisely fit it. Of course, in the real app, I have to allow some slop on the sides to give the cube room to rotate, so I’d need to figure some way to scale the cube so that the side facing the user was precisely 500 by 500 pixels, regardless of the viewport size.

I suspect once I know the answer to #1, I’ll know the answer to #2. I’ve seen many and varied explanations of what glOrtho() actually does, ranging from a simplistic “defines the clipping planes for each axis” to the more complex matrix multiplication explanation. No explanation I’ve seen describes how the settings actually affect your model; I know from experimentation that shrinking the absolute value of the numbers makes the model larger in the X or Y dimensions, and making them larger shrinks the model, which kind of makes sense if you consider the call to be defining the co-ordinate system the model lives in.

But 0.37? Sigh. Back when I was writing MacPaint 2, the world was a simpler place, and my major concern was keeping tight 68K machine code loops for performance’ sake.

0.37? that’s pretty weird… can we have a look at the rest of the code?


OK, it’s official: I’m a moron. Time to stop coding and start gardening…

When I first started working on this code, I though I’d have to scale the images separately to make them fit the cube faces. It was one of the first things I did, and I promptly forgot about it.

That’s what was screwing things up. Remove this code, and if you want an X by Y image, you make the viewport that size and set your ortho factors to 1.0. Works great…