Search code examples
javaopengllwjgl

Unable to render a triangle using VAOs and VBOs-LWJGL3 (OpenGL 3.3)


Im getting no errors, glGetErrors() is returning 0, shaders and compiling and the window setup code was copied directly from the LWJGL website. Ive read all the stack overflow answers i could find related to problems like this and tried out their solutions but to no avail. Could someone please help me fix my code.

Entity code:

public PlainEntity(float[] vertices,float[] texCoords,int[] indices,int ID){
    this.vertices=vertices;
    this.texCoords=texCoords;
    this.indices=indices;
    this.ID=ID;
    generateNormals();

    FloatBuffer verticesBuffer=MemoryUtil.memAllocFloat(vertices.length);
    FloatBuffer texBuffer=MemoryUtil.memAllocFloat(texCoords.length);
    FloatBuffer normBuffer=MemoryUtil.memAllocFloat(normals.length);
    IntBuffer indexBuffer=MemoryUtil.memAllocInt(indices.length);

    verticesBuffer.put(vertices).flip();
    normBuffer.put(normals).flip();
    texBuffer.put(texCoords).flip();
    indexBuffer.put(indices).flip();

    vaoID= GL30.glGenVertexArrays();
    indVBO=GL30.glGenBuffers();
    vertVBO=GL30.glGenBuffers();
    normVBO=GL30.glGenBuffers();
    texVBO=GL30.glGenBuffers();

    GL30.glBindVertexArray(vaoID);

    GL30.glBindBuffer(GL15.GL_ARRAY_BUFFER,vertVBO);
    GL15.glBufferData(GL15.GL_ARRAY_BUFFER,verticesBuffer,GL15.GL_STATIC_DRAW);
    GL20.glVertexAttribPointer(0,3, GL11.GL_FLOAT,false,Float.SIZE*3,0);
    MemoryUtil.memFree(verticesBuffer);

    GL30.glBindBuffer(GL15.GL_ARRAY_BUFFER,normVBO);
    GL15.glBufferData(GL15.GL_ARRAY_BUFFER,normBuffer,GL15.GL_STATIC_DRAW);
    GL20.glVertexAttribPointer(1,3, GL11.GL_FLOAT,false,Float.SIZE*3,0);
    MemoryUtil.memFree(normBuffer);

    GL30.glBindBuffer(GL15.GL_ARRAY_BUFFER,texVBO);
    GL15.glBufferData(GL15.GL_ARRAY_BUFFER,texBuffer,GL15.GL_STATIC_DRAW);
    GL20.glVertexAttribPointer(2,2, GL11.GL_FLOAT,false,Float.SIZE*2,0);
    MemoryUtil.memFree(texBuffer);

    GL30.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER,indVBO);
    GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER,indexBuffer,GL15.GL_STATIC_DRAW);
    MemoryUtil.memFree(indexBuffer);

    GL30.glBindVertexArray(0);

Shader:

Shader shader=new Shader("""
        #version 330
                        
        layout (location=0) in vec3 position;
                        
        void main()
        {
            gl_Position = vec4(position, 0.0);
        }""",
        """
        #version 330
                                        
        out vec4 fragColor;
                                        
        void main()
        {
            fragColor = vec4(0.0, 0.5, 0.5, 1.0);
        }""");

Binding shaders:

public ShaderProgram (Shader shader){

    programID= GL20.glCreateProgram();
    try {
        vID = createShader(shader.vertex, GL20.GL_VERTEX_SHADER);
        fID = createShader(shader.fragment, GL20.GL_FRAGMENT_SHADER);
        GL20.glAttachShader(programID,vID);
        GL20.glAttachShader(programID,fID);
    }catch(Exception e){
        System.out.println("Could not create Shaders");
    }
    if(vID==0){
        System.out.println("error in vertex shader");
    }

    GL20.glLinkProgram(programID);
    GL20.glDetachShader(programID,vID);
    GL20.glDetachShader(programID,fID);
    GL20.glValidateProgram(programID);

    if (GL20.glGetProgrami(programID, GL20.GL_VALIDATE_STATUS) == 0) {
        System.err.println("Warning validating Shader code: " + GL20.glGetProgramInfoLog(programID, 1024));
    }
}

private int createShader (String source,int type){
    int shaderID=GL20.glCreateShader(type);

    GL20.glShaderSource(shaderID,source);
    GL20.glCompileShader(shaderID);

    if (GL20.glGetShaderi(shaderID,GL20.GL_COMPILE_STATUS) == 0) {
        System.err.println("Error compiling Shader code: " + GL20.glGetShaderInfoLog(shaderID, 1024));
    }

    GL20.glAttachShader(programID,shaderID);
    return shaderID;
}

public void bind(){
    GL20.glUseProgram(programID);
}

public void unbind(){
    GL20.glUseProgram(0);
}

Rendering:

private void renderEntity(PlainEntity entity){
    GL30.glBindVertexArray(entity.getVAO());
    GL30.glEnableVertexAttribArray(0);
    GL30.glEnableVertexAttribArray(1);
    GL30.glEnableVertexAttribArray(2);
    GL30.glDrawElements(GL11.GL_TRIANGLES,entity.getVertexCount(),GL11.GL_UNSIGNED_INT,0);
}

public void render(ShaderProgram shader){
    shader.bind();
    for(PlainEntity entity: EntityManager.entities){
        renderEntity(entity);
    }
    shader.unbind();
}

Solution

  • Float.SIZE is not the number of bytes in a float (i.e. 4) but the number of bits in a float (i.e. 32). Therefore, lines like these:

    GL20.glVertexAttribPointer(0,3, GL11.GL_FLOAT,false,Float.SIZE*3,0);
    

    are wrong. This should read as:

    GL20.glVertexAttribPointer(0,3, GL11.GL_FLOAT,false,Float.BYTES*3,0);
    

    Additionally, you set the w component of gl_Position to 0.0, which will lead the vertices to be positioned at infinity. You should change that to 1.0 instead in the vertex shader.