How to manage multiple textures in OpenGL ES 2.0?

本小妞迷上赌 提交于 2019-12-06 04:42:34

问题


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?


回答1:


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.



来源:https://stackoverflow.com/questions/36036068/how-to-manage-multiple-textures-in-opengl-es-2-0

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!