glGetUniformLocation在结构中的2/4字段失败?

mpe*_*pen 2 c# opengl glsl

我在我的GLSL中定义了一个结构,如下所示:

struct Rect {
    float x;
    float y;
    float width;
    float height;
};
Run Code Online (Sandbox Code Playgroud)

我想用作制服:

uniform Rect TextureRect;
Run Code Online (Sandbox Code Playgroud)

所以在我的代码中我创建了一个Uniforms数组:

_hudTexUniform = new[]
    {
        new Uniform(_hudShader, "TextureRect.x"),
        new Uniform(_hudShader, "TextureRect.y"),
        new Uniform(_hudShader, "TextureRect.width"),
        new Uniform(_hudShader, "TextureRect.height"),
    };
Run Code Online (Sandbox Code Playgroud)

其构造函数定义如下:

public Uniform(ShaderProgram shaderProgram, string name)
{
    if (shaderProgram == null) throw new ArgumentNullException("shaderProgram");
    if (Regex.IsMatch(name, @"\s")) throw new ArgumentException("Cannot contain white space.", "name");
    if (name.StartsWith("gl_")) throw new ArgumentException("Cannot start with reserved prefix \"gl_\"", "name");
    Location = shaderProgram.GetUniformLocation(name);
    if (Location < 0) throw new ArgumentException("Name does not correspond to an active uniform variable in program", "name");
}
Run Code Online (Sandbox Code Playgroud)

x并且y完美地工作,但当它到达width异常时抛出("名称不对应......"),即glGetUniformLocation返回-1.

我没有看到任何拼写错误,我只是检查了GLSL 4.1规范,它看起来不像"宽度",也不是"高度"是关键字....所以为什么还会失败呢?

Joh*_*eek 6

glGetUniformLocation为了方便视频驱动程序,允许返回-1,如果着色器实际上没有使用所请求的制服(例如,被剥离了).这不是错误 - glUniform*将忽略对均匀通道的更改.但这意味着您需要将其-1视为有效的统一位置.

顺便说一句,这对于将着色器与渲染分离是一件好事 - 您的代码可以简单地在着色器中抛出所有相关值,而不用担心着色器实际关注哪些.它还意味着您可以测试着色器是否实际使用了某个值,而不是在不需要时首先计算它.