【问题标题】:Drawing 3D polygon using vertex array使用顶点数组绘制 3D 多边形
【发布时间】:2013-08-11 05:50:32
【问题描述】:

我有一个绘制 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. 创建了一个包含GL.GL_QUADS 的所有顶点坐标的float 数组。
  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 的 6 个面。 并将tmpColorVerticesBuf 数组扩展为 72 个索引(每种颜色的 4 倍)。

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

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

【问题讨论】:

    标签: java opengl jogl vertex-array


    【解决方案1】:

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

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

    【讨论】:

    • 我重新排列了数组(现在大小相同),正如我在编辑后的帖子中提到的那样,我希望你能看看。
    猜你喜欢
    • 2023-03-14
    • 1970-01-01
    • 1970-01-01
    • 2019-03-14
    • 2016-02-10
    • 2017-12-07
    • 1970-01-01
    • 2023-01-13
    • 1970-01-01
    相关资源
    最近更新 更多