Java LWJGL OpenGL Exception Access Violation 0xc0000005

Advertisements

I get an error when glDrawElements() is called and I can’t figure out why :/ I’m new to using OpenGL and I’m trying to learn how it works.

Note: I am using this library for turning an OBJ file into arrays that OpenGL should be able to use: https://github.com/korre/java-obj-to-opengl/blob/master/MeshObjectLoader.java

public class Mesh {

    private int vaoId;

    private List<Integer> vboIdList = new ArrayList<>();

    @Getter
    @Setter
    private float scale = 1;

    @Getter
    @Setter
    private Vector3f position = new Vector3f(0, 0, 0);

    @Getter
    @Setter
    private Vector3f rotation = new Vector3f(0, 0, 0);

    @Getter
    @Setter
    private String textureKey;

    private int vertexCount;

    private Mesh(MeshObjectLoader.MeshArrays meshArrays) {
        vaoId = glGenVertexArrays();
        glBindVertexArray(vaoId);

        var vboId = 0;
        vertexCount = meshArrays.getNumVertices();

        // Load vertices
        vboId = glGenBuffers();
        vboIdList.add(vboId);
        var vertexBuffer = (FloatBuffer) meshArrays.getVertices();
        glBindBuffer(GL_ARRAY_BUFFER, vboId);
        glBufferData(GL_ARRAY_BUFFER, vertexBuffer, GL_STATIC_DRAW);
        glVertexAttribPointer(0, 3, GL_FLOAT, false, 0 ,0);

        // Load texture coordinates
        vboId = glGenBuffers();
        vboIdList.add(vboId);
        var textureCoordsBuffer = (FloatBuffer) meshArrays.getTexCoords();
        glBindBuffer(GL_ARRAY_BUFFER, vboId);
        glBufferData(GL_ARRAY_BUFFER, textureCoordsBuffer, GL_STATIC_DRAW);
        glVertexAttribPointer(1, 2, GL_FLOAT, false, 0, 0);

        // Clean everything up
        glBindBuffer(GL_ARRAY_BUFFER, 0);
        glBindVertexArray(0);
    }

    public static Mesh loadFromObjFile(String resourcePath) throws IOException {
        try (var resourceStream = Mesh.class.getResourceAsStream(resourcePath)) {
            return new Mesh(MeshObjectLoader.loadModelMeshFromStream(resourceStream));
        }
    }

    public void render(int textureId) {
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, textureId);

        glBindVertexArray(vaoId);
        glEnableVertexAttribArray(0);
        glEnableVertexAttribArray(1);

        glEnable(GL_DEPTH_TEST);
        glDrawElements(GL_TRIANGLES, vertexCount, GL_UNSIGNED_INT, 0);

        glDisableVertexAttribArray(0);
        glDisableVertexAttribArray(1);
        glBindVertexArray(0);
    }

    public void cleanup() {
        glDisableVertexAttribArray(0);

        glBindBuffer(GL_ARRAY_BUFFER, 0);
        for (int vboId : vboIdList) {
            glDeleteBuffers(vboId);
        }

        glBindVertexArray(0);
        glDeleteVertexArrays(vaoId);
    }

}

>Solution :

The cause of the crash is that you never bind a buffer object to the GL_ELEMENT_ARRAY_BUFFER binding point of the VAO, so the last argument of glDrawElements(..., 0) is interpreted as a host-address pointer instead of an byte-offset in any element array buffer.
And dereferencing the 0 address fails, of course.

Whenever you call an indexed draw call like glDrawElements you also need an element array buffer (also called "index buffer").

The library returns the list of positions, texture coordinates and normals in such a way that you merely need to do a non-indexed draw call via glDrawArrays(). This is also pretty typical of a Wavefront OBJ loader, because the Wavefront OBJ format has separate indexes for positions, normals and texture coordinates, so a typical load will do the cross-product of all face indexes anyways and provide you with a linear/duplicated list of vertex data.

So: Do glDrawArrays instead.

Leave a ReplyCancel reply