文档库 最新最全的文档下载
当前位置:文档库 › OPENGLES1

OPENGLES1

OPENGLES1
OPENGLES1

西蒙-iphone-OpenGL ES

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

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

图1

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

在3d空间里的2d

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

这就是所谓的正投影。本教程系列的目的就是让你掌握

3d,我将不会在正投影做重复介绍;当然,以后也许会。但现在,我们把精力保持在3d上。

启用深度缓冲

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

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

#define USE_DEPTH_BUFFER0

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

现在,我们需要在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

//这个给我们在iphone中显示的尺寸大小

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);

}

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

glEnable(GL_DEPTH_TEST);

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

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

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

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

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

#define USE_DEPTH_BUFFER1

#define DEGREES_TO_RADIANS(__ANGLE)((__ANGLE)/180.0*M_PI) Draw View-绘制函数

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

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

-(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];

}

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

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

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

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

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

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

[self setupView];

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

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

EAGLView.h

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

-(void)setupView;

-(void)checkGLError:(BOOL)visibleCheck;

本教程结束。。。。

下一步:

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

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

AppleCoder-OpenGLES-00.zip

相关文档