I've started learning how to use OpenGL and I absolutely hate having my shaders declared as global variables before my main().
I thought it would be cool to make a structure or class that would read the shader from a file in my project directory. The file reading works perfectly fine, but for some reason it won't actually output an image like it would if I had the shader declared before main. Here is my example.
Shader Reading Structure:
#include "allHeader.h" struct shaderReader { shaderReader::shaderReader(std::string); const GLchar* source; }; shaderReader::shaderReader(std::string name) { std::string line, allLines; std::ifstream theFile(name); if (theFile.is_open()) { while (std::getline(theFile, line)) { allLines = allLines + line + "\n"; } source = allLines.c_str(); std::cout << source; theFile.close(); } else { std::cout << "Unable to open file."; } } Snapshot of Area right before main()
shaderReader vertexShader = shaderReader("vertex.txt"); shaderReader fragmentShader = shaderReader("fragment.txt"); const GLchar* vertexSource = "#version 150 core\n" "in vec2 position;" "void main() {" " gl_Position = vec4(position, 0.0, 1.0);" "}"; const GLchar* fragmentSource = "#version 150 core\n" "out vec4 outColor;" "void main() {" " outColor = vec4(1.0, 1.0, 1.0, 1.0);" "}"; int main() { //stuff } Works
GLuint vertexShaderObject = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertexShaderObject, 1, &vertexSource, NULL); glCompileShader(vertexShaderObject); //Now let's create the Fragment Shader Object GLuint fragmentShaderObject = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragmentShaderObject, 1, &fragmentSource, NULL); glCompileShader(fragmentShaderObject); Doesn't work for some Reason
const GLchar* ob1 = vertexShader.source; const GLchar* ob2 = fragmentShader.source; GLuint vertexShaderObject = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertexShaderObject, 1, &ob1, NULL); glCompileShader(vertexShaderObject); //Now let's create the Fragment Shader Object GLuint fragmentShaderObject = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragmentShaderObject, 1, &ob2, NULL); glCompileShader(fragmentShaderObject); Also Doesn't Work
GLuint vertexShaderObject = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertexShaderObject, 1, &vertexShader.source, NULL); glCompileShader(vertexShaderObject); //Now let's create the Fragment Shader Object GLuint fragmentShaderObject = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragmentShaderObject, 1, &fragmentShader.source, NULL); glCompileShader(fragmentShaderObject); The above code when working prints out a white triangle in the middle of a black screen. However, when not working I just get a black screen. I tried checking the shaders for compile errors and I got no errors at all. I'm think perhaps something is wrong within the structure, something there I didn't do right. Thank you for reading my question, if you had a similar problem I hope my question helps you.
allLinesstring go out of scope after you finished reading the code. So the memory containing the shader code will be freed before you use it..txtfiles. Wrap each line in""at the start and end. End it with a;. Thenconst GLChar* some_shader =, newline,#include "shader.txt". Hey look! Compile time string, no file loading at runtime, and your shaders are out of the way?allLinesgo out of scope? @Yakk could you demonstrate an example as an answer if possible, thank you.allLinesin the constructor. So when the constructor endsallLinesis destroyed.allLinesintosource. You get a pointer to the internal data ofallLines, and assign that pointer tosource. Then whenallLinesgoes out of scope at the end of the constructor, it frees its memory, andsourceis now pointing to freed memory.