我目前正在用OpenGl和C / C ++编写我的第一个程序。我遇到了以下问题:
我编写了一个读取文件的方法(在我的例子中包含顶点或片段着色器)并将内容作为一个字符串返回。
std::string loadShader(const char* filepath)
{
if(filepath){
std::ifstream ifs(filepath, std::ifstream::in);
std::ostringstream oss;
std::string temp;
while(ifs.good()){
getline(ifs, temp);
oss << temp << '\n';
std::cout << temp << std::endl;
}
ifs.close();
return oss.str();
}
else{
exit(EXIT_FAILURE);
}
}
我有两个文件:vertexShader.glsl和fragmentShader.glsl,我想将其转换为两个单独的字符串来创建着色器。上面的代码按以下方式调用:
void createShaders(void){
GLenum errorCheckValue = glGetError();
const GLchar* vertexShader = loadShader("vertexShader.glsl").c_str();
const GLchar* fragmentShader = loadShader("fragmentShader.glsl").c_str();
vertexShaderId = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShaderId, 1, &vertexShader, NULL);
glCompileShader(vertexShaderId);
fragmentShaderId = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShaderId, 1, &fragmentShader, NULL);
glCompileShader(fragmentShaderId);
// some other code follows...
}
我调试了上面的代码并注意到vertexShader const char*
为空,而fragmentShader const char*
包含正确的代码(我刚刚转换为字符串的文件中的内容)。
我不明白该方法的不一致性。我无法弄清楚,如何以正确的方式解析一个着色器而另一个是空的。
我希望有人能搞清楚。 非常感谢你。
答案 0 :(得分:2)
问题是从std::string
返回的未命名loadShader()
仅存在于表达式的范围内:
const GLchar* vertexShader = loadShader("vertexShader.glsl").c_str();
引用标准:
临时对象在评估全表达式(1.9)的最后一步时被销毁,该表达式(词法上)包含创建它们的点。
修复很简单:
const std::string vertexShaderStr = loadShader("vertexShader.glsl");
const GLchar *vertexShader = vertexShaderStr.c_str();
const std::string fragmentShaderStr = loadShader("fragmentShader.glsl");
const GLchar *fragmentShader = fragmentShaderStr.c_str();
答案 1 :(得分:1)
改变这个:
const GLchar* vertexShader = loadShader("vertexShader.glsl").c_str();
const GLchar* fragmentShader = loadShader("fragmentShader.glsl").c_str();
对此:
std::string vertexShaderString = loadShader("vertexShader.glsl");
std::string fragmentShaderString = loadShader("fragmentShader.glsl");
const GLchar* vertexShader = vertexShaderString.c_str();
const GLchar* fragmentShader = fragmentShaderString.c_str();