Technote 2230提出了很多用OpenGL ES来提升iphone程序性能的建议。我们现在远远不能深刻理解OpenGL ES所以你需要学习以下内容。不信?是真的,试试看,我等着你的读后感。
好,就这样定了?副标题为“优化顶点数据”,这里有一些算法上的建议用来"submit strip-ordered indexed triangles with per vertex data interleaved"。当苹果给出这些建议的时候,他们通常有一些非常好的理由,让我们看看如何使用它。
首先让我们了解它的意思。让我们把这句话分解开来:
Strip Ordered:换句话说,如果你的模型有相邻的三角形,组成一个三角形带提交而不是分别提交每一个三角形。我们早期教程讲到过三角形带,你应该多少知道一点该怎么做。对于大多数物体来说你都可以使用这个方法,但不是所有时候都要用它。你什么时候能够使用?当你确定使用三角形带可以有效减少推入OpenGL ES每帧的顶点数据的时候。
indexed:这里仍然没有什么新内容。我们使用顶点索引有一段时间了。我们仅仅用12个顶点来创建旋转的20面体。glDrawElements()是基于索引绘制而不是基于顶点。
见鬼,我们目前已经做的很棒了,不是吗?我们眼下一直在做着正确的事情。让我们来看最后一个建议,然而:
with per vertex data interleaved:好的,恩。。。。它到底是什么意思?
好的,是时候考验你的记忆力了。你还记得在过去几个部分,也就是当我们讨论glVertexPointer(),glNormalPointer(),glColorPointer(),glTexCoordPointer()的时候吗?在前面的部分里,我告诉你不用关注参数stride并把它设置为0。
但是现在你要关注它(stride)了,因为它是用来交叉存取每个顶点数据的关键。
Per Vertex Data
你也许想知道“per vertex data”是什么,并且想知道如何交叉存取它。
你肯定知道,在OpenGL ES里我们用顶点数组来表示几何图形,每一个数组包含3个定义顶点的GLfloat变量,来创造我们的物体。除了这些,我们有时也使用其它数据。举例来说,如果我们用光效就需要顶点法线,我们不得不在法线数组里定义每一个顶点的法线。如果我们使用纹理坐标,我们不得不在纹理数组里定义每一个顶点的纹理坐标。如果我们用颜色数组,我们不得不指定每个点的颜色,你是否注意到我总是强调“per vertex data”?这些数据类型就是苹果公司在它们技术说明里提到的"per vertex data"。这就是你所有在OpenGL ES 中放入数组的任意一种适用于顶点的顶点数组。
Interleaving
这个系列到目前为止,我们已经创造一个数组来存放顶点数据,并把它们与法线数据、颜色数据、纹理坐标分开存在其他独立数组中,像这样:
我们将要学习如何把这所有的数据放在一起作为一个整体数据来存储:
如果你读不懂上图解里面的代码请不要担心。 当那个变得重要的时候,我们会再次列出来讲解的,这个给出的代码列表仅仅是举例说明在一个独立的内存单元中我们可以存入所有的顶点数据。 我们所要做的只是把所有描述一个单一点的数据放在内存的同一个地方。
这样做能够使OpenGL快速的获得读取到每个顶点的信息。 在今天的例子里面,我们要将交叉存储顶点,法线,颜色(vertices, normals, color data),同样的方法可以使用在纹理坐标中,或者仅交叉存储顶点和法线。事实上在一个Xcode工程里面,会附带着一些数据结构定义这三个交叉存储的情况。
Defining a Vertex Node
为了让这个能够工作起来,我们需要一个新的数据结构。下面的数据结构能够让我们把上面提到的顶点, 法线,颜色 交叉存储到一起,
typedef struct {
Vertex3D vertex;
Vector3D normal;
Color3D color;
} ColoredVertexData3D;
啊哈哈,漂亮而简洁不是吗?你只用一个数据结构就包含了我们需要的一个顶点的所有属性。
下一步,当然了,线面我们需要填充顶点数据,所以我们需要把三个static const数组合并成一个。这里是相同的二十面体数据,指定使用了我们自己定义的新数据类型:
static const ColoredVertexData3D vertexData[] = {
{
{0, -0.525731, 0.850651}, {0.000000, -0.417775, 0.675974}, {1.0, 0.0, 0.0, 1.0} },
{
{0.850651, 0, 0.525731}, {0.675973, 0.000000, 0.417775}, {1.0, 0.5, 0.0, 1.0} },
{
{0.850651, 0, -0.525731}, {0.675973, -0.000000, -0.417775}, {1.0, 1.0, 0.0, 1.0} },
{
{-0.850651, 0, -0.525731}, {-0.675973, 0.000000, -0.417775}, {0.5, 1.0, 0.0, 1.0} },
{
{-0.850651, 0, 0.525731}, {-0.675973, -0.000000, 0.417775}, {0.0, 1.0, 0.0, 1.0} },
{
{-0.525731, 0.850651, 0}, {-0.417775, 0.675974, 0.000000}, {0.0, 1.0, 0.5, 1.0} },
{
{0.525731, 0.850651, 0}, {0.417775, 0.675973, -0.000000}, {0.0, 1.0, 1.0, 1.0} },
{
{0.525731, -0.850651, 0}, {0.417775, -0.675974, 0.000000}, {0.0, 0.5, 1.0, 1.0} },
{
{-0.525731, -0.850651, 0}, {-0.417775, -0.675974, 0.000000}, {0.0, 0.0, 1.0, 1.0}, },
{
{0, -0.525731, -0.850651}, {0.000000, -0.417775, -0.675973}, {0.5, 0.0, 1.0, 1.0} },
{
{0, 0.525731, -0.850651}, {0.000000, 0.417775, -0.675974}, {1.0, 0.0, 1.0, 1.0} },
{
{0, 0.525731, 0.850651}, {0.000000, 0.417775, 0.675973}, {1.0, 0.0, 0.5, 1.0} }
};
下面是我们如何传递信息到OpenGL。我们传递在这个数组里面的每个数据成员的第一个顶点的地址,并且提供所传递的数据的长度大小作为步长参数,而不是传递指针到合适的数组。
glVertexPointer(3, GL_FLOAT, sizeof(ColoredVertexData3D), &vertexData[0].vertex);
glColorPointer(4, GL_FLOAT, sizeof(ColoredVertexData3D), &vertexData[0].color);
glNormalPointer(GL_FLOAT, sizeof(ColoredVertexData3D), &vertexData[0].normal);
以上几个方法中,最后一个参数调用了数据里的第一个顶点,例如,&vertexData[0].color指向第一个顶点的颜色信息。stride(跨度)参数表明了在我们读取下一个相同类型的数据时,我们要跳过多少比特的数据。如果你看了下面的图解你也许就有那么一点点感觉了(不好意思它有点宽,你需要适当的调整你的浏览器以便于看到这个图解的所有部分)
变简单了不是吗?如果你一点也不喜欢打字,那么你可以下载这个十二面的交叉存取版本spinning icosahedron。我也会使用新的数据类型更新我的OpenGL ES Xcode Template。
我们现在依然没有使用triangle strips,但是混合三角形到triangle strips是下一步的教程,现在我要去参加WWDC了。
原文:iphonedevelopment,OpenGL ES from the Ground Up Part 8: Interleaving Vertex Data
iTyran翻译讨论地址:http://ityran.com/forum-36-1.html
分享到:
相关推荐
泰然论坛翻译的 OpenGL ES 从零开始系列 文章源码,由于是很早之前的,原连接失效了。 找了很久才找到的,是目前最齐全的。总共7个DEMO, 涵盖了总共9章的内容
OpenGL ES(Open Graphics ...总结而言,学习OpenGL ES从零开始需要掌握其核心概念、数据类型、坐标系统以及对3D图形的处理。在移动和嵌入式平台的应用开发中,这些知识点是构建流畅、高效3D图形应用程序的基础。
OpenGLES 3.0从零开始,绘制点、线、三角形、立方体,相机实时预览等等实践学习 android平台opengles3.0实践学习 android平台下OpenGLES3.0从零开始 android平台下OpenGLES3.0绘制纯色背景 android平台下OpenGLES3.0...
本文将从零开始,详细介绍如何学习OpenGL ES,以及如何利用提供的模板进行快速入门。 首先,我们要理解OpenGL ES的基础概念。OpenGL ES 提供了一个跨平台的编程接口,用于创建2D和3D图形。它包含了一系列函数调用,...
1. "从零开始学习OpenGL+ES"系列:讲解OpenGL ES的基本概念和编程基础。 2. "opengl-es画图步骤":详细介绍OpenGL ES绘制图形的完整流程。 3. "实验6——图形绘制与OpenGL_ES":提供实际的编程练习,加深理论知识的...
本教程将从零开始,带你深入理解OpenGL ES项目的构建和运行,帮助你开启图形编程之旅。 在"Empty.OpenGL.ES.Application.zip"这个压缩包中,你可能会找到以下核心文件和目录,它们是构成一个基本OpenGL ES应用的...
从零开始学习OpenGL_ES 网页文件
作者: (美) 马鲁基-弗伊诺(Marucchi-Foino, R.) 著 ...原作名: Game and Graphics Programming for iOS and Android with OpenGL ES 2.0 译者: 王净 译. 出版年: 2014-2 页数: 288 装帧: 平装 ISBN: 9787302352303
本教程主要探讨如何在Android系统上,利用OpenGLES2.0图形库来处理和显示从Camera获取的YUV原始数据。YUV是一种常见的颜色空间,广泛应用于视频编码和解码,因为它对带宽的要求相对较低,特别适合移动设备。 首先,...
OpenGL ES应用开发实践指南:iOS卷是一本专为iOS开发者设计的深度学习资源,它涵盖了在iOS设备上使用OpenGL ES进行图形编程的核心概念和技术。OpenGL ES(OpenGL for Embedded Systems)是OpenGL的一个轻量级版本,...
它通常与OpenGL ES不直接交互,但在构建例如3D地理信息系统或可视化应用时,可能会利用Elasticsearch来检索和组织数据,然后通过OpenGL ES进行呈现。 总的来说,OpenGL ES 3.0编程指南涵盖了移动和嵌入式设备图形...
OpenGL ES编程指南是一本针对移动设备和嵌入式系统的图形编程权威书籍,主要聚焦于OpenGL ES 2.0版本。OpenGL ES(Embedded Systems)是OpenGL的轻量级版本,专为资源有限但需要高质量3D图形处理能力的平台设计,如...
### Android OpenGL ES 开发教程(19):绘制迷你太阳系 #### 一、引言 OpenGL ES(OpenGL for Embedded Systems)是OpenGL的一个版本,专为手持设备等嵌入式系统设计,支持2D和3D图形渲染。本文将详细介绍如何在...
由资深Android开发专家根据OpenGLES2.0版本撰写,不仅系统地讲解了OpenGLES的核心概念、技术,以及Android的图形机制,还通过大量案例讲解了在Android上进行OpenGLES开发的方法和技巧。 《OpenGL ES应用开发实践...
2. **基础概念**:深入浅出地讲解OpenGL ES 2的基本原理,包括顶点数据、纹理映射、着色器等核心概念。 3. **数学与矩阵运算**:这部分内容对于理解和操作3D图形至关重要。书中提供了大量实例来帮助理解如何使用...