Opengl 如何用GL_UNIFORM_BLOCK_DATA_SIZE解释glGetActiveUniformorMBlockIV的含义
假设我有以下顶点着色器代码:Opengl 如何用GL_UNIFORM_BLOCK_DATA_SIZE解释glGetActiveUniformorMBlockIV的含义,opengl,glsl,opengl-3,Opengl,Glsl,Opengl 3,假设我有以下顶点着色器代码: #version 330 uniform mat4 ProjectionMatrix, CameraMatrix, SingleModelMatrix; uniform uint SingleModel; layout (std140) uniform ModelBlock { mat4 ModelMatrices[128]; }; void main(void) { ... something that uses ModelMatrices } 如果在
#version 330
uniform mat4 ProjectionMatrix, CameraMatrix, SingleModelMatrix;
uniform uint SingleModel;
layout (std140) uniform ModelBlock {
mat4 ModelMatrices[128];
};
void main(void) {
... something that uses ModelMatrices
}
如果在我的程序中,我对表示上述着色器的程序对象发出以下OpenGL调用:
getUniformBlockParameter(GL_UNIFORM_BLOCK_DATA_SIZE)
使用Intel HD Graphics 4000卡,我发现了以下问题:
GLUniformBlock[
name: ModelBlock,
blockSize: 8192,
buffer: java.nio.HeapByteBuffer[pos=0 lim=8192 cap=8192],
metadata: {
ModelMatrices=GLUniformBlockAttributeMetadata[
name: ModelMatrices,
offset: 0,
arrayStride: 64,
matrixStride: 16,
matrixOrder: 0
]},
uniforms: GLUniformInterface[
uniforms: {
ModelMatrices=GLUFloatMat4 [
name:ModelMatrices,
idx:2,
loc:-1,
size:128,
glType:8b5c]
}
]
]
如何解释blockSize
参数?缔约国指出:
如果pname是GL\u UNIFORM\u BLOCK\u DATA\u SIZE
,则返回保存uniformBlockIndex标识的统一块中所有活动制服所需的实现相关的最小缓冲区对象总大小(以基本机器单位为单位)。既不能保证也不能期望给定的实现将统一的值紧密地排列在缓冲区对象中。例外情况是std140统一块布局,它保证了特定的打包行为,并且不需要应用程序查询偏移和跨距。在这种情况下,即使仅基于统一块声明预先确定了最小大小,也可以查询最小大小
那么在这种情况下,我应该如何测量块大小中的8192数字?在float
s中?在字节中
s
如果我计算数字,一个4x4矩阵mat4
uniform总共有16个float
组件,可以容纳64个字节
,因此至少我需要大约16 x 4 x 128个
字节来存储128个矩阵,实际上是8192
那么,为什么硬件也要求64(字节
?)的数组跨距和16(字节
?)的矩阵跨距,但只要求8192字节?getUniformBlockParameter(GL\u UNIFORM\u BLOCK\u DATA\u SIZE)
是否应该请求更多空间用于对齐/填充目的?数组跨距是从一个数组元素的开始到下一个数组元素的开始的字节偏移量。本例中的数组元素是mat4
s,大小为64字节。因此,阵列步幅尽可能小
矩阵步长是从矩阵数据的一列/行到下一列/行的字节偏移量。每个mat4
的列或行大小为vec4
,这意味着它的大小为16字节。因此,矩阵列/行再次被紧密压缩
所以8KiB是这种存储的预期大小
尽管如此,这是完全不相干的。你不应该费心去质疑这些东西。通过使用std140
layout,您已经迫使OpenGL采用特定的布局。尤其需要mat4
s的数组跨距为64字节,矩阵跨距为16字节。您不必为此要求实现;这是标准要求的
您只需询问您是否正在使用共享
或打包
“getUniformBlockParameter(GL_UNIFORM_BLOCK_DATA_SIZE)是否应该请求更多空间用于对齐/填充目的?”嗯,为什么?我看不出填充和对齐需要分配更多内存的原因?也许我当时应该说的是,如果卡/实现声明数组/矩阵跨步需要64和16字节,那么我会期望完整块大小大于8192,因为显然,需要更多字节才能在生成的缓冲区上插入矩阵/数组跨距。这更有意义吗?也许我还不明白在这种情况下,步幅是如何工作的。谢谢啊。我现在明白了。硬件告诉我的是,步幅大小/数量与元素的大小完全相同,因此不需要填充/对齐。我认为,除了使用不同布局的实际元素大小之外,还需要这些跨步。我想在这种情况下,我只会看到比元素大小更大的跨步。无论如何,因为我正在开发一个基于JOGL的OGLPlus端口,所以我确实希望支持其他打包类型的着色器代码。然而,对于这个问题的范围来说,这个答案已经足够好了。再次感谢!