在 OpenGL ES 2.0 中生成和更新 8 位灰度纹理
Generating and updating 8-bit gray-scale texture in OpenGL ES 2.0
对于 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-buffer 至少可以说有点不受欢迎。所以,我尝试了以下方法:
// 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 组件的帧缓冲区,我可以将其用作 glCopyTexImage2D 的源吗?
如果您只想分配一个空纹理,data
可以是 NULL
在您的 glTexImage2D()
调用中:
data
may be a null pointer. In this case, texture memory is allocated to accommodate a texture of width
and height
. You can then download subtextures to initialize this texture memory. The image is undefined if the user tries to apply an uninitialized portion of the texture image to a primitive.
对于 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-buffer 至少可以说有点不受欢迎。所以,我尝试了以下方法:
// 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 组件的帧缓冲区,我可以将其用作 glCopyTexImage2D 的源吗?
data
可以是 NULL
在您的 glTexImage2D()
调用中:
data
may be a null pointer. In this case, texture memory is allocated to accommodate a texture ofwidth
andheight
. You can then download subtextures to initialize this texture memory. The image is undefined if the user tries to apply an uninitialized portion of the texture image to a primitive.