How to initialize a buffer object's data store with data from PyGLM?

允我心安 提交于 2019-12-25 02:28:46

问题


I use PyGLM and PyOpenGL

I have specified the following Shader Storage Buffer in the Vertex Shader:

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

I have initialized the model, view and projection matrix:

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)

How can the buffer object's data store be created and initialized using glBufferData (or glNamedBufferData)

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

respectively initialized by glBufferSubData (or 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, ???, ???);

Since the SSBO contains 3 (tightly packed) mat4, the size of the buffer is 3 * 16 * 4 (3 4x4-matrices with element data type float).
So the initialization of the buffer can be done by a NumPy array.
But how the PyGLM matrices can be effectively assigned to the NumPy array?

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)

Or is there an even more efficient solution, without an copying the data to a NumPy array?


回答1:


Finally I found the solution myself.

It should be noted, that the Shader Storage Buffer consists of 3*4*4=48 tightly packed floats.

PyGlm provides the handy functions glm.value_ptr and glm.sizeof. glm.value_ptr corresponds to the glm::value_ptr. glm.sizeof works like c++ sizeof operator for the glm data types.

This functions can be used with the glBufferSubData wrapping of PyOpenGL to updates the buffer data:

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

A object of type glm.mat4 can be assigned to a numpy.array with shape (4, 4) of type np.float32. So the 3 matrices can be assigned to the elements of a numpy.array with shape (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

This array can be used to updates the entire buffer data at once:

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

Or for the initial glBufferData creation and initialization of the buffer object's data store:

glBufferData(GL_SHADER_STORAGE_BUFFER, buffer_data, GL_DYNAMIC_DRAW)


来源:https://stackoverflow.com/questions/54169613/how-to-initialize-a-buffer-objects-data-store-with-data-from-pyglm

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