OpenGL Overview

If you are familiar with OpenGL and have programmed with in the past, this section may serve as a brief review. The more experienced OpenGL programmer may choose to skip this section and continue on to the JOGL section.

As stated in the previous chapter, OpenGL is a widely used industry-standard real-time 3D graphics API. OpenGL is currently up to version 1.4.

OpenGL is no small system. It is large, complex, and often perplexing because errors (actual programming errors or just incorrect visual effects) can be hard to identify due to OpenGL’s state-based rendering. This section in no way covers everything a developer can create using OpenGL. Dozens of books are dedicated to that subject. At the same time, though, it is possible to use OpenGL (or JOGL) through a render-engine layer that simplifies the task of controlling, manipulating, and rendering a 3D scene, which is typical for 3D games as well. A solid understanding of OpenGL will benefit any developer using a 3D engine, whether or not they are called on to write actual OpenGL code.

High-Level or Low-Level API?

Depending on which group of developers you ask, OpenGL may be considered a low-level or high-level API. Because it allows the developer to work with geometric primitives such as triangles instead of pixels, it can be considered high-level. However, in the world of 3D game development, it is usually considered low-level because it is hardware supported, and you cannot program any lower while still using the hardware to its fullest capabilities. This is due to how video drivers use OpenGL as their main access layer. In theory, a developer could write his own device driver and use that to access the hardware, but it would have to be reverse-engineered because the specific hardware communication is almost always proprietary.

OpenGL provides access only to graphics-rendering operations. There are no facilities for obtaining user input from such devices as keyboards and mice, because it is expected that any system (in particular, a Windows system) under which OpenGL runs, must already provide such facilities.

One of OpenGL’s major strengths from the perceptive of a Java developer is that OpenGL is by far the most cross-platform 3D hardware-accelerated API available. Combining OpenGL with Java gives game developers an excellent cross-platform 3D game-technology foundation.

OpenGL Render Features

OpenGL has numerous features, many of which are not used in typical OpenGL-based games (such as anti-aliased lines) because most games simply don’t need them. It also has even more features that are not used regularly in games for other reasons, such as performance costs. A short subset of hardware-accelerated OpenGL features that do end up in games follows, many of which will be used in our example render engine:

  • Polygon/triangle, line, and pixel rendering

  • Smooth (Gourand) and Flat (Lambert) shading (with diffuse, ambient, and specular lighting effects)

  • Z buffering and double buffering

  • Stencil buffer

  • Colored directional and point light sources

  • Texture mapping

  • Texture filtering (MIPmapping and magmapping)

  • Texture environment controls, such as automatic texture coordinate generation

  • Backface culling

  • Matrix transformations

  • Perspective and parallel projections

  • Vertex programmability (on the latest hardware)

  • Fragments shaders, coming soon as a standard feature, currently supported through extensions

In addition, through the OpenGL extension mechanism, the latest hardware-accelerated features are readily accessible, even if the features are not part of the OpenGL standard yet. This is an excellent benefit for building and testing ahead of the curve for 3D game engines.

Immediate Mode Rendering

The basic model for OpenGL command interpretation is immediate mode, in which a command is executed as soon as the hardware receives it; vertex processing, for example, may begin even before specification of the primitive of which it is a part has been completed. Immediate mode execution is best suited to applications in which primitives and modes are constantly altered.

An example of immediate mode commands follow:

