GLUT provides a way to define which function should be called when the window is resized, i.e. to register a callback for recomputing the perspective. Furthermore, this function will also be called when the window is initially created so that even if you're initial window is not square things will look OK.
GLUT achieves this using the function glutReshapeFunc.
void main(int argc, char **argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_SINGLE | GLUT_RGBA);
glutInitWindowPosition(100,100);
glutInitWindowSize(320,320);
glutCreateWindow("3D Tech- GLUT Tutorial");
glutDisplayFunc(renderScene);
// Here is our new entry in the main function
glutReshapeFunc(changeSize);
glutMainLoop();
}
void changeSize(int w, int h) {
// Prevent a divide by zero, when window is too short
// (you cant make a window of zero width).
if(h == 0)
h = 1;
float ratio = 1.0* w / h;
// Reset the coordinate system before modifying
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// Set the viewport to be the entire window
glViewport(0, 0, w, h);
// Set the correct perspective.
gluPerspective(45,ratio,1,1000);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.0,0.0,5.0,
0.0,0.0,-1.0,
0.0f,1.0f,0.0f);
}
We then set the current matrix to be the projection matrix. This is the matrix that defines the viewing volume. We then load the identity matrix to initialize it. Afterwards we set the viewport to be the whole window with the function glViewport. You can try with different values to see what you come up with, the first two parameters are the top right corner, and the last two are the bottom left. Note that these coordinates are relative to the client area of the window, not the screen. If you do try with different values then don't forget that the ratio computed above should also use the new width and height values.
The gluPerspective function is part of another library for OpenGL, the OpenGL Utility Library, or GLU. GLU is a standard component of the implementation of OpenGL. The gluPerspective function establishes the perspective parameters. The first one defines the field of view angle in the yz plane, the ratio defines the relation between the width and height of the viewport. The last two parameters define the near and far clipping planes. Anything closer than the near value, or further away than the far value will be clipped away from the scene. Beware with these settings or you may end up not seeing anything at all.
Finally, setting the camera. First we set the GL_MODELVIEW as our current matrix. the modelview matrix is where we'll define both the camera settings and the modeling transformations. Before setting the camera it is always healthy to load the identity matrix. this avoids previous transformations to affect the camera settings. The gluLookAt function provides an easy and intuitive way to set the camera position and orientation. Basically it has three groups of parameters, each one is composed of 3 floating point values. The first three values indicate the camera position. The second set of values defines the point we're looking at. Actually it can be any point in our line of sight.The last group indicates the up vector, this is usually set to (0.0, 1.0, 0.0), meaning that the camera's is not tilted. If you want to tilt the camera just play with these values. For example, to see everything upside down try (0.0, -1.0, 0.0).
OK, here's the new VC project ( glut1.zip), try playing with the window size and check if the proportions of our triangle remain constant. Furthermore, do play with the parameters in the new functions now introduced to get a grip of what is really happening.