2

The following GLSL fragment shader compiles and works as expected:

#version 330 core
out vec3 color;
in float U;
in vec4 vertexNormal_worldSpace;
uniform sampler1D TextureSampler;
uniform vec4 LightPos;
void main()
{
    float cosT = dot(normalize(vertexNormal_worldSpace.xyz),normalize(LightPos.xyz));
    color = cosT * texture(TextureSampler,U).rgb;
}

However, when I change line 9 to clamp the value of "cosT" between 0 and 1:

float cosT = clamp(dot(normalize(vertexNormal_worldSpace.xyz),normalize(LightPos.xyz)),0.0,1.0);

I get the errors:

0(1) : error C0000: syntax error, unexpected integer constant, expecting "::" at token "<int-const>"
0(10) : error C7532: global function texture requires "#version 130" or later

This appears to say the error appears on the first line, but nothing has changed there at all. Furthermore the 2nd error suggests that there is an issue with the version of GLSL I am using, however #version 330 core should be a later version than #version 130, as the error message states.

EDIT: This is my code for loading in shaders:

static GLuint LoadShaders(const char* vertex_file_path, const char* frag_file_path){
    GLuint VertID = glCreateShader(GL_VERTEX_SHADER);
    GLuint FragID = glCreateShader(GL_FRAGMENT_SHADER);

    char const* VertPointer = ReadShaderFile(vertex_file_path);
    char const* FragPointer = ReadShaderFile(frag_file_path);
    glShaderSource(VertID,1,&VertPointer,NULL);
    glCompileShader(VertID);


    GLint Result = GL_FALSE;
    int InfoLogLength;
    glGetShaderiv(VertID, GL_COMPILE_STATUS, &Result);
    glGetShaderiv(VertID, GL_INFO_LOG_LENGTH, &InfoLogLength);
    if ( InfoLogLength > 0 ){
        std::vector<char> VertexShaderErrorMessage(InfoLogLength+1);
        glGetShaderInfoLog(VertID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]);
        printf("%s\n", &VertexShaderErrorMessage[0]);
    }


    glShaderSource(FragID,1,&FragPointer,NULL);
    glCompileShader(FragID);
    glGetShaderiv(FragID, GL_COMPILE_STATUS, &Result);
    glGetShaderiv(FragID, GL_INFO_LOG_LENGTH, &InfoLogLength);
    if ( InfoLogLength > 0 ){
        std::vector<char> FragmentShaderErrorMessage(InfoLogLength+1);
        glGetShaderInfoLog(FragID, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]);
        printf("%s\n", &FragmentShaderErrorMessage[0]);
    }



    GLuint ProgramID = glCreateProgram();
    glAttachShader(ProgramID,VertID);
    glAttachShader(ProgramID,FragID);
    glLinkProgram(ProgramID);


    glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result);
    glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength);
    if ( InfoLogLength > 0 ){
        std::vector<char> ProgramErrorMessage(InfoLogLength+1);
        glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]);
        printf("%s\n", &ProgramErrorMessage[0]);
    }
    return ProgramID;


}
static char const* ReadShaderFile(const char* path){
    std::string ShaderCode;
    std::ifstream ShaderStream(path,std::ios::in);
    if(ShaderStream.is_open()){
        std::string line = "";
        while (std::getline(ShaderStream,line)){
            ShaderCode +="\n"+line;
        }
        ShaderStream.close();
        return ShaderCode.c_str();
    }else{

    return 0;}
}

This is basically straight from the tutorial I am following link, only change is putting the file reading in the ReadShaderFile function.

EDIT 2: My OpenGL context is created with the following version:

glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR,3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR,3);
jcg
  • 59
  • 6
  • Try casting the return value of `dot()` to `double` or using `0.0f` and `1.0f` for `clamp()`'s `minVal`/`maxVal` arguments. I'm not seeing a [`clamp()` overload](https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/clamp.xhtml) that takes `(genType, double, double)`. – genpfault Dec 19 '17 at 22:12
  • That gives `0(9) : error C7502: OpenGL does not allow type suffix 'f' on constant literals in versions below 120`. I am following a tutorial [link](http://www.opengl-tutorial.org/beginners-tutorials/tutorial-8-basic-shading/) and there they just use 0 and 1 and it works fine – jcg Dec 19 '17 at 22:16
  • 4
    Wait, aren't you using `#version 330 core`? Type suffixes are perfectly cromulent in `330 core`. Edit in a [mcve] demonstrating your shader loader, it seems like your `#version` directive is getting cut somehow. – genpfault Dec 19 '17 at 22:21

1 Answers1

2

The problem is indeed the shader loader. You are adding with this statement

ShaderCode +="\n"+line;

a newline character (\n) before each line which moves everything one line down compared to your input.

Since the version statement has to be in the first line of a shader and you move it to the second, the statement seems to be ignored by your driver. My NVIDIA driver, for example, states:

error C0204: version directive must be first statement and may not be repeated

A simple fix would be to add to newline character after each line instead of before, but I would strongly encourage you not to read whole files line by line since this will give you a terrible performance. For example, the ShaderCode variable will be resized for each line which means you get a memory allocation and a copy operation for the whole string. Have a look at this question on how to read complete files.

Edit:

Another problem is that you're returning the c_str() pointer of local variable. When the ReadShaderFile method ends, the std::string ShaderCode variable goes out of scope (thus frees it's content) and the returned pointer points to an invalid memory address.

Solution: Return the std::string object instead of the const char pointer to its content.

BDL
  • 18,169
  • 14
  • 45
  • 47
  • Changing this line to `ShaderCode += line + "\n";` results in the same error – jcg Dec 20 '17 at 10:50
  • I found another problem with your code. I'll update the answer in a few minutes, but basically your returning a pointer to a freed memory segment. – BDL Dec 20 '17 at 10:57
  • I can also ensure you that the problem is most probably not in your shader itself. It compiles fine for me on NVIDIA, AMD and Intel. – BDL Dec 20 '17 at 11:03
  • Sure enough, returning a string solved the problem. Unsure why it only broke in some cases but at least it works now, thanks. – jcg Dec 20 '17 at 13:25
  • Glad I could help :) – BDL Dec 20 '17 at 13:38