如何用零有效地初始化纹理?

jir*_*mat 25 opengl

我需要用零初始化OpenGL 2D纹理.

为什么?我用OpenCL渲染到这个纹理.粗略地说,渲染阶段是:

  1. 创建RGBA纹理,用零初始化(因此它包含透明的黑色像素)
  2. OpenCL:计算某些对象可见的像素颜色并将其写入此纹理
  3. OpenGL:将环境映射添加到透明像素并显示最终图像

因此,我不需要传递任何实际的纹理数据glTexImage2d.但根据规范,当我传递data = NULL时,纹理内存被分配但未初始化.

分配一个充满零和传递的客户端内存glTexImage2D不是一个很好的选择,虽然只有一个我能想到的.

编辑:我实际上只想初始化alpha组件(RGB无论如何都会被覆盖),但我怀疑这会使情况变得更容易.

Nic*_*las 37

做这件事有很多种方法:

1:给定纹理的宽度和高度:

std::vector<GLubyte> emptyData(width * height * 4, 0);
glBindTexture(GL_TEXTURE_2D, texture);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_BGRA, GL_UNSIGNED_BYTE, &emptyData[0]);
Run Code Online (Sandbox Code Playgroud)

为了获得最大效率,您应该在打电话和OpenCL开始工作之间留出一些时间.

2:将其附加到FBO并使用glClearBuffer.

glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
glFramebufferTexture(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture, 0); //Only need to do this once.
glDrawBuffer(GL_COLOR_ATTACHMENT0); //Only need to do this once.
GLuint clearColor[4] = {0, 0, 0, 0};
glClearBufferuiv(GL_COLOR, 0, clearColor);
Run Code Online (Sandbox Code Playgroud)

这似乎应该更快,因为没有CPU-GPU DMA正在进行.但FBO的绑定和解除绑定可能会导致效率低下.然后,它可能不会.对其进行剖析以确保.

请注意,这仅适用于可用作渲染目标的图像格式.所以没有压缩纹理.

3:给定足够的驱动程序,您可以使用新的ARB_clear_texture扩展:

glClearTexImage(texture, 0, GL_BGRA, GL_UNSIGNED_BYTE, &clearColor);
Run Code Online (Sandbox Code Playgroud)

请注意,这仅适用于可通过标准像素传输提供数据的图像格式.所以不是压缩格式.


Anc*_*rio 5

只是抬头:新的GL_ARB_clear_texture(4.4中的核心)扩展专门解决了这个问题.