Reputation: 375
I'm currently writing my first programm in OpenGl and C/C++. I came across the following problem:
I wrote a method which reads a file (in my case containing the vertex or fragment shader) and returns the content as one string.
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);
}
}
I've two files: vertexShader.glsl and fragmentShader.glsl which I want to convert to two seperate strings for the creation of the shaders. The code above is called in the following way:
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...
}
I debugged the code above and noticed that the vertexShader const char*
is empty, while the fragmentShader const char*
contains the correct code (the content from the file I just converted to a string).
I don't understand the inconsistency in the method. I can't figure out, how one shader is parsed the right way and the other is empty.
I hope somebody can figure it out. Thank you very much.
Upvotes: 0
Views: 708
Reputation: 7100
The problem is that your unnamed std::string
returned from loadShader()
only exists within the scope of the expression:
const GLchar* vertexShader = loadShader("vertexShader.glsl").c_str();
Quoting the standard:
Temporary objects are destroyed as the last step in evaluating the full-expression (1.9) that (lexically) contains the point where they were created.
The fix is simple:
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();
Upvotes: 2
Reputation: 30136
Change this:
const GLchar* vertexShader = loadShader("vertexShader.glsl").c_str();
const GLchar* fragmentShader = loadShader("fragmentShader.glsl").c_str();
To this:
std::string vertexShaderString = loadShader("vertexShader.glsl");
std::string fragmentShaderString = loadShader("fragmentShader.glsl");
const GLchar* vertexShader = vertexShaderString.c_str();
const GLchar* fragmentShader = fragmentShaderString.c_str();
Upvotes: 1