Vertex buffer objects in PyOpenGL
Decided to move some of my vertex array code over to ARB_vertex_buffer_object
,
to see if I could get a bit of a speed boost out of PyOpenGL. Much to my dismay,
these functions don’t have the sexy extension wrappers I talked about
before, so it was a bit of a chore to get it all
working.
Here’s a little wrapper class I wrote to make things easier:
from OpenGL.GL import *
from OpenGL.raw import GL
from OpenGL.arrays import ArrayDatatype as ADT
class VertexBuffer(object):
def __init__(self, data, usage):
self.buffer = GL.GLuint(0)
glGenBuffers(1, self.buffer)
self.buffer = self.buffer.value
glBindBuffer(GL_ARRAY_BUFFER_ARB, self.buffer)
glBufferData(GL_ARRAY_BUFFER_ARB, ADT.arrayByteCount(data),
ADT.voidDataPointer(data), usage)
def __del__(self):
glDeleteBuffers(1, GL.GLuint(self.buffer))
def bind(self):
glBindBuffer(GL_ARRAY_BUFFER_ARB, self.buffer)
def bind_vertexes(self, size, type, stride=0):
self.bind()
glVertexPointer(size, type, stride, None)
... snipped for length ...
Download buffers.py
.
So, how to use it? Let’s say you have a Python list
with a bunch of vertexes
with float
x
, y
, and z
components:
verts = [[x, y, z], [x, y, z], [x, y, z], ...]
You’ll have to use NumPy or an equivalent to convert it to a PyOpenGL compatible array:
import numpy
numpy_verts = numpy.array(verts, dtype=numpy.float32)
Create the VertexBuffer object with it:
buffer = VertexBuffer(numpy_verts, GL_STATIC_DRAW)
Use it in your day to day rendering:
glEnableClientState(GL_VERTEX_ARRAY)
buffer.bind_vertexes(3, GL_FLOAT)
glDrawElementsui(GL_TRIANGLES, indexes)
They’re not shown in the snippet, but I’ve also defined bind_colors
,
bind_edgeflags
, bind_indexes
, bind_normals
, and bind_texcoords
, as
shortcuts for the rest of the GL array functions.