【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 ...
随机推荐
- Andrew Ng机器学习编程作业:Regularized Linear Regression and Bias/Variance
作业文件: machine-learning-ex5 1. 正则化线性回归 在本次练习的前半部分,我们将会正则化的线性回归模型来利用水库中水位的变化预测流出大坝的水量,后半部分我们对调试的学习算法进行 ...
- redis的ruby客户端(三)
1. 介绍 clients这里列出了redis所支持的语言的所有客户端程序,其中就有ruby的.有这么多的客户端,说明要实现redis的客户端是不难的.其实你只要掌握一种语言的socket编程就可以实 ...
- web项目的getContextPath()
伯乐一看小编的这个博文的标题是不是觉得有些小,以点到面,知道了web中getContextPath()这种获取路径的方式,显然其他的方式的是可以以此类推的.常说,工作学习找共同点嘛. 上一段我们也提高 ...
- HTTP协议简要介绍
1. 网络基础 TCP/IP 通常使用的网络是在TCP/IP协议簇基础上运作的. HTTP属于它内部的一个子集. TCP/IP分为4个层次, 应用层, 传输层, 网络层, 链路层. (Applicat ...
- Java泛型二:通配符的使用
原文地址http://blog.csdn.net/lonelyroamer/article/details/7927212 通配符有三种: 1.无限定通配符 形式<?> 2.上边界限定 ...
- go——数组(二)
1.内部实现 在Go语言里,数组是一个长度固定的数据类型,用于存储一段具有相同的类型的元素的连续块. 数组存储的类型可以是内置类型,如整型或字符串,也可以是某种结构类型. 灰格子代表数组里面的元素,每 ...
- mysql监控报警工具
#!/usr/bin/env python # coding:utf-8 import MySQLdb import requests, json import time url = "ht ...
- python 测试代码
1.使用print()打印 测试代码最简单的就是添加一些print()语句.然而产品开发中,需要记住自己添加的所有print()语句并在最后删除,很容易出现失误. 2.使用pylint.pyflake ...
- WCF RIA SERVICE相关技术
WCF RIA SERVICE实体属性拷贝 private void DoSubmit() { ((IEditableObject)this.RepairContract).EndEdit(); va ...
- Unity,基于layer的碰撞配置
可以通过给对象指定layer,实现相同.不同layer之间碰撞的自由配置,比如我们想让怪物之间不碰撞,英雄和怪物之间碰撞,我们就可以这样指定,去掉enemies之间的勾选. 打开方式-edit-> ...