最近发现了一个很奇怪的问题,应该正常的绘图程序无法输出正确的结果,反复修改测试均不能解决问题。
问题为:几乎相同的代码绘制两个物体,一个绘制正常,另一个在调用glUniform时出错。
两个绘图函数为:
void FieldDraw::DrawBoundingBox()
{
_ProgAux.Use();
glUniformMatrix4fv(_ProgAux.Uniform("matMVP"), 1, GL_FALSE, &_matMVP[0][0]);
glUniform3fv(_ProgAux.Uniform("offset"), 1, &_SceneMin[0]);
glUniform3fv(_ProgAux.Uniform("scale"), 1, &_SceneScale[0]);
glUniform3f(_ProgAux.Uniform("in_color"), 0.7f, 0.7f, 0.5f);
//
_BoundinBox.Draw();
}
void FieldDraw::DrawTerrain()
{
//
_ProgTerrain.Use();
glUniformMatrix4fv(_ProgTerrain.Uniform("matMVP"), 1, GL_FALSE, &_matMVP[0][0]);
glUniform1i(_ProgTerrain.Uniform("depth_bar"), 2);
glUniform1f(_ProgTerrain.Uniform("max_depth"), _TerrainData._DepthMax);
glUniform3fv(_ProgTerrain.Uniform("offset"), 1, &_TerrainOffset[0]);
glUniform3fv(_ProgTerrain.Uniform("scale"), 1, &_TerrainSize[0]);
_TexDepthBar.BindTo(2);
//
_Terrain.Draw();
}
其中用到的GLSL代码如下:
// 辅助物体着色器代码
std::string aux_vs = "\n\
#version 330 core\n\
layout(location = 0) in vec4 Vertex;\n\
uniform mat4 matMVP;\n\
uniform vec3 offset = vec3(0.0);\n\
uniform vec3 scale = vec3(1.0);\n\
void main()\n\
{\n\
gl_Position = matMVP * vec4(Vertex.xyz * scale + offset, 1);\n\
}";
std::string aux_fs = "\n\
#version 330 core\n\
uniform vec3 line_color;\n\
out vec4 color;\n\
void main() \n\
{\n\
color = vec4(line_color, 1);\n\
}";
// 地形着色器代码
std::string terrain_vs = "\n\
#version 330 core\n\
layout(location=0) in vec4 Vertex;\n\
uniform sampler1D depth_bar;\n\
uniform mat4 matMVP;\n\
uniform vec3 offset = vec3(0.0);\n\
uniform vec3 scale = vec3(1.0);\n\
uniform float max_depth;\n\
out vec3 color;\n\
void main()\n\
{\n\
vec3 pos = vec3(Vertex.xy, Vertex.z / max_depth);\n\
color = texture(depth_bar, pos.z).rgb;\n\
gl_Position = matMVP * vec4(pos * scale + offset, 1);\n\
}";
std::string terrain_fs = "\n\
#version 330 core\n\
in vec3 color;\n\
layout(location = 0) out vec4 FragColor;\n\
void main()\n\
{\n\
FragColor = vec4(color, 1);\n\
}";
第一个函数能够正常绘制,第二个在每次调用glUniform时都出错,输出结果为:
AMD Radeon RX 6650 XT, 3.3.0 Core Profile Context 23.12.1.231124
After set uniform DrawTerrain.matMVP: GL_INVALID_OPERATION
After set uniform DrawTerrain.depth_bar: GL_INVALID_OPERATION
After set uniform DrawTerrain.max_depth: GL_INVALID_OPERATION
After set uniform DrawTerrain.offset: GL_INVALID_OPERATION
After set uniform DrawTerrain.scale: GL_INVALID_OPERATION
按照glUniform*的描述,这里最应该出错的地方是Program错误,但是跟踪发现程序完全正常,能够正确取得Uniform索引,glUseProgram也没有报任何错误。而且,这段代码放到N卡下是完全正常的。
这两段代码是绘制程序中最极端的两段,设置Uniform时一段完全正常,一段完全不正常,还有的绘制代码有那么两三个Uniform设置错误,其它的都没问题,甚至调整GLSL中uniform的顺序都可能造成错误的变化,我真的给整晕了。
整了好久,始终没有找到问题的根源所在。目前只能确定,在WIN11+3060下是正常的,在WIN11+6650XT下出错。A卡对OpenGL标准的支持比较严格,而N卡则相对宽松,这个我是知道的,但是完全按照标准来,且几乎相同的代码却有完全不同的结果,这我不能理解。
记录一下,以后有进展了再回来填坑。