OpenGL ES 3.0: 图元重启(Primitive restart)
背景概述
在OpenGL绘制图形时,可能需要绘制多个并不相连的图形。这样的情况下这几个图形没法被当做一个图形来处理。也就需要多次调用 DrawArrays 或 DrawElements. 如果图形很多,可能会需要用一个循环来调用:
for (int i = 0; i < num_objects; i++) {
glDrawArrays(GL_TRIANGLES,
object[n]->first_vertex,
object[n]->vertex_count);
}
每一次调用OpenGL 的绘制函数,都需要一定的资源开销,如果每一帧调用太多次,会对程序的性能产生较大的影响。提高性能的办法就是调用一次绘制函数,画出分散的图形。
一种方法是使用 glMultiDrawElements 函数来代替旧的绘制函数,可以减少调用次数,仅需调用此函数一次即可。但是这个函数在OpenGL ES 没有得到支持。而且使用这个函数,仍然需要将每一个分散的图形维护一组单独的顶点坐标/纹理坐标,这个是免不了的,这些数据仍然需要分开上传,还是会消耗一定的资源。针对这种情况使用图元重启会更加合适。
图元重启介绍
考虑通常的情况,当用户绘制 GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, GL_LINE_STRIP, GL_LINE_LOOP 这些图元时,所有的绘制点按照特定的顺序被连起来,以形成一个最终的复杂图形,也就是说最终的复杂图形由多个相连的三角形或线段组成。像上面提到的情况,想要绘制分散的图形,应该怎么办?
图元重启(Primitive restart) 允许用户绘制不连续的、分散的图形。考虑使用 glDrawElements 函数,绘制时按照indices所指定的顶点的顺序来绘制的。此时可以指定某一个值,该值表示一个重启的标志。遇到这个值的时候,OpenGL不会绘制图元,而是结束上一段绘制,然后重新启动新的绘制,也就是說用后面的索引所指定的顶点来从头绘制一个图形。
举个例子:比如指定8爲重启的标志,遇到8就重启。上面的是不启用图元重启的情况,即通常的情况。下面的是启用图元重启的情况,我们可以看到,从9开始,又重新从头开始绘制Triangle strip了。

