Posted by
James on
Jan 14, 2016; 11:49am
URL: https://forum.jogamp.org/MultiDrawElements-tp4036014.html
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