如何在OpenGL ES 2.0中管理多个纹理?

Dav*_*tos 5 android textures opengl-es

我有一个带有6种不同纹理的OpenGL ES 2.0应用程序.我需要的是同时绘制和移动它们.我能够做到这一点,但运动是滞后的,因为我一直在将位图加载到纹理中.对于每个纹理,我在Render方法上执行以下操作:

    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);
Run Code Online (Sandbox Code Playgroud)

在setupImage方法上,我这样做:

    // 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();
Run Code Online (Sandbox Code Playgroud)

这显然是错误的.但是,我不知道如何将每个位图加载到不同的纹理中,然后如何在Render方法上切换活动纹理.

那么,我怎样才能实现这一目标,以显示和移动所有六种纹理并具有流畅的运动?

Gil*_*yof 6

你是对的,你所做的是非常浪费.维护纹理的一种简单方法textures[]是以更智能的方式简单地使用该数组.

有没有想过为什么这个变量是一个大小为1的数组?好吧,你可以使用它来保存超过1个纹理!只需将其定义为更大的数组(大小为6).完成此操作后,您将能够在应用程序启动时将多个位图加载到纹理中,然后在您即将绘制它时绑定正确的纹理.

这是一个例子:

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);
}
Run Code Online (Sandbox Code Playgroud)

当应用程序启动时,上面的代码应该被调用一次,用于每个要作为纹理加载的位图.如果您有许多位图,您可能需要考虑某种即时纹理加载和卸载 - 但是根据您的需要,它应该足以一次加载它们.

稍后,当您要绘制某个纹理时,请确保首先绑定正确的纹理:

GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textures[textureIndex]);
Run Code Online (Sandbox Code Playgroud)

这将简单地告诉OpenGL层它将用于即将到来的绘制调用的预加载纹理.请务必在每次绘制前调用此方法,以确保每次都绘制正确的纹理.请注意,此时,OpenGL不会重新创建整个纹理,而只是使用已经加载的纹理,使其非常高效.