Использование смещений в буфере в вызовах PyOpenGL - PullRequest
1 голос
/ 21 июня 2011

В OpenGL параметр indices для glDrawElements имеет два разных значения, в зависимости от того, используете ли вы GL_ELEMENT_ARRAY_BUFFER или нет.

Еслиу вас есть привязка к VBO, тогда это смещение для запуска в этом буфере, а не сам буфер.

Когда вы используете PyOpenGL, как вы можете указать смещение, с которого нужно начинать вызов glDrawElements?Как вы можете указать несколько начальных смещений в вызове glMultiDrawElements?

1 Ответ

0 голосов
/ 25 января 2019

В следующих примерах используется список из 6 индексов, которые могут образовывать четырехугольник, состоящий из 2 треугольных примитивов.

indices = [0, 1, 2, 0, 2, 3]

Поскольку данные, которые передаются в функции OpenGL, должны состоять из единиц фиксированного размера в связном буфере, список значений должен храниться в массиве с плавающей запятой. Буферы связного массива могут быть созданы либо библиотекой ctypes , либо библиотекой numpy.array.
Тип элементов массива должен соответствовать константе перечислителя типа значения, которая устанавливается при вызове glDrawElements или glMultiDrawElements:

ctypes.c_ubyte   /  numpy.uint8     <->    GL_UNSIGNED_BYTE
ctypes.c_ushort  /  numpy.uint16    <->    GL_UNSIGNED_SHORT
ctypes.c_uint    /  numpy.uint32    <->    GL_UNSIGNED_INT

Использование ctypes:

import ctypes

indexArray = (ctypes.c_uint * 6)(*indices)

Использование numpy:

import numpy

indexArray = numpy.array(indices, dtype=numpy.uint32)

Для использования индексного буфера и glDrawElements существуют различные возможности.

Используя Legacy OpenGL ( профиль совместимости xontext ), буфер может быть напрямую передан в glDrawElements. Указатель на данные массива передается в функцию.

glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, indexArray)

Если в объекте массива вершин указан объект буфера массива именованных элементов, то последний параметр glDrawElements обрабатывается как смещение байта в хранилище данных объекта буфера.

glBindVertexArray(vao)

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo)
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexArray, GL_STATIC_DRAW)

Если индексы должны быть нарисованы, начиная с 1-го элемента буфера, тогда последний параметр может быть None, что эквивалентно ctypes.c_void_p(0):

glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, None)

Если рисование не должно начинаться с первого индекса, то необходимо рассчитать смещение байта начального индекса. например 3*4 устанавливает начало для индекса 3 для буфера типа GL_UNSIGNED_INT:

glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, ctypes.c_void_p(3 * 4))

Использование glMultiDrawElements очень похоже.

Используя профиль совместимости xontext , указатели буфера можно напрямую передавать в функцию OpenGL.

К массивам индексов должны быть сгенерированы:

Использование ctypes:

indexArray1 = (ctypes.c_uint * 3)(0, 1, 2)
indexArray2 = (ctypes.c_uint * 3)(0, 2, 3)

Использование numpy:

indexArray1 = numpy.array([0, 1, 2], dtype=numpy.uint32)
indexArray2 = numpy.array([0, 2, 3], dtype=numpy.uint32)

Указатели на буферы должны быть расположены на массив указателей:

Используя ctypes, указатель на индексные массивы данных получается по ctypes.addressof():

indexPtr = (ctypes.c_void_p * 2)(ctypes.addressof(indexArray1),ctypes.addressof(indexArray2))

При использовании numpy указатель на индексные массивы данных получается по numpy.ndarray.ctypes:

indexPtr = numpy.array([indexArray1.ctypes.data, indexArray2.ctypes.data], dtype=numpy.intp)

Этот массив указателей может быть передан в функцию OpenGL:

counts   = [3, 3]
glMultiDrawElements(GL_TRIANGLES, counts, GL_UNSIGNED_INT, indexPtr, 2)

Если используется объект массива вершин с буфером массива именованных элементов,

glBindVertexArray(vao)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo)

тогда параметр индекса обрабатывается как указатель на массив смещений байтов. Далее в массив передается 2 смещения. 0 идентифицирует 1-й индекс в массиве и 3 * 4 3-й индекс.

Использование ctypes:

indexPtr = (ctypes.c_void_p * 2)(0, 3 * 4)
counts   = [3, 3]
glMultiDrawElements(GL_TRIANGLES, counts, GL_UNSIGNED_INT, indexPtr, 2)

Использование numpy:

indexPtr = np.array([0, 3*4], dtype=numpy.intp)
counts   = [3, 3]
glMultiDrawElements(GL_TRIANGLES, counts, GL_UNSIGNED_INT, indexPtr, 2)
...