Vertex buffer objects in PyOpenGL
On August 31, 2007 in
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.