由于我非常了解 OpenGL ES,因此我尝试了一个演示项目,做了您所描述的大部分内容。具体目的是在 OpenGL ES 下以最简单的方式完成所有事情,只要性能足够好。
从 Apple 提供的 OpenGL 模板开始,我编写了一个新类,其中包含一个 122 行长的经过大量注释的实现文件,该文件将 PNG 图像加载为纹理。我修改了示例视图控制器,以根据需要绘制天空盒,并使用普通 iPhone 惯性滚动的版本来响应触摸,这意味着编写少于 200 行(也已注释)的代码。
为了实现这一目标,我需要知道:
- CoreGraphics 用于从 PNG 中获取像素数据
- 如何设置 PROJECTION 堆栈以获得具有正确纵横比的透视投影
- 如何操作 MODELVIEW 堆栈以确保根据成员变量进行场景的两轴旋转(第一人称射击游戏或 Google StreetView 风格),并确保我定义的立方体几何体不会与近剪辑平面明显相交
- 如何向 OpenGL 指定顶点位置和纹理坐标
- 如何指定 OpenGL 应在顶点之间构建的三角形
- 如何相应地设置 OpenGL 纹理参数以仅提供纹理的一层细节
- 如何跟踪触摸来操纵指示旋转的成员变量,包括一些提供惯性旋转的机制
当然,会遵守正常的视图控制器生命周期指令。例如,纹理在 viewDidLoad 上加载并在 viewDidUnload 上释放,以确保此视图控制器能够很好地处理潜在的内存警告。
主要观察结果是,除了了解 Objective-C 信号机制之外,大部分都是 C 语言的东西。您主要使用 C 数组和引用来为 OpenGL 和 CoreGraphics 进行 C 函数调用。因此,自己编写代码的先决条件是喜欢使用 C,而不仅仅是 Objective-C。
CoreGraphics 的东西有点乏味,但它只是阅读文档来弄清楚每种类型的事物如何与下一种类型相关 - 没有一个是真正令人困惑的。只要想到您需要一个用于 PNG 数据的数据提供程序,您可以从该数据提供程序创建一个图像,然后使用您自己分配的内存创建一个位图上下文,将图像绘制到上下文中,然后释放所有内容除了您自己分配给结果的内存之外。该结果可以直接上传到OpenGL。它是相对较短的样板内容,但 OpenGL 没有 PNG 的概念,并且 CoreGraphics 没有将内容推送到 OpenGL 的便捷方法。
我假设纹理在磁盘上的大小合适。出于实际目的,这意味着假设它们沿每条边的大小都是二的幂。我的是 512x512。
OpenGL 纹理管理的东西很简单;只是阅读手册来了解纹理名称、名称分配、纹理参数和上传图像数据。更多常规的事情更多的是了解正确的功能而不是管理直观的飞跃。
为了向 OpenGL 提供几何图形,我刚刚完整地写出了数组。我想你需要一点空间思维才能做到这一点,但在纸上画出 3D 立方体草图并对角进行编号将会有很大帮助。共有三个相关数组:
- 顶点位置
- 与每个顶点位置相关的纹理坐标
- 引用定义几何图形的顶点位置的索引列表
在我的代码中,我使用了 24 个顶点,将立方体的每个面视为逻辑上离散的事物(因此,六个面,每个面有四个顶点)。为了简单起见,我仅使用三角形定义了几何形状。当你开始时,向 OpenGL 提供这些东西实际上是相当烦人的;犯错误通常意味着您的程序在 OpenGL 驱动程序深处崩溃,并且没有提示您做错了什么。最好一次积累一点。
就能够托管 OpenGL 内容的 UIView 而言,我或多或少使用了 Apple 在 OpenGL 模板中直接提供的普通内容。我所做的一项更改是明确禁止任何使用 OpenGL ES 2.x 的尝试。 1.x 足以完成此任务,因此我们首先通过不提供两个替代渲染路径来获得简单性,其次是因为 ES 2.x 路径会复杂得多。 ES 2.x 是带有像素和顶点着色器的完全可编程管道,但在 ES 领域,固定管道被完全删除。因此,如果您想要一个,那么您必须提供自己的普通矩阵堆栈的替代品,您必须编写顶点和片段着色器来执行“带有纹理的三角形”等。
触摸跟踪并不是特别复杂,或多或少只需要我了解视锥体的工作原理以及触摸在 Cocoa Touch 中是如何传递的。一旦你完成了其他所有事情,这一步应该很容易。
值得注意的是,我必须实现的数学非常简单。真的只是触摸追踪。例如,假设您想要一个 Google 地图类型的视图,这意味着我可以完全依赖 OpenGL 的内置旋转功能。我在任何时候都不会显式处理矩阵。
所以,你要花多长时间来写取决于你自己对 C 和 CoreGraphics 的信心,以及你有时在黑暗中编码的快乐程度。因为我知道自己在做什么,整个过程花了两三个小时。
我会尝试找到一个地方上传该项目,以便您可以查看。我认为翻阅一下它并看看它看起来有多陌生会很有帮助。这可能会让您很好地了解是否可以在项目的时间范围内实施满足您所有需求的东西。
我将视图控制器保留为只有一个视图,即 OpenGL 视图。但是,普通的 iPhone 合成规则适用,并且在您的项目中,您可以轻松地将普通控件放在顶部。你可以在以下位置获取我的小实现媒体之火。 StackOverflow 帖子长度限制使我无法在此处放置大段代码,但如果您有任何具体问题,请随时询问。