Applying Texture

Although the scene is starting to look more interesting, nobody would mistake it for real life. Everyday objects have textures, like the rough surface of a brick wall or the gravel on a garden path. Do you own a laminated table? A wood laminate is just a photograph of wood grain that is glued on the surface of a less expensive material like plastic or particle board.

Figure 10.5: Rotating the cube

Time-Based Animation

The first version of this example kept track of the current rotation angle and simply incremented it each time through the loop. Can you think of a reason why that was a bad idea?

Since Android can run on a variety of different devices, you can't predict how long it will take to draw a single frame. It might take half a second or 1/100th of a second. If you moved an object a fixed amount every frame, then on slow devices the object would move too slowly, and on fast devices it would move too fast. By tying the amount of movement to how much time has elapsed, you can achieve predictable movement on any device. Faster hardware will draw the animation more smoothly, but objects will get from A to B in the same amount of time.

We're going to do the same thing to our cube using a picture. Unfortunately, the code to do this is fairly long. Don't worry if you don't understand it all right away.

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

private final IntBuffer mTextureBuffer;

public GLCube() {

ByteBuffer tbb = ByteBuffer.allocateDirect(texCoords.length * 4);

tbb.order(Byte0rder.native0rder());

mTextureBuffer = tbb.asIntBuffer();

mTextureBuffer.put(texCoords);

mTextureBuffer.position(0);

static void loadTexture(GL10 gl, Context context, int resource) { Bitmap bmp = BitmapFactory.decodeResource(

context.getResources(), resource); GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bmp, 0); gl.glTexParameterx(GL10.GL_TEXTURE_2D,

GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR); gl.glTexParameterx(GL10.GL_TEXTURE_2D,

GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR); bmp.recycle();

Next we need to tell OpenGL to use the texture coordinates. Add this to the beginning of the draw() method:

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

gl.glEnable(GL10.GL_TEXTURE_2D); //workaround bug 3623 gl.glTexCoordPointer(2, GL10.GL_FIXED, 0, mTextureBuffer);

Download from Library of Wow! eBook <www.wowebook.com>

OpenGL

Figure 10.6: Applying a texture

And finally we need to call the loadTexture( ) method in GLRenderer. Add these lines to the end of the onSurfaceCreated( ) method:

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

// Enable textures gl.glEnableClientState(GL10.GL_TEXTURE_C00RD_ARRAY); gl.glEnable(GL10.GL_TEXTURE_2D);

// Load the cube's texture from a bitmap GLCube.loadTexture(gl, context, R.drawable.android);

This code enables textures and texture coordinates and then calls our loadTexture() method, passing it the Activity context and resource ID so it can load the texture image.

R.drawable.android is a PNG file 128 pixels square that I copied to res/ drawable-nodpi/android.png. You can find it in the downloadable code package that accompanies this book. Note the number 128 doesn't

Figure 10.7: The final version: a see-through cube appear anywhere in the code, so you substitute a larger or smaller image easily.

You can see our progress so far in Figure 10.6, on the previous page.

0 0

Post a comment