PyOpenGL: проблема смещения glVertexPointer () - PullRequest
4 голосов
/ 21 апреля 2010

Мои вершины чередуются в массиве 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 ++, и он работает.

Ответы [ 4 ]

3 голосов
/ 16 января 2011

Я столкнулся с подобной проблемой и обнаружил, что приведение смещения к 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 )
3 голосов
/ 25 апреля 2010

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

Объедините это с правильным шагом, вы, вероятно, можете заставить его работать.

0 голосов
/ 22 апреля 2010

По этой ссылке: http://www.opengl.org/sdk/docs/man/xhtml/glTexCoordPointer.xml

stepde

Определяет смещение байтов между последовательными наборами координат текстуры.Если значение шага равно 0, элементы массива считаются плотно упакованными.Начальное значение равно 0.

Вы уверены, что в вашем случае шаг равен (2 + 3 + 3) * 4?

0 голосов
/ 21 апреля 2010

Я отвечаю на свой вопрос, потому что я нашел альтернативный способ достижения правильного результата. Вместо вызова gl * Pointer () я вызвал:

glInterleavedArrays( GL_T2F_N3F_V3F, stride, self.vertArray )

Мне все еще интересно найти решение, которое работает с gl * Pointer ().

...