【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 ...
随机推荐
- flannel相关资料链接
1.DockOne技术分享(十八):一篇文章带你了解Flannel http://dockone.io/article/618 2.理解Kubernetes网络之flannel网络http://ton ...
- 第一节:web 框架本质
1.web请求本质是什么: web请求本质:就是一个socket. 浏览器充当是客户端,python充当一个服务器端 浏览器请求相当一次tcp请求,请求完成断开连接 ,下次去的时候 ...
- Linux上free命令的输出及其他
一.明确概念 A buffer is something that has yet to be "written" to disk. A cache is something t ...
- linux c编程:互斥锁条件变量
条件变量:等待与信号发送 使用互斥锁虽然可以解决一些资源竞争的问题,但互斥锁只有两种状态(加锁和解锁),这限制了互斥锁的用途. 条件变量(条件锁)也可以解决线程同步和共享资源访问的问题,条件变量是对互 ...
- sql查询原理和Select执行顺序
一 sql语句的执行步骤 1)语法分析,分析语句的语法是否符合规范,衡量语句中各表达式的意义. 2) 语义分析,检查语句中涉及的所有数据库对象是否存在,且用户有相应的权限. 3)视图转换,将涉及视图的 ...
- QT Creator常用快捷键
1.F10,F11 单步调试 2.Ctrl + / :注释/取消注释选定内容. 3.F4 :在 头文件(.h) 和 实现文件(.cpp) 之间进行切换. 4.Ctrl + i :自动格式化选中代码. ...
- centos7 vmware克隆解决网络问题
centos7克隆后,发现两台机子之间的MAC相同,无法获取IP.超找资料,解决办法如下: 只要删除网卡的配置文件中的HWADDR和UUID两行就行.使用ifup启动网卡即可.
- django 快速数据库操作,不用SQL语句
配置models文件 # -*- coding: utf-8 -*- from __future__ import unicode_literals from django.db import mod ...
- 编程语言的介绍(Day2)
1.什么是编程,为什么要编程? 编程==编写程序(写代码) 2.编程语言有哪些 机器语言 优点是最底层,速度最快,缺点是最复杂,开发效率最低 汇编语言 优点是比较底层,速度最快,缺点是复杂,开发效率最 ...
- CodeMatic动软自动生成Nhibernate
前两天调查了下自动生成工具MyGeneration和codesmith前一个版本已经不更新了后面一个太高级生成 的代码包含了太多东西,没整明白.不过生成的xmlmapping很强大.所以干脆整合一下c ...