Search code examples
c++openglglslshaderglew

Why is the glsl '#version' definition giving me an error?


I have a simply shader creation pipeline. Nothing special. The shader source reads in properly from what I can tell. Originally, I had the shader code in files with a suffix of '.glsl' just because I wanted to, but they are now plain '.txt' files.

After reading in the shader code, I compile the shader and link the shader as well as check the compile status and info log for errors. The actual shader code below doesn't look to me like it has an error considering it't now basically a carbon copy of a simple tutorial you can find online which I'll link if you need it.

I do get an error though, which is "0(1) : error C0104: Unknown pre-processor directive #version330". This is the same for both the vertex and the fragment shaders, which have an almost identical creation process.

My driver version is [4.6.0 NVIDIA 445.87] as well, so I should be able to use #version 330. I did also have them both set to '#version 330 core', but I was getting the same error.

This is my program and shader creation process.


   struct s_Program
   {
       uint32_t program, vert, frag;

       s_Program()
       {
           vert = glCreateShader(GL_VERTEX_SHADER);
           frag = glCreateShader(GL_FRAGMENT_SHADER);
           program = glCreateProgram();
       }

       bool genVert(const char* fpath)
       {
           std::fstream file(fpath);
           if (!file)
           {
               logf("[FILE_ERROR] : Failed to read shader file.");
               return(false);
           }

           logf("Reading vert shader.");
           const char* source;
           std::string newSource, line;
           while (file >> line)
           {
               newSource += line;
           }
           source = newSource.c_str();

           glShaderSource(vert, 1, &source, 0);
           glCompileShader(vert);

           int comp;
           glGetShaderiv(vert, GL_COMPILE_STATUS, &comp);
           if (comp == GL_FALSE)
           {
               int maxLength = 0;
               glGetShaderiv(vert, GL_INFO_LOG_LENGTH, &maxLength);

               std::vector<char> errorLog(maxLength);
               glGetShaderInfoLog(vert, maxLength, &maxLength, &errorLog[0]);

               logf(&errorLog[0]);

               glDeleteShader(vert);
               return(false);
           }

           glAttachShader(program, vert);
           return(true);
       }

       bool genFrag(const char* fpath)
       {
           std::fstream file(fpath);
           if (!file)
           {
               logf("[FILE_ERROR] : Failed to read shader file.");
               return(false);
           }

           const char* source;
           std::string newSource = "", line;
           while (file >> line)
           {
               newSource += line;
           }
           source = newSource.c_str();

           glShaderSource(frag, 1, &source, 0);
           glCompileShader(frag);

           int comp;
           glGetShaderiv(frag, GL_COMPILE_STATUS, &comp);
           if (comp == GL_FALSE)
           {
               int maxLength = 0;
               glGetShaderiv(frag, GL_INFO_LOG_LENGTH, &maxLength);

               std::vector<char> errorLog(maxLength);
               glGetShaderInfoLog(frag, maxLength, &maxLength, &errorLog[0]);

               logf(&errorLog[0]);

               glDeleteShader(frag);
               return(false);
           }

           glAttachShader(program, frag);
           return(true);
       }

       void linkProgram()
       {
           glLinkProgram(program); glDetachShader(program, vert); glDetachShader(program, frag);
           glDeleteShader(vert); glDeleteShader(frag);
       }

       void bindProgram()
       { glUseProgram(program); }

       void unbindProgram()
       { glUseProgram(0); }
   };

These are my shaders.


// Vertex
#version 330

in vec4 _pos;

out vec4 aColor;

void main()
{
    _pos = vec4(_pos, 1.0);
    gl_Position = _pos;
}

// Fragment
#version 330

out vec4 FragColor;

in vec4 _color;

void main()
{
    _color = vec4(0.5, 0.5, 0.1, 1.0);
    FragColor = _color;
}

This is the implementation in the main file.


    s_Program mainShader;
    if (!mainShader.genVert("data/shaders/standardVert.txt"))
    { logf("[ERR] : Failed to generate Vertex Shader."); }
    if (mainShader.genFrag("data/shaders/standardFrag.txt"))
    { logf("[ERR] : Failed to generate Fragment Shader."); }
    mainShader.linkProgram();

I then call my function "bindProgram" in my loop witch sets GL to use that program.

I'm clearly missing something, I just want to know what.


Solution

  • Your while (file >> line) loop reads on a word-by-word basis. Appending each word to a string effectively strips all whitespace from your shader.

    Instead, do this to read the file as-is into a std::string:

    std::stringstream src_ss;
    file >> src_ss.rdbuf();
    std::string newSource{ src_ss.str() };