gpt4 book ai didi

python - 使用 PyOpenGL 从索引缓冲区渲染框出现问题

转载 作者:行者123 更新时间:2023-12-01 04:45:24 24 4
gpt4 key购买 nike

我正在尝试完成 OpenGL 红皮书 2.1 版的开头部分,并将我学到的知识转化为 PyOpenGL 绑定(bind),同时使用 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() 结果的几个视频和 glDrawArrays() .

编辑2:我的问题(正如 user1118321 指出的那样)是我将数组长度作为第二个参数传递给 glBufferData() ,我应该在其中传递一个大小(以字节为单位)。 python的解决方案是:

  1. 从 OpenGL.arrays.arraydatatype 导入 ArrayDatatype
  2. 使用 ArrayDatatype.arrayByteCount(self.cubeVtxArray) 作为 glBufferData() 的第二个参数(对于任何其他缓冲区也类似)。

编辑3:我实际上想对此进行更多编辑,因为我刚刚因调用 glBufferData() 而遇到了另一个相关问题。我天真地认为我也应该能够以与 ArrayDatatype.arrayByteCount() 相同的方式使用 sys.getsizeof() 。但如果您的缓冲区数据是我最终使用的 numpy 数组,则情况并非如此。 sys.getsizeof() 返回错误的大小,并且会无意中对数组进行一些切割。再见了我生命中的三天......

最佳答案

我认为错误的一件事是您将数组大小作为第二个参数发送给 glBufferData。您可能需要发送数据的字节数作为该参数。所以它会是这样的:

 len(self.cubeVtxArray) * numBytesPerElement

其中 numBytesPerElement 将为每个浮点 4 个字节乘以每个顶点 3 个浮点 = 12 字节。

在 Python 中,您可以通过执行以下操作来获取数组中的字节数:

  1. OpenGL.arrays.arraydatatype导入ArrayDatatype

  2. 使用 ArrayDatatype.arrayByteCount(self.cubeVtxArray) 作为 glBufferData() 的第二个参数(对于任何其他缓冲区也类似)。

    您需要对 self.cubeIdxArray 执行相同的操作,尽管在这种情况下 numBytesPerElement 将为 1。

关于python - 使用 PyOpenGL 从索引缓冲区渲染框出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29545328/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com