PyOpenGL: glVertexPointer() offset problem

会有一股神秘感。 提交于 2019-12-06 04:10:39

问题


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.


回答1:


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.




回答2:


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 )



回答3:


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().




回答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 ?



来源:https://stackoverflow.com/questions/2683205/pyopengl-glvertexpointer-offset-problem

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!