Game Development Reference
In-Depth Information
We also have a manifest file again. As each of the following examples will be an activity, we also
have to make sure each of them has an entry in the manifest. All the examples will use a fixed
orientation (either portrait or landscape, depending on the example), and will tell Android that
they can handle
keyboard
,
keyboardHidden
, and
orientationChange
events. It's pretty much the
exact same setup as the one we used in Chapter 4.
With that out of our way, let the fun begin!
GLSurfaceView: Making Things Easy Since 2008
The first thing we need is some type of
View
that will allow us to draw via OpenGL ES. Luckily,
there's such a
View
in the Android API—it's called
GLSurfaceView
, and it's a descendent of the
SurfaceView
class, which we already used for drawing the world of Mr. Nom.
We also need a separate main loop thread again so that we don't bog down the UI thread.
Surprise:
GLSurfaceView
already sets up such a thread for us! All we need to do is implement
a listener interface called
GLSurfaceView.Renderer
and register it with the
GLSurfaceView
. The
interface has three methods:
interface
Renderer {
public void
onSurfaceCreated(GL10 gl, EGLConfig config);
public void
onSurfaceChanged(GL10 gl,
int
width,
int
height);
public void
onDrawFrame(GL10 gl);
}
The
onSurfaceCreated()
method is called each time the
GLSurfaceView
surface is created. This
happens the first time we fire up the
Activity
and each time we come back to the
Activity
from a paused state. The method takes two parameters: a
GL10
instance and an
EGLConfig
. The
GL10
instance allows us to issue commands to OpenGL ES. The
EGLConfig
just tells us about the
attributes of the surface, such as the color, depth, and so on. We usually ignore it. We will set up
our geometries and textures in the
onSurfaceCreated()
method.
The
onSurfaceChanged()
method is called each time the surface is resized. We get the new width
and height of the surface in pixels as parameters, along with a
GL10
instance if we want to issue
OpenGL ES commands.
The
onDrawFrame()
method is where the fun happens. It is similar in spirit to our
Screen.render()
method, which gets called as often as possible by the rendering thread that the
GLSurfaceView
sets up for us. In this method, we perform all our rendering.
Besides registering a
Renderer
listener, we also have to call
GLSurfaceView.
onPause()
/
onResume()
in our
Activity
's
onPause()
/
onResume()
methods. The reason for this is
simple. The
GLSurfaceView
will start up the rendering thread in its
onResume()
method and tear it
down in its
onPause()
method. This means that our listener will not be called while our
Activity
is paused, since the rendering thread which calls our listener will also be paused.
Here comes the only bummer: each time our
Activity
is paused, the surface of the
GLSurfaceView
will be destroyed. When the
Activity
is resumed—and
GLSurfaceView.onResume()
is called—the
GLSurfaceView
instantiates a new OpenGL ES rendering surface, and informs us