我有一个绘制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);
....
}
现在我想将上面的绘图更改为"顶点数组"模式并获得相同的结果,所以我做了以下操作:
- 创建了一个包含
GL.GL_QUADS
的所有顶点的float
数组。 - 将此数组
put
为Buffer
。 - 告诉OpenGL顶点在哪里(8个顶点(。
- 告诉 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:(现在效果很好(通过比较cubeVertices
和colorVertices
大小(每个数组 72 个(来解决,并在display()
使用gl.glDrawArrays(GL.GL_QUADS, 0, 24)
(大小为 3 的 24 个元素(
问题是你的数组大小不一样。您的顶点位置数组中有 24 个 vec3,而您的颜色数组只有 6 个。因此,当您的索引数组显示"6"时,它将尝试访问包含 6 个元素的数组中的第 7 个条目。因此崩溃。
每个数组都使用相同的索引。因此,如果要有颜色和位置,那么每种颜色必须有一个对应的位置。反之亦然。你不能让 6 种颜色与 32 个位置一起工作。每个属性也不能使用不同的索引。如果要执行索引渲染,则它们都必须使用相同的索引。