Reputation: 443
I'm trying to display a particular volume of space, the cube from 10,10,10 to 30,30,30. From everything I read, I'd do this like so:
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(10, 30, 10, 30, 10, 30);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(30.0f, 30.0f, 30.0f,
20.0f, 20.0f, 20.0f,
0.0f, 1.0f, 0.0f);
glColor3f(0.0, 0.0, 0.0); //color = black
glPushMatrix();
glTranslated(20,20,20);
glutSolidSphere(.3, 50, 50);
glPopMatrix();
glOrtho
sets up what volume I can see, and gluLookAt
says that the camera is at 30,30,30 and is pointed at 20,20,20. But this doesn't work. With some help and some playing around, I managed to get this working, with this code:
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(10, 30, 10, 30, -1000, 1000); //CHANGED THESE BOUNDS
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslated(20,20,20); //ADDED THIS LINE
gluLookAt(30.0f, 30.0f, 30.0f,
20.0f, 20.0f, 20.0f,
0.0f, 1.0f, 0.0f);
glPushMatrix();
glTranslated(20,20,20);
glutSolidSphere(.3, 50, 50);
glPopMatrix();
Why do I need those changes? Why doesn't the first version of the code work?
Upvotes: 0
Views: 1102
Reputation: 45352
This code
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(10, 30, 10, 30, 10, 30);
will set up a matrix which will transform the cuboid x=[10,30], y=[10,30] and z=[ -10, -30] to the [-1,1]^3 clip space volume (which is OpenGL's viewing volume). Note the negative sign here.
This code
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(30.0f, 30.0f, 30.0f,
20.0f, 20.0f, 20.0f,
0.0f, 1.0f, 0.0f);
set up a translation of all objects of (-30,. -30, -30) and some rotation to look into the direction you specified.
Both matrices will be applied, first the ModelView
to get into eye space, than the Projection
matrix to get into clip space. So now, if you want to think in terms of a global "world space", you end up with a viewing volume which is the 20 units wide, high and deep, but lies somewhere you don't really expect it. It will begin 10 units behind at what you set as the view direction axis. and also be shifted along the camera's local x and y axis - the point you specified your camera to look at will not even end up on the screen.
If you just wanted the [10,30]^3 viewing volume, you could simply use
glOrtho(10, 30, 10, 30, -10, -30);
and remove that gluLookAt()
alltogether. This will at least work for simple cases, but it might screw up lighting and fog, since the "camera" is now at original. You probably want to set up some symmetric viewing volume, so that you actually can have any sane camera setup.
EDIT
To make things more clear: the viewing volume you define in the projection matrix is defined relative to the view transformation in that setup. So, you might for examle want to a viewing volume of size 20x20x20, where your viewing axis lies in the center of the porjection, and showung the volume which lies directly in front of the camera:
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-10, 10, -10, 10, 0, 20);
Now you can set up your camera location as before: glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(30.0f, 30.0f, 30.0f, 20.0f, 20.0f, 20.0f, 0.0f, 1.0f, 0.0f);
Now, the point (20,20,20) (where you draw your sphere) will actually be projected to the center of the screen. However, it will be not at the center of the viewing voulme, since it wall range from 0 to 20 units along the current viewing axis, but (20,20,20) is 17.32 units away from the current camera position of (30,30,30). So you could set the camera to gluLookAt(25.774f, 25.774f, 25.774f, 20.0f, 20.0f, 20.0f, 0.0f, 1.0f, 0.0f);
Now, the object is exaclty in the center of the viewing volume.
Upvotes: 2