在 OpenGL 中,indices
参数 forglDrawElements
有两种不同的含义,具体取决于您是否使用GL_ELEMENT_ARRAY_BUFFER
。
如果您有一个 VBO 界限,那么它是从该缓冲区开始的偏移量,而不是缓冲区本身。
使用 PyOpenGL 时,如何指定在glDrawElements
调用中开始的偏移量?如何在glMultiDrawElements
调用中指定多个起始偏移量?
在以下示例中,使用了 6 个索引的列表,它们可以形成由 2 个三角形基元组成的四边形。
indices = [0, 1, 2, 0, 2, 3]
由于传递给 OpenGL 函数的数据必须由连贯缓冲区中的固定大小单元组成,因此值列表必须存储到浮点数组中。相干数组缓冲区可以由ctypes库或numpy.array
库创建。数组元素的类型必须与在调用or
时设置的值类型枚举器常量匹配:glDrawElements
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
使用ctypes
:
import ctypes
indexArray = (ctypes.c_uint * 6)(*indices)
使用numpy
:
import numpy
indexArray = numpy.array(indices, dtype=numpy.uint32)
对于使用索引缓冲区,glDrawElements
有不同的机会。
使用Legacy OpenGL(兼容性配置文件 xontext),缓冲区可以直接传递给glDrawElements
. 指向数组数据的指针被传递给函数。
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, indexArray)
如果在顶点数组对象中声明了命名元素数组缓冲区对象,则最后一个参数glDrawElements
被视为缓冲区对象数据存储中的字节偏移量。
glBindVertexArray(vao)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo)
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexArray, GL_STATIC_DRAW)
如果应该从缓冲区的第一个元素开始绘制索引,则最后一个参数可以是None
,相当于ctypes.c_void_p(0)
:
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, None)
如果绘图不应从第一个索引开始,则必须计算起始索引的字节偏移量。例如3*4
,对于类型为 3 的缓冲区,将开始设置为 3 索引GL_UNSIGNED_INT
:
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, ctypes.c_void_p(3 * 4))
的使用glMultiDrawElements
非常相似。
使用兼容性配置文件 xontext,缓冲区指针可以直接传递给 OpenGL 函数。
必须生成索引数组:
使用ctypes
:
indexArray1 = (ctypes.c_uint * 3)(0, 1, 2)
indexArray2 = (ctypes.c_uint * 3)(0, 2, 3)
使用numpy
:
indexArray1 = numpy.array([0, 1, 2], dtype=numpy.uint32)
indexArray2 = numpy.array([0, 2, 3], dtype=numpy.uint32)
指向缓冲区的指针必须排列为指针数组:
使用ctypes
指向索引数据数组的指针是通过ctypes.addressof()
:
indexPtr = (ctypes.c_void_p * 2)(ctypes.addressof(indexArray1),ctypes.addressof(indexArray2))
使用numpy
指向索引数据数组的指针是通过numpy.ndarray.ctypes
:
indexPtr = numpy.array([indexArray1.ctypes.data, indexArray2.ctypes.data], dtype=numpy.intp)
这个指针数组可以传递给 OpenGL 函数:
counts = [3, 3]
glMultiDrawElements(GL_TRIANGLES, counts, GL_UNSIGNED_INT, indexPtr, 2)
如果使用具有命名元素数组缓冲区的顶点数组对象,
glBindVertexArray(vao)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo)
然后 index 参数被视为指向字节偏移数组的指针。下面将一个偏移量为 2 的数组传递给函数。0 标识数组中的第一个索引,3*4 标识第三个索引。
使用ctypes
:
indexPtr = (ctypes.c_void_p * 2)(0, 3 * 4)
counts = [3, 3]
glMultiDrawElements(GL_TRIANGLES, counts, GL_UNSIGNED_INT, indexPtr, 2)
使用numpy
:
indexPtr = np.array([0, 3*4], dtype=numpy.intp)
counts = [3, 3]
glMultiDrawElements(GL_TRIANGLES, counts, GL_UNSIGNED_INT, indexPtr, 2)