我在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数组的更有效的解决方案?
答案 0 :(得分:0)
最后我自己找到了解决方法。
应该注意的是,着色器存储缓冲区由3 * 4 * 4 = 48个紧密堆积的浮点组成。
PyGlm提供了方便的功能glm.value_ptr
和glm.sizeof
。 glm.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)