在OpenGL ES 2.0中生成和更新8位灰度纹理

时间:2015-08-07 19:38:35

标签: opengl-es glteximage2d

对于OpenGL纹理缓存,我需要初始化一个大的(≥2048x2048)纹理,然后经常更新它的一小部分。

以下(伪)代码有效:

// Setup texture
int[] buffer = new int[2048*2048 / 4]; // Generate dummy buffer with 1 byte per pixel
int id = glGenTexture();
glBindTexture(GL_TEXTURE_2D, id);
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 2048, 2048, 0, GL_ALPHA, GL_UNSIGNED_BYTE, buffer);

// Perform update
glBindTexture(GL_TEXTURE_2D, id);
glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, width, height, GL_ALPHA, GL_UNSIGNED_BYTE, data);

但是我发现完全不必要的4MB内部缓冲区的创建有点不可取。所以,我尝试了以下方法:

// Setup texture
int id = glGenTexture();
glBindTexture(GL_TEXTURE_2D, id);
glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 0, 0, 2048, 2048, 0);

这给了我一个GL_INVALID_OPERATION错误,我认为这是由于帧缓冲区不包含alpha值这一事实造成的,所以不是将其设置为1,而是调用失败。

下一次尝试:

// Setup texture
int id = glGenTexture();
glBindTexture(GL_TEXTURE_2D, id);
glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 0, 0, 2048, 2048, 0);

这样可行,但现在我的glTexSubImage2D调用因GL_INVALID_OPERATION失败,因为它指定了GL_ALPHA而不是GL_LUMINANCE。所以,我也改变了这一点:

// Perform update
glBindTexture(GL_TEXTURE_2D, id);
glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, width, height, GL_LUMINANCE, GL_UNSIGNED_BYTE, data);

我更改了着色器,以便从r而不是a组件中读取值。

这适用于某些设备,但在iPhone 3GS上,我仍然在glTexSubImage2D调用中得到GL_INVALID_OPERATION错误。为什么?我该如何解决这个问题?有没有办法,例如,更改内部纹理格式?或者我可以创建一些其他具有alpha组件的framebuffer,我可以将其用作glCopyTexImage2D的源吗?

1 个答案:

答案 0 :(得分:1)

如果您只想分配空纹理,

data可以在glTexImage2D()来电中NULL

  

data可能是空指针。在这种情况下,纹理存储器被分配以容纳widthheight的纹理。然后,您可以下载子纹理以初始化此纹理内存。如果用户尝试将未初始化的纹理图像部分应用于基元,则图像未定义。