Sign in to follow this  
ChemicalImbalance

Am I understanding glFrustum properly

Recommended Posts

glFrustum(left, right, bottom, top, near, far); Here's what I interpret it to mean: All points between (x, y, near) and (x, y, far) should be drawn to the screen and visible assuming that (x, y) is within the rectangle (left, right, bottom, top). Is this a correct interpretation?

Share this post


Link to post
Share on other sites
jyk    2094
Quote:
All points between (x, y, near) and (x, y, far) should be drawn to the screen and visible assuming that (x, y) is within the rectangle (left, right, bottom, top).

Is this a correct interpretation?
That's the correct interpretation for an orthographic projection, but glFrustum() creates a perspective projection. Here's a top-down view of the frustum:
         f
\-------------/
\ /
\ /
\ /
l\-----/r
\ n /
\ /
C
The side view is similar. C is the camera position, and l, r, b and t define the bounds of the frustum at the near plane. Everything in the truncated pyramid between n and f is visible.

Share this post


Link to post
Share on other sites
That seems to make sense, but there is still obviously something that I'm not understanding.

If you wouldn't mind taking a look at the following code:


glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-320, 320, -240, 240, 0, 10);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glColor3f(1, 1, 1);
glTranslatef(0, 0, 1.1);

glBegin(GL_POLYGON);
glVertex3f(-0.5f, -0.5f, 0);
glVertex3f(0.5, -0.5f, 0);
glVertex3f(0.5, 0.5f, 0);
glVertex3f(-0.5, 0.5f, 0);
glEnd();




It's supposed to draw a simple white square on a black background.
As long as the square is placed between -1 and 1, it's visible. Otherwise, it's not. (In this case it is not visible since it's been translated to 1.1 (z).)

However, shouldn't the glFrustum command make it so that what's drawn between 0 and 10 is visible?

Share this post


Link to post
Share on other sites
Kalidor    1087
Quote:
Original post by ChemicalImbalance
...It's supposed to draw a simple white square on a black background.
As long as the square is placed between -1 and 1, it's visible. Otherwise, it's not. (In this case it is not visible since it's been translated to 1.1 (z).)

However, shouldn't the glFrustum command make it so that what's drawn between 0 and 10 is visible?
With near=0 and far=10 you will be able to view things that are [0...10] units down the view vector. The default OpenGL "camera" is oriented to view down the negative z-axis, so what you're doing is translating the quad 1.1 units out of the screen instead of into it.

Share this post


Link to post
Share on other sites
LilBudyWizer    491
I doubt it took your glFrustum call since near is never suppose to 0 since that would make the projection matrix singular. So I would assume you have the default frustum.

Share this post


Link to post
Share on other sites
kburkhart84    3187
Actually, I was using near as 0 before myself. It worked, but I don't know how to describe the problems I was getting. So no, you don't get a default, rather many errors at run-time. Atleast, in my case that is how it went.

Share this post


Link to post
Share on other sites
dimebolt    440
Quote:
Original post by kburkhart84
Actually, I was using near as 0 before myself. It worked, but I don't know how to describe the problems I was getting. So no, you don't get a default, rather many errors at run-time. Atleast, in my case that is how it went.

The openGL perspective matrix:

Note that very weird things will happen with n = 0.

Also read the specification of glFrustum.
Quote:
source: MSDN
[...] you should never set near to zero.


Tom

Share this post


Link to post
Share on other sites
kburkhart84    3187
I think that the values that divide by 0 OpenGL might check for you and not do them, but the values that don't still work, so that would explain the "erradic" behaviour. I had never seen why 0 didn't work, I just knew it didn't. Thanks for the chart.

Share this post


Link to post
Share on other sites
kburkhart84    3187
Quote:
Original post by Kalidor
Whoops...

I should've noticed that. Anyway, I'm glad it's fixed now.


Don't feel bad. I didn't see it either, and you wouldn't believe how much time it took me to find it when I had done it. lol

Share this post


Link to post
Share on other sites
Quote:
Original post by LilBudyWizer
I doubt it took your glFrustum call since near is never suppose to 0 since that would make the projection matrix singular. So I would assume you have the default frustum.


You are correct. I checked and glGetError() was returning GL_INVALID_VALUE.
I've modified my code. I'm no longer getting an error. Why is the square still not visible?


GLenum err;

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-320, 320, -240, 240, 1, 10);
err = glGetError();

if(err!=0)
{
MessageBox(NULL, "You dun screwed up!", "Arrr!", MB_OK);
}


glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glColor3f(1, 1, 1);
glTranslatef(0, 0, 2);

glBegin(GL_POLYGON);
glVertex3f(-0.5f, -0.5f, 0);
glVertex3f(0.5, -0.5f, 0);
glVertex3f(0.5, 0.5f, 0);
glVertex3f(-0.5, 0.5f, 0);
glEnd();

return true;





Your help is appreciated.

Share this post


Link to post
Share on other sites
Brother Bob    10344
First, the depth range of your frustum is [-1, -10] but you draw the quad at z=2, which is outside this range, and therefore not visible. You need to translate it to Z=-2 instead of Z=2.

But then there's one more thing. Your quad will be drawn correctly, but you still may not see it. At Z=-1, your frustum is 640x480 units in size (because of the values in glFrustum). That means, at Z=-2, the frustum will be 1280x960 units in size, and you draw a quad 1x1 units in size. So unless your window is at least 1280x960 pixels large, the quad will be less than a pixel large, and may not be drawn just because it's too small.

The horizontal field of view of your frustum is EXTREMELY large, close to 179.5 degrees. If you want, say, a 90 degree horizontal field of view, you should set the top and bottom parameters of glFrustum to about the same values as the near plane. Check out jyk's picture; if n is small and r and l is large, the field of view is large.

Share this post


Link to post
Share on other sites
LilBudyWizer    491
The fun is just beginning. One suggestion would be take advantage of the fact the coordinate system can be pretty much anything that makes drawing easy. Particularly you can have a routine that simply draws a shape and then use transforms to size, orient and position it. So for example I usually draw everything centered at the origin in a unit cube. Particularly remember that you can orient it any way that makes it easy to figure out where the vertices are.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this