Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Hello.Android.3rd.Edition.pdf
Скачиваний:
33
Добавлен:
02.02.2015
Размер:
3.24 Mб
Скачать

RENDERING THE SCENE 202

We override the onPause( ) and onResume( ) methods so they can call the methods of the same name in the view.

We won’t need the layout resource (res/layout/main.xml), so you can delete it. Now let’s define our custom view class:

Download OpenGL/src/org/example/opengl/GLView.java

package org.example.opengl;

import android.content.Context; import android.opengl.GLSurfaceView;

class GLView extends GLSurfaceView { private final GLRenderer renderer;

GLView(Context context) { super(context);

// Uncomment this to turn on error-checking and logging //setDebugFlags(DEBUG_CHECK_GL_ERROR | DEBUG_LOG_GL_CALLS);

renderer = new GLRenderer(context); setRenderer(renderer);

}

}

GLSurfaceView is a new class introduced in Android 1.5 that greatly simplifies using OpenGL in Android. It provides the glue to connect OpenGL ES to the view system and activity life cycle. It takes care of picking the appropriate frame buffer pixel format, and it manages a separate rendering thread to enable smooth animation. All GLView needs to do is extend GLSurfaceView and define a renderer for the view.

In the next section, we’ll fill the screen with a solid color.

10.4Rendering the Scene

As we saw in Section 4.2, Drawing the Board, on page 83, the Android 2D library calls the onDraw( ) method of your view whenever it needs to redraw a section of the screen. OpenGL is a bit different.

In OpenGL ES on Android, drawing is separated into a rendering class that is responsible for initializing and drawing the entire screen. Let’s define that now.

RENDERING THE SCENE 203

Here’s the outline for the GLRenderer class:

Download OpenGL/src/org/example/opengl/GLRenderer.java

package org.example.opengl;

import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10;

import android.content.Context; import android.opengl.GLSurfaceView; import android.opengl.GLU;

import android.util.Log;

class GLRenderer implements GLSurfaceView.Renderer { private static final String TAG = "GLRenderer"; private final Context context;

GLRenderer(Context context) { this.context = context;

}

public void onSurfaceCreated(GL10 gl, EGLConfig config) { // ...

}

public void onSurfaceChanged(GL10 gl, int width, int height) { // ...

}

public void onDrawFrame(GL10 gl) { // ...

}

}

GLRenderer implements the GLSurfaceView.Renderer interface, which has three methods. Let’s start with the onSurfaceCreated( ) method, which is called when the OpenGL Surface (kind of like a Canvas in regular 2D) is created or re-created:

Download OpenGL/src/org/example/opengl/GLRenderer.java

Line 1 public void onSurfaceCreated(GL10 gl, EGLConfig config) {

2// Set up any OpenGL options we need

3gl.glEnable(GL10.GL_DEPTH_TEST);

4gl.glDepthFunc(GL10.GL_LEQUAL);

5gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

6

7 // Optional: disable dither to boost performance

8 // gl.glDisable(GL10.GL_DITHER);

9}

RENDERING THE SCENE 204

On line 3, we set a couple of OpenGL options. OpenGL has dozens of options that can be enabled or disabled with glEnable( ) and glDisable( ). The most commonly used ones include the following:

Option

Description

GL_BLEND

Blend the incoming color values with the values

 

already in the color buffer.

GL_CULL_FACE

Ignore polygons based on their winding (clockwise

 

or counterclockwise) in window coordinates. This is

 

a cheap way to eliminate back faces.

GL_DEPTH_TEST

Do depth comparisons, and update the depth

 

buffer. Pixels farther away than those already

 

drawn will be ignored.

GL_LIGHTi

Include light number i when figuring out an object’s

 

brightness and color.

GL_LIGHTING

Turn on lighting and material calculations.

GL_LINE_SMOOTH

Draw antialiased lines (lines without jaggies).

GL_MULTISAMPLE

Perform multisampling for antialiasing and other

 

effects.

GL_POINT_SMOOTH

Draw antialiased points.

GL_TEXTURE_2D

Use textures to draw surfaces.

All options are off by default except for GL_DITHER and GL_MULTISAMPLE. Note that everything you enable has some cost in performance.

Next let’s fill out the onSurfaceChanged( ) method. This method is called once after the Surface is created and then again whenever the size of the Surface changes:

Download OpenGL/src/org/example/opengl/GLRenderer.java

Line 1 public void onSurfaceChanged(GL10 gl, int width, int height) {

2// Define the view frustum

3gl.glViewport(0, 0, width, height);

4gl.glMatrixMode(GL10.GL_PROJECTION);

5gl.glLoadIdentity();

6float ratio = (float) width / height;

7 GLU.gluPerspective(gl, 45.0f, ratio, 1, 100f);

8}

Here we configure our view frustum and set a few OpenGL options. Note the call to the GLU.gluPerspective( ) helper function on line 7. The last two arguments are the distance from the eye to the near and far clipping planes (see Figure 10.1, on page 199).

RENDERING THE SCENE 205

Figure 10.2: That was a lot of trouble to get a black screen.

It’s time to draw something. The onDrawFrame( ) method is called over and over in the rendering thread created by the GLSurfaceView class.

Download OpenGL/src/org/example/opengl/GLRenderer.java

public void onDrawFrame(GL10 gl) {

//Clear the screen to black gl.glClear(GL10.GL_COLOR_BUFFER_BIT

| GL10.GL_DEPTH_BUFFER_BIT);

//Position model so we can see it gl.glMatrixMode(GL10.GL_MODELVIEW); gl.glLoadIdentity(); gl.glTranslatef(0, 0, -3.0f);

//Other drawing commands go here...

}

To start with, we set the screen to black. We clear both the color and depth buffers. Always remember to clear both, or you’ll get some very

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]