博客
关于我
[OpenGL ES] VBO 顶点缓冲对象
阅读量:254 次
发布时间: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/

你可能感兴趣的文章
EasuUI中的iconCls图标
查看>>
低功耗设计之沈洁版
查看>>
git的使用
查看>>
Python代码审计实战案例总结之反序列化和命令执行!
查看>>
Maven的仓库
查看>>
HTTP/HTTPS协议
查看>>
数据科学包5- pandas基础之基础运算
查看>>
我要偷偷的学C语言,然后惊呆所有人(第八天)
查看>>
【大数据Flink系列】Flink 核心概念综述
查看>>
【Django系列】Django模板所有知识点总结
查看>>
wxPython中TextCtrl的输入上限问题
查看>>
专业mac数据恢复软件Tenorshare UltData Mac
查看>>
alienskineyecandy mac
查看>>
Django 框架技术概况
查看>>
有趣的三个水桶等分8升水问题
查看>>
Leetcode 811. 子域名访问计数
查看>>
02 类加载机制解析二:双亲委派机制
查看>>
jquery select 通过text查找
查看>>
docker 部署springboot+redis
查看>>
mybatisplus生成Id代码备忘
查看>>