void display(void)  { // draw diamond with radius of 10 glBegin( GL_QUADS );     glVertex3f( 10.0, 0.0, 0.0 );     glVertex3f( 0.0, 10.0, 0.0 );     glVertex3f( -10.0, 0.0, 0.0 );     glVertex3f( 0.0, -10.0, 0.0 ); glEnd(); // flush GL buffers glFlush(); }

In immediate mode, a set of glBegin() and glEnd() calls establishing the primitive type contain the appropriate calls for that primitive to be rendered. This is sometimes called a batch.

Whereas immediate mode provides flexibility, it can be inefficient for large and unchanging parameters because each execution of the batch is respecifying the render object’s parameters redundantly. In the past, to accommodate such situations, OpenGL provided a feature known as display lists. A display list encapsulated a sequence of OpenGL commands and stored them on the hardware. The display list was given a numeric ID by the application when it was specified, and the application needed only to reference the display list ID to cause the hardware to effectively execute the list. Another similar option is vertex arrays and vertex buffer objects; we will examine those in a later section.

State Control

OpenGL is a state machine, meaning OpenGL’s render pipeline is defined by certain states at any given time, and those states control how the final image is rendered. Geometric primitives are also specified in a standard way. The current render state determines their shape, material properties, and orientation.

For example, setting the current drawing color could be executed by simply calling glColor3f (float red, float green, float blue) with the color represented as floats.

Calling glColor3f (1.0, 0.0, 0.0) would set the current color to bright red. Once set all geometric primitives rendered are affected by that red state until the states are changed.

Many states can be changed at any time, even per vertex. For example, the current color can potentially be set to a different color for each vertex in a batch, as shown in the following code:

glBegin( GL_QUADS );     // set this vertex’s color     glColor3f( 1.0, 0.0, 0.0 );     // set this vertex’s coordinate     glVertex3f( x1, y1, z1 );     // same as above, but for each new vertex     glColor3f( 0.0, 1.0, 0.0 );         glVertex3f( x2, y2, z2 );     glColor3f( 0.0, 0.0,1.0 );     glVertex3f( x3, y3, z3 );     glColor3f( 1.0, 1.0, 1.0 );     glVertex3f( x4, y4, z4 ); glEnd();

Light and lighting effects are also states in OpenGL. Like many other states, they must first be enabled to be used. In addition, other render states must be properly set in coordination with the lighting states to get the desired lighting effects. For example, object material states and vertex normals are needed for correct lighting, which can also be changed per vertex.

glEnable(GL_LIGHTING);  glEnable(GL_LIGHT0);  glLightfv(GL_LIGHT0, GL_DIFFUSE, color);

Triangle style is another controllable state in OpenGL. For example, you can control whether to draw the front or back of polygons (known as face culling) as well as whether they should be completely filled in or only in outline.

glPolygonStyle(GL_FRONT, GL_FILL);  glFrontFace(GL_CCW); (How is front defined)  glCullFace(GL_BACK);  glEnable(GL_CULL_FACE);

Additional useful miscellaneous functions include setting the background color and clearing the screen and Z-buffer.

// Clears Color buffer and resets Z-buffer  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Sets the clear color often thought of as the background color glClearColor(....); 

Transform Control

3D matrix transformations are key to manipulating 3D graphics. Therefore, OpenGL supports matrix transformations in the form of a render state. The current matrix state is applied to each vertex (and existing normals) during the geometry specification. On the modern graphics cards these transformations are accelerated by the graphics hardware.

There are several commands in OpenGL for matrix state manipulation, including load and multiple for complete, user-supplied matrices, and utility commands such as glLoadIdentity(), glRotate3f(d, x, y, z), glTranslate(tx, ty, tz), and glScale3f(sx, sy, sz). Also, OpenGL currently specifies three matrix modes—GL_MODELVIEW, GL_PROJECTION, and GL_TEXTURE—with the current mode set with the glMatrixMode command. OpenGL also implements for each of the matrix modes a matrix stack, which the user can then utilize with glPushMatrix and glPopMatrix. The stack depth is limited, depending on the mode—at least 32 for GL_MODELVIEW and at least 2 for GL_PROJECTION and GL_TEXTURE.

The glPushMatrix function duplicates the current matrix and then pushes that matrix into the stack. The glPopMatrix function pops the top matrix off of the stack and replaces the current matrix with that matrix. Each stack contains the identity matrix at initialization.

A typical routine setting up a basic camera matrix state (given the camera matrices) might look like the following code sample:

// set up camera view glMatrixMode(GL_PROJECTION); glLoadMatrixd(camera.eyeFrustumMatrix); glMatrixMode(GL_MODELVIEW); glLoadMatrixd(camera.eyeViewMatrix);

The camera or view matrix is usually thought of as the product of the Projection matrix and the ModelView matrix, where the ModelView matrix represents the global camera/model transformation and the Projection matrix contains the view from which the related Projection matrix is to be applied.

Additional Resources

For more on OpenGL from its history to the future, current game-related activity, as well as great tutorials, check out the following Web sites:

www.opengl.org: The official OpenGL Architecture Review Board Web site. Get all the latest news in the OpenGL world here.

www.sgi.com/software/opengl/: SGI’s Web site on OpenGL.

nehe.gamedev.net/: NeHe Productions has a great Web site for pure OpenGL tutorials with a gaming slant.

www.mesa3d.org: Mesa 3D is an open-source software implementation of the OpenGL specification. It is great for testing as well as running on systems without hardware acceleration.



Practical Java Game Programming
Practical Java Game Programming (Charles River Media Game Development)
ISBN: 1584503262
EAN: 2147483647
Year: 2003
Pages: 171

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net