如何使用PyGLM中的数据初始化缓冲区对象的数据存储?

时间:2019-01-13 14:00:48

标签: python numpy opengl pyopengl

我使用PyGLMPyOpenGL

我在Shader Storage Buffer中指定了以下Vertex Shader

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 :(得分:0)

最后我自己找到了解决方法。
应该注意的是,着色器存储缓冲区由3 * 4 * 4 = 48个紧密堆积的浮点组成。

PyGlm提供了方便的功能glm.value_ptrglm.sizeofglm.value_ptr对应于glm::value_ptr。对于 glm 数据类型,glm.sizeof的工作方式类似于c ++ sizeof operator

此功能可以与PyOpenGL的glBufferSubData包装一起使用,以更新缓冲区数据:

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类型的对象分配给形状为(4, 4)的形状np.float32的{​​{3}}。因此,可以将3个矩阵分配给形状为numpy.array的{​​{1}}的元素:

(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

或者对于初始numpy.array创建和初始化缓冲区对象的数据存储区:

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