我有一个非常基本的GLSL程序,在第一次绘制调用后无法正确更新统一值.未收到glGetError任何错误,编译和链接着色器时信息日志中未报告任何错误,并且所有统一位置均有效.
顶点着色器:
#version 120
uniform mat4 mvp;
uniform mat3 nmv;
attribute vec3 position;
attribute vec3 normal;
varying vec3 v_normal;
void main()
{
v_normal = normalize(nmv * normal);
gl_Position = mvp * vec4(position, 1.0);
}
Run Code Online (Sandbox Code Playgroud)
片段着色器:
#version 120
uniform vec3 lightDir;
uniform vec3 lightColor;
uniform vec3 materialColor;
varying vec3 v_normal;
void main()
{
vec3 n = normalize(v_normal);
float nDotL = max(0.0, dot(n, lightDir));
gl_FragColor = vec4(materialColor * lightColor * nDotL, 1.0);
}
Run Code Online (Sandbox Code Playgroud)
渲染代码:
glUseProgram(program);
glUniformMatrix4fv(mvpLoc, 1, GL_FALSE, mvp);
glUniformMatrix3fv(nmvLoc, 1, GL_FALSE, nmv);
glUniform3fv(lightDirLoc, 1, lightDir);
glUniform3fv(lightColorLoc, 1, lightColor);
for (auto mesh: meshes)
{
glUniform3fv(materialColorLoc, 1, mesh.color);
mesh.draw();
}
Run Code Online (Sandbox Code Playgroud)
渲染的网格物体全部以第一个网格物体的颜色绘制,表示在初始设置materialColor制服后,将忽略后续的更改制服的调用.但是,这里有一个特殊条件列表,它们可以独立地允许统一更新:
glUseProgram(program)在循环内调用.mvp或nmv制服.lightDir在循环内设置制服.uniform vec3从着色器程序中删除其中一个.请注意,lightColor在循环内设置制服不会更新materialColor制服.我也在GL_CURRENT_PROGRAM循环中检查过,着色器始终保持绑定.
我一直试图解决这个问题几个小时,绝对找不到问题.这个着色器设置非常简单,我不相信它是一个驱动程序错误.我在Mac OS X 10.8.3上使用OpenGL 2.1和NVIDIA GeForce 9400M.
这是单帧的呼叫追踪:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(1);
glUniformMatrix4fv(1, 1, 0, 0x7fff55512550); // mvp
glUniformMatrix3fv(5, 1, 0, 0x7fff55512528); // nmv
glUniform3fv(0, 1, 0x7fff55512670); // lightDir
glUniform3fv(9, 1, 0x7fff555124e8); // lightColor
// Mesh 0
glUniform3fv(8, 1, 0x7fab820cd7ec); // materialColor
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, 1);
glEnableVertexAttribArray(0);
glVertexAttribPointerARB(0, 3, GL_FLOAT, 0, 24, 0x00000000);
glEnableVertexAttribArray(2);
glVertexAttribPointerARB(2, 3, GL_FLOAT, 0, 24, 0x0000000c);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glDrawArrays(GL_TRIANGLES, 0, 21);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(2);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
// Mesh 1
glUniform3fv(8, 1, 0x7fab823000bc); // materialColor
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, 2);
glEnableVertexAttribArray(0);
glVertexAttribPointerARB(0, 3, GL_FLOAT, 0, 24, 0x00000000);
glEnableVertexAttribArray(2);
glVertexAttribPointerARB(2, 3, GL_FLOAT, 0, 24, 0x0000000c);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glDrawArrays(GL_TRIANGLES, 0, 24);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(2);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
// Mesh 2
glUniform3fv(8, 1, 0x7fab8231f8fc); // materialColor
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, 3);
glEnableVertexAttribArray(0);
glVertexAttribPointerARB(0, 3, GL_FLOAT, 0, 24, 0x00000000);
glEnableVertexAttribArray(2);
glVertexAttribPointerARB(2, 3, GL_FLOAT, 0, 24, 0x0000000c);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glDrawArrays(GL_TRIANGLES, 0, 21);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(2);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
// Mesh 3
glUniform3fv(8, 1, 0x7fab820cf41c); // materialColor
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, 4);
glEnableVertexAttribArray(0);
glVertexAttribPointerARB(0, 3, GL_FLOAT, 0, 24, 0x00000000);
glEnableVertexAttribArray(2);
glVertexAttribPointerARB(2, 3, GL_FLOAT, 0, 24, 0x0000000c);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glDrawArrays(GL_TRIANGLES, 0, 18);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(2);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
CGLFlushDrawable();
Run Code Online (Sandbox Code Playgroud)
编辑:这是用于获取统一位置的代码.在编辑和链接着色器后执行,并验证所有制服是否有效.
GLint mvpLoc = glGetUniformLocation(program, "mvp");
GLint nmvLoc = glGetUniformLocation(program, "nmv");
GLint lightDirLoc = glGetUniformLocation(program, "lightDir");
GLint lightColorLoc = glGetUniformLocation(program, "lightColor");
GLint materialColorLoc = glGetUniformLocation(program, "materialColor");
Run Code Online (Sandbox Code Playgroud)
有时司机会优化你的一些制服(即使不应该,特别是对于老司机)。要测试尝试在顶点着色器中使用材质颜色(将其复制到某个变化的变量,并在片段着色器中使用该变化的变量而不是统一的,这有时对我有用,...当然它会降低性能一点)
尝试使用不同的配置文件版本。在某些情况下,较新的驱动程序无法正确模拟旧版本。您尝试过核心配置文件吗?(我知道用旧代码实现非常棘手)
您可以尝试 nvemulate 来测试不同的驱动程序设置
有时会忘记 glEnd(); 尝试在帧渲染代码之前添加此代码会带来很多麻烦:
glEnd();
glEnd();
glEnd();
glEnd();
glEnd();
glEnd();
glEnd();
glEnd();
glEnd();
glEnd();
glEnd();
... here comes your rendering code
Run Code Online (Sandbox Code Playgroud)
如果这有帮助,那么您忘记调用 glEnd(); 某处或有 glEnd;而不是 glEnd();
[编辑1]
添加CPU端网格绘制相关代码后,很明显您对所有VBO和位置进行了硬编码uniform,但您的片段和顶点着色器在任何地方都没有静态位置
并寻找glGetUniformLocation用法。同样在着色器中你可以这样声明:
layout(location = 0) in vec3 pos;
Run Code Online (Sandbox Code Playgroud)
但这是针对旧版本中的最新GLSL,它可能有点不同,并且懒得搜索语法和关键字......
| 归档时间: |
|
| 查看次数: |
1291 次 |
| 最近记录: |