Search code examples
javaopengljoglvbo

JOGL. OpenGL. How to update a VBO?


The idea - to draw some line by the code like:

gl.glBindBuffer(GL_ARRAY_BUFFER, line.getVertexOpenGLArray());

gl.glVertexAttribPointer(VERTEX_INDEX, 3, GL_FLOAT, false, 0, 0);

gl.glEnableVertexAttribArray(VERTEX_INDEX);

gl.glEnable(GL_DEPTH_TEST);
gl.glDepthFunc(GL_LEQUAL);
gl.glFrontFace(GL_CCW);

gl.glDrawArrays(GL_LINES, 0, line.getVertices().length);

When line.getVertexOpenGLArray() returns the VBO object index that was generated by:

        FloatBuffer vertBuf = Buffers.newDirectFloatBuffer(pvalues);
        gl.glBufferData(GL_ARRAY_BUFFER, vertBuf.limit() * 4, vertBuf, GL_STATIC_DRAW);

pvalues is the float[6] {x1,y1,z1,x2,y2,z2} contains coordinates of two vertexes of this line.

Then I try to change the second vertex in VBO by:

        FloatBuffer line_buf = Buffers.newDirectFloatBuffer(new_vertexes); 

        gl.glBufferSubData(GL_ARRAY_BUFFER, 0, line_buf.limit() * 4, line_buf);
        Buffer f = Buffers.newDirectFloatBuffer(line_vertexes);

        gl.glGetBufferSubData(GL_ARRAY_BUFFER, 0, line_buf.limit() * 4, f);

        System.out.println("Vertexes: " +
                ((FloatBuffer) f).get() + ", "+
                ((FloatBuffer) f).get() + ", "+
                ((FloatBuffer) f).get() + ", "+
                ((FloatBuffer) f).get() + ", "+
                ((FloatBuffer) f).get() + ", "+
                ((FloatBuffer) f).get());

And it report that values was changed successfuly. But when I render the next frame I see that line placed by old vertexes coordinates.

I tried to use gl.glInvalidateBufferData(vbo[VERTEX_INDEX]); but same result.

Is there some cache or something?


Solution

  • When line.getVertexOpenGLArray() returns the VBO object index that was generated by:

    FloatBuffer vertBuf = Buffers.newDirectFloatBuffer(pvalues);
    gl.glBufferData(GL_ARRAY_BUFFER, vertBuf.limit() * 4, vertBuf, GL_STATIC_DRAW);
    

    This code doesn't generate a "VBO object index". glGenBuffers reserves names for the use as a buffer object.
    glBufferData creates and initializes a buffer object's data store.

    So when gl.glBufferData(...) is called then the buffer data are destroyed, recreated and initialized. This causes that the change of the buffer data is lost.
    This has to be done only once, at the initialization of the buffer, rather than in every frame.