我在GLSL中定义了一个结构,如下所示:
struct Rect {
float x;
float y;
float width;
float height;
};
我想用作制服:
uniform Rect TextureRect;
因此,在我的代码中,我创建了一个Uniforms数组:
_hudTexUniform = new[]
{
new Uniform(_hudShader, "TextureRect.x"),
new Uniform(_hudShader, "TextureRect.y"),
new Uniform(_hudShader, "TextureRect.width"),
new Uniform(_hudShader, "TextureRect.height"),
};
其构造函数定义如下:
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");
}
x
和y
可以正常工作,但是当到达width
时,将引发异常(“名称不对应...”),即glGetUniformLocation
返回-1。我看不到任何错字,我只是检查了GLSL 4.1规范,而且看起来好像不是“ width”或“ height”是关键字....那为什么还会失败呢?
最佳答案
为了方便视频驱动程序,如果着色器实际上未使用所请求的制服(例如,经过剥离处理的制服),允许glGetUniformLocation
返回-1。这不是错误-通过glUniform*
更改为该制服的更改将被忽略。但这意味着您需要将-1
视为有效的统一位置。
顺便说一句,这对于将着色器与渲染解耦可能是一件好事—您的代码可以简单地将所有相关值扔到着色器上,而不必担心着色器实际在乎哪个值。这也意味着您可以进行测试以查看着色器是否真正使用了一个值,如果不需要,则不必首先对其进行计算。
关于c# - glGetUniformLocation对于结构中的2/4字段失败?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9253766/