对于 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 组件?