javaopengljoglvertex-array

Drawing 3D polygon using vertex array


I have a short program which draw a 3D GL.GL_QUADS , here its display() method -

public void display(GLAutoDrawable drawable) {
        ....
        gl.glBegin(GL.GL_QUADS); // of the color cube

        // Top-face
        gl.glColor3f(0.0f, 1.0f, 0.0f); // green
        gl.glVertex3f(1.0f, 1.0f, -1.0f);
        gl.glVertex3f(-1.0f, 1.0f, -1.0f);
        gl.glVertex3f(-1.0f, 1.0f, 1.0f);
        gl.glVertex3f(1.0f, 1.0f, 1.0f);

        // Bottom-face
        gl.glColor3f(1.0f, 0.5f, 0.0f); // orange
        gl.glVertex3f(1.0f, -1.0f, 1.0f);
        gl.glVertex3f(-1.0f, -1.0f, 1.0f);
        gl.glVertex3f(-1.0f, -1.0f, -1.0f);
        gl.glVertex3f(1.0f, -1.0f, -1.0f);

        // Front-face
        gl.glColor3f(1.0f, 0.0f, 0.0f); // red
        gl.glVertex3f(1.0f, 1.0f, 1.0f);
        gl.glVertex3f(-1.0f, 1.0f, 1.0f);
        gl.glVertex3f(-1.0f, -1.0f, 1.0f);
        gl.glVertex3f(1.0f, -1.0f, 1.0f);

        // Back-face
        gl.glColor3f(1.0f, 1.0f, 0.0f); // yellow
        gl.glVertex3f(1.0f, -1.0f, -1.0f);
        gl.glVertex3f(-1.0f, -1.0f, -1.0f);
        gl.glVertex3f(-1.0f, 1.0f, -1.0f);
        gl.glVertex3f(1.0f, 1.0f, -1.0f);

        // Left-face
        gl.glColor3f(0.0f, 0.0f, 1.0f); // blue
        gl.glVertex3f(-1.0f, 1.0f, 1.0f);
        gl.glVertex3f(-1.0f, 1.0f, -1.0f);
        gl.glVertex3f(-1.0f, -1.0f, -1.0f);
        gl.glVertex3f(-1.0f, -1.0f, 1.0f);

        // Right-face
        gl.glColor3f(1.0f, 0.0f, 1.0f); // violet
        gl.glVertex3f(1.0f, 1.0f, -1.0f);
        gl.glVertex3f(1.0f, 1.0f, 1.0f);
        gl.glVertex3f(1.0f, -1.0f, 1.0f);
        gl.glVertex3f(1.0f, -1.0f, -1.0f);
            ....
}

Now I want to change the above drawing to "Vertex Arrays" mode and to get same results , so I did the following :

  1. Created a float array of all the vertices coodinates of the GL.GL_QUADS .
  2. put this array to a Buffer .
  3. Tell OpenGL where the vertices are (8 vertices) .
  4. Tell OpenGL which indices to draw .

Here is the main code I wrote (edited) -

public class DisplayWithArray extends GLCanvas implements GLEventListener,
        KeyListener {

    private float[] cubeVertices = { 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f,
            1.0f, 1.0f, 1.0f, 1.0f, 1.0f,

            1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, 1.0f,
            -1.0f, -1.0f,

            1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f,
            -1.0f, 1.0f,

            1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f,
            1.0f, -1.0f,

            -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f,
            -1.0f, 1.0f,

            1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f,
            -1.0f, -1.0f };

    private float[] colorVertices ={ 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
        1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.5f, 0.0f, 1.0f, 0.5f, 0.0f,
        1.0f, 0.5f, 0.0f, 1.0f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
        0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f,
        1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
        0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f,
        1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f };

    // 1st edit  - 24 positions of the GL.GL_QUADS
    private int[] indices = new int[24] ;

    private IntBuffer indicesBuf ;  
}
public DisplayWithArray(GLCapabilities capabilities, int width, int height) {
        for (int i=0 ; i<24 ; i++) {
            this.indices[i] = i ; 
    }
public void init(GLAutoDrawable drawable) {
            ...
        final GL gl = drawable.getGL();
            ...
        setupPointer(gl);
}

public void display(GLAutoDrawable drawable) {

        final GL gl = drawable.getGL();
        // draw
        gl.glDrawArrays(GL.GL_QUADS, 0, 24);
}

public void setupPointer(GL gl) {

        FloatBuffer tmpVerticesBuf = BufferUtil
                .newFloatBuffer(cubeVertices.length);
        ;
        FloatBuffer tmpColorVerticesBuf = BufferUtil
                .newFloatBuffer(colorVertices.length);

        for (int i = 0; i < cubeVertices.length; i++) {
            tmpVerticesBuf.put(cubeVertices[i]);
        }
        for (int i = 0; i < colorVertices.length; i++) {
        tmpColorVerticesBuf.put(colorVertices[i]);
    }
        tmpVerticesBuf.rewind();
        tmpColorVerticesBuf.rewind();
        gl.glEnableClientState(GL.GL_VERTEX_ARRAY);
        gl.glVertexPointer(3, GL.GL_FLOAT, 0, tmpVerticesBuf);
        gl.glColorPointer(3, GL.GL_FLOAT, 0, tmpColorVerticesBuf);
        // Indices of polygon
        IntBuffer tmpIndicesBuf = BufferUtil.newIntBuffer(this.indices.length);
        for (int i = 0; i < indices.length; i++) {
            tmpIndicesBuf.put(indices[i]);
        }
        tmpIndicesBuf.rewind();

        indicesBuf = tmpIndicesBuf ; 
}

When I run it I get an exception Exception in thread "AWT-EventQueue-0" javax.media.opengl.GLException: glGetError() returned the following error codes after a call to glDrawElements(): GL_INVALID_ENUM at DisplayWithArray.display(DisplayWithArray.java:152)

point to the line - gl.glDrawElements(GL.GL_QUADS, indices.length, GL.GL_INT, indicesBuf);

What is wrong here ?

Edit:

I changed the indices array to range [0,5] - according to 6 face of the GL.GL_QUADS. And extend tmpColorVerticesBuf array to 72 indices (4 times each color) .

Still I have same exception as mentioned above .

Edit 2: (now it works well) Solve by comparing between cubeVertices and colorVertices sizes (72 each array) , and in display() use gl.glDrawArrays(GL.GL_QUADS, 0, 24) (24 elements of size 3)


Solution

  • What's wrong is that your arrays are not the same size. Your vertex position array has 24 vec3's in it, while your color array only has six. So when your index array says "6", it's going to try to access the 7'th entry in an array with 6 elements. Hence the crash.

    Every array uses the same index. Therefore, if you want to have colors and positions, then each color must have a single corresponding position. And vice-versa. You can't have 6 colors working with 32 positions. Nor can each attribute use different indices. If you're doing indexed rendering, they all must use the same index.