编程指南
指定重启位置的数值,在桌面版的OpenGL是可以自行设定的, glPrimitiveRestartIndex 函数指定重启的标志。在OpenGL ES 无法自行指定,只能用给定的值。
首先设置启用图元重启
glEnable(GL_PRIMITIVE_RESTART_FIXED_INDEX);
Fixed index就代表了使用固定的重启的标志,具体数值和indices内数据类型有关。glDrawElements 的indices参数类型必须是以下的一种:GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT, GL_UNSIGNED_INT. 那么分别对应的重启的标志就是 2^8 - 1;2^16 - 1;2^32 - 1;也就是說重启的标志的数值就是indices数组所能允许的最大值。这个值一般来说是不会被用到的,拿来当标志正好。
所以我们只需要在 indices 里面的合适的位置插入一个标志,然后再调用 glDrawElements 函数即可实现图元重启。
下面代码片段是一个具体的例子:
// Prepare index buffer data (not shown: vertex buffer data, loading vertex and index buffers)
GLushort indexData[11] = {
0, 1, 2, 3, 4, // triangle strip ABCDE
0xFFFF, // primitive restart index (largest possible GLushort value)
5, 6, 7, 8, 9, // triangle strip FGHIJ
};
// Draw triangle strips
glEnable(GL_PRIMITIVE_RESTART_FIXED_INDEX);
glDrawElements(GL_TRIANGLE_STRIP, 11, GL_UNSIGNED_SHORT, 0);
另外,如果 glDrawElements 的mode是points之类的,那么用不用图元重启其实是一样的,对于性能没有提高。
参考资料:
Primitive Restart Makes GPGPU Tech Sparkle
Combining Drawing Functions, Combining Geometry Using Primitive
TechniquesforWorkingwithVertexData
OpenGL ES 3.0: 图元重启(Primitive restart)的更多相关文章
- OpenGL ES 3.0 图元装配
1. 前言 之前已经把纹理的渲染给弄出来了,但是又遇到一个新的问题,那就是图元装配,比如说我已经把图片给显示出来了,但是呢,并没有做到让它显示到具体的位置,而跟这个位置相关的则需要靠图元装配. 图元装 ...
- OpenGL ES 3.0 图元组合和光栅化(三)
图元是能够被OpenGL ES 绘制的几何物体,如三角形.线条或者精灵.在图元组合过程 中,对每个图元必须判断是否位于投影 截体内,如果图元不完全在平截体内部,将被视图平截体剪贴,如果完全在平截体外, ...
- OpenGL ES 2.0 渲染管线 学习笔记
图中展示整个OpenGL ES 2.0可编程管线 图中Vertex Shader和Fragment Shader 是可编程管线: Vertex Array/Buffer objects 顶点数据来源, ...
- OpenGL ES 3.0 基础知识
首先要了解OpenGL的图形管线有哪些内容,再分别去了解其中的相关的关系: 管线分别包括了顶点缓冲区/数组对象,定点着色器,纹理,片段着色器,变换反馈,图元装配,光栅化,逐片段操作,帧缓冲区.其中顶点 ...
- 《OpenGL® ES™ 3.0 Programming Guide》读书笔记1 ----总览
OpenGL ES 3.0 Graphics Pipeline OpenGL ES 3.0 Vertex Shader Transform feedback: Additionally, OpenGL ...
- OpenGL ES 3.0之VertexAttributes,Vertex Arrays,and Buffer Objects(九)
顶点数据,也称为顶点属性,指每一个顶点数据.指能被用来描述每个顶点的数据,或能被所有顶点使用的常量值.例如你想绘制一个具有颜色的立方体三角形.你指定一个恒定的值用于三角形的所有三个顶点颜色.但三角形的 ...
- OpenGL ES 3.0之Shading Language(八)
每个OpenGL ES 3.0程序要求一个顶点着色器和一个片段着色器去渲染一个图形.着色器概念是API 的中心,本篇将介绍着色器语言部分包含下面几项 1.变量和变量类型 2.矢量和矩阵创建及选择 3. ...
- 基于Cocos2d-x学习OpenGL ES 2.0系列——使用VBO索引(4)
在上一篇文章中,我们介绍了uniform和模型-视图-投影变换,相信大家对于OpenGL ES 2.0应该有一点感觉了.在这篇文章中,我们不再画三角形了,改为画四边形.下篇教程,我们就可以画立方体了, ...
- 【C++ OpenGL ES 2.0编程笔记】8: 使用VBO和IBO绘制立方体 【转】
http://blog.csdn.net/kesalin/article/details/8351935 前言 本文介绍了OpenGL ES 2.0 中的顶点缓冲对象(VBO: Vertex Buff ...
随机推荐
- ExtJS 4.2 评分组件
上一文章是扩展ExtJS自带的Date组件.在这里将创建一个评分组件. 目录 1. 介绍 2. 示例 3. 资源下载 1. 介绍 代码参考的是 Sencha Touch 2上的一个RatingStar ...
- 匹夫细说C#:庖丁解牛迭代器,那些藏在幕后的秘密
0x00 前言 在匹夫的上一篇文章<匹夫细说C#:不是“栈类型”的值类型,从生命周期聊存储位置>的最后,匹夫以总结和后记的方式涉及到一部分迭代器的知识.但是觉得还是不够过瘾,很多需要说清楚 ...
- 基于DDD的现代ASP.NET开发框架--ABP系列文章总目录
ABP相关岗位招聘:给热爱.NET新技术和ABP框架的朋友带来一个高薪的工作机会 ABP交流会录像视频:ABP架构设计交流群-7月18日上海线下交流会的内容分享(有高清录像视频的链接) 代码自动生成: ...
- 【翻译】MongoDB指南/CRUD操作(四)
[原文地址]https://docs.mongodb.com/manual/ CRUD操作(四) 1 查询方案(Query Plans) MongoDB 查询优化程序处理查询并且针对给定可利用的索引选 ...
- HTML BOM Browser对象
BOM:Browser Object Model,即浏览器对象模型,提供了独立于内容的.可以与浏览器窗口进行互动的对象结构. Browser对象:指BOM提供的多个对象,包括:Window.Navig ...
- Android消息传递之基于RxJava实现一个EventBus - RxBus
前言: 上篇文章学习了Android事件总线管理开源框架EventBus,EventBus的出现大大降低了开发成本以及开发难度,今天我们就利用目前大红大紫的RxJava来实现一下类似EventBus事 ...
- OVS 中的各种网络设备 - 每天5分钟玩转 OpenStack(128)
上一节我们启用了 Open vSwitch,本节将查看当前的网络状态并介绍 Open vSwitch 涉及的各种网络设备 初始网络状态 查看一下当前的网络状态. 控制节点 ifconfig 显示控制节 ...
- iOS开发之多种Cell高度自适应实现方案的UI流畅度分析
本篇博客的主题是关于UI操作流畅度优化的一篇博客,我们以TableView中填充多个根据内容自适应高度的Cell来作为本篇博客的使用场景.当然Cell高度的自适应网上的解决方案是铺天盖地呢,今天我们的 ...
- CSS 3学习——文本效果和@font-face
文本效果 关于文本效果,这里仅仅记录得到大多数浏览器支持的几个属性,分别是: text-overflow text-shadow word-break word-wrap text-overflow ...
- 如果你也会C#,那不妨了解下F#(7):面向对象编程之继承、接口和泛型
前言 面向对象三大基本特性:封装.继承.多态.上一篇中介绍了类的定义,下面就了解下F#中继承和多态的使用吧.