如何在OpenGL ES for Android中有效地为一个纹理分配一个纹理

时间:2016-10-09 07:21:36

标签: android copy textures opengl-es-2.0

我想将texture1复制到texture2。背景是我生成15个空纹理id并将它们绑定到GLES11Ext.GL_TEXTURE_EXTERNAL_OES,以下是我的代码:

int[] textures = new int[15];
GLES20.glGenTextures(15, textures, 0);
GlUtil.checkGlError("glGenTextures");

for(int i=0;i<15;i++)
    GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, textures[i]);

然后我总是将相机预览转移到textures[0],我希望将纹理从textures[0]复制到textures[1],以保持时间戳1的帧内容,并从{复制纹理{1}}到textures[0]以保持时间戳2的帧内容...它看起来像缓冲GPU中的一些纹理数据并在将来渲染其中一些。所以我想知道有没有这样做呢?我可以使用textures[2]复制纹理数据吗?

1 个答案:

答案 0 :(得分:1)

在ES 2.0中复制纹理数据并不是一种非常直接的方法。最简单的方法可能是使用glCopyTexImage2D()。要使用它,您必须创建一个FBO,并将源纹理附加到它。假设srcTexId是源纹理的id,dstTexId是目标纹理的id:

GLuint fboId = 0;
glGenFramebuffers(1, &fboId);
glBindFramebuffer(GL_FRAMEBUFFER, fboId);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, srcTexId, 0);

glBindTexture(GL_TEXTURE_2D, dstTexId);
glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, width, height, 0);

话虽如此,根据您的描述,我不相信这是您应该做的事情,原因如下:

  • 我不认为如上所示复制纹理数据适用于您正在使用的外部纹理。
  • 复制纹理数据总是很昂贵,听起来完全没必要解决你的问题。

听起来你想要保留15张最近的相机图像。为此,您可以简单地跟踪15个纹理中的哪个包含最新图像,并将15个纹理ID的列表视为循环缓冲区。

首先说你创建了纹理ID:

int[] textures = new int[15];
GLES20.glGenTextures(15, textures, 0);
int newestIdx = 0;

然后,每次收到新框架时,都会将其写入纹理ID列表中的下一个条目,并在15处包围:

newestIdx = (newestIdx + 1) % 15;
GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, textures[newestIdx]);
// Capture new frame into currently bound texture.

然后,每次你想要使用i帧时,0表示最近的帧,1表示之前的帧,等等,你将它绑定到:

GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, textures[(newestIdx + i) % 15]);

所以纹理永远不会被复制。您只需跟踪哪个纹理包含哪个帧,然后相应地访问它们。