【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 ...
随机推荐
- FatMouse's Speed---hdu1160(简单dp)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1160 题意就是给你一些老鼠(编号1,2,3,4,5,6,7,8...)的体重和他们的速度然后求出最大的 ...
- git 设置 .gitignore 为全局global + 配置.gitignore为全局后不生效解决办法
outline 什么是 .gitignore 以及 .gitignore 的作用,这里不做赘述,自行网上查阅. 设置 .gitignore 为全局生效 懒得自己逐行敲忽略规则的话,建议移步:https ...
- DBA学习参考绝佳资料
原文来自:pursuer.chen 原文地址:https://www.cnblogs.com/chenmh/default.aspx?page=1 [置顶]MongoDB 文章目录 2018-02-0 ...
- mysql密码忘记该怎么办?
环境:linux;mysql5.7 mysql密码忘记: [root@izwz9f40l0qo5cpnn8qwmpz ~]# mysql -u root -pEnter password: ERROR ...
- SQL LEFT JOIN
SQL LEFT JOIN 关键字 SQL LEFT JOIN 关键字 LEFT JOIN 关键字会从左表 (table_name1) 那里返回所有的行,即使在右表 (table_name2) 中没有 ...
- C#驱动级模拟按键操作
C#驱动级模拟按键操作 2013-09-26 03:17 ·AB叔 447 3 <- 点击左侧的数字“攒”一个吧 昨天遇到一个程序自动输入财付通密码的任务. 因为财付通密码控件是有安全保护的,所 ...
- 在线修改GTID模式
在线修改GTID模式 1. 在每一台机器上执行命令 SET @@GLOBAL.ENFORCE_GTID_CONSISTENCY = WARN; 这是很重要的一步,必须确保服务器上没有违反GTID规范的 ...
- 解析库之re、beautifulsoup、pyquery
BeatifulSoup模块 一.介绍 Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库.它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式.Be ...
- 20145109 《Java程序设计》第六周学习总结
Chapter 10 I/O 10.1 InputStream & OutputStream a new 'try' edition: try (InputStream input = src ...
- jquery中ajax回调函数使用this
今天在写ajax请求的的时候success中代码老是不能正常执行,找了半天的原因,代码如下: 1 $.ajax({type: 'GET', 2 url: url, 3 data: oData, 4 s ...