OpenGL VAO and shaders not rendering

I’m trying to write a C++ application that will be render VAO and shaders.

That’s my algorithm:

  1. GLUT initialization
  2. GLEW initialization
  3. Shaders loading
  4. Shaders attaching
  5. Program linking
  6. Attribute’s and uniform’s location getting
  7. Buffers generating
  8. Data buffering
  9. Main loop (display() callback)
  10. Buffers and program deleting

This algorithm is correct? Anyway, application doesn’t render anything. Where is my mistake?

My code is here (glew and freeglut required):


#include <GL/glew.h>
#include <GL/freeglut.h>

#include <iostream>
#include <exception>

using namespace std;

/************************** SERVICE CLASSES AND FUNCTIONS ******************/
class ProgramException : public exception {
private:
    const char *message;
    const exception *cause;

public:
    ProgramException(const char *message) : message(message), cause(nullptr) { }

    ProgramException(const char *message, const exception *cause) : message(message), cause(cause) { }

    virtual const char *what() const throw() { return message; }

    const exception *why() const throw() { return cause; }
};

void checkOpenGLError() {
    GLenum errCode;
    if ((errCode = glGetError()) != GL_NO_ERROR) {
        string error = "OpenGl error: ";
        error.append((char *) gluErrorString(errCode));
        throw new ProgramException(error.c_str());
    }
}

void shaderLog(unsigned int shader, string shaderType) {
    int infoLogLen = 0;
    int charsWritten = 0;
    char *infoLog;

    glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLen);

    if (infoLogLen > 1) {
        infoLog = new char[infoLogLen];
        glGetShaderInfoLog(shader, infoLogLen, &charsWritten, infoLog);
        shaderType.append(" -> ");
        shaderType.append(infoLog);
        cerr << shaderType << endl;
        delete[] infoLog;
    }
}

/************************* SHADER SOURCES **************************/
const char *vShaderSrc = 
    "#version 330
"
    "attribute vec3 in_Position;
"
    "void main() {
"
    "    gl_Position = vec4(in_Position, 1.0);
"
    "}
";

const char *fShaderSrc =
    "#version 330
"
    "uniform vec4 in_Color;
"
    "void main() {
"
    "    gl_FragColor = in_Color;
"
    "}
";

/************************ GL identificators *****************/
int idWindowHandle;
GLuint idProgram;
GLuint idVao;
GLuint idVbo[2]; // positions and colors
GLuint idEbo;
GLuint idVShader;
GLuint idFShader;
GLuint idAttributePosition;
GLuint idUniformColor;

/***************************** INPUT DATA ********************/
int vertexIndices[3] = { 
    0, 1, 2 
};
long lengthVertexIndices = 3;

float vertexPositions[9] = { 
    0.0, 0.0, 0.0,
    1.0, 0.0, 0.0,
    1.0, 1.0, 0.0 
};
long lengthVertexPositions = 9;
float vertexColors[12] = {
    1.0, 0.0, 0.0, 1.0,
    0.0, 1.0, 0.0, 1.0,
    0.0, 0.0, 1.0, 1.0
};
long lengthVertexColors = 12;

/******************************* CALLBACKS ***********************/
void reshape(int w, int h) {
    glViewport(0, 0, w, h);
}

void idle() {
    glutPostRedisplay();
}

void display() {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glBindVertexArray(idVao);
    glUseProgram(idProgram);

    glDrawArrays(GL_TRIANGLES, 0, 3);

    glUseProgram(0);
    glBindVertexArray(0);

    glutSwapBuffers();
}

