我需要用零初始化OpenGL 2D纹理。
为什么呢?我用OpenCL渲染到这个纹理。粗略地说,渲染阶段是:
因此,我不需要将任何实际纹理数据传递给glTexImage2d
。但根据规范,当我传递data = NULL时,纹理内存已分配但未初始化。
分配一个充满零的客户端内存并传递给glTexImage2D
并不是一个很好的选择,尽管我只能想到一个。
编辑:我实际上只想初始化alpha组件(无论如何RGB都会被覆盖),但我怀疑这会让情况变得更容易。
答案 0 :(得分:36)
有几种方法可以做到这一点:
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]);
为了获得最大效率,您应该在打电话和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);
这似乎应该更快,因为没有CPU-GPU DMA正在进行。但FBO的绑定和解除绑定可能会导致效率低下。然后,它可能不会。对其进行剖析以确保。
请注意,这仅适用于可用作渲染目标的图像格式。所以不是压缩纹理。
3:如果有足够的驱动程序,您可以使用新的ARB_clear_texture扩展程序:
glClearTexImage(texture, 0, GL_BGRA, GL_UNSIGNED_BYTE, &clearColor);
请注意,这仅适用于standard pixel transfers可提供数据的图像格式。所以不是压缩格式。
答案 1 :(得分:5)
只是提前:新的GL_ARB_clear_texture(核心4.4)扩展专门解决了这个问题。
答案 2 :(得分:1)
也许您可以将纹理设置为第一遍的渲染目标并绘制黑色基元。它可能更快,因为ram和显卡之间没有内存传输。
答案 3 :(得分:1)
glTexSubImage
充满整个图片:
GLfloat* pData = new GLfloat[1024*768*4];
memset(pData, 0x00, 1024*768*4*sizeof(GLfloat));
glBindTexture(GL_TEXTURE_2D, m_ImageTex);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1024, 768, GL_RGBA, GL_FLOAT, pData);
glBindTexture(GL_TEXTURE_2D, 0);
delete pData;
使用 Pixel Buffer 从gpu复制数据,这种方法更快更好
我。 init PBO
glGenBuffers(1, &m_PixelBuffer);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, m_PixelBuffer);
glBufferData(GL_PIXEL_UNPACK_BUFFER, SCREEN_WIDTH*SCREEN_HEIGHT*4*sizeof(GLfloat), NULL, GL_STATIC_DRAW);
GLfloat* pData = nullptr;
pData = (GLfloat*)glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY);
memset(pData, 0x00, 1024*768*4*sizeof(GLfloat));
glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
II。
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, m_PixelBuffer);
glBindTexture(GL_TEXTURE_2D, m_ImageTex);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, GL_RGBA, GL_FLOAT, NULL);
glBindTexture(GL_TEXTURE_2D, 0);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);