VAO VBO IBO大乱炖
最近对程序中绘制卡顿的问题忍无可忍,终于决定下手处理了。程序涉及的绘制比较多,除了点、线、三角形、多边形、圆柱体之外,还有自组格式模型。开始想全部采用显示列表优化,毕竟效率最高,虽然显示列表存在编译之后不能更改的缺点,但是程序中更改模型的情况不多,更改每个类别的模型后重新加载该类别的显示列表就行了。
1.显示列表+顶点数组
显示列表的使用就不赘述了。主要想说一下配合顶点数组使用显示列表,可以带来更大的性能提升。对于三角网格和基于顶点的自组格式模型来说,摒弃一个个三角形画吧,效果绝对令你满意!当然,这么做的前提应该是顶点vertex在不同三角形中的属性相同(法线、颜色……)
list = glGenLists(1);
glNewList(list);
……
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture);
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);//纹理
glTexCoordPointer(2,GL_FLOAT,0,textures);
glColorPointer(3,GL_FLOAT,0,colors);//颜色 nTri*3
glNormalPointer(GL_FLOAT,0,normals);//法线 nTri*3
glVertexPointer(3,GL_FLOAT,0,vertexs);//顶点 nVer
glDrawElements(GL_TRIANGLES,nTri*3,GL_UNSIGNED_INT,iIndex);//索引 nTri*3
glEndList();
2.VBO(vertex buffer object)+VAO(vertex array object)
另一个选择是采用VBO进行绘制。VBO的好处是采用将数据提交到高速缓存的同时还保留数据的存取入口,可以直接获取并更新数据。VBO有两种方式,一种是使用glEnableClientState进行绘制,另一种就是组合VAO进行使用,也就是将对应不同属性的多组VBO存储到同一个VAO中(在渲染的时候可以少写很多代码)。
关于两种方式的取舍在这篇文章里面有介绍(http://www.zwqxin.com/archives/opengl/vao-and-vbo-stuff.html),这里我使用了第二种方式,也就是VBO+VAO进行使用。
GLuint vao;
GLuint vbo;
……
//初始化代码
glGenVertexArrays(1,&vao);
glBindVertexArray(vao);//当前VAO 到glBindVertexArray(NULL)之间的vbo等都成为该vao的属性
//
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER,12 * 3 * sizeof(float),vertexs,GL_STATIC_DRAW);//此处点坐标按照每个四边形四个点进行存入
glEnableVertexAttribArray(0); //坐标
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
glBindBuffer(GL_ARRAY_BUFFER,NULL);
//
glBindVertexArray(NULL);
glBindBuffer(GL_ARRAY_BUFFER,NULL);
……
//渲染代码
glBindVertexArray(vbo);
glDrawArrays(GL_QUADS,0,4);
glBindVertexArray(vbo);
之后突然想到,VA的使用中,共用顶点的索引方式index会比直接每个多边形顶点暴力存储效率高很多。所以查了下,果然有关于索引的用法:
---IBO(http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-9-vbo-indexing/)
其实就是VBO的方式运用索引而已,GL_ELEMENT_ARRAY_BUFFER。经过修改,代码就变成了下面的样式:
GLuint vao;
……
glGenVertexArrays(1,&vao);
glBindVertexArray(vao);//当前VAO 到glBindVertexArray(NULL)之间的vbo等都成为该vao的属性
//
GLuint vbo;
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER,nVert * 3 * sizeof(float),vertexs,GL_STATIC_DRAW);
glEnableVertexAttribArray(0); //坐标
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
glBindBuffer(GL_ARRAY_BUFFER,NULL);
//
GLuint colorVbo;//
glGenBuffers(1, &colorVbo);
glBindBuffer(GL_ARRAY_BUFFER, colorVbo);
glBufferData(GL_ARRAY_BUFFER,nVert * 3 * sizeof(float),colors,GL_STATIC_DRAW);
glEnableVertexAttribArray(1); //颜色
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, NULL);
glBindBuffer(GL_ARRAY_BUFFER,NULL);
//
GLuint normalVbo;//
glGenBuffers(1, &normalVbo);
glBindBuffer(GL_ARRAY_BUFFER, normalVbo);
glBufferData(GL_ARRAY_BUFFER,nVert * 3 * sizeof(float),normals,GL_STATIC_DRAW);
glEnableVertexAttribArray(2); //法线
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, NULL);
glBindBuffer(GL_ARRAY_BUFFER,NULL);
//
GLuint ibo;
glGenBuffers(1, &ibo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,nElem * 4 * sizeof(short), index,GL_STATIC_DRAW);//由于是绘制六棱柱侧面,nElem = nVert/2
//
glBindVertexArray(NULL);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, NULL);
glBindBuffer(GL_ARRAY_BUFFER,NULL);
渲染部分代码稍作改变
glBindVertexArray(vao);
glDrawElements(GL_QUADS,24, GL_UNSIGNED_SHORT, 0);
glBindVertexArray(NULL);
3.目前存在的问题
(1)由于我的程序仍在opengl 2.0下写的,并没有采用shader和GLSL,要做的事情实在太多,明知道需要学习,但还是无法在技术上投入太多时间。
(2)在上面VAO+VBO+IBO版的代码中遇到了一个问题:颜色没有设置成功(法线没问题),不知为何,仍在寻找中。如果有高手看到烦请赐教。
(3)关于VBO的更新:目前还没测试更新的效率。GL_STATIC_DRAW之后两种更新方式(复制和直接给出内存映射地址)貌似都需要重新设置/更新数据,还未测试GL_DYNAMIC_DRAW的使用效率。
(4)对其后台机制还是模棱两可。还是那句话,烦请高手赐教!也欢迎新手讨论!
VAO VBO IBO大乱炖的更多相关文章
- opengl中VAO,VBO,IBO用法小结(zz) 【转】
http://cowboy.1988.blog.163.com/blog/static/751057982014380251300/ opengl中VAO,VBO,IBO用法小结 这三个玩意全面取代旧 ...
- opengl中VAO,VBO,IBO用法小结【转】
http://cowboy.1988.blog.163.com/blog/static/751057982014380251300/ opengl中VAO,VBO,IBO用法小结 这三个玩意全面取代旧 ...
- HTM CSS 笔记乱炖
一.常用实体(字符转义) '<' == '<' '©' == '©' '>' == '>' '"' == '"' ' ' == ' ' '®' == '®' ...
- 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 ...
- GridView的 PreRender事件与 RowCreated、RowDataBound事件大乱斗
GridView的 PreRender事件与 RowCreated.RowDataBound事件大乱斗 之前写了几个范例,做了GridView的 PreRender事件与 RowCreated.Row ...
- python红蓝英雄大乱斗(面向对象实现)
红蓝英雄大乱斗 游戏规则 ''' 有红蓝两方英雄(可自定义个数) 随机一方英雄使用随机攻击方式攻击另一方英雄,任意一方英雄全部阵亡则游戏结束 每个英雄有 名字.生命值.普通攻击.Q技能攻击.W技能攻击 ...
- OpenGL渲染管道,Shader,VAO&VBO&EBO
OpenGL渲染管线 (也就是)OpenGL渲染一帧图形的流程 以下列举最简单的,渲染一个三角形的流程,你可以将它视为 精简版OpenGL渲染管线 更复杂的流程也仅仅就是:在此基础上的各个流程中 添加 ...
- openGL 提升渲染性能 之 顶点数组 VBO IBO VAO
使用openGL图形库绘制,都需要通过openGL接口向图像显卡提交顶点数据,显卡根据提交的数据绘制出相应的图形. openGL绘制方式有:直接模式,显示列表,顶点数组,顶点索引. 直接模式:最简单, ...
- OpenGL中VA,VAO,VBO和EBO的区别
1,顶点数组(Vertex Array) VA,顶点数组也是收集好所有的顶点,一次性发送给GPU.不过数据不是存储于GPU中的,绘制速度上没有显示列表快,优点是可以修改数据. 4.VBO(Vertex ...
随机推荐
- CSS3 3D变形效果
CSS3 3D变形效果 CSS3 transform3D变形 transform的含义是:改变,使-变形:转换 三维变换使用基于二维变换的相同属性,如果您熟悉二维变换,你们发现3D变形的功能和2D变换 ...
- 访问量分类统计(QQ,微信,微博,网页,网站APP,其他)
刚准备敲键盘,突然想起今天已经星期五了,有点小兴奋,一周又这么愉快的结束,又可以休息了,等等..我好像是来写Java博客的,怎么变成了写日记,好吧,言归正传. 不知道大家有没有遇到过这样的需求:统计一 ...
- sass 基础——回顾
1.webstorm 自动编译SASS 下载安装包 http://rubyinstaller.org/downloads/ 然后点击安装,路径为默认路径就行, 勾选以下两项 add Ruby exec ...
- Git本地操作相关介绍
本地使用git时遇到问题及解决方案总结: 1.git push origin master 后,终端上出现错误信息: push失败,原因多半是因为github上远程仓库中有Reademe.md文件 解 ...
- 非名校毕业年薪20W程序员 心得分享
大家好,我是落落http://blog.csdn.net/robinson1988/ QQ692162374,其实我选择Oracle是一件很神奇的事情,但是现在回想起来又觉得是命中注定.我2006年就 ...
- JSP 学习一
今天开始JSP的学习,作为Web开发人员,对JSP的开发是必不可少的,因此有必要对JSP进行掌握和学习:为此开始JSP的学习: 今日目标: 1)什么是JSP? 2)JSP的运行机制? 3)JSP的三种 ...
- jquery序列化form表单
在开发中有时需要在js中提交form表单数据,就需要将form表单进行序列化. jquery提供的serialize方法能够实现. $("#searchForm").seriali ...
- web及H5 的链接测试
1:先下载一个Xenu工具 2:安装完成之后,进入页面(将弹出框关闭) 3:进行设置(一般不用修改设置) 4:修改完成之后点击工具栏中的file按钮,并输入想要测试的URL地址 5:点击OK测试完成之 ...
- 【openstack N版】——创建云主机
一.启动实例 1.1 已准备服务介绍 MySql:为各个服务提供数据存储. RabbitMQ:为各个服务之间通信提供交通枢纽. keystone:为各个服务之间通信提供认证和服务注册. Glance: ...
- [bzoj3196]Tyvj 1730 二逼平衡树——线段树套平衡树
题目 Description 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 1.查询k在区间内的排名 2.查询区间内排名为k的值 3.修改某一位值上的数值 4.查 ...