There are many reasons to render 3D geometry that appears 2D. For example, rendering text on the screen can be done by rendering polygons with textures of the corresponding
letters
. Similarly, textured polygons can be used to display the menus and the heads-up display (HUD) of your game. In fact, most
games
use this technique instead of pasting an image on top of the 3D context. In this chapter, you will learn how to set up the coordinate system so that you can use typical 2D coordinates to draw the geometry on screen. The section on text rendering shows different ways of drawing text on the screen, which is a good way to see the different approaches to getting 2D-looking content on the screen. Also, note that text rendering is necessary for just about every game. After learning the basics, you will learn how to create GUI APIs that can be used to create the menu and HUD for your game. This chapter comes with a working demo that shows animated and interactive in-game menus that run in a 3D context. The examples section explains the demo and shows how the in-game menu, console, and HUD work.
Setting Up a 2D Coordinate System
Typical perspective frustums are set up such that the lower-left corner is coordinate (-1, -1) and the upper-right corner is (1, 1), which would make the center of the screen (0, 0). If you want to render primitives such as
quads
as if they were 2D, it will be
convenient
to define a coordinate system where the
upper-left
corner is (0, 0) and the lower-right, say, (640, 480).
The
glOrtho
and
glFrustum
methods
can be used to set up the
frustum
and the coordinate system in which the objects are rendered. The difference between them is perspective and the sense of depth. When using a perspective projection, objects that are farther from the camera appear smaller and move more slowly. The
glOrtho
method can be used to produce a parallel projection in much the same way that the
glFrustum
method can be used to produce a perspective projection. The following line sets up a parallel projection matrix. The upper-left corner is (0, 0) and the lower-right corner is (640, 480).
// left, right, bottom, top, zNear, zFar gl.glOrtho( 0, 640, 480, 0, -1, 1 );
Note that the
zNear
and
zFar
have been set to -1 and 1 correspondingly. When drawing, you can simply set the z-coordinate to 0 or use
glVertex2i
instead of
glVertex3i
. It is a good practice to avoid using perspective projection if you want to render polygons right in front of the camera. But if you want to use a perspective projection instead, you must render the geometry right passed the near clip and use the new and far clip appropriately. An example of a quad drawn using the orthographic projection matrix we set up earlier
follows
:
gl.glBegin(GL.GL_QUADS); g gl.glVertex2i(100, 200); // South West g gl.glVertex2i(200, 200); // South East g gl.glVertex2i(200, 100); // North East g gl.glVertex2i(100, 100); // North West g gl.glEnd();
Unlike console games, PC
games
must be able to run in different screen
resolutions
, so menu systems may have to compensate for the possible changes. By using a virtual 640 x 480 coordinate system, you can choose to change the coordinate of the projection matrix, or leave it as is. If the width and height parameters that are passed to
glOrtho
change, the
size
of the components will shrink and allow more components to fit. On the other hand, by not changing them, the
components
take the same amount of space, regardless of the screen resolution.