Open GL Super Bible

Previous Table of Contents Next


Setting the Viewport and Clipping Volume

In Chapter 2 we discussed how viewports and clipping volumes affect the coordinate range and scaling of 2D and 3D drawings in a 2D window on the computer screen. Now we will examine the setting of viewport and clipping volume coordinates in OpenGL. When we created our window with the function call

   auxInitPosition(100,100,250,250);

the AUX library by default created a viewport that matched the window size exactly (0, 0, 250, 250). The clipping volume by default was set to be the first quadrant of Cartesian space, with the x- and y-axis extending the length and height of the window. The z-axis extends perpendicular to the viewer, giving a flat 2D appearance to objects drawn in the xy plane. Figure 3-6 illustrates this graphically.


Figure 3-6  The viewport and clipping volume for friendly.c

Although our drawing is a 2D flat rectangle, we are actually drawing in a 3D coordinate space. The glRectf() function draws the rectangle in the xy plane at z = 0. Your perspective is down along the positive z-axis to see the square rectangle at z = 0.

Whenever the window size changes, the viewport and clipping volume must be redefined for the new window dimensions. Otherwise, youíll see the effect shown in Figure 3-5, where the mapping of the coordinate system to screen coordinates stays the same regardless of window size.

Because window size changes are detected and handled differently under various environments, the AUX library provides the function auxReshapeFunc(), which registers a callback that the AUX library will call whenever the window dimensions change. The function you pass to auxReshapeFunc() is prototyped like this:

void CALLBACK ChangeSize(GLsizei w, GLsizei h);

We have chosen ChangeSize as a descriptive name for this function and will use that name for our future examples.

The ChangeSize() function will receive the new width and height whenever the window size changes. We can use this information to modify the mapping of our desired coordinate system to real screen coordinates, with the help of two OpenGL functions: glViewport() and glOrtho(). Listing 3-3 shows our previous example modified to account for various window sizes and dimensions. Only the changed main() function and our new ChangeSize() function are shown.

Listing 3-3 Scaling in OpenGL

// Scale.c
// Scaling an OpenGL Window.

// Called by AUX Library when the window has changed size
void CALLBACK ChangeSize(GLsizei w, GLsizei h)
        {
        // Prevent a divide by zero
        if(h == 0)
                h = 1;

        // Set Viewport to window dimensions
        glViewport(0, 0, w, h);

        // Reset coordinate system
        glLoadIdentity();

        // Establish clipping volume (left, right, bottom, top, near, far)
        if (w <= h)
                glOrtho (0.0f, 250.0f, 0.0f, 250.0f*h/w, 1.0, -1.0);
        else
                glOrtho (0.0f, 250.0f*w/h, 0.0f, 250.0f, 1.0, -1.0);
        }

void main(void)
        {
        // Set up and initialize AUX window
        auxInitDisplayMode(AUX_SINGLE | AUX_RGBA);
        auxInitPosition(100,100,250,250);
        auxInitWindow("Scaling Window");

        // Set function to call when window changes size
        auxReshapeFunc(ChangeSize);

        // Set function to call when window needs updating
        auxMainLoop(RenderScene);
        }

Now, when you change the size or dimensions of the window, the square will change size as well. A much larger window will have a much larger square and a much smaller window will have a much smaller square. If you make the window long horizontally, the square will be centered vertically, far left of center. If you make the window tall vertically, the square will be centered horizontally, closer to the bottom of the window. Note that the rectangle always remains square. To see a square scaled as the window resizes, see Figure 3-7a and Figure 3-7b.


Figure 3-7a  Image scaled to match window size


Figure 3-7b  Square scaled as the window resizes

Defining the Viewport

To understand how the viewport definition is achieved, letís look more carefully at the ChangeSize() function. It first calls glViewport() with the new width and height of the window. The glViewport function is defined as

void glViewport(GLint x, GLint y, GLsizei width, GLsizei height);

The x and y parameters specify the lower-right corner of the viewport within the window, and the width and height parameters specify these dimensions in pixels. Usually x and y will both be zero, but you can use viewports to render more than one drawing in different areas of a window. The viewport defines the area within the window in actual screen coordinates that OpenGL can use to draw in (see Figure 3-8). The current clipping volume is then mapped to the new viewport. If you specify a viewport that is smaller than the window coordinates, the rendering will be scaled smaller, as you see in Figure 3-8.


Figure 3-8  Viewport-to-window mapping


Previous Table of Contents Next