MultiDrawElements

classic Classic list List threaded Threaded
17 messages Options
Reply | Threaded
Open this post in threaded view
|

MultiDrawElements

James
Hi

I am new to OpenGL and JOGL. I am using GL3 and GL4 I have set up a basic app to create a NEWT window and link a program using shaders. I have been learning how to draw basic shapes mainly triangles, squares, and circles using different primitive tokens and drawing methods. I have drawn 3 colored squares: red, green, and blue using DrawArrays, MultiDrawArrays, and DrawElements but 1 cannot get it to work using MultiDrawElements at best I get the first red square to draw

This is what it should look like



I can draw the first red square if i use DrawElement method which is commented out in following code but MultiDrawElementsDraws nothing. I can get MultiDrawElements to draw the first red square to draw if I move the glVertexAttribPointer methods into the display method and enable and disable these along with binding the buffers but I want to hopefully just use the display method and set the state in the init method. Below is  the code

package demo;

import com.jogamp.common.nio.PointerBuffer;
import com.jogamp.opengl.GL4;
import com.jogamp.opengl.GLAutoDrawable;
import com.jogamp.opengl.util.GLBuffers;
import demo.common.core.BasicDemo;

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

import static com.jogamp.opengl.GL.*;

/**
 * Created by James on 20/12/2015.
 *
 * Draws 3 squares using method drawElements
 * 3 primitive each made up of 2 triangles using 4 vertices (6 elements)
 * 1 red, 1 green, and 1 blue
 */
public class MultiDrawElements2 extends BasicDemo {

    private static final boolean fps = false;

    public MultiDrawElements2(final boolean fps) {
        super(fps);
    }

    public static void main(final String... args) {
        new MultiDrawElements2(fps);
    }

    // 3 0
    // 2 1
    private static final float[] VERTEX_DATA = {
            250.0f, 250.0f, 0.0f, 1.0f, // 0 right top
            250.0f, 350.0f, 0.0f, 1.0f, // 1 right bottom - reused
            150.0f, 350.0f, 0.0f, 1.0f, // 2 left bottom
            150.0f, 250.0f, 0.0f, 1.0f, // 3 left top - reused

            450.0f, 250.0f, 0.0f, 1.0f,
            450.0f, 350.0f, 0.0f, 1.0f,
            350.0f, 350.0f, 0.0f, 1.0f,
            350.0f, 250.0f, 0.0f, 1.0f,

            650.0f, 250.0f, 0.0f, 1.0f,
            650.0f, 350.0f, 0.0f, 1.0f,
            550.0f, 350.0f, 0.0f, 1.0f,
            550.0f, 250.0f, 0.0f, 1.0f,

            1.0f, 0.0f, 0.0f, 1.0f,
            1.0f, 0.0f, 0.0f, 1.0f,
            1.0f, 0.0f, 0.0f, 1.0f,
            1.0f, 0.0f, 0.0f, 1.0f,

            0.0f, 1.0f, 0.0f, 1.0f,
            0.0f, 1.0f, 0.0f, 1.0f,
            0.0f, 1.0f, 0.0f, 1.0f,
            0.0f, 1.0f, 0.0f, 1.0f,

            0.0f, 0.0f, 1.0f, 1.0f,
            0.0f, 0.0f, 1.0f, 1.0f,
            0.0f, 0.0f, 1.0f, 1.0f,
            0.0f, 0.0f, 1.0f, 1.0f
    };

    private static final short[] ELEMENT_DATA = { // Note that we start from 0!
            0, 1, 3,
            1, 2, 3,

            0, 1, 3,
            1, 2, 3,

            0, 1, 3,
            1, 2, 3
    };

    private static final int PRIM_COUNT = 3;
    private static final int VERTICES_COUNT = 4;
    private static final int VERTICES_SIZE = 4;
    private static final int COLOUR_SIZE = 4;
    private static final int ELEMENT_COUNT = 6;
    private static final int COLOUR_START = PRIM_COUNT * VERTICES_COUNT * VERTICES_SIZE * GLBuffers.SIZEOF_FLOAT;

    private static final int[] COUNT = { ELEMENT_COUNT, ELEMENT_COUNT, ELEMENT_COUNT };
    private static final IntBuffer ELEMENT_COUNT_INT_BUFFER = GLBuffers.newDirectIntBuffer(COUNT);

