OpenGL:PixelBufferObjects
A Buffer Object that is used for asynchronous pixel transfer operations is called a Pixel Buffer Object.
APIs
glMapBuffer
- glMapBuffer : PyOpenGL 3.1.0 GL Man Pages
- opengl-programmable/08-pbo.py at master · pelson/opengl-programmable
PyOpenGL Example
from ctypes import addressof, c_void_p, create_string_buffer, memmove
from OpenGL import GL
# ...
@override
def on_create(self) -> None:
assert self._texture == 0
assert self._pbo == 0
self._texture = GL.glGenTextures(1)
GL.glBindTexture(GL.GL_TEXTURE_2D, self._texture)
GL.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR)
GL.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR)
GL.glTexImage2D(
GL.GL_TEXTURE_2D,
0,
GL.GL_RGB,
self._min_width,
self._min_height,
0,
GL.GL_RGB,
GL.GL_UNSIGNED_BYTE,
None,
)
GL.glBindTexture(GL.GL_TEXTURE_2D, 0)
self._pbo = GL.glGenBuffers(1)
GL.glBindBuffer(GL.GL_PIXEL_UNPACK_BUFFER, self._pbo)
size = self._min_width * self._min_height * 3
GL.glBufferData(GL.GL_PIXEL_UNPACK_BUFFER, size, None, GL.GL_STREAM_DRAW)
GL.glBindBuffer(GL.GL_PIXEL_UNPACK_BUFFER, 0)
assert self._texture != 0
assert self._pbo != 0
@override
def on_destroy(self) -> None:
assert self._texture != 0
assert self._pbo != 0
GL.glDeleteTextures(1, self._texture)
self._texture = 0
GL.glDeleteBuffers(1, self._pbo)
self._pbo = 0
def update_texture_image_2d(self, width: int, height: int, pixels: bytes) -> None:
GL.glBindTexture(GL.GL_TEXTURE_2D, self._texture)
GL.glTexImage2D(
GL.GL_TEXTURE_2D,
0,
GL.GL_RGB,
width,
height,
0,
GL.GL_RGB,
GL.GL_UNSIGNED_BYTE,
pixels,
)
GL.glBindTexture(GL.GL_TEXTURE_2D, 0)
def update_texture_with_pbo(
self,
width: int,
height: int,
channels: int,
pixels: bytes,
) -> None:
GL.glBindBuffer(GL.GL_PIXEL_UNPACK_BUFFER, self._pbo)
GL.glBindTexture(GL.GL_TEXTURE_2D, self._texture)
GL.glTexSubImage2D(
GL.GL_TEXTURE_2D,
0,
0,
0,
width,
height,
GL.GL_RGB,
GL.GL_UNSIGNED_BYTE,
c_void_p(0),
)
size = width * height * channels
GL.glBindBuffer(GL.GL_PIXEL_UNPACK_BUFFER, self._pbo)
GL.glBufferData(GL.GL_PIXEL_UNPACK_BUFFER, size, None, GL.GL_STREAM_DRAW)
buffer_ptr = GL.glMapBuffer(GL.GL_PIXEL_UNPACK_BUFFER, GL.GL_WRITE_ONLY)
if buffer_ptr:
pixels_ptr = addressof(create_string_buffer(pixels, size))
memmove(buffer_ptr, pixels_ptr, size)
GL.glUnmapBuffer(GL.GL_PIXEL_UNPACK_BUFFER)
GL.glBindBuffer(GL.GL_PIXEL_UNPACK_BUFFER, 0)