PyOpenGL:glVertexPointer()偏移问题

发布于 2024-08-30 09:15:44 字数 617 浏览 4 评论 0原文

我的顶点在 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++ 应用程序中使用了几乎完全相同的代码,并且它有效。

My vertices are interleaved in a numpy array (dtype = float32) like this: ... tu, tv, nx, ny, nz, vx, vy, vz, ...

When rendering, I'm calling gl*Pointer() like this (I have enabled the arrays before):

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 )

The result is that nothing renders. However, if I organize my array so that the vertex position is the first element ( ... vx, vy, vz, tu, tv, nx, ny, nz, ... ) I get correct positions for vertices while rendering but texture coords and normals aren't rendered correctly.

This leads me to believe that I'm not setting the pointer offset right. How should I set it? I'm using almost the exact same code in my other app in C++ and it works.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

等你爱我 2024-09-06 09:15:44

在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])

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

In python, you can't do pointer arithmetic. What you're trying to do only works for C/C++.

With normal Python list:

>>> 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

With numpy arrays:

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

See how neither does what you want: starting the array at a certain position.

I think you have basically two options:

  1. Don't use interleaved arrays. This does have one advantage: when you only need to update the vertices (like in bone animations), you don't need to update the texture coordinates.
  2. Using slices might work for you.

Like this:

>>> 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])

Combine this with a correct stride, you can probably get it to work.

甜扑 2024-09-06 09:15:44

我遇到了类似的问题,发现将偏移量转换为 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 )

I ran into a similar problem and found that casting the offset to ctypes.c_void_p did the trick.

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 )
北笙凉宸 2024-09-06 09:15:44

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

glInterleavedArrays( GL_T2F_N3F_V3F, stride, self.vertArray )

我仍然很好奇找到一个与 gl*Pointer() 一起使用的解决方案。

I'm answering my own question, because I found an alternative way to accomplish the correct result. Instead of calling gl*Pointer(), I called:

glInterleavedArrays( GL_T2F_N3F_V3F, stride, self.vertArray )

I'm still curious to find a solution that works with gl*Pointer().

极致的悲 2024-09-06 09:15:44

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

跨步

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

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

According to this link: http://www.opengl.org/sdk/docs/man/xhtml/glTexCoordPointer.xml

stride

Specifies the byte offset between
consecutive texture coordinate sets.
If stride is 0, the array elements are
understood to be tightly packed. The
initial value is 0.

Are you sure, that in your case stride is (2 + 3 + 3) * 4 ?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文