Is there a way that I can compress a texture within an OpenGL context, send the compressed texture into main memory, and then later bring that compressed texture back into OpenGL? I know this is a strange thing to want to do, but unfortunately I do not have a choice. If you’re curious as to why, see below:
I have a 3rd party application that uses OpenGL. I need to copy the renders from this application as a texture, and then bring that texture into my own OpenGL context. The SDK for this application allows me to tell it when to render, and I can copy the render into a texture within that context. But I cannot share resources between this context and my own, so I am forced to save the texture as a bmp in main memory, then read that bmp into a texture in my own context. It’s a bit slow, but if I can reduce the size of the texture/bmp by a factor of 4-6 using S3TC (or something), then it will be plenty fast enough.
Take a look at glCompressedTexImage2D and glGetCompressedTexImage.
I guess the steps would then be something like:
- Copy the applications output into a buffer object, i.e. glReadPixels with a buffer object bound to GL_PIXEL_PACK_BUFFER
- Use glCompressedTexImage2D with the buffer bound to GL_PIXEL_UNPACK_BUFFER
- Use glGetCompressedTexImage to get the texture into main memory
- Upload again in the other context with glCompressedTexImage2D
If you’re using glCopyTexImage, simply give it a compressed <internalformat>. Then use glGetCompressedTexImage to retrieve the bytes.
I cannot share resources between this context and my own
Some platforms have solutions for cross-process surface sharing (without any GPU<->CPU roundtrip.)
if I can reduce the size of the texture/bmp by a factor of 4-6 using S3TC (or something), then it will be plenty fast enough.
The bandwidth reduction will come at the computational expense of compressing. It might be slower.
Thanks guys, I appreciate the responses. Arekkusu, you were correct, the computational expense of compression actually makes it slightly slower. I didn’t think compression would be so expensive on a GPU, but my call to glCopyTexImage2D takes 20ms when using a compressed texture, compared to <1ms for an uncompressed texture (both copying a 640x800 buffer).
I know that the Windows 7 API provides a method to copy the backbuffer of the entire monitor into a D3D surface, but that won’t work very well for me. Perhaps they do have a method to just share surfaces between contexts…I’ll see what I can find. Thanks again.