最近在写毕设的时候用到OpenGL ES中的VBO,由于对一些接口用到的变量不了解被坑得很惨,在此记录一下防止以后再被坑。

本文为大便一箩筐的原创内容,转载请注明出处,谢谢:http://www.cnblogs.com/dbylk/p/4492306.html


使用VBO的好处在此就不多说了,在Java中操作VBO绘图涉及到的OpenGL接口主要有以下几个:

1. void glGenBuffers(int n, int[] buffers, int offset)

向OpenGL ES申请开辟新的VBO,并通过buffers数组获取VBO handle,handle的类型为整型。

int n      申请的VBO个数

int[] buffers  用于存储VBO handle的数组

int offset    buffers数组的偏移量,即从buffers的第offset个位置开始存储handle

注意需要满足 n + offset <= buffers.length

2. void glBindBuffer(int target, int buffer)

通过handle绑定指定的VBO,同一时间只能绑定一个同类型的VBO,只有当前被绑定的VBO才会被用户操作。通过绑定handle为0的VBO,可以取消对所有同类型VBO的绑定。

int target    指定绑定的VBO类型,具体类型有GL_ARRAY_BUFFER(用于为顶点数组传值)和GL_ELEMENT_ARRAY_BUFFER(用于为索引数组传值)

int buffer    指定绑定的VBO handle

3. void glBufferData(int target, int size, Buffer data, int usage)

将数据传递给当前绑定的VBO。

int target    指定VBO类型,同上

int size      指定VBO的大小,单位为byte

Buffer data   指定需要传递的数据

int usage    指定VBO的存储方式,例如GL_STATIC_DRAW或GL_DYNAMIC_DRAW

4. void glVertexAttribPointer(int indx, int size, int type, boolean normalized, int stride, int offset)

将VBO中的数据传递给顶点数组。

int indx           指定Shader属性的顶点数组handle

int size        指定该属性的顶点数组大小,单位为数组元素的类型

int type         指定该属性的顶点数组元素类型,如GL_FLOAT和GL_UNSIGNED_BYTE

boolean normalize  指定传递给该属性顶点数组的数据是否需要归一化(转化为单位向量)

int stride       指定该属性的顶点数据在VBO中的跃度,即每个顶点所占的数据长度,单位为byte

int offset       指定该属性在VBO中起始位置的偏移量,单位为byte

5. void glDrawArrays(int mode, int first, int count)

直接使用顶点数组绘制图元。

int mode    指定绘图的模式,如GL_TRIANGLES和GL_TRIANGLE_STRIP

int first     指定从第几个顶点开始绘制

int count    指定绘制几个顶点

本人博客地址,防止无脑抄袭,影响阅读见谅:http://www.cnblogs.com/dbylk

6. void glDrawElements(int mode, int count, int type, int offset)

使用索引数组绘制图元。

int mode    指定绘图的模式,如GL_TRIANGLES和GL_TRIANGLE_STRIP

int count    指定绘制几个顶点

int type      指定索引数组的数据类型,如GL_UNSIGNED_SHORT和GL_UNSIGNED_INT

int offset      指定索引数组起始位置的偏移量,单位为byte 

通过下面的简单实例中可以了解这些方法在实际操作中如何使用:

// Author DaBianYiLuoKuang.
// http://www.cnblogs.com/dbylk/ public void onDrawFrame(GL10 gl) {
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT); // 设置旋转矩阵的函数,在此可以忽略
setRotationView(); // 获取Position属性的location
int positionHandle = GLES20.glGetAttribLocation(programHandle, "Position");
// 获取SourceColor属性的location
int colorHandle = GLES20.glGetAttribLocation(programHandle, "SourceColor"); // 激活两个属性的数组
GLES20.glEnableVertexAttribArray(positionHandle);
GLES20.glEnableVertexAttribArray(colorHandle); // 每个顶点的跃度,即一个顶点占有的数据类型个数
int stride = ;
// 顶点数据数组,6个float组成一个顶点,前2个float为位置坐标,后4个float为颜色RGBA
float[] data = {
-0.5f, -0.5f, 1f, 1f, 1f, 1f,
0.5f, -0.5f, 1f, 1f, 1f, 1f,
0f, 1f, 1f, 1f, 1f, 1f
}; // 将顶点数组封装进Buffer中
// 值得注意的一点是通过Buffer.wrap()方法生成的Buffer无法在OpenGL ES中使用,必须通过如下方法创建Buffer
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(data.length * );
// OpenGL ES中使用的数据为小端字节序(低位字节在前,高位字节在后),而Java的Buffer默认使用大端字节序(高位字节在前,低位字节在后)存储数据,所以在此需要通过下面的方法进行转换
byteBuffer.order(ByteOrder.nativeOrder());
// 将ByteBuffer转换为FloatBuffer
FloatBuffer floatBuffer = byteBuffer.asFloatBuffer();
// 将data中的数据放入FloatBuffer中
floatBuffer.put(data);
// 重新定义Buffer的起点和终点,等价于同时使用postion(0)方法和limit(data.length)方法
floatBuffer.flip(); // 用于获取VBO handle的临时变量
int[] temp = new int[];
// 向OpenGL申请新的VBO,将handle存于temp中
GLES20.glGenBuffers(, temp, );
// 从temp中取出VBO handle
vertexBufferHandle = temp[];
// 绑定刚刚申请到的VBO
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vertexBufferHandle);
// 将FLoatBuffer中的数据传递给OpenGL ES
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, floatBuffer.limit() * , floatBuffer, GLES20.GL_STATIC_DRAW); // 将VBO中的数据传递给shader中的顶点数组
GLES20.glVertexAttribPointer(positionHandle, , GLES20.GL_FLOAT, false, stride * , );
GLES20.glVertexAttribPointer(colorHandle, , GLES20.GL_FLOAT, false, stride * , * ); // 绘制三角形
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, , ); // 取消buffer的绑定
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, ); // 反激活顶点数组
GLES20.glDisableVertexAttribArray(positionSlot);
GLES20.glDisableVertexAttribArray(colorSlot);
}

