此处glGetActiveUniformBlockName()
记录了OpenGL 函数。简短的描述如下:
[它] 在程序中的 uniformBlockIndex 处检索活动统一块的名称。`
如何使统一块处于活动状态?
统一块的活动方式与统一块的活动方式相同:您在一些产生输出的表达式中使用它。如果您希望统一块处于活动状态,则需要对其成员之一实际执行一些操作,从而对着色器的输出产生实质性影响。
根据 OpenGL 文档,“活动”统一块的定义取决于实现,因此取决于驱动程序。但是,如果您只需要使一个块“活动”,那么只需在您的 GLSL 代码中使用它。只要您在块中使用了制服,就可以保证该块处于活动状态。
但是,如果您不使用它,则该块可能处于活动状态或处于非活动状态,具体取决于您的硬件。即使您将块标记为使用std140
布局,编译器仍然可以优化它。棘手的部分是,您的驱动程序甚至可能以不同的方式对待统一块和统一块数组。这是一个例子:
#version 460
layout(std140, binding = 0) uniform Camera {
vec3 position;
vec3 direction;
} camera;
layout(std140, binding = 1) uniform Foo {
float foo;
vec3 vec_foo;
} myFoo[2];
layout(std140, binding = 3) uniform Bar {
float bar;
vec3 vec_bar;
} myBar[4];
layout(std140, binding = 7) uniform Baz {
float baz1;
float baz2;
};
void main() {
vec3 use_camera = camera.position; // use the Camera block
vec3 use_foo = myFoo[0].vec_foo; // use the Foo block
color = vec4(1.0);
}
在这个片段着色器中,我们有 8std140
个统一块,正在使用Camera
和块,因此它们必须处于活动状态。Foo
另一方面,Bar
并Baz
没有被使用,所以你可能认为它们是非活动的,但在我的机器上,虽然Bar
是非活动的,但Baz
仍然被认为是活动的。我不确定是否可以在其他机器上复制结果,但您可以使用OpenGL 文档中的示例代码对其进行测试。
由于它依赖于实现,因此使用统一块的最安全方法是始终在您的硬件上进行试验。如果您想在所有机器上获得稳定的结果,唯一的方法就是全部使用它们,否则可能很难。正如其他人建议的那样,您可以尝试关闭编译器优化,如下所示,但不幸的是,这仍然不会阻止未使用的块被优化,因为删除不活动的制服不是优化,它只是编译器的工作方式。
#pragma optimize(off)
...