1

对于 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 int 缓冲区的创建至少可以说有点不可取。所以,我尝试了以下方法:

// 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 错误。为什么?我该如何解决这个问题?有没有办法,例如,改变内部纹理格式?或者我可以创建一些其他的帧缓冲区,它有一个可以用作 glCopyTexImage2D 源的 alpha 组件?

4

1 回答 1

1

data如果您只想分配一个空纹理,可以NULL在您的通话中:glTexImage2D()

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

于 2015-08-07T19:50:33.760 回答