I have a OpenGL ES 2.0 app with 6 different textures. What I need is to draw and move them all at the same time. I was able to do it, but the movement was laggy because I was loading the bitmaps into the textures all the time. For each texture, I do the following on the Render method:
setupImage(texture1);
GLES20.glVertexAttribPointer(mPositionHandle, 3, GLES20.GL_FLOAT, false, 0, vertexBufferT1);
GLES20.glVertexAttribPointer(mTexCoordLoc, 2, GLES20.GL_FLOAT, false, 0, uvBufferT1);
GLES20.glDrawElements(GLES20.GL_TRIANGLES, indicesT1.length, GLES20.GL_UNSIGNED_SHORT, drawListBufferT1);
And on the setupImage method, I do this:
// Create the bitmap
int id = mContext.getResources().getIdentifier("drawable/texture1", null, mContext.getPackageName());
Bitmap bmp = BitmapFactory.decodeResource(mContext.getResources(), id);
// Bind texture to texturename
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textures[0]);
// Set filtering
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
// Set wrapping mode
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
// Load the bitmap into the bound texture.
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bmp, 0);
// Free bitmap
bmp.recycle();
This is obviously wrong. However, I don't know how to load each bitmap into a different texture and then how can I switch the active texture on the Render method.
So, how can I achieve this, in order to display and move all the six textures and have a fluid movement?
You are right, what you're doing is very wasteful. An easy way to maintain the textures is to simply use that textures[]
array in a smarter way.
Ever wonder why that variable is an array of size 1? Well, you can use it to hold more than 1 texture! Simply define it as a larger array (size 6 for you). Once you do this, you will be able to load multiple bitmaps into textures when the app starts and then just bind the correct texture when you're about to draw it.
Here's an example:
private int[] textures = new int[6];
private void loadTexture(Bitmap bitmap, int textureIndex) {
GLES20.glGenTextures ( 1, textures, textureIndex );
GLES20.glBindTexture ( GLES20.GL_TEXTURE_2D, textures[textureIndex] );
//.. call glTexParameter as needed
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
}
The code above should be called once, when the app starts up, for every bitmap you want to load as a texture. If you have many bitmaps, you might want to consider some sort of just-in-time texture loading, and unloading - but for your needs, it should be enough to just load them all at once.
Later, when you're about to draw a certain texture, make sure you first bind the correct one:
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textures[textureIndex]);
This will simply tell the OpenGL layer which pre-loaded texture it's going to be using for the up-coming draw call. Be sure to call this before each draw to ensure you draw the correct texture each time. Note that at this point, OpenGL will not re-create the whole texture, but rather, just use the already loaded one, making it very efficient.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With