如何在OpenGL ES 2中创建和使用VBO

我正在寻求帮助理解维生素生态系统。 我做了大量的研究,并找到了关于这个主题的教程,但它们对我来说仍然含糊不清。 我有几个问题:

应该在哪里创建VBO,我应该如何创建VBO?

我目前正在使用下面的代码来初始化我的顶点和索引缓冲区:

vertices = new float[] { p[0].x, p[0].y, 0.0f, p[1].x, p[1].y, 0.0f, p[2].x, p[2].y, 0.0f, p[3].x, p[3].y, 0.0f, }; // The order of vertex rendering for a quad indices = new short[] {0, 1, 2, 0, 2, 3}; ByteBuffer bb = ByteBuffer.allocateDirect(vertices.length * 4); bb.order(ByteOrder.nativeOrder()); vertexBuffer = bb.asFloatBuffer(); vertexBuffer.put(vertices); vertexBuffer.position(0); ByteBuffer dlb = ByteBuffer.allocateDirect(indices.length * 2); dlb.order(ByteOrder.nativeOrder()); drawListBuffer = dlb.asShortBuffer(); drawListBuffer.put(indices); drawListBuffer.position(0); 

如果我是正确的,这不是创建一个VBO。 那么,如果我想制作一个VBO,创建VBO的代码是否会在上面列出的代码之后? 如果是这样,它将如何创建?

另外,如何渲染VBO并将其绘制到屏幕上?

它是否仅使用顶点和索引数组进行渲染和绘制? 如果没有,过程是什么? 目前,我渲染并绘制我的对象,如下面的代码所示:

  GLES20.glUseProgram(GraphicTools.sp_SolidColor); mPositionHandle = GLES20.glGetAttribLocation(GraphicTools.sp_SolidColor, "vPosition"); GLES20.glEnableVertexAttribArray(mPositionHandle); GLES20.glVertexAttribPointer(mPositionHandle, 3, GLES20.GL_FLOAT, false, 0, vertexBuffer); mtrxHandle = GLES20.glGetUniformLocation(GraphicTools.sp_SolidColor, "uMVPMatrix"); GLES20.glUniformMatrix4fv(mtrxHandle, 1, false, m, 0); GLES20.glDrawElements(GLES20.GL_TRIANGLES, indices.length, GLES20.GL_UNSIGNED_SHORT, drawListBuffer); GLES20.glDisableVertexAttribArray(mPositionHandle); 

如果您有任何疑问,请告诉我。 提前致谢。

顶点缓冲区对象是可以存储顶点数组数据的缓冲区。 数据上传一次到图形内存(GPU),可以重复使用来绘制网格。

首先,您必须创建2个缓冲区对象,一个用于顶点,另一个用于索引:

 int buffers[] = new int[2]; GLES20.glGenBuffers(2, buffers, 0); int vbo = buffers[0]; int ibo = buffers[1]; 

然后,您必须绑定缓冲区并传输数据

 GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vbo); GLES20.glBufferData( GLES20.GL_ARRAY_BUFFER, vertexBuffer.capacity() * 4, // 4 = bytes per float vertexBuffer, GLES20.GL_STATIC_DRAW); GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0); GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, ibo); GLES20.glBufferData( GLES20.GL_ELEMENT_ARRAY_BUFFER, drawListBuffer.capacity() * 2, // 2 = bytes per short drawListBuffer, GLES20.GL_STATIC_DRAW); GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0); 

如果要绘制网格,则必须定义通用顶点属性数据的数组,并且必须绑定索引缓冲区,但不必将任何数据传输到GPU:

 GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vbo); GLES20.glVertexAttribPointer( mPositionHandle, 3, GLES20.GL_FLOAT, false, 0, 0); // <----- 0, because "vbo" is bound GLES20.glEnableVertexAttribArray(mPositionHandle); GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, ibo); GLES20.glDrawElements( GLES20.GL_TRIANGLES, indices.length, GLES20.GL_UNSIGNED_SHORT, 0); // <----- 0, because "ibo" is bound GLES20.glDisableVertexAttribArray(mPositionHandle); GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0); GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0); 

另请参见顶点缓冲区对象(VBO)简介