您的位置:首页 > 运维架构

OpenGL ES 00 - Xcode Project Set Up

2010-04-02 16:26 316 查看
OpenGL ES on the iPhone is a cinch to set up with Xcode, especially
since Apple introduced the template with the SDK release. All we really
need is a place where you can get to and start adding in code quickly
and easily. This is what we’re going to do today.

关于iPhone的 OpenGL ES是建立在Xcode下,苹果推出的sdk版本中包含这个模板。我们要做的的就是帮助您建立这个模板,并在真正需要的地方方便快捷的添加有用的代码。这就是我们今天要做的。

To be quite honest, I really don’t think that it’s necessary to
type everything in from this and if you just want to get into the
meatier OpenGL tutorials which follow, skip this by all means. In this
case, there’s nothing wrong with skipping the set up as I’m not going
to go into the detail of it. Just head down to the end of this tutorial
and download the project file.

说实话,我真的不认为你有必要看这篇文章如果你只想很快进入OpenGL的学习,你完全可以跳过他。直接到最下面去下载项目文件就可以了。

Start by firing up Xcode and creating a new project. Choose the
template called: “OpenGL ES Application” (Figure 1) and save the
project somewhere convenient for you.

打开 XCode并创建一个新的工程。选择”OpenGL ES Application”(图1),并且保存工程在你经常使用的位置。



图1

OK, I’m going to assume at this point that you’ve probably
already had a quick look around this template at some point in the
past, probably had a look at the running application. What we’re going
to do is to remove the code for the spinning coloured square and
convert the view to use a depth buffer (ie make it “true” 3D). This
will give us a space for our tutorials.

好吧,我要承认一点,你之前可能快速浏览过模板,或者看过模板的运行程序。我们要做的就是删除自旋的彩色立方体的代码,并添加用深度缓冲来转换视图(让它看起来更象是一个真的3d)。这将为我们的教程提供一个空间。

2D in a 3D Space

在3d空间里的2d

Like this Apple template, most OpenGL tutorials start off by
ignoring depth, usually using a 2 point co-ordinate system (X, Y)
rather than the more standard 3 co-ordinate system (X, Y, Z). You may
have noticed that the vertices for the square in Apple’s template only
uses the (X, Y) co-ordinates, that’s because they are not using depth!

像这个苹果的模板一样,大多数的OpenGL教程都是从忽略深度(缓冲)开始,通常使用2点的坐标系统(x,y),而不是更为标准的3点的坐标系(x,y,z)。你可能已经注意到了,苹果模板里的立方体的顶点只使用了(x,y)的坐标,这是因为他们没有使用深度。

This is called Orthographic projection. As the goal of this
tutorial series is to get you to 3D, I’l not going to cover
orthographic projection at this point; maybe later in the series but
for now, we’re going to keep heading into 3D.

这就是所谓的正投影。本教程系列的目的就是让你掌握3d,我将不会在正投影做重复介绍;当然,以后也许会。但现在,我们把精力保持在3d上。

Enabling Depth Buffer

启用深度缓冲

The first thing we need to do is to enable the depth buffer.
Apple’s example square is only a 2D object so doesn’t actually need a
depth buffer. We need depth so we’ll enable it. Apple has kindly
provided the code to setup the depth buffer so we’ll just take
advantage of it.

第一件事我们需要启动深度缓冲。苹果的例子中,正方形只是一个2d的物体,所以实际上不需要深度缓冲。我们需要深度所以我们启用它。苹果热心的提供了关于设置深度缓冲的代码,所以我们只需要利用它。

Open EAGLView.m in the editor and look for the following line:

打开 EAGLView.mm在编辑区,看下面这行代码:

#define USE_DEPTH_BUFFER 0

Needless to say, change that 0 to a 1. This will turn on the code in
the view setup area to create the depth buffer. This code is contained
in the createFrameBuffer method. Don’t worry too much about this method
at the moment. It’s written by Apple so just accept it does what it’s
supposed to.

不用说,将0修改为1。这将打开视窗里的设置区域并创建深度缓冲。这个代码包含在createFrameBuffer这个函数中。此刻不要对这个函数担心太多。这是苹果写的,必然支持这样的写法。

Now, we need to enable depth testing within OpenGL. To do this,
we do need to create a new method which will be called once to enable
our view to work. Start by creating a new method called setupView and
insert the following code into this new method:

现在,我们需要在OpenGL内部启用深度缓冲。要做到这一点,我们需要创建一个新的函数,这个函数将被启用在我们视窗工作的时候。我们开始创建一个新的函数,叫 setupView 并且将下列的代码添加到这个新的函数里。

