我正在尝试学习如何使用统一的缓冲区对象,阅读OpenGL Superbible 5.我的着色器中有一个统一的块:
layout(std140) uniform SkeletonBlock
{
vec3 position[64];
vec4 orientation[64];
} Skeleton;
现在我获取索引的代码是:
const GLchar* uniformNames[2] =
{
"SkeletonBlock.position",
"SkeletonBlock.orientation"
};
GLuint uniformIndex[2];
glGetUniformIndices(shaderProgram, 2, uniformNames, uniformIndex);
出于某种原因,这个电话给了我一个非常高的索引(4294967295,一致),我不知道为什么。我觉得我错过了一些明显的东西。 OpenGL报告一个活动的统一块,这是正确的,超出允许的最大值15。在此段代码之前或之后,没有错误标志处于活动状态。任何可能出错的建议?
答案 0 :(得分:2)
layout(std140) uniform SkeletonBlock
{
vec3 position[64];
vec4 orientation[64];
} Skeleton;
这个定义的内容如下:
SkeletonBlock
的统一块。vec3
的64个position
数组,后跟一个名为vec4
的64个orientation
数组。Skeleton
限定。请注意最后一部分。在GLSL中, 仅在GLSL 中,position
数组由Skeleton.position
标识。在C ++中,数组由SkeletonBlock.position
或SkeletonBlock.position[0]
标识。这里的要点是from C++ code you use the block name SkeletonBlock
作为前缀,而不是实例名称Skeleton
。
SkeletonBlock
块有一个可以用glGetUniformBlockIndex
查询的索引(注意“块”一词的使用和“索引”中缺少多个)。个别制服成员也有指数,但它们是制服清单的索引。并且必须正确命名这些变量。如果统一块具有实例名称,则统一块成员必须以块名称为前缀,而不是实例名称。
如果您将这些名称传递给OpenGL函数并且没有获得有效的索引,那么您可能会遇到驱动程序错误。
答案 1 :(得分:1)
我相信你想要
const GLchar* uniformNames[2] =
{
"Skeleton.position",
"Skeleton.orientation"
};
由于C风格语言(如GLSL)的语义具有它,您声明了一个名为uniform SkeletonBlock
的{{1}}类型的变量。因此,Skeleton
的格式为"SkeletonBlock.position"
,您需要<typename>.<member>
。
OpenGL文档说当你给它一个糟糕的统一名称时,你会从<variable>.<member>
得到一个GL_INVALID_INDEX
。检查每个返回的索引可能是明智的。我敢打赌glGetUniformIndices()
。
另外,这个数字4294967295是32位-1(二进制补码)的无符号解释。