Chapter 5
Some Topics Not Covered
This page contains a few examples that demonstrate topics not covered in Chapters 1 through 4. The source code for the examples might be useful to people who want to learn more. The next version of this book should cover these topics -- and more -- in detail.
In stereoscopic viewing, a slightly different image is presented to each eye. The images for the left eye and the right eye are rendered from slightly different viewing directions, imitating the way that a two-eyed viewer sees the real world. For many people, stereoscopic views can be visually fused to create a convincing illusion of 3D depth. One way to do stereoscopic viewing on a computer screen is to combine the view from the left eye, drawn in red, and the view from the right eye, drawn in green. To see the 3D effect, the image must be viewed with red/green (or red/blue or red/cyan) glasses designed for such 3D viewing. This type of 3D viewing is referred to as anaglyph (search for it on Google Images).
The sample program Sterographer.java, in the package stereoGraph3d, can render an anaglyph stereo view of the graph of a function. The program uses modified versions of the Classname and TrackBall classes that can be found in the same package. In order to combine the red and green images, the program uses the method glColorMask method. (The program is also a nice example of using vector buffer objects and glDrawElements for drawing primitives.) Here is an applet version of the program:
Mouse interaction with a 3D scene is complicated by the fact that the mouse coordinates are given in device (pixel) coordinates, while the objects in the scene are created in object coordinates. This makes it difficult to tell which object the user is clicking on. OpenGL can help with this "selection" problem. It offers the GL_SELECT render mode to make selection easier. Unfortunately, it's still fairly complicated and I won't describe it here.
The sample program SelectionDemo.java in the package selection demonstrates the use of the GL_SELECT render mode. The program is a version of WalkThroughDemo.java where the user can click on objects to select it. The size of the selected object is animated to show that it is selected, but otherwise nothing special can be done with it. Here is an applet version:
Throughout the text, we have been talking about the standard OpenGL "rendering pipeline." The operations performed by this pipeline are are actually rather limited when compared to the full range of graphics operations that are commonly used in modern computer graphics. And new techniques are constantly being discovered. It would be impossible to make every new technique a standard part of OpenGL. To help with this problem, OpenGL 2.0 introduced the OpenGL Shading Language (GLSL). Parts of the OpenGL rendering pipeline can be replaced with programs written in GLSL. GLSL programs are referred to as shaders. A vertex shader written in OpenGL can replace the part of the pipeline that does lighting, transformation and other operations on each vertex. A fragment shader can replace the part that operates on each pixel in a primitive. GLSL is a complete programming language, based on C, which makes GLSL shaders very versitile. In the newest versions of OpenGL, shaders are preferred over the standard OpenGL processing.
Since the OpenGL API for working with shaders is rather complicated, I wrote the class GLSLProgram to represent a GLSL program (source code GLSLProgram.java in package glsl). The sample programs MovingLightDemoGLSL.java and IcosphereIFS_GLSL.java, both in package glsl, demonstrate the use of simple GLSL programs with the GLSLProgram class. These examples are not meant as a demonstration of what GLSL can do; they just show how to use GLSL with Java. The GLSL programs can only be used if the version of OpenGL is 2.0 or higher; the program will run with lower version numbers, but the GLSL programs will not be applied.
The first sample program, MovingLightDemoGLSL.java is a version of MovingLightDemo.java that allows the user to turn a GLSL program on and off. The GLSL program consists of a fragment shader that converts all pixel colors to gray scale. (Note, by the way, that the conversion applies only to pixels in primitives, not to the background color that is used by glClear). Here is an applet version:
The second sample program, IcosphereIFS_GLSL.java, uses both a fragment shader and a vertex shader. This example is a version of IcosphereIFS.java, which draws polyhdral approximations for a sphere by subdividing an icosahedron. The vertices of the icosphere are generated by a recursive algorithm, and the colors in the GLSL version are meant to show the level of the recursion at which each vertex is generated. (The effect is not as interesting as I had hoped.) Here is an applet version: