1
votes

I'm working on my custom game engine, and thus far everything is working fine.
Until I stumbled upon a weird error.
When I try to validate my shader program it returns GL_FALSE, to ensure good debugging I check the log info for error messages when something fails, but this error doesn't have a info log message, I checked whether it reads the files correctly and there's no error there... So I'm kinda stuck, I've looked all over the internet without any success, I hope someone on here can help me out with this one.
Thanks in advance!

In the main function I create a new shader program with 2 shader files, a vertex shader and a fragment shader, both compile without any errors.

    GLuint shaderProgram = glCreateProgram();
    std::string vertexFile = FileUtils::read_file("shaders/basic.vert");
    std::string fragmentFile = FileUtils::read_file("shaders/basic.frag");

    const char* vertexSource = vertexFile.c_str();
    const char* fragmentSource = fragmentFile.c_str();

    GLuint vertex = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertex, 1, &vertexSource, NULL);
    glCompileShader(vertex);

    GLint result;
    glGetShaderiv(vertex, GL_COMPILE_STATUS, &result);
    if (result != GL_TRUE)
    {
        GLint length;
        glGetShaderiv(vertex, GL_INFO_LOG_LENGTH, &length);
        std::vector<char> error(length);
        glGetShaderInfoLog(vertex, length, &length, &error[0]);
        std::cerr << "Failed to compile the vertex shader!" << std::endl;
        std::cerr << &error[0] << std::endl;
        glDeleteShader(vertex);
        return -1;
    }
    glAttachShader(shaderProgram, vertex);

    GLuint fragment = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(fragment, 1, &fragmentSource, NULL);
    glCompileShader(fragment);

    glGetShaderiv(fragment, GL_COMPILE_STATUS, &result);
    if (result != GL_TRUE)
    {
        GLint length;
        glGetShaderiv(fragment, GL_INFO_LOG_LENGTH, &length);
        std::vector<char> error(length);
        glGetShaderInfoLog(fragment , length, &length, &error[0]);
        std::cerr << "Failed to compile the fragment shader!" << std::endl;
        std::cerr << &error[0] << std::endl;
        glDeleteShader(fragment);
        return -1;
    }
    glAttachShader(shaderProgram, fragment);

    glValidateProgram(shaderProgram);
    glGetProgramiv(shaderProgram, GL_VALIDATE_STATUS, &result);
    if (result != GL_TRUE)
    {
        GLint length;
        glGetProgramiv(shaderProgram, GL_INFO_LOG_LENGTH, &length);
        std::vector<char> error(length);
        glGetProgramInfoLog(shaderProgram, length, &length, &error[0]);
        std::cerr << "Failed to validate the shader program!" << std::endl;
        std::cerr << &error[0] << std::endl;
        glDeleteProgram(shaderProgram);
        return -1;
    }
    glLinkProgram(shaderProgram);
    glGetProgramiv(shaderProgram, GL_LINK_STATUS, &result);
    if (result != GL_TRUE)
    {
        GLint length;
        glGetProgramiv(shaderProgram, GL_INFO_LOG_LENGTH, &length);
        std::vector<char> error(length);
        glGetProgramInfoLog(shaderProgram, length, &length, &error[0]);
        std::cerr << "Failed to link the shader program!" << std::endl;
        std::cerr << &error[0] << std::endl;
        glDeleteProgram(shaderProgram);
        return -1;
    }
    glUseProgram(shaderProgram);

Here's the read_file function from my FileUtils class:

std::string FileUtils::read_file(const char* filepath)
{
    FILE* file = fopen(filepath, "rt");
    fseek(file, 0, SEEK_END);
    unsigned long length = ftell(file);
    char data[length + 1];
    memset(data, 0, length + 1);
    fseek(file, 0, SEEK_SET);
    fread(data, 1, length, file);
    fclose(file);

    std::string result(data);
    return result;
}

I know it loads the files correctly because I made them print to the console to make sure the paths and files were correct, no errors there!

P.S.
If you see any errors in the code (such as "shader" as variable name) that is because I had to edit the original code to make it all fit in 1 code block for this.

1
You don't need to append solved to the title. By accepting an answer you have told others that the question is now solved. Thank you.Bugs

1 Answers

2
votes

glValidateProgram should be placed after glLinkProgram, but before glUseProgram.

A quote from here:

glValidateProgram checks to see whether the executables contained in program can execute given the current OpenGL state

If the program is not linked yet, it cannot be executed.