博客
关于我
[OpenGL ES] VBO 顶点缓冲对象
阅读量:256 次
发布时间:2019-03-01

本文共 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/

你可能感兴趣的文章
Java学习进阶—高级编程
查看>>
C++介绍与入门学习
查看>>
Java语言特点与学习
查看>>
阿里云数据库MySQL版快速上手!
查看>>
C++介绍与入门学习
查看>>
了解多线程!
查看>>
Java数据库开发
查看>>
第六章第一节(二叉堆)
查看>>
第九章第六节(floyd算法多源有权最小路径)
查看>>
字符串反转
查看>>
字符串包含
查看>>
数据库表设计-------三个范式
查看>>
夜光带你走走进全栈式web开发(25)擅长领域
查看>>
夜光带你走进Vue.js(二十三)擅长的领域
查看>>
夜光带你走进Vue.js(三十二)擅长的领域
查看>>
夜光带你走进Vue.js(三十三)擅长的领域
查看>>
夜光带你走进JavaScript(五十二)擅长的领域
查看>>
夜光带你走进JavaScript(五十四)擅长的领域
查看>>
夜光带你走进JavaScript(五十五)擅长的领域
查看>>
Java工程师培训课(十三【可以坚持看完前十二章说明毅力尚可~~】)
查看>>