1

I was trying to create an OpenGL application which simply draws a triangle, but im getting Linker error: linking with uncompiled shader. from the call to glLinkProgram:

#include <GL/glew.h>
#include <GL/glut.h>
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
#include <assert.h>
using namespace std;

GLuint VBO;
void draw();
void CreateVBO();
GLuint MakeShader(const string& shaderFile);
GLuint CreateProgram();
string GetCode(const string& path);

int main(int argc, char* argv[])
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);

    glutInitWindowSize(768, 512);
    glutInitWindowPosition(0, 0);
    glutCreateWindow("Test");

    glutDisplayFunc(draw);

    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);

    GLenum var = glewInit();
    if(var != GLEW_OK){
        cerr << "Couldn't initialize glew" << endl;
        return -1;
    }

    CreateVBO();

    glutMainLoop();
    return 0;
}

void draw(){
    glClear(GL_COLOR_BUFFER_BIT);

    static GLuint program = CreateProgram();
    glUseProgram(program);
    glEnableVertexAttribArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);

    glDrawArrays(GL_TRIANGLES, 0, 3);

    glDisableVertexAttribArray(0);
    glutSwapBuffers();
}

GLuint CreateProgram(){
    GLuint program = glCreateProgram();
    vector<GLuint> shaders;
    shaders.push_back(MakeShader("shade.frag"));
    shaders.push_back(MakeShader("shader.vert"));
    for(size_t i = 0; i!= shaders.size(); ++i){
        glAttachShader(program, shaders[i]);
    }
    glLinkProgram(program);

    GLint linked;
    glGetProgramiv(program, GL_LINK_STATUS, &linked);
    if(linked == GL_FALSE){
        GLint infoLogLength;
        glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLogLength);

        GLchar* strInfoLog = new GLchar[infoLogLength+1];
        glGetProgramInfoLog(program, infoLogLength, NULL, strInfoLog);
        printf("Linker failure: %s \n", strInfoLog);
        delete strInfoLog;
    }
    return program;
}

string GetCode(const string &path){
    ifstream file(path);
    string ret = "";
    string line;
    if(file.is_open()){
        while(getline(file, line)){
            ret += line + '\n';
        }
    }
    return ret;
}

GLuint MakeShader(const string& shaderFile){
    string extension = shaderFile.substr(shaderFile.length()-4, 4);
    GLenum type;
    string shaderType;
    if(extension == "vert")
    {
        type = GL_VERTEX_SHADER;
        shaderType = "Vertex";
    }
    else if(extension == "frag")
    {
        type = GL_FRAGMENT_SHADER;
        shaderType = "Fragment";
    }

    const char* code = (GetCode(shaderFile)).c_str();
    GLuint shader = glCreateShader(type);
    glShaderSource(shader, 1, &code, NULL);

    glCompileShader(shader);

    GLint status;
    glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
    if(status != GLEW_OK){
        GLint logSize;
        glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logSize);
        GLchar* errorLog = new GLchar[logSize+1];
        glGetShaderInfoLog(shader, logSize, NULL, errorLog);
        printf("Compile failed in %s shader: %s \n", shaderType.c_str(), errorLog);
        delete errorLog;
    }
    return shader;
}

void CreateVBO(){
    float Vertices[12]= {
        0.0f, 0.0f, 0.0f, 1.0f,
        1.0f, 0.0f, 0.0f, 1.0f,
        0.0f, 1.0f, 0.0f, 1.0f
    };

    glGenBuffers(1, &VBO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);
}

I'm sorry if my question is noobish, but i'm sort of struggling with OpenGL

J.Dev
  • 66
  • 1
  • 8
  • If you are using code blocks IDE, then you can follow my [this](http://stackoverflow.com/questions/22747110/c-graphics-h-lbgi-not-found/31242642#31242642) answer. – Enamul Hassan Nov 24 '15 at 01:00
  • Are you sure your `glCompileShader` call succeeds? You always return shader name from `MakeShader` whether it compiles or not. – n0rd Nov 24 '15 at 01:04
  • Im actually using QtCreator, and yes the only error msg i get is the linker error – J.Dev Nov 24 '15 at 01:06

1 Answers1

4

You are incorrectly checking for shader compilation success. You compare GL_COMPILE_STATUS against GLEW_OK (which is 0 and has nothing to do with OpenGL), while you should compare with GL_TRUE (which is 1). Also the code does not do anything besides reporting the failure to stdout (i.e. there is no way for the caller to know if it failed or succeeded).

n0rd
  • 11,850
  • 5
  • 35
  • 56