【问题标题】:PyOpenGL: glVertexPointer() offset problemPyOpenGL:glVertexPointer() 偏移问题
【发布时间】:2010-04-21 13:20:02
【问题描述】:

我的顶点交错在一个 numpy 数组 (dtype = float32) 中,如下所示:... tu, tv, nx, ny, nz, vx, vy, vz, ...

渲染时,我像这样调用 gl*Pointer() (我之前启用了数组):

stride = (2 + 3 + 3) * 4
glTexCoordPointer( 2, GL_FLOAT, stride, self.vertArray )
glNormalPointer( GL_FLOAT, stride, self.vertArray + 2 )
glVertexPointer( 3, GL_FLOAT, stride, self.vertArray + 5 )
glDrawElements( GL_TRIANGLES, len( self.indices ), GL_UNSIGNED_SHORT, self.indices )

结果是没有渲染。但是,如果我组织我的数组,使顶点位置是第一个元素(... vx, vy, vz, tu, tv, nx, ny, nz, ... )我在渲染时得到正确的顶点位置但纹理坐标和法线没有正确渲染。

这让我相信我没有正确设置指针偏移量。我应该如何设置它?我在我的其他 C++ 应用程序中使用几乎完全相同的代码并且它可以工作。

【问题讨论】:

  • 我不是 PyOpenGL 用户,但从您的描述来看,数组上的 + 听起来不像您认为它在该语言中所做的那样。是时候检查语言规范了?
  • @Bahbar:这就是我的想法,但我一直无法找到任何有关它的信息。我用谷歌搜索了很多无济于事。

标签: opengl rendering pyopengl


【解决方案1】:

在python中,你不能做指针运算。您尝试做的仅适用于 C/C++。

使用普通 Python 列表:

>>> array = [1, 2, 3, 4]
>>> array
[1, 2, 3, 4]
>>> array + 2
Traceback (most recent call last):
  File "<input>", line 1, in <module>
TypeError: can only concatenate list (not "int") to list

使用 numpy 数组:

>>> import numpy
>>> a = numpy.array([1, 2, 3])
>>> a + 2
array([3, 4, 5])

看看两者都不是你想要的:从某个位置开始数组。

我认为你基本上有两种选择:

  1. 不要使用交错数组。这确实有一个优点:当您只需要更新顶点时(例如在骨骼动画中),您不需要更新纹理坐标。
  2. 使用切片可能对你有用。

像这样:

>>> a = numpy.array(range(10))
>>> a
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> a[3:]
array([3, 4, 5, 6, 7, 8, 9])

将此与正确的步幅结合起来,您可能可以让它发挥作用。

【讨论】:

  • @Xavier Ho:谢谢,使用切片就可以了!但是,我不知道它的性能,所以我必须运行一些测试。
  • @SurvivalMachine:使用切片的唯一缺点是它会创建列表的新副本。目前我想不出另一种方法来克服这个问题。
【解决方案2】:

我遇到了类似的问题,发现将偏移量转换为 ctypes.c_void_p 可以解决问题。

from ctypes import c_void_p

t_size = self.vertArray.itemsize * 2
n_size = self.vertArray.itemsize * 3

t_offset = c_void_p(0)
n_offset = c_void_p(t_size)
v_offset = c_void_p(t_size+n_size)

glTexCoordPointer( 2, GL_FLOAT, stride, t_offset )
glNormalPointer( GL_FLOAT, stride, n_offset )
glVertexPointer( 3, GL_FLOAT, stride, v_offset )
glDrawElements( GL_TRIANGLES, len( self.indices ), GL_UNSIGNED_SHORT, self.indices )

【讨论】:

  • 这个例子看起来很有希望,但我不认为只是将字节偏移量作为 glPointer 中的最后一个参数传入就行了。第三个参数是指向数组的指针,而不是偏移量。
  • 我今天花了很多时间自己遇到了这个问题,所以即使线程很旧,我也会加入以防万一它对其他人有帮助。 Exide 是正确的,例如,opengl.org/sdk/docs/man2/xhtml/glVertexPointer.xml 表示当 glBindBuffer / glBufferData 生效时,glVertexPointer 将第四个参数计算为偏移量。他的代码 sn-p 未能显示的是如何使用 self.vertArray 来做到这一点。
  • 就像@jdowdell 说的,最后一个参数是一个偏移量。关于self.vertArray,我不确定我还能补充什么。我只是从最初的问题中得到的。
【解决方案3】:

我正在回答我自己的问题,因为我找到了另一种方法来完成正确的结果。我没有调用 gl*Pointer(),而是调用了:

glInterleavedArrays( GL_T2F_N3F_V3F, stride, self.vertArray )

我仍然很想找到一个适用于 gl*Pointer() 的解决方案。

【讨论】:

  • 很多人反对glInterleavedArrays()
【解决方案4】:

根据此链接:http://www.opengl.org/sdk/docs/man/xhtml/glTexCoordPointer.xml

步幅

指定之间的字节偏移量 连续的纹理坐标集。 如果 stride 为 0,则数组元素为 被理解为紧密包装。这 初始值为0。

您确定在您的情况下步幅是 (2 + 3 + 3) * 4 吗?

【讨论】:

  • 我很确定。 TexCoords = 2 个元素,Normals = 3 个元素,Vertices = 3 个元素。我的数组是 float32,所以步幅的 4 个字节乘以元素数。我在我的 C++ 代码中也使用了相同的步幅,它在那里工作。
  • 好的,那为什么你的 glNormalPointer 调用中没有“3”作为第一个参数?
  • 我仍然不确定,您是否应该迈出这一步。如果您在组成数组时使用相等的步幅,您仍然可以获得正确的值,但为什么要麻烦呢?零步幅也可以(在我看来)。
  • 零步幅绝对不适用于交错数组。
  • glNormalPointer 没有元素计数参数,它始终为 3。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多