iOS开发OpenGL ES教程(1)构成复杂物体基本绘图要素

移动开发 iOS
三角形是最“复杂”的图元,但是很容易使用,并且非常实用,这将是你可以绘制的第一个OpenGL的图元。当我们绘制一个三角形的时候,我们需要告诉OpenGL在3d空间中的三角形的3系坐标,并且,OpenGL将非常顺利的渲染这个三角形。

图元是构成复杂物体的基本绘图要素。在OpenGL ES中,你可以使用的图元有点,线,三角形。它们都有非常强的自我解释性,我觉得你需要有些例子让你看到它们。

首先,让我们来看看一些代码,然后我们可以谈论这是怎么回事,这样您就可以使用它来创建一些自己的代码。

三角形是最“复杂”的图元,但是很容易使用,并且非常实用,这将是你可以绘制的第一个OpenGL的图元。当我们绘制一个三角形的时候,我们需要告诉OpenGL在3d空间中的三角形的3系坐标,并且,OpenGL将非常顺利的渲染这个三角形。

在开始之前,复制00教程中的项目代码或者从这里下载下项目代码: AppleCoder-OpenGLES-00.tar.gz .在XCode中打开,开启EAGLView.m文件,找到drawView函数。这里就是施展魔法的地方。

首先,我们需要定义一个三角形。要做到这点,我们需要知道在我们要处理的坐标的两种类型:模型和世界。模型坐标是指我们正在绘制的实际图元,世界坐标告诉OpenGL观察者在哪里。(在世界坐标中,观察者一般在(0.0,0.0,0.0)的地方)

第一个例子将说明这点。首先,我们定义这个三角形在模型空间使用3 x 3d 坐标(x,y,z):

  1. const GLfloat triangleVertices[] = { 
  2.         0.0, 1.0, -6.0,// Triangle top centre 
  3.         -1.0, -1.0, -6.0,// bottom left 
  4.         1.0, -1.0, -6.0,// bottom right 
  5.     }; 

如上所示,这里使用了3个坐标来表示一个三角形,需要注意的是,我们定义三角形顶点是逆时针来显示的。虽然描述三角形的可以用逆时针也可以用顺时针,但是 我们必须和上述一样用逆时针来描述三角形。不过,我建议你用逆时针来描述三角形,因为我们以后可以用逆三角形来达到一些先进的功能。

(补充:逆三角形在3d中被认为是正面,而顺三角形则被认为是反面。在纹理渲染中被使用到)

虽然本教程应该是纯粹的iPhone OpenGL ES的,对于初学者来说,我会简要的描述三维坐标系统。看看这张图片:

对于我的绘画技巧,我深表遗憾。不过这个图代表了模型空间和世界空间。 试想一下,这是您的计算机屏幕, X和Y的横向和纵向的,你应该预料到, Z表示深入。这个中心位置就是(0.0,0.0,0.0).

所以,看我们的三角形中所描述的顶点上述情况,第一点( 0.0 , 1.0 , -6.0 )中心将在的Y轴,上涨1点,在屏幕的深度为6点。 第二个坐标是右边的Y轴1.0点,低于X轴(因此-1.0的Y值) ,仍然回到屏幕-6.0点。这同样适用于第三个坐标。

为此,我们确定目标在我们眼睛之前(z值是负的),所以这个目标是可见的(记得吗,观察者或者说照相机是在(0.0,0.0,0.0)的位置上)所以说OpenGL的深度测试是失败的并且它没有被渲染。

我可以听到你尖叫“嘿,我还以为你说,这是模型坐标不是世界坐标! ” 。 是的,这是对的,但是,当我们去渲染这个三角形之前, OpenGL的将只是把对象放在( 0.0 , 0.0 , 0.0 ) 的位置上。 因此,我们将它放到屏幕内才可见。 当我们进入转换(移动,旋转等) ,您会看到,您将不必设置对象Z值为负,也可以使之可见。在此之前,让目标的Z坐标在-6.0的位置上。

绘制函数:

所以我们这样做是为了说明目前的三角形。我们现在需要告诉OpenGL,数据保存在哪里,以及如何去绘制它。这个过程只需要很少的几行代码。回到drawView函数,并且实行以下的代码:

  1. - (void)drawView { 
  2.  
  3. const GLfloat triangleVertices[] = { 
  4.         0.0, 1.0, -6.0,                    // Triangle top centre 
  5.         -1.0, -1.0, -6.0,                  // bottom left 
  6.         1.0, -1.0, -6.0                    // bottom right 
  7.     }; 
  8.  
  9.     [EAGLContext setCurrentContext:context]; 
  10.     glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer); 
  11.     glViewport(0, 0, backingWidth, backingHeight); 
  12.  
  13. // -- BEGIN NEW CODE 
  14.  
  15. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
  16.  
  17. glVertexPointer(3, GL_FLOAT, 0, triangleVertices); 
  18. glEnableClientState(GL_VERTEX_ARRAY); 
  19. glDrawArrays(GL_TRIANGLES, 0, 3); 
  20.  
  21. // -- END NEW CODE 
  22.  
  23.     glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer); 
  24.     [context presentRenderbuffer:GL_RENDERBUFFER_OES]; 
  25.  
  26. [self checkGLError:NO]; 

如你所见,这4行代码就是我们渲染一个三角形的。让我们从上往下一行行的打断这些代码来分析,你会发现它们是非常的简单。

  1. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

这行代码只是简单的清除了屏幕。这个控制位告诉OpenGL,我们使用上次教程里面setupView函数中设置的颜色(黑色)来清除屏幕,并且清除了深度 缓冲。 请注意,如果我们没有创建深度缓冲和开启深度缓冲(如我们应该做的),这个屏幕将不会渲染。如果我们不使用深度缓冲,我们将不需要通过glClear() 里的 GL_DEPTH_BUFFER_BIT.

因此,我们无论是清除以前绘制的这个缓冲区(请记住,这是双重缓冲动画;利用一个缓冲区而另一个缓冲区显示) 。

  1. glVertexPointer(3, GL_FLOAT, 0, triangleVertices);  

此函数告诉OpenGL的情况下我们的数据是什么格式,它是有4个参数,这个功能是很简单细分:

1.Size-这个值表示了每个坐标有几个数字。我们现在是3,是因为是3d坐标(x,y,z).如果我们使用2d绘制,不加入深度(就是z),我们只要在这里写2就可以了。

2.Data Type- GL_FLOAT 意味着我们用float点值。 您也可以使用整数值,但如果你想你需要习惯于使用浮点值的3D世界的浮点运算。

3.Stride -  这个stride告诉OpenGL 在每个坐标之间忽略哪几个点。别对这个表示疑惑,保持它是0就行了。你使用它

当您载入顶点数据文件的格式有更多的填充数据或肤色的数据,也就是说,一个3D程序像搅拌机。

4.Pointer to the Data – 数据本身,正是因为它,三角形才会出现。

因此,我们告诉OpenGL清除缓冲区,告诉它的数据是我们的目标和它的格式,现在我们需要告诉OpenGL的东西很重要:

  1. glEnableClientState(GL_VERTEX_ARRAY); 

OpenGL 是一个状态机。 这意味着你打开和关闭功能的要求就是启用和禁用命令。之前,我们使用过glEnable(),这影响到OpenGL的服务。 glEnableClientState ()影响到我们的程序方面(就是客户端面)。所以我们要做的就是告诉OpenGL我们顶点数据是一个顶点数组并且转换到OpenGL的绘制顶点功能。在这 个情况下,顶点可以是一个颜色数组,我们将呼叫 glEnableClientState (GL_COLOR_ARRAY)或者一个纹理坐标数组如同纹理映射。(别垂涎三尺,你需要掌握所有的基本知识包括纹理映射)

随着我们进一步的研究OpenGL ,我们会使用不同的客户端状态,这将使用变得更为清晰。

现在命令OpenGL渲染一个三角形。

  1. glDrawArrays(GL_TRIANGLES, 0, 3); 

一旦这个方法被调用,OpenGL将用我们之前的两个函数的信息开始执行。屏幕中间出现一个白色的实心的三角形(白色是默认的绘制颜色)。现在的三角形是一个实心的,如果你需要一个镂空的三角形,你将要用不同的绘制方法。

分析这个方法里的三个参数:

1.Drawing Method- 在这种情况下,我们已通过GL_TRIANGLES这似乎相当明显,因为我们画一个三角形。然而,这一方法的第一个参数将变得很明显,当我们使用此功能,来绘制一个平面体。

2.First Vertex- 我们阵列只有3点,所以我们想要的OpenGL提请第一坐标的数组,这里指定零就像进入一个标准数组。 如果我们有多种原始的顶点数组,我们可以在这里处理。我会在以后的教程教你,当我告诉您该如何建立复杂的物体的时候。现在,这里只要使用0。

3.Vertex Count-这将告诉OpenGL在我们的数组中有多少顶点需要被绘制。比如说,我们绘制一个三角形,所以至少要3点,一个平方形需要4点,一个线需要2点(或更多),一个点需要一个(或者多点)

当你把这些代码都输入到你的drawView函数里面以后。点击“Build and Go”运行这个程序在模拟器里面。你的模拟器应该看起来象如下的图:

如我们所说的,有一个实心的白色的三角形出现在屏幕的中间。

在我们做其他的图元之前,尝试修改z值,你就会明白我所说的是什么意思。如果你把z改为0,你将什么也看不到。

如果你自己输入几行代码,我希望你可以来发现OpenGL ES 是如何工作的。如果你学习过“标准”的OpenGL的教程,我希望你可以发现OpenGL与OpenGL ES的不同。

期待。。。

下个教程将着重于扩大代码量并生产一个平方形。

责任编辑:闫佳明 来源: cocoachina
相关推荐

2013-09-26 14:09:31

iOS开发OpenGL ES教程绘制矩形

2014-04-29 14:16:54

2014-04-24 13:35:11

OpenGL ES2.iOSAndroid

2014-04-29 14:27:59

OpenGL ES 2Android绘制纹理

2014-04-29 14:49:37

OpenGL ES 2Android应用投影

2010-01-12 16:05:46

VB.NET绘图

2011-08-10 18:24:22

iPhone 图形 绘图

2014-04-24 13:26:24

OpenGL ES2.iOSiPhone

2014-04-24 11:16:00

OpenGL ES 2入门

2013-07-05 14:45:05

AndroidOpenGL ES开发

2023-04-25 09:53:30

开发者计算

2010-02-14 15:27:25

2013-04-26 11:17:48

2011-07-08 14:58:16

iPhone Xcode iOS

2014-04-29 14:05:02

OpenGL ESAndroid添加动作

2017-07-19 15:25:16

iOS开发ARKitOpen GL

2017-07-04 12:26:14

ARARKit

2014-04-24 14:00:35

OpenGL ES 2编程

2014-05-05 10:01:51

数据可视化

2017-07-06 15:02:53

OpenGL ES架构GPU
点赞
收藏

51CTO技术栈公众号