I need to initialize an OpenGL 2D texture with zeroes.
Why? I render to this texture with OpenCL. Roughly, rendering stages are:
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.
There are several ways to do this:
1: Given a width and a height for a texture:
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]);
For maximum efficiency, you should leave some time between when you call this and when OpenCL starts its work.
2: Attach it to an FBO and use 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);
This seems like it should be faster, since there is no CPU-GPU DMA going on. But the binding and unbinding of FBOs may introduce inefficiencies. Then again, it may not. Profile it to make sure.
Note that this only works for image formats that can be used as render targets. So not compressed textures.
3: Given sufficient drivers, you can use the new ARB_clear_texture extension:
glClearTexImage(texture, 0, GL_BGRA, GL_UNSIGNED_BYTE, &clearColor);
Note that this only works for image formats whose data can be provided by standard pixel transfers. So not compressed formats.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With