- (void)setupView {

const GLfloat zNear = 0.1, zFar = 1000.0, fieldOfView = 60.0;

GLfloat size;

glEnable(GL_DEPTH_TEST);

glMatrixMode(GL_PROJECTION);

size = zNear * tanf(DEGREES_TO_RADIANS(fieldOfView) / 2.0);

// This give us the size of the iPhone display

CGRect rect = self.bounds;

glFrustumf(-size, size, -size / (rect.size.width / rect.size.height), size / (rect.size.width / rect.size.height), zNear, zFar);

glViewport(0, 0, rect.size.width, rect.size.height);

glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

}


All this code does is set up the conditions in which OpenGL will
operate by creating a View Port which will be mapped to the actual size
of our display. Like I said, I’ll go into detail about this later on
but for now, just take note of the following:

所有的这些代码的作用是设置OpenGl的参数,它将操作于创建一个视窗端口正在被映射到我们显示的实际大小。就象我说的一样,我将详细谈这点,但现在,只需要注意以下内容:

glEnable(GL_DEPTH_TEST);

This enables the Depth Testing in OpenGL. You need to remember
that once you turn something “on” in OpenGL, you need to turn it off
later if you don’t want to continue using it. As we will only turn on
depth testing and never turn it off, it can go here in the view setup.

这将在OpenGL中启用深度测试。你必须记得,一旦你在OpenGL中将某些事物改为“开启”,你必须在不要使用它的时候关闭它。我们开启了深度测试并且不再关闭它,它可以在视窗的这里设置。

glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

What we’re doing here is defining what colour to use when we
clear the screen. All colours in OpenGL ES must be RGBA values (ie Red,
Green, Blue, Alpha), and cannot just be RGB values as in OpenGL. So,
later on when we clear our screen, OpenGL ES will already know we want
it cleared in a black colour. It will continue to use this colour until
we change it.

我们要做的就是用默认的颜色去清除屏幕。在OpenGL ES中使用的所有颜色都必须是是RGBA值,而不是在OpenGL中的RGB值,所以当我们清除屏幕,OpenGL ES就知道我们要用黑色来清除屏幕。它将继续使用这个颜色直到我们改变它。

The colour values can be 0 -> 1 if using floating point or 0
-> 255 if using unsigned bytes. The higher the value, the higher the
colour intensity.

这个颜色的值范围,浮点是0-1,无符号数是0-255。这个颜色的值越高,这个颜色的强度也越高。

OK, back to the top of the file and find the #define we had
changed earlier. We just need to install a macro here which is needed
for the setupView method we just inserted.

Ok,返回文件的开头,到我们刚才修改的 #define的地方。我们需要在这里定义一个宏,这个宏将在 setupView函数中使用到。

#define USE_DEPTH_BUFFER 1

#define DEGREES_TO_RADIANS(__ANGLE) ((__ANGLE) / 180.0 * M_PI)

Draw View - The drawing method

Draw View -绘制函数

Now, go down to the drawView method. This is where everything
happens in our tutorials. You can see here where Apple has even given
us a pointer to the fact this is where we’re going to be doing our
work.

现在,到下面的 drawView 函数。在我们的教程中,发生的所有事都在这里。你可以在这里看到,苹果给了我们一个事实上的指针,这正是我们需要做的工作。

First of all, delete everything in this method, and replace the contents with the following code:

首先,删除一切这个函数中的代码,并用我们下面的代码去填充它。

- (void)drawView {

[EAGLContext setCurrentContext:context];

glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);

glViewport(0, 0, backingWidth, backingHeight);

glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);

[context presentRenderbuffer:GL_RENDERBUFFER_OES];

}


The first three lines of the code above, just sets up our
drawing space. The last two lines swaps our drawing space with the
space which is currently viewed on screen. If you’ve ever done
animation or game programming before, you’ll know that this is what’s
called “double buffered”.

上面的头三行代码,就是设置我们的绘制空间。后面两行代码,将我们的绘制空间与屏幕显示空间互换。如果你之前做过动画或游戏的编程,你会知道,这就是所谓的“双缓冲”。

For those who don’t know, what this means is that we create two
identical buffers: one which is displayed to the user, the other is
cleared and we draw on it. When we finish drawing, we swap the views so
the user sees the new view. The reason why we go to all this trouble is
to make the animation smooth.

