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
的现代非弃用版本,早在GLSL1.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啊,很有趣。感谢您的指点。