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);  
        } 
        

}

 

顯示繪制了一個三角形




 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM