Search code examples
javaeclipseopengllwjgl

OpenGL vertex arrays throw invalid operation error


I've recently started using OpenGL and LWJGL but ever since I tried to mess with/add vertex array objects, I've been getting the same error over and over:

GL_INVALID_OPERATION

I am having a hard time understanding why but I managed to pin down to problem to these methods:

glEnableClientState(GL_VERTEX_ARRAY);
vao = glGenVertexArrays();

glBindVertexArray(vao);
glEnableVertexAttribArray(vao);     
glVertexAttribPointer(0, count, GL_FLOAT, false, Float.SIZE * 2, 0);

glBindVertexArray(0);

...so basically anything that has to do with vertex arrays throws this error. If anyone could point out what exactly I am doing wrong, that would be great. This is the rest of my code:

import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL15.*;
import static org.lwjgl.opengl.GL20.*;
import static org.lwjgl.opengl.GL30.*;

import java.nio.FloatBuffer;
import java.nio.IntBuffer;

import org.lwjgl.BufferUtils; 

public class Model {

    private int count;
    private int ibo, vao;

    public Model(float[] vertices, int[] indices) {

        count = indices.length;

        glEnableClientState(GL_VERTEX_ARRAY);
        vao = glGenVertexArrays();

        glBindVertexArray(vao);
        glEnableVertexAttribArray(vao);
        glVertexAttribPointer(0, count, GL_FLOAT, false, Float.SIZE * 2, 0);

        glBindVertexArray(0);

        FloatBuffer vBuffer = BufferUtils.createFloatBuffer(vertices.length);
        vBuffer.put(vertices).flip();

        int vbo = glGenBuffers();
        glBindBuffer(GL_ARRAY_BUFFER, vbo);
        glBufferData(GL_ARRAY_BUFFER, vBuffer, GL_STATIC_DRAW);

        IntBuffer iBuffer = BufferUtils.createIntBuffer(indices.length);
        iBuffer.put(indices).flip();

        ibo = glGenBuffers();
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, iBuffer, GL_STATIC_DRAW);

        glBindBuffer(GL_ARRAY_BUFFER, 0);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

    }
    public void draw() {

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

        glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_INT, 0);

    }
}

Solution

  • The parameter of glEnableVertexAttribArray is the attibute index. This means you have to change your code like this:

    glBindVertexArray( vao );
    glEnableVertexAttribArray( 0 ); // <--- attribute index instead of object name
    

    Or you may use glEnableVertexArrayAttrib:

    glEnableVertexArrayAttrib( vao, 0 );
    


    OpenGL 4.6 core profile specification, 10.3. VERTEX ARRAYS, page 354:

    An individual generic vertex attribute array in a vertex array object is enabled with the commands

    void EnableVertexAttribArray( uint index );
    void EnableVertexArrayAttrib( uint vaobj, uint index );
    


    Note, glEnableClientState is part of the deprecated fixed function pipeline. If you want to use the fixed function pipeline and glEnableClientState, then you have to use glVertexPointer instead of glVertexAttribPointer.