OpenGL程序中glGetAttribLocation获取vertexIn属性返回-1求助
OpenGL glGetAttribLocation返回-1的问题排查与修复
问题根源
你的代码中Shader.cpp的CompileShaders函数里,判断着色器类型的逻辑存在严重错误,导致顶点着色器和片段着色器的代码被错误地编译到了同一个着色器对象中,另一个着色器对象始终未被正确加载代码,最终链接后的程序无法识别顶点属性vertexIn和colorIn,因此glGetAttribLocation返回-1。
错误代码行:
auto shaderID = (filename.find(".vert")) ? vertexShaderID : fragmentShaderID;
错误原因
C++中std::string::find如果找到子串,返回的是子串在字符串中的起始位置(非0整数);如果未找到,返回std::string::npos(一个极大的无符号整数)。这两种情况在布尔判断中都会被视为true,因此无论传入的是顶点着色器还是片段着色器文件,代码都会将shaderID赋值为vertexShaderID。这会导致:
- 顶点着色器的代码被正确编译到
vertexShaderID - 片段着色器的代码被覆盖编译到
vertexShaderID,而fragmentShaderID始终是空的未编译状态 - 链接程序时,附加的是被覆盖的顶点着色器和未编译的片段着色器,最终程序无法正确解析顶点属性
修复方法
将判断逻辑修改为检查find的结果是否不等于std::string::npos,即确认文件名中包含.vert后缀:
auto shaderID = (filename.find(".vert") != std::string::npos) ? vertexShaderID : fragmentShaderID;
额外优化建议
- 在
CompileShaders函数中添加着色器类型的输出,方便调试:
std::cout << "Compiling " << ((filename.find(".vert") != std::string::npos) ? "vertex" : "fragment") << " shader: " << filename << std::endl;
- 修正文件读取逻辑,避免最后一行重复读取:
// 替换原while (!file.eof())循环 std::string line; std::string sourceCode; while (std::getline(file, line)) { sourceCode += line + "\n"; }
内容的提问来源于stack exchange,提问作者Alex Gama
相关产品推荐
相关产品推荐

