First we have to load our bitmap. We already know how to do that on Android:
Bitmap bitmap = BitmapFactory.decodeStream(game.getFileIO().readAsset("bobrgb888.png"));
Here we load Bob in an RGB888 configuration. The next thing we need to do is tell OpenGL ES that we want to create a new texture. OpenGL ES has the notion of objects for a couple of things, such as textures. To create a texture object, we can call the following method:
GL10.glGenTextures(int numTextures, int ids, int offset)
The first parameter specifies how many texture objects we want to create. Usually we only want to create one. The next parameter is an int array to which OpenGL ES will write the IDs of the generated texture objects. The final parameter just tells OpenGL ES where in the array it should start writing the IDs to.
You already learned that OpenGL ES is a C API. Naturally it can't return a Java object to us for a new texture. Instead it gives us an ID, or handle, to that texture. Each time we want OpenGL ES to do something with that specific texture, we specify its ID. So here's a more complete code snippet showing how to generate a single new texture object and get its ID:
int textureIds = new int; gl.glGenTextures(1, textureIds, 0); int textureId = textureIds;
The texture object is still empty, which means it doesn't have any image data yet. Let's upload our bitmap. For this we have to first bind the texture. To bind something in OpenGL ES means that we want OpenGL ES to use that specific object for all subsequent calls until we change the binding again. Here we want to bind a texture object for which the method glBindTexture() is available. Once we have bound a texture, we can manipulate its attributes, such as its image data. Here's how we can upload Bob to our new texture object:
gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId); GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
First we bind the texture object with glBindTexture(). The first parameter specifies the type of texture we want to bind. Our image of Bob is 2D, so we use GL10.GL_TEXTURE_2D. There are other texture types, but we don't have a need for them in this book. We'll always specify GL10.GL_TEXTURE_2D for the methods that need to know the texture type we want to work with. The second parameter of that method is our texture ID. Once the method returns, all subsequent methods that work with a 2D texture will work with our texture object.
The next method call invokes a method of the GLUtils class, a class provided by the Android framework. Usually the task of uploading a texture image is pretty involved; this little helper class eases the pain for us a lot. All we need to do is specify the texture type (GL10.GL_TEXTURE_2D) the mip mapping level (we'll look at that in Chapter 11; it defaults to zero), the bitmap we want to upload, and another argument, which has to be set to zero in all cases. After this call our texture object has image data attached to it.
NOTE: The texture object and its image data are actually held in video RAM, not in our usual RAM. The texture object (and the image data) will get lost when the OpenGL ES context is destroyed (e.g., when our activity is paused and resumed). This means that we have to re-create the texture object and reupload our image data every time the OpenGL ES context is (re)-created. If we don't do this, all we'll see is a white triangle.
Was this article helpful?