如何使用来自 PyGLM 的数据初始化缓冲区对象的数据存储?
How to initialize a buffer object's data store with data from PyGLM?
我指定了以下 Shader Storage Buffer in the 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 数组?
最后我自己找到了解决方案。
需要注意的是,Shader Storage Buffer 由 344=48 个紧密排列的浮点数组成。
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 用于 glm 数据类型。
这个函数可以与glBufferSubData
wrapping of 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
的对象可以分配给形状 (4, 4)
类型 np.float32
的 numpy.array
。所以这 3 个矩阵可以分配给形状为 (3, 4, 4)
:
的 numpy.array
的元素
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)
从 PyGLM 版本 2.0.0 开始,有一种更简单的方法来
这个。见 Using Arrays:
PyGLM's array type was introduced in version 2.0.0 to reduce the likelihood of requiring users to also use numpy besides glm. It's mainly intended to provide a way of passing multiple glm type instances (such as vectors) to external C functions
(such as glBufferData).
buffer_data = glm.array(model, view, proj)
glBufferData(GL_SHADER_STORAGE_BUFFER, buffer_data.nbytes, buffer_data.ptr, GL_STATIC_DRAW)
有一种方法可以一次更新所有数据,而无需使用 numpy。
在 PyGLM 文档中,它说 (https://github.com/Zuzu-Typ/PyGLM/wiki/Using-arrays):
PyGLM's array type was introduced in version 2.0.0 to reduce the likelihood of requiring users to also use numpy besides glm. It's mainly intended to provide a way of passing multiple glm type instances (such as vectors) to external C functions
(such as glBufferData).
你可以做的是像这样用 glm.array 包裹矩阵:
buffer_data = glm.array(model, view, proj)
然后像这样更新数据:
glBufferData(GL_SHADER_STORAGE_BUFFER, buffer_data.nbytes, buffer_data.ptr, GL_STATIC_DRAW)
注意:nbytes
和 ptr
内置于 glm.array 的成员中,您使用它们代替 glm.sizeof
和 glm.value_ptr
。
我指定了以下 Shader Storage Buffer in the 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 数组?
最后我自己找到了解决方案。
需要注意的是,Shader Storage Buffer 由 344=48 个紧密排列的浮点数组成。
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 用于 glm 数据类型。
这个函数可以与glBufferSubData
wrapping of 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
的对象可以分配给形状 (4, 4)
类型 np.float32
的 numpy.array
。所以这 3 个矩阵可以分配给形状为 (3, 4, 4)
:
numpy.array
的元素
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)
从 PyGLM 版本 2.0.0 开始,有一种更简单的方法来 这个。见 Using Arrays:
PyGLM's array type was introduced in version 2.0.0 to reduce the likelihood of requiring users to also use numpy besides glm. It's mainly intended to provide a way of passing multiple glm type instances (such as vectors) to external C functions (such as glBufferData).
buffer_data = glm.array(model, view, proj)
glBufferData(GL_SHADER_STORAGE_BUFFER, buffer_data.nbytes, buffer_data.ptr, GL_STATIC_DRAW)
有一种方法可以一次更新所有数据,而无需使用 numpy。
在 PyGLM 文档中,它说 (https://github.com/Zuzu-Typ/PyGLM/wiki/Using-arrays):
PyGLM's array type was introduced in version 2.0.0 to reduce the likelihood of requiring users to also use numpy besides glm. It's mainly intended to provide a way of passing multiple glm type instances (such as vectors) to external C functions (such as glBufferData).
你可以做的是像这样用 glm.array 包裹矩阵:
buffer_data = glm.array(model, view, proj)
然后像这样更新数据:
glBufferData(GL_SHADER_STORAGE_BUFFER, buffer_data.nbytes, buffer_data.ptr, GL_STATIC_DRAW)
注意:nbytes
和 ptr
内置于 glm.array 的成员中,您使用它们代替 glm.sizeof
和 glm.value_ptr
。