    private static final byte[] OFFSET = { (byte) 0, (byte) 6, (byte) 12};
    private static final PointerBuffer ELEMENT_OFFSET_POINTER_BUFFER = PointerBuffer.allocateDirect(OFFSET.length);
    static {
        ELEMENT_OFFSET_POINTER_BUFFER.put(OFFSET[0]);
        ELEMENT_OFFSET_POINTER_BUFFER.put(OFFSET[1]);
        ELEMENT_OFFSET_POINTER_BUFFER.put(OFFSET[2]);
    }

    private static final int[] VAO = new int[1];
    private static final int[] VBO = new int[1];
    private static final int[] EBO = new int[1];

    @Override
    public void init(GLAutoDrawable glAutoDrawable) {
        super.init(glAutoDrawable);
        final GL4 gl = glAutoDrawable.getGL().getGL4();

        gl.glGenVertexArrays(VAO.length, IntBuffer.wrap(VAO));
        gl.glGenBuffers(VBO.length, IntBuffer.wrap(VBO));
        gl.glGenBuffers(EBO.length, IntBuffer.wrap(EBO));

        gl.glBindVertexArray(VAO[0]);
        gl.glBindBuffer(GL_ARRAY_BUFFER, VBO[0]);
        {
            final FloatBuffer buffer = GLBuffers.newDirectFloatBuffer(VERTEX_DATA);
            gl.glBufferData(GL_ARRAY_BUFFER, VERTEX_DATA.length * GLBuffers.SIZEOF_FLOAT, buffer, GL_STATIC_DRAW);
        }
        gl.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO[0]);
        {
            final ShortBuffer buffer = GLBuffers.newDirectShortBuffer(ELEMENT_DATA);
            gl.glBufferData(GL_ELEMENT_ARRAY_BUFFER, ELEMENT_DATA.length * GLBuffers.SIZEOF_SHORT, buffer, GL_STATIC_DRAW);
        }
        gl.glVertexAttribPointer(0, VERTICES_SIZE, GL_FLOAT, false, 0, 0);
        gl.glEnableVertexAttribArray(0);
        gl.glVertexAttribPointer(1, COLOUR_SIZE,   GL_FLOAT, false, 0, COLOUR_START);
        gl.glEnableVertexAttribArray(1);
    }

    @Override
    public void display(GLAutoDrawable glAutoDrawable) {
        super.display(glAutoDrawable);
        final GL4 gl = glAutoDrawable.getGL().getGL4();

        gl.glUseProgram(PROGRAM[0]);
        {
            gl.glBindVertexArray(VAO[0]);
            gl.glUniformMatrix4fv(LOCATIONS[Location.PROJECTION_MATRIX.getLocation()], 1, false, PROJECTION_MATRIX, 0);
//            gl.glDrawElements(GL_TRIANGLES, ELEMENT_COUNT, GL_UNSIGNED_SHORT, 0); // Draws first square (red)
            gl.glMultiDrawElements(GL_TRIANGLES, ELEMENT_COUNT_INT_BUFFER, GL_UNSIGNED_SHORT, ELEMENT_OFFSET_POINTER_BUFFER, PRIM_COUNT);
        }
        gl.glUseProgram(0);
    }
}


I have searched the internet for a example but have not been able to find one that uses GL3 or above and MultiDrawElements

Thanks in advance

James
Reply | Threaded
Open this post in threaded view
|

Re: MultiDrawElements

elect
Hi James,

this may help you, https://github.com/elect86/jogl-samples/blob/master/jogl-samples/src/tests/gl_320/draw/Gl_320_draw_multiple.java

Anyway, I am coming with a gl4 example if you are interested as well
Reply | Threaded
Open this post in threaded view
|

Re: MultiDrawElements

James
Thanks I've been looking at the example and made a few changes it now draws first red square using MultidrawElements but still not fully working here's my updated code. Yes  I would definitely be interested in GL4 example

package demo;

import com.jogamp.common.nio.PointerBuffer;
import com.jogamp.opengl.GL4;
import com.jogamp.opengl.GLAutoDrawable;
import com.jogamp.opengl.util.GLBuffers;
import demo.common.core.BasicDemo;

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

import static com.jogamp.opengl.GL.*;