对于那些不知道的朋友呢,我们再解释一下,我们创建了两个缓冲界面,一个用于给用户显示,一个我们清除掉并且我们在它上面进行绘制。当我们完成绘制后,我们就翻转视窗,那么用户就看到了新的视窗。为什么我们要搞的这么麻烦呢?这是为了要动画流畅。

We’re not going to add any more code to make this display anything at the moment, we’ve still got some more set up to do.

此刻,我们不要为了显示添加任何代码了,我们仍然要做一些设置工作。

Firstly, right before the dealloc method, insert the following code:

首先,在dealloc函数之前,插入以下的代码:

- (void)checkGLError:(BOOL)visibleCheck {

GLenum error = glGetError();

switch (error) {

case GL_INVALID_ENUM:

NSLog(@"GL Error: Enum argument is out of range");

break;

case GL_INVALID_VALUE:

NSLog(@"GL Error: Numeric value is out of range");

break;

case GL_INVALID_OPERATION:

NSLog(@"GL Error: Operation illegal in current state");

break;

case GL_STACK_OVERFLOW:

NSLog(@"GL Error: Command would cause a stack overflow");

break;

case GL_STACK_UNDERFLOW:

NSLog(@"GL Error: Command would cause a stack underflow");

break;

case GL_OUT_OF_MEMORY:

NSLog(@"GL Error: Not enough memory to execute command");

break;

case GL_NO_ERROR:

if (visibleCheck) {

NSLog(@"No GL Error");

}

break;

default:

NSLog(@"Unknown GL Error");

break;

}

}


OpenGL has an error checking method as called above
(glGetError()) but the error code returned needs to be manually
converted to a human readable message from the error code. That is what
the above method does.

OpenGL 有一个错误检测的函数,叫做(glGetError()),但是这个函数返回的出错信息,我们要手动转换下,不然开发者将无法阅读。这个就是上面这个函数的作用。

The BOOL parameter “visibleCheck” is only there so that
sometimes you can check and see that the routine was called and when
there are no errors.

这个bool参数“visibleCheck”只能在这,有时候你可以检测并且看到这个例子调用,并且这时候他们没有错误。

The last thing we need to do in EAGLView.m is to go to the
initWithCoder method and actually call the “setupView” method we
created earlier. Below the setting of the variable “animationInterval”,
insert the following to call the setupView method:

最后一件事,我们需要回到 EAGLView.m 文件中,进入initWithCoder函数,并且调用我们之前创建的”setupView”函数。接下来设置” animationInterval”的值,插入下列代码来调用setupView函数。

[self setupView];


Note of course that we could have put the setupView method’s
code in the initWithCoder method rather than create a new method, as
generally it’s only ever called once.

需要注意下,我们当然可以将setupView函数代码直接写在initWithCoder函数中而不是创建一个新的函数,这样的方式通常仅仅适用于只调用一次的情况下。

OK, done in EAGLView.m; Switch to EAGLView.h!

好了,关掉EAGLView.m,看 EAGLView.h

EAGLView.h

Fortunately, there is not much work to be done here. All we need
to do is to create the prototypes for the two methods we created as
follows:

幸运的是,我们不需要在这里做很多的工作。我们只需要创建两个函数的原型,代码如下:

- (void)setupView;

- (void)checkGLError:(BOOL)visibleCheck;

And that’s us done for this tutorial.

本教程结束。。。。

Next Steps...

下一步:

If you were to build and run this in the simulator, you’d just
get a blank screen and nothing interesting would happen. In the next
tutorial, we’re going to start drawing primitives on the screen,
primitives are just basic drawings like points, lines and triangles.

如果你编译并且在模拟器中运行本例,你只会获得一个黑色的屏幕并且不会发生任何有趣的事。在下一个教程中,我们将开始在这个屏幕中绘制图元,图元是基本单元,如点,线,三角形。

For those of you who just want to download the project files and not type it all in, here it is:

如果你只想下载项目文件,在下面下载。

AppleCoder-OpenGLES-00.zip

The home of the tutorials is in the “Tutorials” section of the iphonedevsdk.com forums. Check out the thread there.

这篇教程的主页在iphonedevsdk.com这个论坛的"Tutorials"里面。

Until then, hooroo!

梦想实现中 嘿嘿

Simon Maurice

Copyright 2009 Simon Maurice. All Rights Reserved.

The code provided in these pages are for educational purposes
only and may not be used for commercial purposes without Simon
Maurice’s expressed permission in writing. Information contained within
this site cannot be duplicated in any form without Simon Maurice’s
expressed permission in writing; this includes, but is not limited to,
publishing in printed format, reproduced on web pages, or other forms
of electronic distribution.

Linking to these pages on other websites is permitted.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: