Simplifying OpenGL

The OpenGL-related changes in the Android 1.5 SDK are primarily aimed at providing a simplified interface to the OpenGL drawing capabilities. This simplification will make OpenGL a lot more approachable to beginning OpenGL programmers. We discussed this need in Chapter 10, and to address it, we designed an OpenGL test harness that exhibits the following characteristics:

• Hide how one needs to initialize and get an EGLContext

• Hide the complexities of drawing on a SurfaceView using a secondary thread

• Expose only the interfaces that are dedicated to the core OpenGL drawing APIs

In that framework, you only needed to worry about inheriting from an AbstractRenderer to start drawing. The changes in the 1.5 SDK follow a similar pattern, introducing these key new classes and interfaces into the android.opengl package:

• GLSurfaceView: This class is responsible for drawing on a surface view using a secondary thread. It's equivalent to the OpenGLTestHarness and GLThread classes covered in Chapter 10.

• GLSurfaceView.Renderer: This is an interface that defines a contract for the inheriting drawing classes. All rendering subclasses need to implement this interface.

With these classes and interfaces, you should use OpenGL like this:

1. Implement the Renderer interface and provide the necessary OpenGL setup such as the OpenGL camera. Then override the onDraw method to draw.

2. Instantiate a GLSurfaceView and associate it with the subclassed Renderer from step 1.

3. Set the GLSurfaceView object in the activity.

You should familiarize yourself with the Renderer interface (see Listing 13-1) because it's the primary contract that developers will use to implement their drawing code.

Listing 13-1. The 1.5 SDK Renderer Interface public static interface GLSurfaceView.Renderer {

void onDrawFrame(GLl0 gl);

void onSuraceChanged(GLl0 gl, int width, int height); void onSurfaceCreated(GLl0 gl, EGLConfig config);

As you might have noticed, this renderer resembles the Renderer interface that we introduced in Chapter 10 (see Listing 10-10). The methods in both interfaces have similar responsibilities, so we won't explain what each method does.

By further following the test harness in Chapter 10, we can gain even more simplicity by having all our renderers inherit from an AbstractRenderer. This would let us factor out the code that is common to all renderers and place it in the AbstractRenderer. Let us implement this AbstractRenderer using the new standardized 1.5 SDK Renderer interface (see Listing 13-2).

Listing 13-2. AbstractRenderer Source Code

//filename: AbstractRenderer.java public abstract class AbstractRenderer implements GLSurfaceView.Renderer {

public int[] getConfigSpec() { int[] configSpec = {

EGL10.EGL_DEPTH_SIZE, 0, EGL10.EGL_NONE

return configSpec;

public void onSurfaceCreated(GL10 gl, EGLConfig eglConfig) { gl.glDisable(GL10.GL_DITHER); gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,

GL10.GL_FASTEST); gl.glClearColor(.5f, .5f, .5f, 1); gl.glShadeModel(GL10.GL_SMOOTH); gl.glEnable(GL10.GL_DEPTH_TEST);

public void onSurfaceChanged(GL10 gl, int w, int h) { gl.glViewport(0, 0, w, h); float ratio = (float) w / h; gl.glMatrixMode(GL10.GL_PROJECTION); gl.glLoadIdentity();

public void onDrawFrame(GL10 gl) {

gl.glDisable(GL10.GL_DITHER);

gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);

gl.glMatrixMode(GL10.GL_MODELVIEW);

gl.glLoadIdentity();

GLU.gluLookAt(gl, 0, 0, -5, 0f, 0f, 0f, 0f, 1.0f, 0.0f);

gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

protected abstract void draw(GL10 gl);

As you can see, the AbstractRenderer in Listing 13-2 takes care of the settings for an OpenGL scene (see the Chapter 10 discussion about setting up the OpenGL camera).

We are now in a good position to show you how to use these 1.5 OpenGL classes with the AbstractRenderer effectively. We will first implement a simple drawing class by bringing over the SimpleTriangleRenderer class that we introduced in Chapter 10. This will demonstrate the simple inheritance required to start drawing in OpenGL. We will also introduce a simple activity to test this SimpleTriangleRenderer. We will then close this OpenGL topic by showing how you can use these classes for introducing animation. Again, we will demonstrate this animation through a working sample along with source code.

Note We are not recommending that you circumvent the Android 1.5 OpenGL approach in favor of the Android 1.1 test harness that we built in Chapter 10. By simply adding the AbstractRenderer to the classes in 1.5, you will arrive at the equivalent of the Chapter 10 test harness. You can use this resulting 1.5 test harness for most of your beginning needs. As you become more skilled with OpenGL, you can derive classes similar to AbstractRenderer as necessary. Or you can just ignore the AbstractRenderer and implement that functionality directly in the class you derive from the Renderer.

Now let's proceed to draw the simple OpenGL triangle.

0 0

Post a comment