0

我有一个绘制 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);
            ....
}

现在我想将上面的绘图更改为“顶点数组”模式并获得相同的结果,所以我做了以下操作:

  1. 创建了一个float包含所有顶点坐标的数组GL.GL_QUADS
  2. put这个数组到一个Buffer.
  3. 告诉 OpenGL 顶点在哪里(8 个顶点)。
  4. 告诉 OpenGL 要绘制哪些索引。

这是我编写的主要代码(已编辑)-

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数组更改为范围 [0,5] - 根据GL.GL_QUADS. 并将tmpColorVerticesBuf数组扩展到 72 个索引(每种颜色的 4 倍)。

我仍然有与上面提到的相同的例外。

编辑2:(现在效果很好)通过比较 大小(每个数组72)和使用中cubeVertices(大小为3的24个元素)来解决colorVerticesdisplay()gl.glDrawArrays(GL.GL_QUADS, 0, 24)

4

1 回答 1

1

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

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

于 2013-08-11T07:23:26.437 回答