我有一个带有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);
在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();
这显然是错误的。但是,我不知道如何将每个位图加载到不同的纹理中,然后如何在Render方法上切换活动纹理。
那么,我怎样才能实现这一点,以显示和移动所有六种纹理并具有流畅的运动?
答案 0 :(得分: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);
}
当应用启动时,上面的代码应该被调用一次,以便为要加载为纹理的每个位图。如果您有很多位图,您可能需要考虑某种即时纹理加载和卸载 - 但是根据您的需要,它应该足以一次加载它们。
稍后,当您要绘制某个纹理时,请确保首先绑定正确的纹理:
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textures[textureIndex]);
这将简单地告诉OpenGL图层它将用于即将到来的绘制调用的预加载纹理。请务必在每次绘制前调用此方法,以确保每次都绘制正确的纹理。请注意,此时,OpenGL不会重新创建整个纹理,而是只使用已经加载的纹理,使其非常高效。