/**
 * Created by James on 20/12/2015.
 *
 * Draws 3 squares using method drawElements
 * 3 primitive each made up of 2 triangles using 4 vertices (6 elements)
 * 1 red, 1 green, and 1 blue
 */
public class MultiDrawElements2 extends BasicDemo {

    private static final boolean fps = false;

    public MultiDrawElements2(final boolean fps) {
        super(fps);
    }

    public static void main(final String... args) {
        new MultiDrawElements2(fps);
    }

    // 3 0
    // 2 1
    private static final float[] VERTEX_DATA = {
            250.0f, 250.0f, 0.0f, 1.0f, // 0 right top
            250.0f, 350.0f, 0.0f, 1.0f, // 1 right bottom - reused
            150.0f, 350.0f, 0.0f, 1.0f, // 2 left bottom
            150.0f, 250.0f, 0.0f, 1.0f, // 3 left top - reused

            450.0f, 250.0f, 0.0f, 1.0f,
            450.0f, 350.0f, 0.0f, 1.0f,
            350.0f, 350.0f, 0.0f, 1.0f,
            350.0f, 250.0f, 0.0f, 1.0f,

            650.0f, 250.0f, 0.0f, 1.0f,
            650.0f, 350.0f, 0.0f, 1.0f,
            550.0f, 350.0f, 0.0f, 1.0f,
            550.0f, 250.0f, 0.0f, 1.0f,

            1.0f, 0.0f, 0.0f, 1.0f,
            1.0f, 0.0f, 0.0f, 1.0f,
            1.0f, 0.0f, 0.0f, 1.0f,
            1.0f, 0.0f, 0.0f, 1.0f,

            0.0f, 1.0f, 0.0f, 1.0f,
            0.0f, 1.0f, 0.0f, 1.0f,
            0.0f, 1.0f, 0.0f, 1.0f,
            0.0f, 1.0f, 0.0f, 1.0f,

            0.0f, 0.0f, 1.0f, 1.0f,
            0.0f, 0.0f, 1.0f, 1.0f,
            0.0f, 0.0f, 1.0f, 1.0f,
            0.0f, 0.0f, 1.0f, 1.0f
    };

    private static final int[] ELEMENT_DATA = { // Note that we start from 0!
            0, 1, 3,
            1, 2, 3
    };

    private static final int PRIM_COUNT = 3;
    private static final int VERTICES_COUNT = 4;
    private static final int VERTICES_SIZE = 4;
    private static final int COLOUR_SIZE = 4;
    private static final int ELEMENT_COUNT = 6;
    private static final int COLOUR_START = PRIM_COUNT * VERTICES_COUNT * VERTICES_SIZE * GLBuffers.SIZEOF_FLOAT;

    private static final int[] COUNT = { ELEMENT_COUNT, ELEMENT_COUNT, ELEMENT_COUNT };
    private static final IntBuffer ELEMENT_COUNT_INT_BUFFER = GLBuffers.newDirectIntBuffer(COUNT);

    private static final int[] VAO = new int[1];
    private static final int[] VBO = new int[1];
    private static final int[] EBO = new int[1];

