PDA

View Full Version : Simple example, don't get it ...



medi84
01-15-2009, 02:47 PM
I read several OpenGL tutorials, and now I'm trying to experiment with simple examples. But, I have results which I can't understand. Let's look at the following example. I have a rectangle in Z=0 plane. When my camera is looking from (0.0, 0.0, 1.0) to (0.0, 0.0, 0.0) rectangle is visible. But, when looking from (0.0, 0.0, 1.1) rectangle is not visible. Why camera can't see rectangle in front of it, when viewing from Z>1.0?




void Redraw() {
glClearColor( 0.0, 0.0, 0.0, 0.0 );
glClear(GL_COLOR_BUFFER_BIT);

glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
gluLookAt( 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0 ); // rectangle is visible
// gluLookAt( 0.0, 0.0, 1.1, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0 ); rectangle is not visible

glColor3f( 1.0, 0.0, 0.0 );
glBegin(GL_LINE_LOOP);
glVertex3f( 0.5, 0.5, 0.0 );
glVertex3f( 0.5, -0.5, 0.0 );
glVertex3f( -0.5, -0.5, 0.0 );
glVertex3f( -0.5, 0.5, 0.0 );
glEnd();

glFlush();
}

int main(int argc, char **argv) {

glutInitDisplayMode( GLUT_RGB | GLUT_SINGLE );
glutInit( &argc, argv );

glutInitWindowPosition( 200, 200 );
glutInitWindowSize( 300, 300 );
glutCreateWindow( "Test" );

glutDisplayFunc( Redraw );

glutMainLoop();

return 0;
}

Nicolai de Haan Brøgger
01-15-2009, 08:01 PM
Because polygons are thought of as having front and back faces, and because the OpenGL default state is to cull (not rasterize) back face polygons. A front facing is one in which the winding is usually counter-clockwise (this is the default). If you want to see both sides (i.e. faces), you have to instruct OpenGL NOT to cull back faces with the function call, glDisable(GL_CULL_FACE) when initializing. If you have some polygon with clockwise winding (the opposite of the default), you can temporarily change the way GL determines polygon winding with glFrontFace(GL_CW). I recommend you revert to the default (GL_CCW) after specifying your clockwise-winding polygon, to avoid potential problems with mixed winding if you later enable face culling.

Most of the tutorials on the net are not very thorough. I think you will benefit from picking up a good book if you want to learn the details and avoid these pitfalls ;)

Nicolai de Haan Brøgger
01-15-2009, 08:08 PM
Ouch, I'm sorry. I completely misread your post and the problem :)

