how to keep 3D object position/size the same visually while the viewport changes

I draw a 3D object and use glTranslate() to change the Z coord. and make it occupy a particular section of my window (the whole window in this case). When i change screen resolution, the window/viewport becomes bigger/smaller (in pixels) and my 3D object seems to be zoomed in/out and does not occupy the same space anymore (i am still using the same values in glTranslate()). How can i fix this ? Is there a math formula to be used ?

When you resize your window, are you telling openGL that you have change viewport with the glViewport command?

I actually change the screen resolution between invocations of my app so yes the viewport is reset each time with glViewport(). It seems like the size of the viewport changes how much of a scene one can see and that i need to change the Z value of glTranslate() or my zoom factor since i always want my object to occupy the whole window up to the edge. I don’t know how to compute this correctly for arbitrary viewport sizes…
May be there is a simple solution that i am missing.

Originally posted by nexusone:
When you resize your window, are you telling openGL that you have change viewport with the glViewport command?

Are also at resize are you changeing ortho or prespective view settings?

YES i use gluPerspective(), everything looks good (my cube fits my window perfectly) on 1024 by 768 using a particular Z value for glTranslate() before drawing my cube, then when i switch to say 1600 by 1200 and restart the app (keeping the same Z value) the cube appears bigger than my window…

Originally posted by nexusone:
[b]Are also at resize are you changeing ortho or prespective view settings?

[/b]

Can you post the code you use to set the viewport and perspective view.

Take a look at some of my example code and how I handle resize. www.angelfire.com/linux/nexusone/

[This message has been edited by nexusone (edited 02-17-2004).]

here is objective-c snippet (it should be understandable):

  • (void)setViewportRect: (NSRect) _bounds {
    bounds = _bounds;
    glViewport (0.0, 0.0, bounds.size.width, bounds.size.height);

    glMatrixMode( GL_PROJECTION );
    glLoadIdentity();
    gluPerspective( 45.0, bounds.size.width / bounds.size.height, 1.0, 1000.0 );
    }

i guess what i am trying to find out is a formula between screen size/location and 3D coords. I know where i want my object to appear and how big it should be on the screen so how do i figure out its 3D coords given the Perspective Viewing Volume i am using ?

Originally posted by nexusone:
[b]Can you post the code you use to set the viewport and perspective view.

Take a look at some of my example code and how I handle resize. www.angelfire.com/linux/nexusone/

[This message has been edited by nexusone (edited 02-17-2004).][/b]

You can make all of settings of gluPerspective fixed.
This:
gluPerspective( 45.0, bounds.size.width / bounds.size.height, 1.0, 1000.0 );
Becomes:
gluPerspective( 45.0, 1, 1.0, 1000.0 );
So that no mater how the window is resized all the object stay in there location. Now you will have to add a routine to re-adjust the window to keep that aspect ratio while being dragged.

The other idea of moving the objects to adjust for the dragging of the window, could become a complex routine.

[This message has been edited by nexusone (edited 02-18-2004).]

i can’t constrain my window to a fixed aspect ratio and i thought that gluPerspective should use the viewport/window’s aspect ratio to avoid distortion… To simplify let’s say i am using the whole screen as my viewport, when the user changes resolution (from 1024x768 to 1900x1200 for example) the aspect ratio will change but i need to make sure that an object that used to exactly occupy the whole screen (or one of its sides) still does after the resolution change. In my case i want the face of a cube to always fill the screen’s whole height regardless of resolution and aspect ratio… how can i compute this ?

Originally posted by nexusone:
[b]You can make all of settings of gluPerspective fixed.
This:
gluPerspective( 45.0, bounds.size.width / bounds.size.height, 1.0, 1000.0 );
Becomes:
gluPerspective( 45.0, 1, 1.0, 1000.0 );
So that no mater how the window is resized all the object stay in there location. Now you will have to add a routine to re-adjust the window to keep that aspect ratio while being dragged.

The other idea of moving the objects to adjust for the dragging of the window, could become a complex routine.

[This message has been edited by nexusone (edited 02-18-2004).][/b]

I think if you want to place an object so it is bounded by a region on the screen, you have to invert the matrix, effectively pick the corners, and find out the corresponding points in the space. Then you scale the object to reach those points.

If you don’t need to do the full solution, you can just iteratively play around until you’ve got it right, but if this is a dynamic issue, I think the above is the only way to actually do it robustly.

dovkruger,
That does make sense… I am new at 3D and OpenGL how would i do the steps that you suggested ?
thanks !

Originally posted by dovkruger:
[b]I think if you want to place an object so it is bounded by a region on the screen, you have to invert the matrix, effectively pick the corners, and find out the corresponding points in the space. Then you scale the object to reach those points.

If you don’t need to do the full solution, you can just iteratively play around until you’ve got it right, but if this is a dynamic issue, I think the above is the only way to actually do it robustly.[/b]

Here are just my thoughts on it.

Yes the aspect ratio will change between 1024x768 and 1900x1200, here in lies the problem with just making the cube match the screen.
In order to have the whole scene fill the screen you are:
a: going to have to ether show more or less area depending on aspect ratio, like going from standard TV to wide screen on a DVD.

b: distort the image to fit the cube.

You could keep the projection aspect the same, and just fill in the unused area with a black border to look at though the screen is taking up the full screen. Pick some ration that is close to most resolutions you would use to keep down the amounth of black area.

Indeed i am already doing this (leaving black border on one of the sides) but i just don’t know how to guarantee that the cube will always fit the other side perfectly when the resolution changes. What you said about the inverse matrice makes sense i just don’t know how to use the matrices to do it…
I assume we’re talking about the modelview matrix, would you know how to map pixels coords to 3D coords ?

Originally posted by nexusone:
[b]Here are just my thoughts on it.

Yes the aspect ratio will change between 1024x768 and 1900x1200, here in lies the problem with just making the cube match the screen.
In order to have the whole scene fill the screen you are:
a: going to have to ether show more or less area depending on aspect ratio, like going from standard TV to wide screen on a DVD.

b: distort the image to fit the cube.

You could keep the projection aspect the same, and just fill in the unused area with a black border to look at though the screen is taking up the full screen. Pick some ration that is close to most resolutions you would use to keep down the amounth of black area.

[/b]