    @Override
    public void init(GLAutoDrawable glAutoDrawable) {
        super.init(glAutoDrawable);
        final GL4 gl = glAutoDrawable.getGL().getGL4();

        gl.glGenVertexArrays(VAO.length, IntBuffer.wrap(VAO));
        gl.glGenBuffers(VBO.length, IntBuffer.wrap(VBO));
        gl.glGenBuffers(EBO.length, IntBuffer.wrap(EBO));

        gl.glBindVertexArray(VAO[0]);
        gl.glBindBuffer(GL_ARRAY_BUFFER, VBO[0]);
        {
            final FloatBuffer buffer = GLBuffers.newDirectFloatBuffer(VERTEX_DATA);
            gl.glBufferData(GL_ARRAY_BUFFER, VERTEX_DATA.length * GLBuffers.SIZEOF_FLOAT, buffer, GL_STATIC_DRAW);
        }
        gl.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO[0]);
        {
            final IntBuffer buffer = GLBuffers.newDirectIntBuffer(ELEMENT_DATA);
            gl.glBufferData(GL_ELEMENT_ARRAY_BUFFER, ELEMENT_DATA.length * GLBuffers.SIZEOF_INT, buffer, GL_STATIC_DRAW);
        }
        gl.glVertexAttribPointer(0, VERTICES_SIZE, GL_FLOAT, false, 0, 0);
        gl.glEnableVertexAttribArray(0);
        gl.glVertexAttribPointer(1, COLOUR_SIZE,   GL_FLOAT, false, 0, COLOUR_START);
        gl.glEnableVertexAttribArray(1);
    }

    @Override
    public void display(GLAutoDrawable glAutoDrawable) {
        super.display(glAutoDrawable);
        final GL4 gl = glAutoDrawable.getGL().getGL4();

        gl.glUseProgram(PROGRAM[0]);
        {
            gl.glBindVertexArray(VAO[0]);

            final PointerBuffer pointerBuffer = PointerBuffer.allocateDirect(3);
            pointerBuffer.put(0);
            pointerBuffer.put(0);
            pointerBuffer.put(0);
            pointerBuffer.rewind();

            gl.glUniformMatrix4fv(LOCATIONS[Location.PROJECTION_MATRIX.getLocation()], 1, false, PROJECTION_MATRIX, 0);
            gl.glMultiDrawElements(GL_TRIANGLES, ELEMENT_COUNT_INT_BUFFER, GL_UNSIGNED_INT, pointerBuffer, PRIM_COUNT);
        }
        gl.glUseProgram(0);
    }
}
Reply | Threaded
Open this post in threaded view
|

Re: MultiDrawElements

elect
This post was updated on .
I don't see anything wrong there..

Anyway, just for curiosity, try

1)

private static final int[] ELEMENT_DATA = { // Note that we start from 0!
            0, 1, 3,
            1, 2, 3,
            0, 1, 3,
            1, 2, 3,
            0, 1, 3,
            1, 2, 3

    };

and pointbuffer = 0, 6*4, (6+6)*4

2) private static final int[] ELEMENT_DATA = { // Note that we start from 0!
            0, 1, 3,
            1, 2, 3

    };

and pointbuffer = 0

3) modify the first 4 colors

            1.0f, 0.0f, 0.0f, 1.0f,
            1.0f, 0.0f, 0.0f, 1.0f,
            1.0f, 0.0f, 0.0f, 1.0f,
            1.0f, 0.0f, 0.0f, 1.0f,

to

            1.0f, 0.0f, 0.0f, 1.0f,
            0.0f, 1.0f, 0.0f, 1.0f,
            0.0f, 0.0f, 1.0f, 1.0f,
            0.5f, 0.5f, 0.5f, 1.0f,

What you see?


Ps: do you catch any gl error?

Pps: is your whole code visible anywhere?
Reply | Threaded
Open this post in threaded view
|

Re: MultiDrawElements

James
Just first red square still
Reply | Threaded
Open this post in threaded view
|

Re: MultiDrawElements

elect
Try the other two, I modified it
Reply | Threaded
Open this post in threaded view
|

Re: MultiDrawElements

James
In reply to this post by elect
Tried that still draws just first square. I'm using intellij and there is no errors in run window and it starts up and shuts down fine. My codes not visible anywhere. I could post full app 5 classes and 2 shaders if you want.
Reply | Threaded
Open this post in threaded view
|

Re: MultiDrawElements

James
just trying 2 and 3
Reply | Threaded
Open this post in threaded view
|

Re: MultiDrawElements

James
2. didn't work 3. i square blue bottom left cornner, red top right corner and green diagnol
Reply | Threaded
Open this post in threaded view
|

Re: MultiDrawElements

elect
Try

glMultiDrawElementsBaseVertex(
    GL_TRIANGLES,
    ELEMENT_COUNT_INT_BUFFER,
    GL_UNSIGNED_INT,
    pointerBuffer,
    PRIM_COUNT,
    GLBuffers.newDirectIntBuffer(new int[]{0, 4,8})
);
Reply | Threaded
Open this post in threaded view
|

Re: MultiDrawElements

