Search code examples
javaopengllwjgl

VBO and VAO not drawing opengl and LWJGL3


Ive been playing around with open GL for a while now and i got to the point that i can draw 3d shapes, My shapes and vertices and indices are definitely right and my shape was getting messed up. I am now wanting to redo my drawing. I used to only use VBO with no VAO and just bind and draw them. This worked but im suspicious of this being my bug. So i started using VAO's and i dont see anything that is wrong with my code and i still cant get it to draw my white square(no shaders just like the wiki tutorials).

My code for initializing the window is here:

private void initWindow() {
    //Makes sure window can work
    if (!glfwInit()) {
        throw new IllegalStateException("Failed to Initialize GLFW!");
    }

    //Create window object and set its hints
    glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);

    this.windowRef = glfwCreateWindow(width, height, name, NULL, NULL);

    if (windowRef == 0) {
        throw new IllegalStateException("Failed to create Window!");
    }

    GLFWVidMode videoMode = glfwGetVideoMode(glfwGetPrimaryMonitor());
    glfwSetWindowPos(windowRef, (videoMode.width() - width) / 2, (videoMode.height() - height) / 2);

    // Make the OpenGL context current
    glfwMakeContextCurrent(windowRef);
    // Enable v-sync
    glfwSwapInterval(1);

    //Make GL capabilites for window
    GL.createCapabilities();
    glfwShowWindow(windowRef);
}

my code for initializing my buffers and objects is here

public void loadGL() {
    float[] vertex = {
        0f, 0f, 0f, //0
        0.5f, 0, 0, //1
        0.5f, 0, 0.5f, //2
        0f, 0f, 0.5f, //3
        0f, 0.5f, 0f, //4
        0.5f, 0.5f, 0, //5
        0.5f, 0.5f, 0.5f,//6
        0f, 0.5f, 0.5f//7
    };

    int[] index = {
        0, 1, 2, //0
        0, 2, 3, //1
        0, 3, 4, //2
        3, 7, 4,//3
        0, 4, 1,//4
        1, 5, 4,//5
        1, 5, 2,//6
        2, 6, 5,//7
        2, 3, 6,//8
        3, 7, 6,//9
        4, 5, 7,//10
        5, 6, 7//11
    };
    size = 12*3;

    indicesBuff = BufferUtils.createIntBuffer(index.length);
    vertBuff = BufferUtils.createFloatBuffer(vertex.length);
    indicesBuff.put(index);
    vertBuff.put(vertex);
    indicesBuff.flip();
    vertBuff.flip();

    vao = glGenVertexArrays();
    glBindVertexArray(vao);

    vboID = glGenBuffers();
    glBindBuffer(GL_ARRAY_BUFFER, vboID);
    glBufferData(GL_ARRAY_BUFFER, vertBuff, GL_STATIC_DRAW);
    GL20.glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);

    ibo = glGenBuffers();
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, indicesBuff, GL_STATIC_DRAW);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    glBindVertexArray(0);

}

and finally my main loop is here, it is called after the window init:

    private void mainLoop() {
    loadGL();
    glClearColor(0.5f, 0.5f, 0.5f, 1);
    while (!glfwWindowShouldClose(windowRef)) {

        //Render Stuff here
        //TODO: later skip this block if nothing has changed
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear 
the framebuffer

        glBindVertexArray(vao);
        glEnableVertexAttribArray(0);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);

        glDrawElements(GL_TRIANGLES, size, GL_UNSIGNED_INT, 0);

//            glBegin(GL_QUADS);
//            glVertex3f(-0.5f, -0.5f, 0);
//            glVertex3f(-0.5f, 0.5f, 0);
//            glVertex3f(0.5f, -0.5f, 0);
//            glVertex3f(0.5f, 0.5f, 0);
//            glEnd();

        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
        glDisableVertexAttribArray(0);
        glBindVertexArray(0);

        glfwSwapBuffers(windowRef);
        glfwPollEvents();
    }
}

btw drawing it with glBegin and so works but its not efficient for what i want to do.


Solution

  • The modern way of rendering in OpenGL, would be to use a Shader program.

    If you don't use a shader program, than you have to define the array of vertex data using the deprected way by glVertexPointer and you have to enable the client-side capability for vertex coordinates by glEnableClientState( GL_VERTEX_ARRAY ):

    vao = glGenVertexArrays();
    glBindVertexArray(vao);
    
    vboID = glGenBuffers();
    glBindBuffer(GL_ARRAY_BUFFER, vboID);
    glBufferData(GL_ARRAY_BUFFER, vertBuff, GL_STATIC_DRAW);
    GL20.glVertexPointer(3, GL_FLOAT, 0, 0);  // <--------------
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    

     glBindVertexArray(vao);
     glEnableClientState( GL_VERTEX_ARRAY );   // <--------------
     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
    
     glDrawElements(GL_TRIANGLES, size, GL_UNSIGNED_INT, 0);
    
     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
     glDisableClientState( GL_VERTEX_ARRAY ); // <---------------
     glBindVertexArray(0);
    

    Further note, that the state of the client-side capability (or vertex attribute array) and the reference to the index (element) buffer is stored in the Vertex Array Objects state vector. So it is sufficient to enable the vertex coordinates, when the vertex array object is specified and to bid the index buffer when the vertex array object is bound. The enabling and disabling of the vertex coordinates and binding of the index buffer, when drawing the geometry, can be omitted:

    vao = glGenVertexArrays();
    glBindVertexArray(vao);
    
    vboID = glGenBuffers();
    glBindBuffer(GL_ARRAY_BUFFER, vboID);
    glBufferData(GL_ARRAY_BUFFER, vertBuff, GL_STATIC_DRAW);
    GL20.glVertexPointer(3, GL_FLOAT, 0, 0);    // <--------------
    glEnableClientState( GL_VERTEX_ARRAY );     // <--------------
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    
    ibo = glGenBuffers();
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, indicesBuff, GL_STATIC_DRAW);
    // skip glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    glBindVertexArray(0);
    

    glBindVertexArray(vao);
    
    glDrawElements(GL_TRIANGLES, size, GL_UNSIGNED_INT, 0);
    
    glBindVertexArray(0);