【问题标题】:Using offsets into the buffer in PyOpenGL calls在 OpenGL 调用中使用缓冲区的偏移量
【发布时间】:2011-09-19 20:10:33
【问题描述】:

在 OpenGL 中,glDrawElementsindices 参数有两种不同的含义,具体取决于您是否使用 GL_ELEMENT_ARRAY_BUFFER

如果您有一个 VBO 界限,那么它是从该缓冲区开始的偏移量,而不是缓冲区本身。

使用 PyOpenGL 时,如何在 glDrawElements 调用中指定起始偏移量?如何在glMultiDrawElements 调用中指定多个起始偏移量?

【问题讨论】:

  • 顺便说一下,GL_INDEX_ARRAY 具有完全不同的含义(每个顶点颜色索引)。你的意思是GL_ELEMENT_ARRAY_BUFFER
  • 是的,我打错了一千次​​pan>

标签: python numpy opengl ctypes pyopengl


【解决方案1】:

在以下示例中,使用了 6 个索引的列表,它们可以形成一个由 2 个三角形基元组成的四边形。

indices = [0, 1, 2, 0, 2, 3]

由于传递给 OpenGL 函数的数据必须由连贯缓冲区中的固定大小单元组成,因此值列表必须存储到浮点数组中。 相干数组缓冲区可以通过ctypes 库或numpy.array 库创建。
数组元素的类型必须匹配值类型枚举常量,该常量在调用glDrawElementsglMultiDrawElements 时设置:

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 OpenGLcompatibility profile 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 索引,用于 GL_UNSIGNED_INT 类型的缓冲区:

glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, ctypes.c_void_p(3 * 4))

glMultiDrawElements的用法很相似。

使用compatibility profile 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)

然后索引参数被视为指向字节偏移数组的指针。下面将一个偏移量为 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)

【讨论】:

    猜你喜欢
    • 2012-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多