James
Thanks a lot that works what would array be if data was packed has following

            250.0f, 250.0f, 0.0f, 1.0f, // 0 right top
            250.0f, 350.0f, 0.0f, 1.0f, // 1 right bottom - reused
            150.0f, 350.0f, 0.0f, 1.0f, // 2 left bottom
            150.0f, 250.0f, 0.0f, 1.0f, // 3 left top - reused

            1.0f, 0.0f, 0.0f, 1.0f,
            1.0f, 0.0f, 0.0f, 1.0f,
            1.0f, 0.0f, 0.0f, 1.0f,
            1.0f, 0.0f, 0.0f, 1.0f,

            450.0f, 250.0f, 0.0f, 1.0f,
            450.0f, 350.0f, 0.0f, 1.0f,
            350.0f, 350.0f, 0.0f, 1.0f,
            350.0f, 250.0f, 0.0f, 1.0f,

            0.0f, 1.0f, 0.0f, 1.0f,
            0.0f, 1.0f, 0.0f, 1.0f,
            0.0f, 1.0f, 0.0f, 1.0f,
            0.0f, 1.0f, 0.0f, 1.0f,

            650.0f, 250.0f, 0.0f, 1.0f,
            650.0f, 350.0f, 0.0f, 1.0f,
            550.0f, 350.0f, 0.0f, 1.0f,
            550.0f, 250.0f, 0.0f, 1.0f,

            0.0f, 0.0f, 1.0f, 1.0f,
            0.0f, 0.0f, 1.0f, 1.0f,
            0.0f, 0.0f, 1.0f, 1.0f,
            0.0f, 0.0f, 1.0f, 1.0f

tried 0, 8 , 16 but draws green, blue then black from left to right instead of red green blue from left to right (red square drawn last instead of first and is black)
Reply | Threaded
Open this post in threaded view
|

Re: MultiDrawElements

elect
James wrote
Thanks a lot that works
You'r welcome, I should have seen since the begin. Opengl needed an array of offset to start the n-th element drawing from, and that was the base vertex..

James wrote
what would array be if data was packed has following

            250.0f, 250.0f, 0.0f, 1.0f, // 0 right top
            250.0f, 350.0f, 0.0f, 1.0f, // 1 right bottom - reused
            150.0f, 350.0f, 0.0f, 1.0f, // 2 left bottom
            150.0f, 250.0f, 0.0f, 1.0f, // 3 left top - reused

            1.0f, 0.0f, 0.0f, 1.0f,
            1.0f, 0.0f, 0.0f, 1.0f,
            1.0f, 0.0f, 0.0f, 1.0f,
            1.0f, 0.0f, 0.0f, 1.0f,

            450.0f, 250.0f, 0.0f, 1.0f,
            450.0f, 350.0f, 0.0f, 1.0f,
            350.0f, 350.0f, 0.0f, 1.0f,
            350.0f, 250.0f, 0.0f, 1.0f,

            0.0f, 1.0f, 0.0f, 1.0f,
            0.0f, 1.0f, 0.0f, 1.0f,
            0.0f, 1.0f, 0.0f, 1.0f,
            0.0f, 1.0f, 0.0f, 1.0f,

            650.0f, 250.0f, 0.0f, 1.0f,
            650.0f, 350.0f, 0.0f, 1.0f,
            550.0f, 350.0f, 0.0f, 1.0f,
            550.0f, 250.0f, 0.0f, 1.0f,

            0.0f, 0.0f, 1.0f, 1.0f,
            0.0f, 0.0f, 1.0f, 1.0f,
            0.0f, 0.0f, 1.0f, 1.0f,
            0.0f, 0.0f, 1.0f, 1.0f

tried 0, 8 , 16 but draws green, blue then black from left to right instead of red green blue from left to right (red square drawn last instead of first and is black)
If [0,8,16] doesnt work then I guess you can't do like that with glMultiDrawElementsBaseVertex, either interleaved (the best since it exploits data locality)

position0, color0,
position1, color1,
position2, color2

or one after each other

position0,
position1,
position2,
color0,
color1,
color2

or separate

position0,
position1,
position2

color0,
color1,
color2

or (I think) glMultiDrawElementsIndirect
Reply | Threaded
Open this post in threaded view
|

Re: MultiDrawElements

elect
Or try [0,4,8] with COLOR_START = 4*4*Float.BYTES
Reply | Threaded
Open this post in threaded view
|

Re: MultiDrawElements

James
In reply to this post by James
Sorted index 0 8 and 16 worked needed to change the following
    private static final int COLOUR_START = PRIM_COUNT * VERTICES_COUNT * VERTICES_SIZE * GLBuffers.SIZEOF_FLOAT;