What you need to do is to set up a perspective projection with a far and near plane, that contains what you want to render. You can do this, for instance, with the utility function gluPerspective (see http://www.opengl.org/sdk/docs/man/xhtml/gluPerspective.xml).

medi84
01-16-2009, 02:13 AM
You're saying that this is because I didn't defined projection transformation? This leads me to the following questions:

- Is there a default transformation which defines clipping space which makes my rectangle unvisible when it is too far from camera (outside of clipping space)?

- Can gluLookAt function be used without defining projection transformation?

- Can it be used with orthographic projection also?

I already read some interesting chapters of popular OpenGL books, but they doesn't answer most of the questions I have. These questions are for start, a have a bunch of them ...

dletozeun
01-16-2009, 06:43 AM
- Is there a default transformation which defines clipping space which makes my rectangle unvisible when it is too far from camera (outside of clipping space)?


The default projection matrix should be the identity matrix, but it is not said in the spec, so this may change depending on the hardware. I advise you to always set explicitly the projection matrix, even if it is identity.



Can gluLookAt function be used without defining projection transformation?


It does not have any sense, since gluLookAt only affect the modelview matrix. This function is only used to change the view not the projection.

_NK47
01-16-2009, 06:51 AM
to put it the simple way, modelview matrix describes your object orientation in the view space. imagine you have a camera always at point (0,0,0) looking at down some axes and seeing some objects. the projection matrix on the other hand defines how all those visible objects in your view get "projected" on your screen. f.e. parallel projection or perspective projection or oblique projection and so on. because of that any application needs to define how it wants the vertices to be projected. without a proper projection matrix you wont be able to go far. references gluPerspective/gluOrtho.

medi84
01-16-2009, 07:26 AM
- So, the problem with my example is projection matrix, which I didn't set, which default value I don't know (because it isn't specified)?

- If I don't know default projection matrix, projection transformation should always be defined?

- I read in few tutorials on the net that the default OpenGL projection transformation is orthogonal, gluOrtho2D( -1.0, 1.0, -1.0, 1.0); is that true?

It would be much easier for me if those opengl tutorials had more always and never words ...

_NK47
01-16-2009, 07:46 AM
"- So, the problem with my example is projection matrix, which I didn't set, which default value I don't know (because it isn't specified)?"
actually i never saw an OpenGL sample which hasn't defined the projection matrix before rendering.

"- If I don't know default projection matrix, projection transformation should always be defined?"
you can always retrieve a matrix with glGet (glGetFloat(GL_PROJECTION_MATRIX,array)) but at startup its either identity or data trash (INFs or NANs or something).

"- I read in few tutorials on the net that the default OpenGL projection transformation is orthogonal, gluOrtho2D( -1.0, 1.0, -1.0, 1.0); is that true?"
see above and check yourself.

MaxH
01-16-2009, 07:55 PM
Is there a default transformation which defines clipping space which makes my rectangle unvisible when it is too far from camera (outside of clipping space)?
I read through my OpenGL texts and could not find the answer to your question. No where did I find it stated where the default clipping planes are. So I don't blame you for being a little upset by that. I took your sample program and played around with it to discover where the default clipping planes are. The results seem natural. The near clipping plane is where the eyepoint is, and the far clipping plane is one unit away. In your example, this would put the near clipping plane at z = 1.0, and the far clipping plane at z = 0.0. Your line of sight is in the -Z direction. My version of your code is here. (http://pastebin.com/m6e886529) Instead of changing the gluLookAt parameters, I added a variable 'z' which can be used to move the rectangle towards or away from the eyepoint (0,0,1). In your version of the code, the red square doesn't show up when the eyepoint is at z = 1.1, simply because it is MORE than one unit away. I agree with the other posters who said that it's a good idea to explicitly state how far the clipping planes are from the camera via glOrtho or gluPerspective commands.

medi84
01-17-2009, 04:18 AM
Thanks Max.

Let's stop on orthographic projection. I moved camera back a little bit, from (0.0, 0.0, 1.0) to position (0.0, 0.0, 1.5), and tried to experiment with orthographic projection and it's clipping planes. But, whatever value I use for near and far clipping planes I can't get that rectangle (Z=0) displayed.
I read OpenGL reference pages, and a bunch of tutorials and neither of them explains clearly what is the reference point from which near and far are measured, and in which direction. Is that a camera (eye) point, in this case (0.0, 0.0, 1.5), with it's direction to (0.0, 0.0, 0.0)?

This is the example, variable parts are commented. None of them makes my rectagle displayed.



void Redraw() {
glClearColor( 0.0, 0.0, 0.0, 0.0 );
glClear(GL_COLOR_BUFFER_BIT);

// VIEW TRANSFORMATION
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
gluLookAt( 0.0, 0.0, 1.5, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0 ); // camera point moved to z=1.5 position

// MODEL TRANSFORMATION
glColor3f( 1.0, 0.0, 0.0 );
glBegin(GL_LINE_LOOP);
glVertex3f( 0.5, 0.5, 0.0 );
glVertex3f( 0.5, -0.5, 0.0 );
glVertex3f( -0.5, -0.5, 0.0 );
glVertex3f( -0.5, 0.5, 0.0 );
glEnd();

// PROJECTION TRANSFORMATION - none of these below work
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glOrtho( -1.0, 1.0, -1.0, 1.0, -5.0, 5.0);
// glOrtho( -1.0, 1.0, -1.0, 1.0, 0.0, 5.0);
// glOrtho( -1.0, 1.0, -1.0, 1.0, -5.0, 0.0);
// glOrtho( -1.0, 1.0, -1.0, 1.0, 5.0, -5.0);
// etc.

glFlush();
}

int main(int argc, char **argv) {

glutInitDisplayMode( GLUT_RGB | GLUT_SINGLE );
glutInit( &argc, argv );

glutInitWindowPosition( 200, 200 );
glutInitWindowSize( 300, 300 );
glutCreateWindow( "Test" );

glutDisplayFunc( Redraw );

glutMainLoop();

return 0;
}

MaxH
01-17-2009, 01:50 PM
Remember that the commands are executed in the order they are written. Your square is red because the Color3f command comes BEFORE the glBegin...glEnd block. If you moved the Color3f command to after glEnd, would you expect the square to be red? It wouldn't be. Because OpenGL would draw the square when it encountered the glVertex commands. Since no color would be specified at that time, it would use the default color (white). It's the same with the glOrtho commands. They have no effect on the drawing of your square because they are called AFTER the square is drawn. All you have to do is move the glMatrixMode, glLoadIdentity, and glOrtho to BEFORE glBegin. It's recommended that Projection stuff is done before Modeling stuff. So the best place to move those lines is just after the call to glClear. Then you'll find that most of your glOrtho calls will work.