What is the proper parameter for glOrtho to make a Top View?

2.7k views Asked by At

I try to learn OpenGL by creating some sort of 3D Modeler application using Visual C++. The screen will be divied into three window : perspective, front and top (isometric). And I almost give up try to implement the top view. This is my current top view code :


glOrtho(-1,1,-1,1,1,3.5f);
gluLookAt(
  0,2,0,//eye
  0,0,0,//center
  0,0,-1);//up 

But if I move the object to to the far Z, it will certainly disappear. How can I make the top view able to look at all object in the scene???

How can I compute the required parameter fo glOrtho and glLookAt?

3

There are 3 answers

1
tibur On BEST ANSWER

You need to adapt the z far value according to your geometry. You should compute a bounding sphere or bounding box of your model, find the Z range and adapt your camera according to it.

2
datenwolf On

You should not use gluLookAt (note the 'u' in 'glu', gluLookAt is not a part of OpenGL), but set the modelview matrices directly. First you must define what's up, far and sideways. Most people using OpenGL prefer a right handed coordinate system (RHCS). The first base is X, the second Y and the third Z. In a RHCS X is sideways (to the right), Y is into the far and Z is upwards. The default projection of OpenGL is, as if the camera looks down the Z axis in negative direction, i.e. the look goes down.

So we can say the matrix

1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1

is looking down. Looking into the far you've to yaw up. The X remains the same, but Y and Z are swapped. The matrix corresponding to this would be

1 0 0 0
0 0 1 0
0 1 0 0
0 0 0 1

And looking sideways the global Y maps to the view X, global X maps to Z and global Z maps to Y resulting in

0 1 0 0
0 0 1 0
1 0 0 0
0 0 0 1

Now you probably want to pan and zoom that view. You can do this either using glScale and glTranslate, or directly in the matrix.

s 0 0 pan.x
0 s 0 pan.y
0 0 s pan.z
0 0 0 1

s 0 0 pan.x
0 0 s pan.y
0 s 0 pan.z
0 0 0 1

0 s 0 pan.x
0 0 s pan.y
s 0 0 pan.z
0 0 0 1

Now, panning in the Z direction makes little sense in an orthographic projection. So you can leave pan.z zero.

Now lets address your depth clipping problem. One of the nice properties of othographic projection is, that the depth clip-range will be mapped linearily into depth buffer, whereas in perspective projection it follows a 1/x law. Also mixed signs for the far and near distance are perfectly allowed and there is also no constraint that |near| < |far|. So for each of your views all you've to do is determine the minimum and maximum positions of all objects' transformed vertices and use those to set the apropriate clip values in each view's projection. A good approximation, so that you don't have to iterate over each and every vertex is using the objects bounding spheres and positions (add/subract the bounding sphere radius to it's position) to get min/max ranges.

0
Roger Leigh On

glm (GL mathematics, http://glm.g-truc.net/) is probably what datenwolf was looking for at the time the answer was written. This provides the facilities of GLU but intended to work with modern GL. For example, there is a glm::ortho function. For example, this is glm used to compute and set the model-view-projection matrix for a vertex shader uniform using an orthographic view, with GLM:

glm::mat4 model = ...
glm::mat4 view = ...

glm::mat4 projection = glm::ortho(-xrange, xrange,
                                  -yrange, yrange,
                                  -10.0f, 10.0f);

glm::mat4 mvp = projection * view * model;

glUniformMatrix4fv(uniform_mvp, 1, GL_FALSE, glm::value_ptr(mvp));