简体   繁体   English

Skybox OpenGL ES iPhone和iPad

[英]Skybox OpenGL ES iPhone and iPad

I need to create a virtual tour tool for iOS . 我需要为iOS创建一个虚拟游览工具。 It's an archaeological application: the user could open it when he's inside an historic building or when he's visiting an archaeological dig. 这是一个考古应用:用户可以在他在一座历史建筑内或在他参观考古挖掘时打开它。 No need of doom-like subjective point of view: just a skybox. 不需要像厄运一样的主观观点:只是一个天空盒。 The application will have a list of points of interest (POIs). 该应用程序将有一个兴趣点(POI)列表。 Every POI will have its own skybox. 每个POI都有自己的天空盒。

I thought that I could use using OpenGL-ES to create a sort of textured skyboxes that could be driven/rotated by touches. 我认为我可以使用OpenGL-ES创建一种可以通过触摸驱动/旋转的纹理天空盒。 Textures are hi-resolution PNG photos. 纹理是高分辨率的PNG照片。

It's a funded project and I have 4 months. 这是一个资助项目,我有4个月。

Where do I have to go to learn how to develop it? 我该去哪里学习如何开发它? Do I have to purchase a book? 我必须购买一本书吗? Which one? 哪一个?

I have just moderate Objectve-C and Cocoa-touch skills, since I've built just one application for the iPad. 我只有适度的Objectve-C和Cocoa-touch技能,因为我只为iPad构建了一个应用程序。 I have zero knowledge of OpenGL-ES . 我对OpenGL-ES一无所知。

Since I know OpenGL ES quite well, I had a go at a demo project, doing much of what you describe. 由于我非常了解OpenGL ES,所以我参加了一个演示项目,完成了你所描述的大部分内容。 The specific intention was to do everything in the simplest way available under OpenGL ES as long as the performance was good enough. 具体的意图是只要性能足够好,就可以在OpenGL ES下以最简单的方式完成所有工作。

Starting from the OpenGL template that Apple supply, I have written one new class with a heavily commented implementation file 122 lines long that loads PNG images as textures. 从Apple提供的OpenGL模板开始,我编写了一个新类,其中包含一个评论很多的实现文件,长度为122行,可以将PNG图像作为纹理加载。 I've modified the sample view controller to draw a skybox as required and to respond to touches with a version of the normal iPhone inertial scrolling, which has meant writing less than 200 lines of (also commented) code. 我已经修改了示例视图控制器以根据需要绘制天空盒,并使用正常的iPhone惯性滚动版本来响应触摸,这意味着编写少于200行(也已注释)的代码。

To achieve this I needed to know: 要实现这一点,我需要知道:

  • the CoreGraphics means for getting pixel data from a PNG CoreGraphics意味着从PNG获取像素数据
  • how to set up the PROJECTION stack to get a perspective projection with the correct aspect ratio 如何设置PROJECTION堆栈以获得具有正确宽高比的透视投影
  • how to manipulate the MODELVIEW stack to ensure two-axis rotation (first person shooter or Google StreetView style) of the scene according to member variables and to ensure that the cube geometry I defined doesn't visibly intersect the near clip plane 如何根据成员变量操纵MODELVIEW堆栈以确保场景的双轴旋转(第一人称射击游戏或Google街景风格),并确保我定义的立方体几何体与近剪裁平面不明显相交
  • how to specify vertex locations and texture coordinates to OpenGL 如何为OpenGL指定顶点位置和纹理坐标
  • how to specify the triangles OpenGL should construct between vertices 如何指定三角形OpenGL应该在顶点之间构造
  • how to set the OpenGL texture parameters accordingly to supply only one level of detail for the texture 如何相应地设置OpenGL纹理参数以仅为纹理提供一个细节级别
  • how to track a touch to manipulate the member variables dictating rotation, including a tiny bit of mechanics to give an inertial rotation 如何跟踪触摸来操纵指示旋转的成员变量,包括一些惯性旋转的机制

Of course, the normal view controller lifecycle instructions are obeyed. 当然,遵守普通视图控制器生命周期指令。 Textures are loaded on viewDidLoad and released on viewDidUnload, for example, to ensure that this view controller plays nicely with potential memory warnings. 纹理在viewDidLoad上加载并在viewDidUnload上释放,例如,以确保此视图控制器可以很好地处理潜在的内存警告。

