如何在OpenGL ES for Android中有效地将一个纹理分配给另一个纹理 [英] how to assign one texture to another efficiently in OpenGL ES for Android

查看:629
本文介绍了如何在OpenGL ES for Android中有效地将一个纹理分配给另一个纹理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I want to copy texture1 to texture2. The background is that I generate 15 empty texture id and bind them to GLES11Ext.GL_TEXTURE_EXTERNAL_OES, the following is my code:

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的内容,并将纹理从 textures [0] 复制到 textures [2] 时间戳2的帧内容...它看起来像在GPU中缓冲一些纹理数据,并且在将来渲染一些。所以我想知道有没有反正这样做?我可以使用 textures [2] = textures [0] 来复制纹理数据吗?

then I always transfer camera preview to textures[0], I want copy the texture from textures[0] to textures[1] in order to keep the frame content of timestamp 1, and copy the texture from textures[0] to textures[2] in order to keep the frame content of timestamp 2... it looks like buffer some texture data in GPU and render some of that in the future. So I want to know is there anyway to do this? And can I just use textures[2]=textures[0] to copy texture data?

推荐答案

在ES 2.0中没有一个非常直接的方法来复制纹理数据。最简单的方法是使用 glCopyTexImage2D()。要使用它,你必须创建一个FBO,并附加源纹理。说如果 srcTexId 是源纹理的id, dstTexId 目标纹理的ID:

There isn't a very direct way to copy texture data in ES 2.0. The easiest way is probably using glCopyTexImage2D(). To use this, you have to create an FBO, and attach the source texture to it. Say if srcTexId is the id of the source texture, and dstTexId the id of the destination texture:

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);

话虽如此,从你的描述,我不相信这真的是你应该这是因为以下原因:

That being said, from your description, I don't believe that this is really what you should be doing, for the following reasons:


  • 我不认为复制纹理数据如上所示将适用于您正在使用的外部纹理。

  • 复制纹理数据总是昂贵的,完全没有必要解决您的问题。

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

It sounds like you want to keep the 15 most recent camera images. To do this, you can simply track which of your 15 textures contains the most recent image, and treat the list of the 15 texture ids as a circular buffer.

最初说你创建你的纹理ids:

Say initially you create your texture ids:

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

然后每次你收到一个新的框架,你写它到纹理列表中的下一个条目ids,环绕15:

Then every time you receive a new frame, you write it to the next entry in your list of texture ids, wrapping around at 15:

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

然后,每次要使用 i

Then, every time you want to use the ith frame, with 0 referring to the most recent, 1 to the frame before that, etc, you bind it with:

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

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

So the textures never get copied. You just keep track of which texture contains which frame, and access them accordingly.

这篇关于如何在OpenGL ES for Android中有效地将一个纹理分配给另一个纹理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