Skip to content

OpenGL:PixelBufferObjects

A Buffer Object that is used for asynchronous pixel transfer operations is called a Pixel Buffer Object.

APIs

glMapBuffer

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)

See also

Favorite site