从文件读取字符串不能按预期工作

时间:2014-04-05 16:04:51

标签: c++ opengl io

我目前正在用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*包含正确的代码(我刚刚转换为字符串的文件中的内容)。

我不明白该方法的不一致性。我无法弄清楚,如何以正确的方式解析一个着色器而另一个是空的。

我希望有人能搞清楚。 非常感谢你。

2 个答案:

答案 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();