Как инициализировать хранилище данных буферного объекта данными из PyGLM? - PullRequest
0 голосов
/ 13 января 2019

Я использую PyGLM и PyOpenGL

Я указал следующий буфер хранения шейдера в вершинном шейдере :

layout(std430, binding = 1) buffer MVP
{
    mat4 u_proj;
    mat4 u_view;
    mat4 u_model;
} mvp_data;

Я инициализировал модель, вид и матрицу проекции:

model = glm.mat4(1)
view  = glm.lookAt(glm.vec3(0,-3,0), glm.vec3(0,0,0), glm.vec3(0,0,1))
proj  = glm.perspective(glm.radians(90), self.__vp_size[0]/self.__vp_size[1], 0.1, 100)

Как создать и инициализировать хранилище данных буферного объекта с помощью glBufferData (или glNamedBufferData)

ssbo = glGenBuffers( 1 )
glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo )
glBufferData(GL_SHADER_STORAGE_BUFFER, 3*16*4, ???, GL_STATIC_DRAW )

соответственно инициализируется glBufferSubData (или glNamedBufferSubData)

ssbo = glGenBuffers( 1 )
glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo )
glBufferData(GL_SHADER_STORAGE_BUFFER, 3*16*4, None, GL_STATIC_DRAW )
glBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, ???, ???);

Поскольку SSBO содержит 3 (плотно упакованные) mat4, размер буфера составляет 3 * 16 * 4 (3 4x4-матрицы с типом данных элемента float).
Таким образом, инициализация буфера может быть выполнена с помощью массива NumPy .
Но как эффективно использовать матрицы PyGLM для массива NumPy?

buffer_data = numpy.zeros(3*16, dtype=numpy.float32)

??? buffer_data = model, view, proj

glBufferData(GL_SHADER_STORAGE_BUFFER, buffer_data.nbytes, buffer_data, GL_STATIC_DRAW)

Или есть еще более эффективное решение без копирования данных в массив NumPy?

1 Ответ

0 голосов
/ 29 июня 2019

Наконец-то я сам нашел решение.
Следует отметить, что буфер хранения шейдера состоит из 3 * 4 * 4 = 48 плотно упакованных поплавков.

PyGlm предоставляет удобные функции glm.value_ptr и glm.sizeof. glm.value_ptr соответствует glm::value_ptr. glm.sizeof работает как оператор c ++ sizeof для типов данных glm .

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

glBufferSubData(GL_SHADER_STORAGE_BUFFER, 0,                      glm.sizeof(glm.mat4), glm.value_ptr(model))
glBufferSubData(GL_SHADER_STORAGE_BUFFER, 1*glm.sizeof(glm.mat4), glm.sizeof(glm.mat4), glm.value_ptr(view))
glBufferSubData(GL_SHADER_STORAGE_BUFFER, 2*glm.sizeof(glm.mat4), glm.sizeof(glm.mat4), glm.value_ptr(proj))

Объект типа glm.mat4 может быть назначен на numpy.array с формой (4, 4) типа np.float32. Таким образом, 3 матрицы могут быть назначены элементам numpy.array с формой (3, 4, 4):

buffer_data = np.empty([3, 4, 4], dtype=np.float32)
buffer_data[0] = model
buffer_data[1] = view
buffer_data[2] = proj

Этот массив можно использовать для одновременного обновления всех данных буфера:

buffer_size = buffer_data.size * buffer_data.itemsize
glBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, buffer_size, buffer_data)

Или для первоначального glBufferData создания и инициализации хранилища данных буферного объекта:

glBufferData(GL_SHADER_STORAGE_BUFFER, buffer_data, GL_DYNAMIC_DRAW)
...