Search code examples
opengljoglvbovao

Opengl Exception after glBufferData


i am getting a Exception_access_violation from my jogl program. The code sample contains the point where the error gets thrown according to logs (and tested with Sys out). I happens right at the glBufferData call for the vertices.

So currently i am merging together smaller meshes into a single bigger one by combining the vertices and adjusting the indices aswell. The Program can run with same amount of vertices spread out over multiple meshes (vaos) but after i combine them i get this error. When i render a combined mesh with lesser vertices it also works.

When it crashed I am loading a mesh with 24834 vertices and 12618 indices. Is that just to big for the Buffer?

public static int loadToGPU(Mesh mesh){


    GL4 gl = GLContext.getCurrentGL().getGL4();

    int[] vaoids = new int[1];
    gl.glGenVertexArrays(1,vaoids,0);


    int[] vboids = new int[3];
    gl.glGenBuffers(3,vboids,0);

    gl.glBindVertexArray(vaoids[0]);

    FloatBuffer verticesBuffer = FloatBuffer.allocate(mesh.vertices.length);
    verticesBuffer.put(mesh.vertices);
    verticesBuffer.flip();

    gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vboids[0]);
    gl.glBufferData(gl.GL_ARRAY_BUFFER, mesh.vertices.length * gl.GL_FLOAT ,verticesBuffer,gl.GL_STATIC_DRAW);
    gl.glEnableVertexAttribArray(0);
    gl.glVertexAttribPointer(0, 3, gl.GL_FLOAT, false, 0, 0);

    verticesBuffer.clear();
    verticesBuffer = null;

    IntBuffer indicesBuffer = IntBuffer.allocate(mesh.indices.length);
    indicesBuffer.put(mesh.indices);
    indicesBuffer.flip();

    gl.glBindBuffer(gl.GL_ELEMENT_ARRAY_BUFFER, vboids[1]);
    gl.glBufferData(gl.GL_ELEMENT_ARRAY_BUFFER, mesh.indices.length * gl.GL_UNSIGNED_INT ,indicesBuffer,gl.GL_STATIC_DRAW);
    gl.glEnableVertexAttribArray(1);
    gl.glVertexAttribPointer(1, 3, gl.GL_UNSIGNED_INT, false, 0, 0);

    indicesBuffer.clear();
    indicesBuffer = null;

    FloatBuffer normalBuffer = FloatBuffer.allocate(mesh.normals.length);
    normalBuffer.put(mesh.normals);
    normalBuffer.flip();

    gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vboids[2]);
    gl.glBufferData(gl.GL_ARRAY_BUFFER, mesh.normals.length * gl.GL_FLOAT ,normalBuffer,gl.GL_STATIC_DRAW);
    gl.glEnableVertexAttribArray(2);
    gl.glVertexAttribPointer(2, 3, gl.GL_FLOAT, false, 0, 0);

    normalBuffer.clear();
    normalBuffer = null;

    gl.glBindBuffer(gl.GL_ARRAY_BUFFER,0);
    gl.glBindVertexArray(0);


    return vaoids[0];

}

Solution

  • mesh.vertices.length * gl.GL_FLOAT doesn't do, what you expect it to do.
    gl.GL_FLOAT is an enumerator constant and it' value is not 4 (It is 0x1406 respectively 5126). What you actually do is to calculate mesh.vertices.length * 5126
    You've to calculate the size of the buffer in bytes, so you've to multiply the number of elements by the size of the data type float:

    gl.glBufferData(gl.GL_ARRAY_BUFFER, mesh.vertices.length * gl.GL_FLOAT, ...); gl.glBufferData(gl.GL_ARRAY_BUFFER, mesh.vertices.length * 4, ...);

    The same issue is when you create and initialize the data store of the element buffer:

    gl.glBufferData(gl.GL_ELEMENT_ARRAY_BUFFER, mesh.indices.length * gl.GL_UNSIGNED_INT, ...);
    gl.glBufferData(gl.GL_ELEMENT_ARRAY_BUFFER, mesh.indices.length * 4, ...);

    and the vertex buffer for the normal vectors:

    gl.glBufferData(gl.GL_ARRAY_BUFFER, mesh.normals.length * gl.GL_FLOAT, ...)
    gl.glBufferData(gl.GL_ARRAY_BUFFER, mesh.normals.length * 4, ...)