Opengl GLSL着色器在添加简单语句时中断

Opengl GLSL着色器在添加简单语句时中断,opengl,glsl,Opengl,Glsl,我有一个简单的工作顶点着色器。全文: #version 150 uniform mat4 projection; uniform mat4 view; uniform mat4 model; in vec4 in_pos; out vec4 color; main(void) { gl_Position = projection * view * model * in_pos; color = vec4(0.6, 0.1, 0.1, 1.0); } 这完全符合预期 我正

我有一个简单的工作顶点着色器。全文:

#version 150

uniform mat4 projection;
uniform mat4 view;
uniform mat4 model;

in vec4 in_pos;

out vec4 color;

main(void) {
    gl_Position = projection * view * model * in_pos;
    color = vec4(0.6, 0.1, 0.1, 1.0);
}
这完全符合预期

我正在尝试添加法线,并选择使用多个VBO,而不是交错。因此,我添加了第二个属性,如下所示

glBindAttribLocation(shaderProgramID, 1, "in_normal");
启用它

glEnableVertexAttribArray(1);
并向其提供书面数据:

int nVBO = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, nVBO);
glBufferData(GL_ARRAY_BUFFER, nBuffer, GL_STATIC_DRAW);
glVertexAttribPointer(1, 3, GL_FLOAT, false, 0, 0);
这三个阶段中的每一个都精确地反映了我的
in_pos
属性的代码,该属性似乎工作得很好,所以我假设以上所有步骤都可以

在这个阶段,如果我编译并运行,它的工作原理与以前完全一样。尝试编辑着色器文件时出现问题

我在属性中添加新的
<代码>在vec4中处于正常状态,它仍然编译并运行,而不更改渲染

只要我在
main()
主体(例如
vec4 n=in\u normal;
)中添加对
的任何引用,程序就会有一个完全黑色的渲染。着色器报告它编译得很好,
glGetError()
在整个程序中为空

为什么这么简单的改变会破坏管道?尤其是当它对
color
变量没有影响,并且编译时仍然没有错误时

最后,为完整起见,着色器的损坏版本:

#version 150

uniform mat4 projection;
uniform mat4 view;
uniform mat4 model;

in vec4 in_pos;
in vec4 in_normal;

out vec4 color;

main(void) {
    gl_Position = projection * view * model * in_pos;
    vec4 n = in_normal;
    color = vec4(0.6, 0.1, 0.1, 1.0);
}

因此,通过在调用
glBindAttribLocation()
之后将
glLinkProgram()
语句移动到,我成功地使管道再次工作


由于默认情况下属性0起作用(我假设…

作为旁注(虽然与问题无关),因此没有注意到这一点,您应该将法线视为
vec3
,因为它肯定是一个向量,实际上获取其
w
坐标集
1
(德国劳埃德船级社在上传3个向量时会自动执行此操作),因为向量需要
w
0
(如果您不想通过上传4分量法线来明确设置,这将更加不直观,那么将其作为
vec3
是最佳选择)。也许问题出在你的#版本?@fullfrontal裸体这些是
attribute
的现代非弃用版本,早在GLSL
1.50
(OP使用的版本)之前就已经推出了@ChristianRau谢谢,我对vec4的用法还是有点困惑。我知道in_pos需要是vec4来计算gl_位置,但我不确定为什么。哦,哇,我修好了。等待自我回答。我不确定我是否完全理解它,所以稍微解释一下就好了。这正是预期的行为。
glBindAttribLocation
仅在下一次链接时生效。如果属性未显式绑定,则
glLinkProgram
将分配一个索引本身,可以使用
glGetAttriblLocation
检索该索引。对于单属性版本,这恰好是0,但对于另一个版本,它可能分配了其他内容(可能是改变了顺序或其他).FYI在实际使用
main
函数中的新属性之前,这一功能起作用的原因是,允许并鼓励GLSL编译器优化掉所有未使用的属性和一致性,因此此版本仅与position-only-shader等效。最后一个但并非最不重要的原因是,自GLSL 3.30以来(这是属于OpenGL 3.3的版本,因此是属于OpenGL 3.2的1.50之后的版本)不需要任何API调用就更容易了:
layout(location=0)在vec4位置;layout(location=1)在vec3正常;
@ChristianRau啊,很有趣。感谢您的指点。