The main observations are that, beyond knowing the Objective-C signalling mechanisms, most of this is C stuff. 主要观察结果是,除了了解Objective-C信号机制之外,大部分都是C的东西。 You're primarily using C arrays and references to make C function calls, both for OpenGL and CoreGraphics. 您主要使用C数组和引用来为OpenGL和CoreGraphics进行C函数调用。 So a prerequisite for coding this yourself is being happy in C, not just Objective-C. 因此,自己编码的先决条件是在C中感到高兴,而不仅仅是Objective-C。

The CoreGraphics stuff is a bit tedious but it's all just reading the docs to figure out how each type of thing relates to the next — none of it is really confusing. CoreGraphics的东西有点单调乏味,但它只是阅读文档来弄清楚每种类型的东西与下一种东西的关系 - 没有一个真的令人困惑。 Just get into your head that you need a data provider for the PNG data, you can create an image from that data provider and then create a bitmap context with memory that you've allocated yourself, draw the image into the context and then release everything except the memory you allocated yourself to be left with the result. 只需了解您需要PNG数据的数据提供者,您可以从该数据提供者创建一个图像,然后创建一个具有您自己分配的内存的位图上下文,将图像绘制到上下文中然后释放所有内容除了你自己分配的结果留给结果。 That result can be directly uploaded to OpenGL. 该结果可以直接上传到OpenGL。 It's relatively short boilerplate stuff, but OpenGL has no concept of PNGs and CoreGraphics has no convenient methods of pushing things into OpenGL. 这是一个相对较短的样板文件,但OpenGL没有PNG的概念,而CoreGraphics没有方便的方法将内容推入OpenGL。

I've assumed that textures are a suitable size on disk. 我假设纹理在磁盘上是合适的大小。 For practical purposes, that means assuming they're a power-of-two in size along each edge. 出于实际目的,这意味着假设它们在每个边缘都是一个2的幂。 Mine are 512x512. 我的是512x512。

The OpenGL texture management stuff is easy enough; OpenGL纹理管理很容易; it's just reading the manual to learn about texture names, name allocation, texture parameters and uploading image data. 它只是阅读手册来了解纹理名称,名称分配,纹理参数和上传图像数据。 More routine stuff that is more about knowing the right functions than managing an intuitive leap. 更常见的事情更多的是了解正确的功能而不是管理直观的飞跃。

For supplying the geometry to OpenGL I've just written out the arrays in full. 为了向OpenGL提供几何,我只是完整地写出了数组。 I guess you need a bit of a spatial mind to do it, but sketching out a 3d cube on paper and numbering the corners would be a big help. 我想你需要一点空间思维才能做到这一点,但在纸上画出一个三维立方体并对角落进行编号将是一个很大的帮助。 There are three relevant arrays: 有三个相关的数组:

  • the vertex positions 顶点位置
  • the texture coordinates that go with each vertex location 与每个顶点位置一起的纹理坐标
  • a list of indices referring to vertex positions that defines the geometry 引用定义几何的顶点位置的索引列表

In my code I've used 24 vertices, treating each face of the cube as a logically discrete thing (so, six faces, each with four vertices). 在我的代码中,我使用了24个顶点,将立方体的每个面视为逻辑上离散的东西(因此,六个面,每个面都有四个顶点)。 I've defined the geometry using triangles only, for simplicity. 为简单起见,我仅使用三角形定义了几何体。 Supplying this stuff to OpenGL is actually quite annoying when you're starting; 当你开始时,将这些东西提供给OpenGL实际上非常烦人; making an error generally means your program crashes deep inside the OpenGL driver without giving you a hint as to what you did wrong. 发生错误通常意味着你的程序在OpenGL驱动程序内部崩溃,而不会给你一个关于你做错了什么的提示。 It's probably best to build up a bit at a time. 最好一次建立一点。

In terms of a UIView capable of hosting OpenGL content, I've more or less used the vanilla stuff Apple directly supply in the OpenGL template. 对于能够托管OpenGL内容的UIView而言,我或多或少地使用了Apple在OpenGL模板中直接提供的vanilla。 The one change I made was explicitly to disable any attempted use of OpenGL ES 2.x. 我做的一个更改是明确禁用任何尝试使用OpenGL ES 2.x. 1.x is more than sufficient for this task, so we gain simplicity firstly by not providing two alternative rendering paths and secondly because the ES 2.x path would be a lot more complicated. 1.x对于这项任务来说已经足够了,所以我们首先通过不提供两个备选渲染路径来获得简单性,其次因为ES 2.x路径会更加复杂。 ES 2.x is the fully programmable pipeline with pixel and vertex shaders, but in ES land the fixed pipeline is completely removed. ES 2.x是具有像素和顶点着色器的完全可编程管道,但在ES域中,固定管道被完全移除。 So if you want one then you have to supply your own substitutes for the normal matrix stacks, you have to write vertex and fragment shaders to do 'a triangle with a texture', etc. 因此,如果你想要一个,那么你必须为普通的矩阵堆栈提供自己的替代品,你必须编写顶点和片段着色器来做'带纹理的三角形'等。

