'How to efficiently initialize texture with zeroes?
I need to initialize an OpenGL 2D texture with zeroes.
Why? I render to this texture with OpenCL. Roughly, rendering stages are:
- Create RGBA texture, initialize with zeros (so it contains transparent black pixels)
- OpenCL: compute color of pixels where some objects are visible and write them to this texture
- OpenGL: add environment mapping to the transparent pixels and display final image
I therefore do not need to pass any actual texture data to glTexImage2d. But according to the spec, when I pass data=NULL, the texture memory is allocated but not initialized.
Allocating a client-side memory filled with zeroes and passing to glTexImage2D is not a very good option although only one I can think of.
EDIT: I actually want to init only alpha component (RGB will get overriden anyway), but I doubt this make the situation any easier.
Solution 1:[1]
Just a heads up: The new GL_ARB_clear_texture (core in 4.4) extension specifically addresses this problem.
Solution 2:[2]
glTexSubImageis filled with the whole image:
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;
use Pixel Buffer to copy data from gpu, this method is faster and better
i. 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);
Solution 3:[3]
Maybe you can set the texture as the rendering target for the first pass and draw a black primitive. It may be faster since there are no memory transfert between the ram and graphic card.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | jeyko |
| Solution 3 | neodelphi |
