Fit 3d model inside a window
I want to display models of different sizes fitted into a view, so that the whole model is visible inside the screen.
What is the best way to do it? I tried scaling (using glScale) the model using this formulascaleFactor = ( screenSize / (maxModelSize * constant) )
Where size is height or width, depending on what 开发者_如何学编程is bigger.
Constant is1 / (length of one screen pixel in OpenGL units)
There are two problems with this:
1. After doing some transformations, I want to be able to return to this initial scale (model is scaled to fit window) using Identity. Currently calling identity will bring the model to its original dimensions (before the "fixing" scale).
2. The "constant" is something I got by trial and error, I feels wrong method to me. I also suspect that it is not a constant at all, and depends on screen resolution and god knows what else.Section 8.070:
The following is from a posting by Dave Shreiner on setting up a basic viewing system:
First, compute a bounding sphere for all objects in your scene. This should provide you with two bits of information: the center of the sphere (let ( c.x, c.y, c.z ) be that point) and its diameter (call it "diam").
Next, choose a value for the zNear clipping plane. General guidelines are to choose something larger than, but close to 1.0. So, let's say you set
zNear = 1.0; zFar = zNear + diam;
Structure your matrix calls in this order (for an Orthographic projection):
GLdouble left = c.x - diam; GLdouble right = c.x + diam; GLdouble bottom c.y - diam; GLdouble top = c.y + diam; glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(left, right, bottom, top, zNear, zFar); glMatrixMode(GL_MODELVIEW); glLoadIdentity();
This approach should center your objects in the middle of the window and stretch them to fit (i.e., its assuming that you're using a window with aspect ratio = 1.0). If your window isn't square, compute left, right, bottom, and top, as above, and put in the following logic before the call to glOrtho():
GLdouble aspect = (GLdouble) windowWidth / windowHeight; if ( aspect < 1.0 ) { // window taller than wide bottom /= aspect; top /= aspect; } else { left *= aspect; right *= aspect; }
The above code should position the objects in your scene appropriately. If you intend to manipulate (i.e. rotate, etc.), you need to add a viewing transform to it.
A typical viewing transform will go on the ModelView matrix and might look like this:
GluLookAt (0., 0., 2.*diam, c.x, c.y, c.z, 0.0, 1.0, 0.0);
精彩评论