关于注释中提到的大端字节序和小端字节序,具体可以查阅下篇博文:

http://www.cnblogs.com/xiehy/archive/2010/11/25/1887779.html

【OpenGL ES】关于VBO(Vertex Buffer Object)的一些坑——解析一些关于glBuffer的函数的更多相关文章

  1. Opengl ES之VBO和VAO

    前言 本文主要介绍了什么是VBO/VAO,为什么需要使用VBO/VAO以及如何使用VBO和VAO. VBO 什么是VBO VBO(vertex Buffer Object):顶点缓冲对象.是在显卡存储 ...

  2. CSharpGL(38)带初始数据创建Vertex Buffer Object的情形汇总

    CSharpGL(38)带初始数据创建Vertex Buffer Object的情形汇总 开始 总的来说,OpenGL应用开发者会遇到为如下三种数据创建Vertex Buffer Object的情形: ...

  3. 【C++ OpenGL ES 2.0编程笔记】8: 使用VBO和IBO绘制立方体 【转】

    http://blog.csdn.net/kesalin/article/details/8351935 前言 本文介绍了OpenGL ES 2.0 中的顶点缓冲对象(VBO: Vertex Buff ...

  4. 基于Cocos2d-x学习OpenGL ES 2.0系列——纹理贴图(6)

    在上一篇文章中,我们介绍了如何绘制一个立方体,里面涉及的知识点有VBO(Vertex Buffer Object).IBO(Index Buffer Object)和MVP(Modile-View-P ...

  5. OpenGL ES 2: debugging, and improvements to VAO, VBO

    OpenGL ES 2: debugging, and improvements to VAO, VBO http://www.altdevblogaday.com/2013/10/12/opengl ...

  6. OpenGL.Vertex Array Object (VAO).

    OpenGL抛弃glEnable(),glColor(),glVertex(),glEnable()这一套流程的函数和管线以后,就需要一种新的方法来传递数据到Graphics Card来渲染几何体,我 ...

  7. OpenGL.Vertex Array Object (VAO) [转]

    http://www.cppblog.com/init/archive/2012/02/21/166098.html 一 OpenGL抛弃glEnable(),glColor(),glVertex() ...

  8. OpenGL.Vertex Array Object (VAO) 【转】

    http://www.cppblog.com/init/archive/2012/02/21/166098.html 一 OpenGL抛弃glEnable(),glColor(),glVertex() ...

  9. OpenGL ES 3.0之Fragment buffer objects(FBO)详解(一)

    片段操作图 这篇文章将介绍从写入帧缓冲和读取帧缓冲的方式. Buffers(缓冲) OpenGL ES支持三种缓冲: OpenGL ES •• Color buffer颜色缓冲 •• Depth bu ...

随机推荐

  1. java中byte[] 和16进制字符串互转

    //将byte[]转换为16进制字符串 public static String byte2hex(byte[] b) { StringBuilder hs = new StringBuilder() ...

  2. mysql以下c连接mysql数据库

    1.安装sudo yum install mysql-devel  安装组件和库 2. #include <stdio.h> #include <stdlib.h> #incl ...

  3. Linux学习笔记(4)磁盘分区(fdisk)、挂载与文件系统命令

    Linux学习笔记(4)磁盘分区(fdisk).挂载与文件系统命令 1.磁盘分区是怎么表示的? 1.1 对于IDE接口,第一主盘为hda,第1从盘为hdb,第1从盘的第1个分区为hdb1 1.2 对于 ...

  4. 你真的会用Retrofit2吗?Retrofit2完全教程

    本文注目录: Retrofit入门 Retrofit注解详解 Gson与Converter RxJava与CallAdapter 自定义Converter 自定义CallAdapter 其它说明 前言 ...

  5. Jquery 实现跨域处理

    JS部分代码: $.ajax({ url:url, dataType:'jsonp', data:{title:title}, jsonp:'callback', success:function(l ...

  6. C#数组的笔记

    Array.Copy的笔记: 1.将值类型的元素装箱位引用类型的元素,比如讲一个Int32[]的元素复制到Object[]中 2.将引用类型的元素拆箱为值类型的元素 3.加宽CLR基元值类型,比如讲一 ...

  7. 快速排序算法C语言版

    快速排序(Quicksort)是对冒泡排序的一种改进.  快速排序由C. A. R. Hoare在1962年提出.它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比 ...

  8. 【转】Python操作 RabbitMQ、Redis、Memcache、SQLAlchemy

    Memcached Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载.它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态.数据库驱动网站的速度 ...

  9. python之路 面向对象进阶篇

    一.字段 字段包括:普通字段和静态字段,他们在定义和使用中有所区别,而最本质的区别是内存中保存的位置不同, 普通字段属于对象 静态字段属于类 class Province: # 静态字段 countr ...

  10. PHP范例注册审核

    <body> <h1>注册</h1> <form action="zcchuli.php" method="post" ...