Search code examples
javaopengllwjgl

Trying to draw a basic shape with LWJGL3


so i want to draw a shape using VAO and VBOs and i think im doing everything right but whenever i run my code i just get the window with the clear color. I had an issue before when i tried to initialize the triangles before i called create capabilities, am i missing some function to start drawing?

here is my code:

int vaoId, vboId, vertexCount;

float[] vertices = {
    // Left bottom triangle
    -0.5f, 0.5f,
    -0.5f, -0.5f,
    0.5f, -0.5f,};

private void init() {
    if (!glfwInit()) {
        throw new IllegalStateException("Failed to Initialize GLFW!");
    }

    int width = 1000;
    int height = 1000;

    glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
    window = glfwCreateWindow(width, height, "App", NULL, NULL);

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

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

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

    glfwShowWindow(window);
}

private void loop() {
    // This line is critical for LWJGL's interoperation with GLFW's
    // OpenGL context, or any context that is managed externally.
    // LWJGL detects the context that is current in the current thread,
    // creates the GLCapabilities instance and makes the OpenGL
    // bindings available for use.
    GL.createCapabilities();

    initTriangle();

    // Run the rendering loop until the user has attempted to close
    // the window or has pressed the ESCAPE key.
    while (!glfwWindowShouldClose(window)) {
        glClear(GL_COLOR_BUFFER_BIT); // clear the framebuffer

        glBindVertexArray(vaoId);
        glEnableVertexAttribArray(0);

        glDrawArrays(GL_TRIANGLES, 0, vertexCount);

        glDisableVertexAttribArray(0);
        glBindVertexArray(0);

        glfwSwapBuffers(window); // swap the color buffers

        // Poll for window events. The key callback above will only be
        // invoked during this call.
        glfwPollEvents();

    }
}

private void initTriangle() {

    FloatBuffer vertBuf = MemoryUtil.memAllocFloat(vertices.length);
    vertBuf.put(vertices);
    vertBuf.flip();

    vaoId = glGenVertexArrays();
    glBindVertexArray(vaoId);

    vboId = glGenBuffers();
    glBindBuffer(GL_ARRAY_BUFFER, vboId);
    glBufferData(GL_ARRAY_BUFFER, vertBuf, GL_STATIC_DRAW);

    glVertexAttribPointer(0, 2, GL_FLOAT, false, 0, 0);

    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);
}

I hope you guys can help, thanks a lot.


Solution

  • I am not using shaders. Is that my problem? And is it a necessity

    The state of the art way of rendering in OpenGL, would be to use a Shader.

    If you don't use a shader, than you have to define the array of vertex data by glVertexPointer

    vaoId = glGenVertexArrays();
    glBindVertexArray(vaoId);
    
    vboId = glGenBuffers();
    glBindBuffer(GL_ARRAY_BUFFER, vboId);
    glBufferData(GL_ARRAY_BUFFER, vertBuf, GL_STATIC_DRAW);
    
    glVertexPointer( 2, GL_FLOAT, 0, 0 ); // <---------------
    
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);
    

    and you have to enable the client-side capability for vertex coordinates by glEnableClientState( GL_VERTEX_ARRAY ):

    glBindVertexArray(vaoId);
    glEnableClientState( GL_VERTEX_ARRAY ); // <---------------
    
    glDrawArrays(GL_TRIANGLES, 0, vertexCount);
    
    glDisableClientState( GL_VERTEX_ARRAY ); // <---------------
    glBindVertexArray(0);
    

    Note, this state of the client-side capability (or vertex attribute array) is stored in the Vertex Array Object. So it is sufficient to enable the vertex coordinates, when the vertex array object is specified. The enabling and disabling of the vertex coordinates, when drawing the geometry, can be omitted:

    vaoId = glGenVertexArrays();
    glBindVertexArray(vaoId);
    
    vboId = glGenBuffers();
    glBindBuffer(GL_ARRAY_BUFFER, vboId);
    glBufferData(GL_ARRAY_BUFFER, vertBuf, GL_STATIC_DRAW);
    
    glVertexPointer( 2, GL_FLOAT, 0, 0 ); 
    glEnableClientState( GL_VERTEX_ARRAY ); // <---------------
    
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);
    

    glBindVertexArray(vaoId);
    
    glDrawArrays(GL_TRIANGLES, 0, vertexCount);
    
    glBindVertexArray(0);