0

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.

1
  • 2
    You are taking a c_str() of a temporary, which becomes garbage Commented Apr 5, 2014 at 16:09

2 Answers 2

2

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(); 
Sign up to request clarification or add additional context in comments.

2 Comments

Although i get the idead behind the scope of the temporary expression it doesn't seem to do the trick. The variable for the vertexShader remains empty whereas the fragmentShader contains the correct String... Btw I'm pretty sure it's something stupid I made while coding, I just can't find the mistake.
Ok, it seems there is another problem with the OpenGL part I have to figure out. Your approach works just fine ;)
1

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.