转载

OpenGL ES 3.0 顶点缓冲区VBO使用

一般情况下数据都是有CPU从RAM取数据 然后传给GPU去处理,相对于GPU速度要慢一些。

使用VBO技术 可以把数据存储到GPU的内存空间中,这样GPU可以直接从GPU的内存中取得数据进行处理 速度会提升很多。

使用VBO,主要有3个函数

glGenBuffers() 申请缓冲对象

glBindBuffer() 绑定缓冲对象

glBufferData() 需要缓冲的数据 存储起来

下面演示用法

private int vboId[] = new int[1];          //顶点缓冲数据     void initVBO () {         GLES30.glGenBuffers(1, vboId, 0);//申请一个缓冲区         GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, vboId[0]);//绑定缓冲区         GLES30.glBufferData(GLES30.GL_ARRAY_BUFFER, vertexBuffer.capacity() * 4, vertexBuffer, GLES30.GL_STATIC_DRAW);//把数据存储到GPU中                GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, 0);//现在不使用这个缓冲区     }
vertexBuffer 数据被存储到缓冲区中。

绘制的时候我们使用缓冲区的数据
void drawVBO () {  GLES30.glUseProgram(programId);    Matrix.setRotateM(GLRenderer.matrixs, 0, 0, 1, 0, 0);    Matrix.translateM(GLRenderer.matrixs, 0, 0, 0, 1);    GLRenderer.mViewPjMatrix = new float[16];    Matrix.multiplyMM(GLRenderer.mViewPjMatrix, 0, GLRenderer.viewMatrix,0, GLRenderer.matrixs, 0);    Matrix.multiplyMM(GLRenderer.mViewPjMatrix, 0, GLRenderer.projMatrix,0, GLRenderer.mViewPjMatrix, 0);    GLES30.glUniformMatrix4fv(mVPMatrixHandle, 1, false, GLRenderer.mViewPjMatrix, 0);    //begin  GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, vboId[0]);//绑定存在的VBO  GLES30.glEnableVertexAttribArray(0);//开启顶点  GLES30.glVertexAttribPointer(0, 3, GLES30.GL_FLOAT, false, 0, 0);//顶点XYZ,三个点,使用GPU中的缓冲数据,不再从RAM中取数据,所以后面的2个参数都是0  GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, 0);//数据已经得到 就可以不再使用这个绑定了  GLES30.glDrawArrays(GLES30.GL_TRIANGLES, 0, 6);//从顶点缓存中绘制数据 } 

对于大量的顶点,比如绘制一个3D汽车, 使用缓冲数据方式 能提高速度。

下面补充缺失的代码。

final static float vertices1[] = new float[] {    -1,1,0,  -0.5f,0,0,  0,-1,0,  -1,0,0,  0.5f,0,0,  1,-1,0 };    ByteBuffer vb = ByteBuffer.allocateDirect(vertices1.length * 4);    vb.order(ByteOrder.nativeOrder());    vertexBuffer = vb.asFloatBuffer();    vertexBuffer.put(vertices1);    vertexBuffer.position(0); 

Note: initVBO方法需要在onSurfaceCreate中初始化

脚本如下

public static final String fragment5 =   "#version 300 es /n" +      "precision mediump float;/n"        + "in vec2 vTextureCoord;/n"        + "out vec4 v_color;/n"      + "void main() { /n"        + "v_color = vec4(1.0,1.0,1.0,0.0); /n"        + "}/n"        ;   public static final String vertex3 =  "#version 300 es /n" +  "uniform mat4 uMVPMatrix;/n"    + "layout(location = 0) in vec3 aPosition;/n"    + "layout(location = 1) in vec2 aTexCoor;/n"    + "out vec2 vTextureCoord;/n"     + "void main() { /n"    + "gl_Position  = uMVPMatrix * vec4(aPosition,1);/n"   + "gl_PointSize = 20.0;/n"  + "vTextureCoord = aTexCoor;/n"     + "}/n"          ; 
package com.example.gles300; import java.io.IOException; import java.io.InputStream; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.opengl.GLES30; import android.opengl.GLSurfaceView.Renderer; import android.opengl.GLUtils; import android.opengl.Matrix; import android.util.Log; /**  * @author gaofeng  *  */ public class GLRenderer implements Renderer {  public static float[] projMatrix = new float[16];  public static float[] viewMatrix = new float[16];  public static float[] mViewPjMatrix;  public static float[] matrixs = new float[16];    public static int textureId = -1;    public Context context;    public MyDrawModel drawModel;    public void setContext(Context context) {   this.context = context;  }  public GLRenderer() {  }    @Override     public void onDrawFrame(GL10 arg0) {      GLES30.glClear( GLES30.GL_DEPTH_BUFFER_BIT | GLES30.GL_COLOR_BUFFER_BIT);      drawModel.drawVBO();   }     @Override     public void onSurfaceChanged(GL10 arg0, int w, int h) {      GLES30.glViewport(0, 0, w, h);      float ratio = (float) w / h;      Matrix.frustumM(projMatrix, 0, -ratio, ratio, -1, 1, 1, 10);    Matrix.setLookAtM(viewMatrix, 0, 0, 0, 3, 0, 0, 0, 0.0f, 1.0f, 0.0f);   }     @Override     public void onSurfaceCreated(GL10 g, EGLConfig eglConfig) {      GLES30.glClearColor(0.0f,0.0f,0.0f, 0.0f);     GLES30.glEnable(GLES30.GL_DEPTH_TEST);      InputStream ins = null;      drawModel = new MyDrawModel();      drawModel.init();      GLES30.glDisable(GLES30.GL_CULL_FACE);     }  } 

显示绘制了一个三角形

OpenGL ES 3.0 顶点缓冲区VBO使用

正文到此结束
Loading...