【OpenGL ES】关于VBO(Vertex Buffer Object)的一些坑——解析一些关于glBuffer的函数
最近在写毕设的时候用到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的函数的更多相关文章
- Opengl ES之VBO和VAO
前言 本文主要介绍了什么是VBO/VAO,为什么需要使用VBO/VAO以及如何使用VBO和VAO. VBO 什么是VBO VBO(vertex Buffer Object):顶点缓冲对象.是在显卡存储 ...
- CSharpGL(38)带初始数据创建Vertex Buffer Object的情形汇总
CSharpGL(38)带初始数据创建Vertex Buffer Object的情形汇总 开始 总的来说,OpenGL应用开发者会遇到为如下三种数据创建Vertex Buffer Object的情形: ...
- 【C++ OpenGL ES 2.0编程笔记】8: 使用VBO和IBO绘制立方体 【转】
http://blog.csdn.net/kesalin/article/details/8351935 前言 本文介绍了OpenGL ES 2.0 中的顶点缓冲对象(VBO: Vertex Buff ...
- 基于Cocos2d-x学习OpenGL ES 2.0系列——纹理贴图(6)
在上一篇文章中,我们介绍了如何绘制一个立方体,里面涉及的知识点有VBO(Vertex Buffer Object).IBO(Index Buffer Object)和MVP(Modile-View-P ...
- 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 ...
- OpenGL.Vertex Array Object (VAO).
OpenGL抛弃glEnable(),glColor(),glVertex(),glEnable()这一套流程的函数和管线以后,就需要一种新的方法来传递数据到Graphics Card来渲染几何体,我 ...
- OpenGL.Vertex Array Object (VAO) [转]
http://www.cppblog.com/init/archive/2012/02/21/166098.html 一 OpenGL抛弃glEnable(),glColor(),glVertex() ...
- OpenGL.Vertex Array Object (VAO) 【转】
http://www.cppblog.com/init/archive/2012/02/21/166098.html 一 OpenGL抛弃glEnable(),glColor(),glVertex() ...
- OpenGL ES 3.0之Fragment buffer objects(FBO)详解(一)
片段操作图 这篇文章将介绍从写入帧缓冲和读取帧缓冲的方式. Buffers(缓冲) OpenGL ES支持三种缓冲: OpenGL ES •• Color buffer颜色缓冲 •• Depth bu ...
随机推荐
- DotNetBar.Bar图标列表的使用
DotNetBar.Bar图标列表的使用 老帅 控件DevComponents.DotNetBar.Bar怎样使用图像列表呢?比方给工具条或者菜单加上图标.例如以下几步就可以! 方法1: 1.放一个S ...
- Android Paint setXfermode
背景: dst 前景: src PorterDuff.Mode.CLEAR 清除画布上图像 PorterDuff.Mode.XOR 取两层图像的非交集部门 PorterDuff.Mo ...
- 部署Node.js的应用
原创:作者 mashihua 最近Node.js很火,让很多的前端看到了可以直接从前端写到后端的希望.但是每次部署一个Node.js的应用却让前端苦恼不已.每次登陆服务器,用自己不熟悉的方式从版本控制 ...
- [设计模式]迭代子模式 Iterator
迭代子模式又叫做游标cursor模式,是对象的行为模式.迭代子模式可以顺序的访问一个聚集中的元素而不必暴露聚集的内部表象. 迭代子模式被广泛的应用在Java语言的API中的几个设计模式之一.在Java ...
- Windows工作区目录创建
Windows工作区目录创建批处理脚本,目的是养成工作区目录规范的好习惯. @echo off echo 'Create Jingyu Workshop!' rem Author: Alfred Zh ...
- python 测试代码
1.使用print()打印 测试代码最简单的就是添加一些print()语句.然而产品开发中,需要记住自己添加的所有print()语句并在最后删除,很容易出现失误. 2.使用pylint.pyflake ...
- Python框架之Tornado (源码之褪去模板外衣)
上一篇介绍了客户端请求在tornado框架中的生命周期,其本质就是利用epoll和socket来获取并处理请求.在上一篇的内容中,我们只是给客户端返回了简单的字符串,如:“Hello World”,而 ...
- LightOJ - 1236 (唯一分解定理)
题意:求有多少对数对(i,j)满足lcm(i,j) = n,1<=i<=j, 1<=n<=1e14. 分析:根据整数的唯一分解定理,n可以分解为(p1^e1)*(p2^e2)* ...
- 获取配置文件信息——configparser
配置文件host.int格式如下: [host]product=xxxxxxxxxxtest=xxxxxxxxxx python 3.x代码如下: import os,configparser def ...
- Matlab 使用的一些常用技巧
主要是编程过程中遇到的一些问题和解决,大多数都是来自于Matlab文档.随时总结: Vectorization 向量化是Matlab作为一种专注数值.矩阵计算的语言,和其他语言的一个差别.这也是Mat ...