本文共 6529 字,大约阅读时间需要 21 分钟。
VBO: Vertex Buffer object 顶点缓冲对象
为什么要用VBO?
不使用VBO时,每次绘制( glDrawArrays )图形时都是从本地内存处获取顶点数据然后传输给OpenGL来绘制,这样就会频繁的操作CPU->GPU增大开销,从而降低效率。使用VBO,可以把顶点数据缓存到GPU开辟的一段内存中,然后使用时不必再从本地获取,而是直接从显存中获取,这样就能提升绘制的效率。
创建VBO
1、创建VBO
GLES20.glGenBuffers(1, vbos, 0);2、绑定VBO
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vbos[0]);3、分配VBO需要的缓存大小
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, vertex.length * 4,null, GLES20. GL_STATIC_DRAW);4、为VBO设置顶点数据的值
GLES20.glBufferSubData(GLES20.GL_ARRAY_BUFFER, 0, vertexData.length * 4, vertexBuffer);5、解绑VBO
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);使用VBO
1、绑定VBO
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vbos[0]);2、设置顶点数据
GLES20.glVertexAttribPointer(vPosition, 2, GLES20.GL_FLOAT, false, 8, 0);3、解绑VBO
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);GGLTextureRender VBO的使用
package com.example.opengldemo;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.opengl.GLES20;import android.opengl.GLUtils;import java.nio.ByteBuffer;import java.nio.ByteOrder;import java.nio.FloatBuffer;public class GGLTextureRender implements MyGLSurfaceView.MyGLRender { private Context context; //顶点坐标 private final float[] vertexData = { -1f, -1f, 1f, -1f, -1f, 1f, 1f, 1f }; //纹理坐标 private final float[] fragmentData = { 0f, 1f, 1f, 1f, 0f, 0f, 1f, 0f }; private FloatBuffer vertexBuffer; private FloatBuffer fragmentBuffer; public GGLTextureRender(Context context) { this.context = context; vertexBuffer = ByteBuffer.allocateDirect(vertexData.length * 4) .order(ByteOrder.nativeOrder()) .asFloatBuffer() .put(vertexData); vertexBuffer.position(0); fragmentBuffer = ByteBuffer.allocateDirect(fragmentData.length * 4) .order(ByteOrder.nativeOrder()) .asFloatBuffer() .put(fragmentData); fragmentBuffer.position(0); } private int program; private int vPosition; private int fPosition; private int textureid; private int sampler; private int vboId; @Override public void onSufaceCreated() { String vertexSource = GShaderUtil.getRawResource(context, R.raw.vertex_shader); String fragmentSource = GShaderUtil.getRawResource(context, R.raw.fragment_shader); program = GShaderUtil.createProgram(vertexSource, fragmentSource); if (program > 0) { //顶点坐标 vPosition = GLES20.glGetAttribLocation(program, "v_Position"); //纹理坐标 fPosition = GLES20.glGetAttribLocation(program, "f_Position"); sampler = GLES20.glGetUniformLocation(program,"sTexture"); /**********************创建VBO-START************************************************/ int [] vbos = new int[1]; GLES20.glGenBuffers(1, vbos, 0); vboId = vbos[0]; //绑定 GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vboId); //分配内存 GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, vertexData.length*4 + fragmentData.length*4, null,GLES20. GL_STATIC_DRAW); //缓存到显存 GLES20.glBufferSubData(GLES20.GL_ARRAY_BUFFER, 0, vertexData.length * 4, vertexBuffer); GLES20.glBufferSubData(GLES20.GL_ARRAY_BUFFER, vertexData.length * 4, fragmentData.length*4, fragmentBuffer); //解绑 GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0); /******************************VBO-END***********************************************/ int[] textureIds = new int[1]; GLES20.glGenTextures(1, textureIds, 0); textureid = textureIds[0]; GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureid); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); GLES20.glUniform1i(sampler, 0); //设置环绕过滤方法 GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_REPEAT); GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_REPEAT); GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.androids); if (bitmap == null) { return; } GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0); //回收 bitmap.recycle(); bitmap = null; //解绑 GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); } } @Override public void onSufaceChanged(int width, int height) { GLES20.glViewport(0,0,width,height); } @Override public void onDrawFrame() { //清屏 GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT); //使用颜色清屏 GLES20.glClearColor(1.0f, 0.0f, 0.0f, 1.0f); //使用program GLES20.glUseProgram(program); //绑定 GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureid); /**********************VBO-START************************************************/ //绑定VBO GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vboId); /**********************VBO-END************************************************/ //使用顶点坐标 GLES20.glEnableVertexAttribArray(vPosition); /**********************VBO-START************************************************/ //传0 从VBO中取值 GLES20.glVertexAttribPointer(vPosition, 2, GLES20.GL_FLOAT, false, 8, 0); /**********************VBO-END************************************************/ GLES20.glEnableVertexAttribArray(fPosition); /**********************VBO-START************************************************/ //VBO GLES20.glVertexAttribPointer(fPosition, 2, GLES20.GL_FLOAT, false, 8, vertexData.length * 4); /**********************VBO-END************************************************/ GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); //解绑 GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); /**********************VBO-START************************************************/ //解绑VBO GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0); /**********************VBO-END************************************************/ }}
转载地址:http://ndzo.baihongyu.com/