如果在GLSL a中
Uniform block
是这样指定的
layout(binding = 0) uniform UniformBufferObject {
mat4 model;
mat4 view;
mat4 proj;
} ubo;
那么OpenGL不能保证th块中的成员是按连续顺序存储的。OpenGL对元素的内存布局、对齐方式或顺序没有任何保证。
要实现定义良好的顺序和内存布局
memory layout qualifier
std140
要使用的ahs。这个
ARB_uniform_buffer_object
:
layout(std140, binding = 0) uniform UniformBufferObject {
mat4 model;
mat4 view;
mat4 proj;
} ubo;
有关布局的详细说明,请访问:
如果是上述均匀块体,则
std140
float
S
在一行中,大小为192字节
mat4 model byte offset 0: size in bytes 64 = 4*4*sizeof(float)
mat4 view byte offset 64: size in bytes 64 = 4*4*sizeof(float)
mat4 proj byte offset 128: size in bytes 64 = 4*4*sizeof(float)
--------------------------------------------------------------------
size in bytes 192 = 3*4*4*sizeof(float)
要创建与此内存布局对应的缓冲区,请使用平面
numpy.array
可用于:
例如
model = [0.1, 0.1, 0.1, 1, 0.1, 0.1, 0.1, 1, 0.1, 0.1, 0.1, 1, 0.1, 0.1, 0.1, 0,]
view = [0.2, 0.2, 0.2, 1, 0.2, 0.2, 0.2, 1, 0.2, 0.2, 0.2, 1, 0.2, 0.2, 0.2, 0,]
proj = [0.3, 0.3, 0.3, 1, 0.3, 0.3, 0.3, 1, 0.3, 0.3, 0.3, 1, 0.3, 0.3, 0.3, 0,]
import numpy as np
ubo_data = np.array([model, view, proj], dtype='f4')
没有必要
reshap()
阵列。但是,如果您想访问模型矩阵的元素,当然可以这样做(
ubo_data[0]
),视图矩阵(
ubo_data[1]
ubo_data[2]
)直接:
ubo_data = np.array([model, view, proj], dtype='f4').reshape(3, 4, 4)
注意,甚至不需要使用
NumPy
. 具有相同内存布局的缓冲区可以由
ctypes
数组:
import ctypes
ubo_data = (ctypes.c_float * 48)(*model, *view, *proj)
使用
PyOpenGL
,上述每个数据数组都可用于装箱和初始化统一块缓冲区的缓冲区存储
glBufferData
ubo = glGenBuffers( 1 )
glBindBuffer(GL_UNIFORM_BUFFER, ubo)
glBufferData(GL_UNIFORM_BUFFER, ubo_data, GL_STATIC_DRAW)
glBindBufferBase(GL_UNIFORM_BUFFER, 0, ubo)
glBindBuffer(GL_UNIFORM_BUFFER, 0)
glBufferSubData
glBindBuffer(GL_UNIFORM_BUFFER, ubo)
glBufferSubData(GL_UNIFORM_BUFFER, 0, ubo_data)
注意,当使用
PyGLM
例如。:
import glm
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), 800.0/600.0, 0.1, 100)
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))