to
    private static final int COLOUR_START = VERTICES_COUNT * VERTICES_SIZE * GLBuffers.SIZEOF_FLOAT;

Thanks
Reply | Threaded
Open this post in threaded view
|

Re: MultiDrawElements

elect
In reply to this post by James
James wrote
Yes  I would definitely be interested in GL4 example
I almost forgot

https://github.com/elect86/jogl-samples/blob/master/jogl-samples/src/tests/gl_430/Gl_430_multi_draw_indirect.java
Reply | Threaded
Open this post in threaded view
|

Re: MultiDrawElements

Martin
Hi,

5 years later, I found this discussion instructive to understand glMultiDrawElements but I still thrive to make it work. Using JOGL 2.3.2, Mac 10.12.6, I get a JVM crash. I think I did not understand properly how to build the PointerBuffer.

Here is what I want to do

I have a collection of vertices/normals/colors in their dedicated buffers.

I want to draw quads (based on GL_TRIANGLE_FAN) that share vertex between each other. I want to do like this because input data is made of shared vertices described in an input file and I want to avoid repeating them manually.



Here is how I try to do it

I first register vertices, normals and colors with FloatBuffers. I think I do this properly since I can use glMultiDrawArrays properly with other case where vertices are repeated (hence I do not need an index since vertices of the same triangle fan will be contiguous, and all triangle fans have their start index and length defined).

Then I invoke glMultiDrawElements as follow :

gl2.glMultiDrawElements(glGeometryType, elementsCountBuffer, GL.GL_UNSIGNED_INT, elementsIndicesBuffer, elementsIndicesBuffer.capacity());

where elementsCount is filled with a 1D array as follow :

IntBuffer elementCountBuffer = Buffers.newDirectIntBuffer(elementsCount); // int[] elementsCount
elementCountBuffer.rewind();


and elementsIndices is filled with a 2D array as follow :

PointerBuffer elementIndicesBuffer = PointerBuffer.allocateDirect(size(elementsIndices)); // int[][] elementsIndices, where size(array) returns #row x #columns

for (int i = 0; i < elementsIndices.length; i++) {
  // Each i is the ID of a GL_TRIANGLE_FAN

  for (int j = 0; j < elementsIndices[i].length; j++) {
    // Each j is the index of a vertex to use in the vertex/normal/color buffers to draw the ith triangle fan

    elementIndicesBuffer.put(elementsIndices[i][j]);
  }
}
elementIndicesBuffer.rewind();


I am almost sure I do this wrong because the man page of the function states that the last argument - drawcount - should describe the length of the two buffer, hence that they should be equals.

As the purpose of this function is to draw multiple elements based on vertices that may be shared among these elements, I wonder how elementIndicesBuffer could be anything else than a 2D array? Otherwise, if it is a 1D array, how can I register in it the list of indices for the first triangle fan, then second triangle fan, etc?

Thanks for your help!
Reply | Threaded
Open this post in threaded view
|

Re: MultiDrawElements

Martin
Resolved! There is a method in PointerBuffer that was not used by James and Elect which simplify the 2D index. Here is an example assuming an input int[][] elementsIndice, where each line is a list of indices for 1 element (e.g. a triangle fan). Each line can have a different number of vertex indices.

PointerBuffer elementIndicesBuffer = PointerBuffer.allocateDirect(elementsIndices.length);
IntBuffer elementCountBuffer = Buffers.newDirectIntBuffer(elementsCount);

for (int i = 0; i < elementsIndices.length; i++) {
  IntBuffer elementDataBufferI =  Buffers.newDirectIntBuffer(elementsIndices[i]);
  elementDataBufferI.rewind();
 
  elementIndicesBuffer.referenceBuffer(elementDataBufferI);
  elementCountBuffer.put(elementsIndices[i].length);
}

elementCountBuffer.rewind();
elementIndicesBuffer.rewind();



Surprisingly, there is no need to bind any element buffer. Vertex, color and normal buffer must be bind. Then one simply invoke

glMultiDrawElements(GL.GL_TRIANGLE_FAN, elementCountBuffer, GL.GL_UNSIGNED_INT, elementsIndicesBuffer, elementCountBuffer.capacity());