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章的内容
ios游戏编程的OpenGL ES入门非常好的资料。
作者: (美) 马鲁基-弗伊诺(Marucchi-Foino, R.) 著 ...原作名: Game and Graphics Programming for iOS and Android with OpenGL ES 2.0 译者: 王净 译. 出版年: 2014-2 页数: 288 装帧: 平装 ISBN: 9787302352303
Opengl ES 入门 从零开始学习OpenGL ES
从零开始学习OpenGL_ES 网页文件
Android OpenGL ES 开发教程(19):绘制迷你太阳系
opengl es 入门级教程,虽然是IOS的代码,android java 及 ndk 是一样可移植使用的,opengl es的函数名在各平台是一致的
从零开始学习OpenGL ES之基础概念权威版本,内附有讲解代码!
从零开始学习OpenGL ES中的项目文件 Empty.OpenGL.ES.Application.zip
现代OpenGL+Qt学习笔记之二:程序框架http://blog.csdn.net/chaojiwudixiaofeixia/article/details/77917697源码。
顶点 缓存对象允许OpenGL ES 3.0应用程序分配和缓存 顶点数据在高性能图形内存和渲染从这 内存,从而避免每次绘制原语时重新发送数据。 不仅是顶点数据,还有用来描述的元素索引 原语的顶点索引,并作为参数传递给...
iphone上学习opengles的必备资料,完全零基础开始学习
OPENGL基础教程,从编译和安装开始讲起,入门的好资料
由资深Android开发专家根据OpenGLES2.0版本撰写,不仅系统地讲解了OpenGLES的核心概念、技术,以及Android的图形机制,还通过大量案例讲解了在Android上进行OpenGLES开发的方法和技巧。 《OpenGL ES应用开发实践...
教程名称:OpenGL ES经典教程大全课程目录:【】Android应用OpenGLES制作3D图像【技术文档】【】OpenGL ES 2.0 官方手册【】OpenGL ES 2.0 编程指南【】OpenGL ES 2.0【】OpenGL ES【】OpenGL ES教程以及COCOS 2D...
由资深Android开发专家根据OpenGLES2.0版本撰写,不仅系统地讲解了OpenGLES的核心概念、技术,以及Android的图形机制,还通过大量案例讲解了在Android上进行OpenGLES开发的方法和技巧。 《OpenGL ES应用开发实践...
Android OpenGL ES 简明开发教程四:3D 坐标变换
Android平台采集Camera的YUV原始数据后使用OpenGLES2.0显示,内置YV12格式的YUV分量分离。 附件为完整例子,感谢“李狗蛋52635”提供的GLProgram类。
OpenGL ES应用开发实践指南:iOS卷(源码),提供给大家学习交流使用,
1.从零开始学习OpenGL+ES 2.opengl-es画图步骤 3.图形绘制与OpenGL_ES 4.Android开发之OpenGL+ES教程