使用 PyOpenGL 从索引缓冲区渲染框时出现问题
Trouble rendering box from index buffer with PyOpenGL
我正在努力完成 2.1 版 OpenGL 红皮书的开头部分,并将我学到的知识转化为 PyOpenGL 绑定,同时将 Qt 用于窗口框架。但出于某种原因,我似乎无法接到 glDrawElements()
的电话以实际在屏幕上绘制任何内容。这是我到目前为止的相关功能。
def initializeGL(self):
self.qglClearColor(QtGui.QColor(0,0,150))
self.initGeometry()
GL.glEnable(GL.GL_DEPTH_TEST)
self.buffers = GL.glGenBuffers(2)
def paintGL(self):
GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT)
GL.glLoadIdentity()
GL.glTranslate(0.0, 0.0, -50.0)
GL.glScale(20.0, 20.0, 20.0)
GL.glRotate(self.yRotDeg, 0.2, 1.0, 0.3)
GL.glTranslate(-0.5, -0.5, -0.5)
VERTICES = 0
INDICES = 1
GL.glBindBuffer(GL.GL_ARRAY_BUFFER, self.buffers[VERTICES])
GL.glBufferData(GL.GL_ARRAY_BUFFER, len(self.cubeVtxArray), self.cubeVtxArray, GL.GL_STATIC_DRAW)
offset = ctypes.c_void_p(0)
GL.glVertexPointer(3, GL.GL_FLOAT, 0, offset)
#GL.glVertexPointerf(self.cubeVtxArray)
GL.glEnableClientState(GL.GL_VERTEX_ARRAY)
GL.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, self.buffers[INDICES])
GL.glBufferData(GL.GL_ELEMENT_ARRAY_BUFFER, len(self.cubeIdxArray), self.cubeIdxArray, GL.GL_STATIC_DRAW)
GL.glDrawElements(GL.GL_QUADS, 24, GL.GL_UNSIGNED_BYTE, offset)
#GL.glDrawArrays(GL.GL_QUADS, 0, 24)
def initGeometry(self):
self.cubeVtxArray = np.array(
[[0.0, 0.0, 0.0],
[1.0, 0.0, 0.0],
[1.0, 1.0, 0.0],
[0.0, 1.0, 0.0],
[0.0, 0.0, 1.0],
[1.0, 0.0, 1.0],
[1.0, 1.0, 1.0],
[0.0, 1.0, 1.0]], dtype=np.float32)
self.cubeIdxArray = np.array([
0, 1, 2, 3,
3, 2, 6, 7,
1, 0, 4, 5,
2, 1, 5, 6,
0, 3, 7, 4,
7, 6, 5, 4], dtype=np.uint8)
当我 运行 程序时,它确实将屏幕清除为正确的颜色,但未绘制立方体。有趣的是,如果我尝试使用 glDrawArray()
函数进行渲染,它确实会渲染(尽管它看起来不像立方体,因为它正在渲染索引)。这里可能出了什么问题?
编辑:
这是 glDrawElements() and glDrawArrays().
结果的几个视频
编辑2:
我的问题(正如 user1118321 指出的那样)是我将一个数组长度作为第二个参数传递给 glBufferData()
,我应该在其中传递一个以字节为单位的大小。 python 的解决方案是:
from OpenGL.arrays.arraydatatype import ArrayDatatype
- 使用
ArrayDatatype.arrayByteCount(self.cubeVtxArray)
作为 glBufferData()
的第二个参数(对于任何其他缓冲区也是如此)。
编辑 3:
我实际上想对此进行更多编辑,因为我刚刚结束了对 glBufferData() 调用的另一个相关问题。我天真地想,我应该也可以像ArrayDatatype.arrayByteCount()一样使用sys.getsizeof()。如果您的缓冲区数据是我最终使用的 numpy 数组,则情况并非如此。 sys.getsizeof() returns 大小错误,会不经意地把你的数组切碎一点。再见了我生命中的三天....
我觉得有一点不对劲,就是您将数组大小作为第二个参数发送给 glBufferData
。您可能需要将数据的字节数作为该参数发送。所以它会是这样的:
len(self.cubeVtxArray) * numBytesPerElement
其中 numBytesPerElement
每个浮点数 4 个字节乘以每个顶点 3 个浮点数 = 12 个字节。
在Python中,您可以通过执行以下操作获取数组中的字节数:
来自 OpenGL.arrays.arraydatatype import ArrayDatatype
使用 ArrayDatatype.arrayByteCount(self.cubeVtxArray)
作为 glBufferData()
的第二个参数(对于任何其他缓冲区也是如此)。
你需要为 self.cubeIdxArray
做同样的事情,尽管在这种情况下 numBytesPerElement
将是 1。
我正在努力完成 2.1 版 OpenGL 红皮书的开头部分,并将我学到的知识转化为 PyOpenGL 绑定,同时将 Qt 用于窗口框架。但出于某种原因,我似乎无法接到 glDrawElements()
的电话以实际在屏幕上绘制任何内容。这是我到目前为止的相关功能。
def initializeGL(self):
self.qglClearColor(QtGui.QColor(0,0,150))
self.initGeometry()
GL.glEnable(GL.GL_DEPTH_TEST)
self.buffers = GL.glGenBuffers(2)
def paintGL(self):
GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT)
GL.glLoadIdentity()
GL.glTranslate(0.0, 0.0, -50.0)
GL.glScale(20.0, 20.0, 20.0)
GL.glRotate(self.yRotDeg, 0.2, 1.0, 0.3)
GL.glTranslate(-0.5, -0.5, -0.5)
VERTICES = 0
INDICES = 1
GL.glBindBuffer(GL.GL_ARRAY_BUFFER, self.buffers[VERTICES])
GL.glBufferData(GL.GL_ARRAY_BUFFER, len(self.cubeVtxArray), self.cubeVtxArray, GL.GL_STATIC_DRAW)
offset = ctypes.c_void_p(0)
GL.glVertexPointer(3, GL.GL_FLOAT, 0, offset)
#GL.glVertexPointerf(self.cubeVtxArray)
GL.glEnableClientState(GL.GL_VERTEX_ARRAY)
GL.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, self.buffers[INDICES])
GL.glBufferData(GL.GL_ELEMENT_ARRAY_BUFFER, len(self.cubeIdxArray), self.cubeIdxArray, GL.GL_STATIC_DRAW)
GL.glDrawElements(GL.GL_QUADS, 24, GL.GL_UNSIGNED_BYTE, offset)
#GL.glDrawArrays(GL.GL_QUADS, 0, 24)
def initGeometry(self):
self.cubeVtxArray = np.array(
[[0.0, 0.0, 0.0],
[1.0, 0.0, 0.0],
[1.0, 1.0, 0.0],
[0.0, 1.0, 0.0],
[0.0, 0.0, 1.0],
[1.0, 0.0, 1.0],
[1.0, 1.0, 1.0],
[0.0, 1.0, 1.0]], dtype=np.float32)
self.cubeIdxArray = np.array([
0, 1, 2, 3,
3, 2, 6, 7,
1, 0, 4, 5,
2, 1, 5, 6,
0, 3, 7, 4,
7, 6, 5, 4], dtype=np.uint8)
当我 运行 程序时,它确实将屏幕清除为正确的颜色,但未绘制立方体。有趣的是,如果我尝试使用 glDrawArray()
函数进行渲染,它确实会渲染(尽管它看起来不像立方体,因为它正在渲染索引)。这里可能出了什么问题?
编辑: 这是 glDrawElements() and glDrawArrays().
结果的几个视频编辑2:
我的问题(正如 user1118321 指出的那样)是我将一个数组长度作为第二个参数传递给 glBufferData()
,我应该在其中传递一个以字节为单位的大小。 python 的解决方案是:
from OpenGL.arrays.arraydatatype import ArrayDatatype
- 使用
ArrayDatatype.arrayByteCount(self.cubeVtxArray)
作为glBufferData()
的第二个参数(对于任何其他缓冲区也是如此)。
编辑 3: 我实际上想对此进行更多编辑,因为我刚刚结束了对 glBufferData() 调用的另一个相关问题。我天真地想,我应该也可以像ArrayDatatype.arrayByteCount()一样使用sys.getsizeof()。如果您的缓冲区数据是我最终使用的 numpy 数组,则情况并非如此。 sys.getsizeof() returns 大小错误,会不经意地把你的数组切碎一点。再见了我生命中的三天....
我觉得有一点不对劲,就是您将数组大小作为第二个参数发送给 glBufferData
。您可能需要将数据的字节数作为该参数发送。所以它会是这样的:
len(self.cubeVtxArray) * numBytesPerElement
其中 numBytesPerElement
每个浮点数 4 个字节乘以每个顶点 3 个浮点数 = 12 个字节。
在Python中,您可以通过执行以下操作获取数组中的字节数:
来自
OpenGL.arrays.arraydatatype import ArrayDatatype
使用
ArrayDatatype.arrayByteCount(self.cubeVtxArray)
作为glBufferData()
的第二个参数(对于任何其他缓冲区也是如此)。你需要为
self.cubeIdxArray
做同样的事情,尽管在这种情况下numBytesPerElement
将是 1。