glGetUniformIndices没有返回正确的索引

时间:2012-01-09 20:37:31

标签: c++ opengl opengl-3

我正在尝试学习如何使用统一的缓冲区对象,阅读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。在此段代码之前或之后,没有错误标志处于活动状态。任何可能出错的建议?

2 个答案:

答案 0 :(得分:2)

layout(std140) uniform SkeletonBlock  
{  
    vec3 position[64];  
    vec4 orientation[64];  
} Skeleton;

这个定义的内容如下:

  • 有一个名为SkeletonBlock的统一块。
  • 它包含一个名为vec3的64个position数组,后跟一个名为vec4的64个orientation数组。
  • 其所有成员的名称在GLSL中由标识符Skeleton限定。

请注意最后一部分。在GLSL中, 仅在GLSL 中,position数组由Skeleton.position标识。在C ++中,数组由SkeletonBlock.positionSkeletonBlock.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(二进制补码)的无符号解释。