使用顶点数组绘制3D多边形

时间:2013-08-11 05:50:33

标签: java opengl jogl vertex-array

我有一个简短的程序,用于绘制3D GL.GL_QUADS,此处为display()方法 -

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);
            ....
}

现在我想将上面的绘图更改为“Vertex Arrays”模式并获得相同的结果,所以我做了以下内容:

  1. 创建了float的所有顶点坐标的GL.GL_QUADS数组。
  2. put此数组为Buffer
  3. 告诉OpenGL顶点在哪里(8个顶点)。
  4. 告诉OpenGL要绘制哪些索引。
  5. 以下是我编写的主要代码(已编辑) -

    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 ; 
    }
    

    当我运行它时,我得到一个异常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)

    指向该行 - gl.glDrawElements(GL.GL_QUADS, indices.length, GL.GL_INT, indicesBuf);

    这里有什么问题?

    修改

    根据indices的6面,我将GL.GL_QUADS数组更改为范围[0,5]。 并将tmpColorVerticesBuf数组扩展为72个索引(每种颜色4次)。

    我仍然有如上所述的相同例外。

    编辑2:(现在效果很好) 通过比较cubeVerticescolorVertices尺寸(每个阵列72个)和display()使用gl.glDrawArrays(GL.GL_QUADS, 0, 24)(24个3个元素)来解决

1 个答案:

答案 0 :(得分:1)

错误的是您的阵列大小不同。你的顶点位置数组中有24个vec3,而你的颜色数组只有 6个。因此,当您的索引数组显示“6”时,它将尝试访问包含6个元素的数组中的第7个条目。因此崩溃。

每个数组都使用相同的索引。因此,如果您想要颜色和位置,那么每种颜色必须具有单个对应的位置。反之亦然。你有6种颜色可以使用32个位置。每个属性也不能使用不同的索引。如果您正在进行索引渲染,那么所有必须使用相同的索引。