openGl ES(二)

- (void)drawView:(UIView *)theView

{

//Draw code here

    static      GLfloat rotation = 0.0;

    

    Vertex3D    vertex1 = Vertex3DMake(0.0, 1.0, -3.0);

    Vertex3D    vertex2 = Vertex3DMake(1.0, 0.0, -3.0);

    Vertex3D    vertex3 = Vertex3DMake(-1.0, 0.0, -3.0);

    Triangle3D  triangle = Triangle3DMake(vertex1, vertex2, vertex3);

    

    glLoadIdentity();

    glRotatef(rotation, 0.0, 0.0, 1.0);

    glClearColor(0.7, 0.7, 0.7, 1.0);

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glEnableClientState(GL_VERTEX_ARRAY);

    glColor4f(1.0, 0.0, 0.0, 1.0);

    glVertexPointer(3, GL_FLOAT, 0, &triangle);

    glDrawArrays(GL_TRIANGLES, 0, 9);

    glDisableClientState(GL_VERTEX_ARRAY);

    

    rotation+= 0.5;

}

 


Vertex3D    vertex1 = Vertex3DMake(0.0, 1.0, -3.0);
    Vertex3D    vertex2 = Vertex3DMake(1.0, 0.0, -3.0);
    Vertex3D    vertex3 = Vertex3DMake(-1.0, 0.0, -3.0);

你应该注意到了三个顶点的z值是一样的,其值(-3.0)是处于原点 “之后”的。因为我们还没有做任何改变,所以我们是站在原点上观察虚拟世界的,这是默认的起点位置。将三角形放置在z值为-3处,可以保证我们可以在屏幕上看到它。

将其视为OpenGL的“复位开关”。它将清除虚拟世界中的一切旋转,移动或其他变化并将观察者置于原点。

    glLoadIdentity();

之后,我们告诉OpenGL所有的绘制工作是在一个灰色背景上进行的。OpenGL通常需要用四个钳位值来定义颜色。上一篇文章中有提过,钳位浮点数是0.0 到 1.0之间的浮点数。我们通过定义红,绿,蓝以及alpha元素来定义颜色, alpha值定义了颜色之后物体的透视程度。现在暂时不用管它,将其设为1.0,代表完全不透明。

    glClearColor(0.7, 0.7, 0.7, 1.0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
第二行是通知OpenGL清除以前的一切图形并将其设为clear颜色。你可能想知道 glClear()的两个参数是什么意思。简单地说,它们是存储与位域中的常量。OpenGL 保存了一系列 缓存(buffers),即用于绘图各方面的内存块。将这两个值进行逻辑或是通知OpenGL清除两个不同的缓存 – 颜色缓存(color buffer) 和 深度缓存(depth buffer)。

 颜色缓存保存当前帧各像素的颜色。基本上就是你在屏幕上看到的。深度缓存(有时也称为“z-buffer”)保存每个潜在像素离观察者距离的信息。使用此信息可以确定一个像素是否需要被绘制出来。这两个缓存是OpenGL中最常见的缓存。还有其他一些缓存,如模板缓存(stencil buffer)和累积缓存(accumulation buffer),但现在我们暂时不讨论这些。我们现在只需记住在绘制一帧之前,必须清除这两个缓存以保证不会和以前的内容混杂。


然后,我们要启动OpenGL的一项称为vertex arrays(顶点数组)的特性。此特性可能只需要setupView:方法中启动一次,但作为基本准则,我喜欢启动和禁止我使用的功能。你永远也不会知道是否另一段代码会做不同处理。如果你打开你需要的功能然后关闭它,产生问题的几率将大为减小。就本例来说,如果另一个类不使用顶点数组而使用顶点缓存的话,任何一段代码遗留了启动了的特性或没有显性启动其需要的特性,这一段或两段代码都会导致不可预知的结果。

    glEnableClientState(GL_VERTEX_ARRAY);

接下来我们设置了绘图时所需的颜色。此行代码将绘图颜色设为鲜艳的红色。

    glColor4f(1.0, 0.0, 0.0, 1.0);

由于我们使用顶点数组,我们必须通知OpenGL顶点的数组在什么地方。记住,顶点数组只是一个GLfloat的C数组,每三个值代表一个顶点。我们创建了Triangle3D 对象,但在内存中,它完全等同于9个连续的GLfloat, 所以我们可以传递此三角形对象的地址。

    glVertexPointer(3, GL_FLOAT, 0, &triangle);

glVertexPointer() 的第一个参数指示了多少个GLfloat代表一个顶点。根据你是在进行二维或三维绘图,你可以传递2或者3。

然后,我们传递一个枚举值告诉OpenGL顶点是由GLfloat构成。

我们通知OpenGL通过刚才提交的顶点数组来绘制三角形。

    glDrawArrays(GL_TRIANGLES, 0, 9);

随后,我们通知OpenGL通过刚才提交的顶点数组来绘制三角形。

    glDrawArrays(GL_TRIANGLES, 0, 9);

你可能已经可以猜到,第一个枚举值是告诉OpenGL绘制什么。尽管OpenGL ES不支持绘制三角形之外的四边形或其他多边形,但它仍然支持一些其他绘图模式,如绘制点,线,线回路,三角形条和三角形扇



当处理这类复杂的几何体时,有一种方法可以避免多次传递同一个顶点,就是使用通过顶点对应于顶点数组中的索引的方法,此方法称之为元素(elements)。其原理是创建一个每个顶点只使用一次的数组。然后使用另一个使用最小的无符号整型数的数组来保存所需的唯一顶点号。换句话说,如果顶点数组具有小于256个顶点,那么你应创建一个GLubyte数组,如果大于 256,但小于 65,536,应使用 GLushort。你可以通过映射顶点在第一个数组中的索引值来创建三角形(或其他形状)。所以,如果你创建了一个具有12个顶点的数组,那么数组中的第一个顶点为0。你可以按以前一样的方法绘制图形,只不过不是调用glDrawArrays(),而是调用不同的函数 glDrawElements()并传递整数数组。


记住:如果你按绘制的正确次序提供顶点,那么你应该使用glDrawArrays(),但是如果你提供一个数组然后用另一个以索引值区分顶点次序的数组的话,那么你应该使用glDrawElements()

请花些时间测试绘图代码,添加更多的多边形,改变颜色等。OpenGL绘图功能远超过本文涉及的内容,但你应该清楚iPhone上3D物体绘制的基本概念了:创建一块内存保存所有的顶点,传递顶点数组给OpenGL,然后由OpenGL绘制出来。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值