Using Offsets Into The Buffer In Pyopengl Calls
Solution 1:
In the following examples a list of 6 indices is used, which may form a quad which consists of 2 triangle primitives.
indices = [0, 1, 2, 0, 2, 3]
Since the data which is passed to the OpenGL functions has to consist of fixed size units in a coherent buffer, the list of values has to be stored to an array of floats.
Coherent array buffers can be created either by ctypes library or numpy.array
library.
The type of the array elements has to match value type enumerator constant, which is set, at the call of glDrawElements
or glMultiDrawElements
:
ctypes.c_ubyte / numpy.uint8 <-> GL_UNSIGNED_BYTE
ctypes.c_ushort / numpy.uint16 <-> GL_UNSIGNED_SHORT
ctypes.c_uint / numpy.uint32 <-> GL_UNSIGNED_INT
Using ctypes
:
import ctypes
indexArray = (ctypes.c_uint * 6)(*indices)
Using numpy
:
import numpy
indexArray = numpy.array(indices, dtype=numpy.uint32)
For using an index buffer and glDrawElements
there are different opportunities.
Using Legacy OpenGL (compatibility profile xontext), the buffer can be directly passed to glDrawElements
. The pointer to the array data is passed to the function.
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, indexArray)
If named element array buffer object is stated in the vertex array object, then the last parameter of glDrawElements
is treated as a byte offset into the buffer object's data store.
glBindVertexArray(vao)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo)
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexArray, GL_STATIC_DRAW)
If the indices should be drawn, starting at the 1st element of the buffer, then the last parameter can be None
, which is equivalent to ctypes.c_void_p(0)
:
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, None)
If the drawing should not start with the first index, then the byte offset of the start index has to be calculated. e.g. 3*4
sets the start to the 3 index, for a buffer of type GL_UNSIGNED_INT
:
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, ctypes.c_void_p(3 * 4))
The use of glMultiDrawElements
is very similar.
Using a compatibility profile xontext, the buffer pointers can be directly passed to the OpenGL function.
To arrays of indices have to be generated:
Using ctypes
:
indexArray1 = (ctypes.c_uint * 3)(0, 1, 2)
indexArray2 = (ctypes.c_uint * 3)(0, 2, 3)
Using numpy
:
indexArray1 = numpy.array([0, 1, 2], dtype=numpy.uint32)
indexArray2 = numpy.array([0, 2, 3], dtype=numpy.uint32)
The pointers to the buffers have to be arranged to an array of pointers:
Using ctypes
the pointer to the index data arrays is get by ctypes.addressof()
:
indexPtr = (ctypes.c_void_p * 2)(ctypes.addressof(indexArray1),ctypes.addressof(indexArray2))
Using numpy
the pointer to the index data arrays is get by numpy.ndarray.ctypes
:
indexPtr = numpy.array([indexArray1.ctypes.data, indexArray2.ctypes.data], dtype=numpy.intp)
This array of pointer can be passed to the OpenGL function:
counts = [3, 3]
glMultiDrawElements(GL_TRIANGLES, counts, GL_UNSIGNED_INT, indexPtr, 2)
If a vertex array object with an named element array buffer is used,
glBindVertexArray(vao)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo)
then the index parameter is treated as a pointer to an array of byte offsets. In the following an array with 2 offset is passed to the function. 0 identifies the 1st index in the array and 3*4 the 3rd index.
Using ctypes
:
indexPtr = (ctypes.c_void_p * 2)(0, 3 * 4)
counts = [3, 3]
glMultiDrawElements(GL_TRIANGLES, counts, GL_UNSIGNED_INT, indexPtr, 2)
Using numpy
:
indexPtr = np.array([0, 3*4], dtype=numpy.intp)
counts = [3, 3]
glMultiDrawElements(GL_TRIANGLES, counts, GL_UNSIGNED_INT, indexPtr, 2)
Post a Comment for "Using Offsets Into The Buffer In Pyopengl Calls"