Sunday, December 10, 2006

Streaming texture updates

It is possible to stream updates to a texture, often skipping a costly data copy, using the GL_ARB_pixel_buffer_object extension which was promoted to core in OpenGL 2.1

To do this, you must bind a buffer to GL_PIXEL_UNPACK_BUFFER_ARB, map it, write your texture data into the mapped buffer, unmap it, and call glTexSubImage2D referencing into the buffer.

// Bind buffer
glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, myBuffer);

// Null existing data
glBufferData(GL_PIXEL_UNPACK_BUFFER_ARB, width * height * bytesPerPixel, NULL, GL_STREAM_DRAW);

// Map buffer. Returns pointer to buffer memory
void *pboMemory = glMapBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, GL_WRITE_ONLY);

writeImage(pboMemory); // Writes data into pboMemory

// Unmaps buffer, indicating we are done writing data to it
glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER_ARB);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, (char *)NULL);

// Unbind buffer
glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, 0);


Normally the driver must copy the data you pass into glTexSubImage2D. However, by storing the data in a buffer, which is memory managed by the driver, we can avoid this copy. Furthermore, by using a universally hardware accelerated texture format (see this tip) we prevent any data processing, ensuring the fastest possible download to the GPU.


References:

GL_ARB_pixel_buffer_object specification

0 comments: