0
\$\begingroup\$

StackExchange!

I've been working with opengl for a bit and I'm trying to finally load the shaders instead of having them inline. I'm having a ton of issues, though. As soon as I solve one, another pops up. Now, the issue is glGetProgramInfoLog reporting "Fragment Shader output type error." I thought it might be caused by the old graphics card - Intel Graphics 300, but it was working when it was inline (directly as a const char *). Does anyone know what this might mean, and how to solve this? Thanks in advance!

Vertex Shader:

#version 400 compatibility

layout (location = 0) in vec3 vertexPosition;

uniform mat4 Model;
uniform mat4 View;
uniform mat4 Projection;

void main () {
    gl_Position = Projection * View * Model * vec4(vertexPosition, 1.0);
}

Fragment Shader:

#version 330

layout(location = 0) out vec4 fragColor;

void main()
{
    fragColor = vec4(1.0, 0.0, 0.0, 1.0);
}

Shader Loading Code:

GLuint getShaders(const char *vertexpath, const char *fragmentpath) {

    printf("****************** Loading Shaders ******************\nVertex: %s\nFragment: %s\n\n", vertexpath, fragmentpath);
    std::string VertexShaderCode;
    std::ifstream VertexShaderStream(vertexpath, std::ios::in);
    if (VertexShaderStream.is_open()){
        std::string Line = "";
        while (getline(VertexShaderStream, Line))
            VertexShaderCode += "\n" + Line;
        VertexShaderStream.close();
    }
    else{
        printf("Impossible to open %s. Are you in the right directory ? Don't forget to read the FAQ !\n", vertexpath);
        getchar();
        return 0;
    }

    std::string FragShaderCode;
    std::ifstream FragShaderStream(fragmentpath, std::ios::in);
    if (FragShaderStream.is_open()){
        std::string Line = "";
        while (getline(FragShaderStream, Line))
            FragShaderCode += "\n" + Line;
        FragShaderStream.close();
    }

    GLuint vs = glCreateShader(GL_VERTEX_SHADER);
    char const * VertexSourcePointer = VertexShaderCode.c_str();
    glShaderSource(vs, 1, &VertexSourcePointer, NULL);
    glCompileShader(vs);

    GLint logSize = 0;
    glGetShaderiv(vs, GL_INFO_LOG_LENGTH, &logSize);
    printf("Size: %i\n", logSize);

    GLint isCompiled = 0;
    glGetShaderiv(vs, GL_COMPILE_STATUS, &isCompiled);
    if (isCompiled == GL_FALSE) {
        GLint maxLength = 0;
        glGetShaderiv(vs, GL_INFO_LOG_LENGTH, &maxLength);

        // The maxLength includes the NULL character
        std::vector<GLchar> errorLog(maxLength);
        glGetShaderInfoLog(vs, maxLength, &maxLength, &errorLog[0]);

        printf("Vertex Shader Error Report:\nSize: %i\n%s\n----------------------------\n", logSize, errorLog);

        // Exit with failure.
        glDeleteShader(vs); // Don't leak the shader.
        return 0;
    }

    GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);
    char const * FragSourcePointer = FragShaderCode.c_str();
    glShaderSource(fs, 1, &FragSourcePointer, NULL);
    glCompileShader(fs);

    logSize = 0;
    std::string shaderInfo;
    glGetShaderiv(fs, GL_INFO_LOG_LENGTH, &logSize);
    printf("Size: %i\n", logSize);

    isCompiled = 0;
    glGetShaderiv(fs, GL_COMPILE_STATUS, &isCompiled);
    if (isCompiled == GL_FALSE) {
        GLint maxLength = 0;
        glGetShaderiv(fs, GL_INFO_LOG_LENGTH, &maxLength);

        // The maxLength includes the NULL character
        std::vector<GLchar> errorLog(maxLength);
        glGetShaderInfoLog(fs, maxLength, &maxLength, &errorLog[0]);

        printf("Fragment Shader Error Report:\nSize: %i\n%s\n----------------------------\n", logSize, errorLog);


        // Exit with failure.
        glDeleteShader(fs); // Don't leak the shader.
        return 0;
    }

    GLuint program = glCreateProgram();
    glAttachShader(program, fs);
    glAttachShader(program, vs);
    glLinkProgram(program);

    GLint isLinked = 0;
    glGetProgramiv(program, GL_LINK_STATUS, &isLinked);
    if (isLinked == GL_FALSE) {
        GLint maxLength = 0;
        glGetProgramiv(program, GL_INFO_LOG_LENGTH, &maxLength);

        //The maxLength includes the NULL character
        std::vector<GLchar> infoLog(maxLength);
        glGetProgramInfoLog(program, maxLength, &maxLength, &infoLog[0]);

        //The program is useless now. So delete it.
        glDeleteProgram(program);

        printf("Program Error Report:\n%s\n----------------------------\n", infoLog);

        return 0;
    }

    glDeleteShader(vs);
    glDeleteShader(fs);

    return program;
}
\$\endgroup\$
  • \$\begingroup\$ Is "Fragment Shader output type error." literally the GLSL error message you are getting? That sounds fishy, usually they include a line number or something more descriptive. \$\endgroup\$ – Andon M. Coleman Dec 19 '14 at 2:30
  • \$\begingroup\$ It's what I get from the info log of the program. \$\endgroup\$ – Karim Abdel Hamid Dec 19 '14 at 8:17
  • \$\begingroup\$ Have you tried removing the layout method of color output and tried setting gl_FragColor instead? \$\endgroup\$ – XNargaHuntress Dec 19 '14 at 13:01
  • \$\begingroup\$ @KarimAbdelHamid: Well that sounds like you tried to link a vertex shader as a fragment shader. Try outputting the shader info log even when compilation is successful. \$\endgroup\$ – Andon M. Coleman Dec 19 '14 at 13:36
  • \$\begingroup\$ Okay, well, I don't have any more errors anymore, but it still simply doesn't work. All I see is a donut shape to the most basic of shaders. #version 330 core layout(location = 0) in vec3 position; void main () { gl_Position = vec4(position, 1.0); } #version 330 core out vec4 FragColor; void main() { FragColor = vec4(1.0, 1.0, 1.0, 1.0); } I tried using gl_FragColor, removing layout, changing versions, checking the render code, still nothing works. Any ideas? \$\endgroup\$ – Karim Abdel Hamid Dec 20 '14 at 1:42
1
\$\begingroup\$

The issue was with the loading. I'm not sure what exactly the problem was, because I changed the code significantly, but it's working now.

EDIT Current loading code:

GLuint getShaders(const char *vertexpath, const char *fragmentpath) {

printf("****************** Loading Shaders ******************\nVertex: %s\nFragment: %s\n\n", vertexpath, fragmentpath);
std::string VertexShaderCode;
std::ifstream VertexShaderStream(vertexpath, std::ios::in);
if (VertexShaderStream.is_open()){
    std::string Line = "";
    while (getline(VertexShaderStream, Line))
        VertexShaderCode += "\n" + Line;
    VertexShaderStream.close();
}
else{
    printf("Impossible to open %s. Are you in the right directory ? Don't forget to read the FAQ !\n", vertexpath);
    getchar();
    return 0;
}

// Read the Fragment Shader code from the file
std::string FragmentShaderCode;
std::ifstream FragmentShaderStream(fragmentpath, std::ios::in);
if (FragmentShaderStream.is_open()){
    std::string Line = "";
    while (getline(FragmentShaderStream, Line))
        FragmentShaderCode += "\n" + Line;
    FragmentShaderStream.close();
}

GLuint vs = glCreateShader(GL_VERTEX_SHADER);
char const * VertexSourcePointer = VertexShaderCode.c_str();
glShaderSource(vs, 1, &VertexSourcePointer, NULL);
glCompileShader(vs);

GLint Result = GL_FALSE;
int InfoLogLength;

// Check Vertex Shader
glGetShaderiv(vs, GL_COMPILE_STATUS, &Result);
glGetShaderiv(vs, GL_INFO_LOG_LENGTH, &InfoLogLength);
if (InfoLogLength > 0){
    std::vector<char> VertexShaderErrorMessage(InfoLogLength + 1);
    glGetShaderInfoLog(vs, InfoLogLength, NULL, &VertexShaderErrorMessage[0]);
    printf("%s\n", &VertexShaderErrorMessage[0]);
}

GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);
char const * FragSourcePointer = FragmentShaderCode.c_str();
glShaderSource(fs, 1, &FragSourcePointer, NULL);
glCompileShader(fs);

// Check Fragment Shader
glGetShaderiv(fs, GL_COMPILE_STATUS, &Result);
glGetShaderiv(fs, GL_INFO_LOG_LENGTH, &InfoLogLength);
if (InfoLogLength > 0){
    std::vector<char> FragmentShaderErrorMessage(InfoLogLength + 1);
    glGetShaderInfoLog(fs, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]);
    printf("%s\n", &FragmentShaderErrorMessage[0]);
}

GLuint program = glCreateProgram();
glAttachShader(program, fs);
glAttachShader(program, vs);
glLinkProgram(program);

GLint isLinked = 0;
glGetProgramiv(program, GL_LINK_STATUS, &isLinked);
if (isLinked == GL_FALSE) {
    GLint maxLength = 0;
    glGetProgramiv(program, GL_INFO_LOG_LENGTH, &maxLength);

    //The maxLength includes the NULL character
    std::vector<GLchar> infoLog(maxLength);
    glGetProgramInfoLog(program, maxLength, &maxLength, &infoLog[0]);

    //The program is useless now. So delete it.
    glDeleteProgram(program);

    printf("Program Error Report:\n%s\n----------------------------\n", infoLog);

    return 0;
}

glDeleteShader(vs);
glDeleteShader(fs);

return program;
}
\$\endgroup\$
  • \$\begingroup\$ can you post your changed shader loading code? so that it would be useful for anyone stumbling on this question with a similar issue. \$\endgroup\$ – JeanLuc Dec 21 '14 at 15:32
  • \$\begingroup\$ I've gone over a diff of the two versions of the loading code; the only material differences (besides different indenting and a few modified variable names) is the code for printing out the shader info logs. The original code destroyed shaders and exited when a compile error was reported. The new code does not. (In fact, the new code doesn't even check whether the shader compilation succeeded) Whatever solved the problem, it seems implausible for it to have been related to this code. \$\endgroup\$ – Trevor Powell Dec 23 '14 at 5:29
  • \$\begingroup\$ Trevor, I was continually messing with the code, but here's what I had realised: the constant size I reported was the size of the error report. I know, bonehead issue. But that must mean either a problem with loading or compiling. \$\endgroup\$ – Karim Abdel Hamid Dec 27 '14 at 0:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.