/******************************** START OF MAIN *********************/
int main(int argc, char **argv ) {

    /******************** GLUT INIT ********************/ 
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_ALPHA);

    glutInitContextVersion(3, 3);
    glutInitContextProfile(GLUT_CORE_PROFILE);
    glutInitContextFlags(GLUT_FORWARD_COMPATIBLE);

    glutInitWindowSize(320, 240);

    glutCreateWindow("Hello");

    glutIdleFunc(idle);
    glutReshapeFunc(reshape);
    glutDisplayFunc(display);

    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glClearDepth(1.0f);
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_CULL_FACE);

    /******************** GLEW INIT ********************/ 
    glewExperimental = GL_TRUE;

    GLenum glew_status;

    try {
        /* glewInit() may be caused of OpenGL invalid enumerant error,
         * but this is not critical*/
        glew_status = glewInit();
        checkOpenGLError();
    } catch (ProgramException *ignored) { }

    if (glew_status != GLEW_OK) {
        /* GLEW is not initialized */
        string error = "GLEW error: ";
        error.append((char *) glewGetErrorString(glew_status));
        throw new ProgramException(error.c_str());
    }

    /* Check for accessibility of OpenGL 3.3 */
    if (!GLEW_VERSION_3_3) {
        string error = "No support for OpenGL 3.3 found : ";
        error.append((char *) glewGetErrorString(glew_status));
        throw new ProgramException(error.c_str());
    }

    /***************************** LOAD SHADERS *************************/
    /* Vertex shader */
    idVShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(idVShader, 1, &vShaderSrc, NULL);
    glCompileShader(idVShader);
    shaderLog(idVShader, "VShader");

    /* Fragment shader */
    idFShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(idFShader, 1, &fShaderSrc, NULL);
    glCompileShader(idFShader);
    shaderLog(idFShader, "FShader");

    /***************************** ATTACH SHADERS *************************/
    idProgram = glCreateProgram();
    glAttachShader(idProgram, idVShader);
    glAttachShader(idProgram, idFShader);

    checkOpenGLError();

    /************************** LINK PROGRAM ******************************/
    glLinkProgram(idProgram);

    int link_ok;
    glGetProgramiv(idProgram, GL_LINK_STATUS, &link_ok);
    if (!link_ok) {
        throw new ProgramException("Error attach shaders");
    }

    checkOpenGLError();

    /************************** GET ATTRIBUTES AND UNIFORMS ***************/
    const char *positionAttributeName = "in_Position";
    idAttributePosition = (GLuint) glGetAttribLocation(idProgram, positionAttributeName);
    if (idAttributePosition == -1) {
        string error = "Could not bind attribute ";
        error.append(positionAttributeName);
        throw new ProgramException(error.c_str());
    }

    const char *colorAttributeName = "in_Color";
    idUniformColor = (GLuint) glGetUniformLocation(idProgram, colorAttributeName);
    if (idUniformColor == -1) {
        string error = "Could not bind uniform ";
        error.append(colorAttributeName);
        throw new ProgramException(error.c_str());
    }

    checkOpenGLError();

    /******************** GEN BUFFERS ****************/
    glGenVertexArrays(1, &idVao);
    glGenBuffers(2, idVbo);
    glGenBuffers(1, &idEbo);

    checkOpenGLError();

    /********************** BUFFER DATA ******************/
    glBindVertexArray(idVao);

    /* Element array */
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, idEbo);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, lengthVertexIndices * sizeof(int), 
                 vertexIndices, GL_STATIC_DRAW);
    checkOpenGLError();

    /* Position array */
    glBindBuffer(GL_ARRAY_BUFFER, idVbo[0]);
    glBufferData(GL_ARRAY_BUFFER, lengthVertexPositions * sizeof(float), 
                 vertexPositions, GL_STATIC_DRAW);
    glVertexAttribPointer(idAttributePosition, 3,
                          GL_FLOAT, GL_FALSE, 0, 0);
    glEnableVertexAttribArray(idAttributePosition);
    checkOpenGLError();

    /* Color array */
    glBindBuffer(GL_ARRAY_BUFFER, idVbo[1]);
    glBufferData(GL_ARRAY_BUFFER, lengthVertexColors * sizeof(float), 
                 vertexColors, GL_STATIC_DRAW);
    glVertexAttribPointer(idUniformColor, 4,
                          GL_FLOAT, GL_FALSE, 0, 0);
    glEnableVertexAttribArray(idAttributePosition);

    /*********************** MAIN LOOP ********************/
    glutMainLoop();

    /********************** DISABLE ***********************/
    glDisableVertexAttribArray(idAttributePosition);
    glDisableVertexAttribArray(idUniformColor);

    glBindVertexArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glDeleteBuffers(2, idVbo);

    glUseProgram(0);
    glDeleteProgram(idProgram);

    checkOpenGLError();
}

in your fragment shader:


uniform vec4 in_Color;

i dont see where you’ve uploaded that value … something like:
float mycolor[] = {0, 0, 1, 1};
glUniform4fv(glGetUniformLocation(idProgram, “in_Color”), 1, mycolor);

or try that:


uniform vec4 in_Color = vec4(0, 0 ,1, 1); // setting a default value

another thing:


glVertexAttribPointer(idAttributePosition, 3, GL_FLOAT, GL_FALSE, 0, 0);

try replacing that with:


glVertexAttribPointer(idAttributePosition, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 3, 0);

and for the color buffer:


glVertexAttribPointer(idUniformColor, 4, GL_FLOAT, GL_FALSE, sizeof(float) * 4, 0);

if you want to use the colors from your buffer, you have to add another attribute in the vertex shader an pass that to the fragment shader