The touch tracking isn't particularly complicated, more or less just requiring me to understand how the view frustum works and how touches are delivered in Cocoa Touch. 触摸跟踪并不是特别复杂,或多或少只需要我了解视锥体如何工作以及如何在Cocoa Touch中提供触摸。 Once you've done everything else, this bit should be quite easy. 一旦你完成了其他所有事情,这一点应该很容易。

Notably, the maths I had to implement was extremely simple. 值得注意的是,我必须实现的数学非常简单。 Just the touch tracking, really. 只是触摸跟踪,真的。 Assuming you wanted a Google Maps-type view meant that I could rely entirely on OpenGL's built-in ability to rotate things, for example. 假设您想要一个谷歌地图类型的视图意味着我可以完全依赖OpenGL的内置旋转功能。 At no point do I explicitly handle a matrix. 在任何时候我都没有明确处理矩阵。

So, how long it would take you to write depends on your own confidence with C and with CoreGraphics, and how happy you are sometimes coding in the dark. 因此,你需要多长时间才能写出来取决于你对C和CoreGraphics的信心,以及你有时在黑暗中编码的快乐程度。 Because I know what I'm doing, the whole thing took two or three hours. 因为我知道我在做什么,整个过程需要两三个小时。

I'll try to find somewhere to upload the project so that you can have a look at it. 我会尝试找到上传项目的地方,以便您可以查看它。 I think it'd be helpful to leaf through it and see how alien it looks. 我认为翻阅它并看看它看起来多么陌生是有帮助的。 That'll probably give you a good idea about whether you could implement something that meets all of your needs within the time frame of your project. 这可能会让您对在项目的时间范围内是否能够实现满足所有需求的内容有所了解。

I've left the view controller as having exactly one view, which is the OpenGL view. 我已经将视图控制器保留为只有一个视图,这是OpenGL视图。 However, the normal iPhone compositing rules apply and in your project you can easily put normal controls on top. 但是,正常的iPhone合成规则适用,在您的项目中,您可以轻松地将常规控件置于顶部。 You can grab my little implementation at mediafire . 你可以在mediafire上抓住我的小实现。 StackOverflow post length limits prevent me from putting big snippets of code here, but please feel free to ask if you have any specific questions. StackOverflow帖子长度限制阻止我在这里放大代码片段,但请随时询问您是否有任何具体问题。

It's going to be pretty tough if you're learning OpenGL ES from scratch. 如果你从头开始学习OpenGL ES,那将是非常艰难的。 I'd use a graphics engine to do most of the heavy lifting. 我会使用图形引擎来完成大部分繁重的工作。 I'm currently playing Ogre3d, from what I've seen so far I can recommend it: http://www.ogre3d.org/ . 我正在玩Ogre3d,从我到目前为止看到的我可以推荐它: http ://www.ogre3d.org/。 It has Skybox (and much more) out of the box, and should be pretty straight forward to do. 它开箱即用Skybox(以及更多),应该非常直接。

I think you can do this, here are some links to help get you started: 我想你可以这样做,这里有一些帮助你入门的链接:

http://sidvind.com/wiki/Skybox_tutorial http://sidvind.com/wiki/Skybox_tutorial

common problems: 常见问题:

( i would post direct links but stackoverflow wont let me ) (我会发布直接链接但stackoverflow不会让我)

look on stackoverflow items no 2859722 and 2297564. 查看stackoverflow项目号2859722和2297564。

some programs and tips to help make the textures: 一些帮助制作纹理的程序和技巧:

spacescape spacescape

there are some great opengl tutorials here: 这里有一些很棒的opengl教程:

nehe.gamedev.net nehe.gamedev.net

they are not iphone specific, but they explain opengl pretty well. 它们不是特定于iPhone的,但是它们很好地解释了opengl。 i think some folks have ported these to the phone as well, i just cant find them now. 我想有些人也将这些移植到手机上,我现在无法找到它们。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM