向我上个教程说的那样,我厌倦了在屏幕上绘制白色的物体,让我们增加一些颜色,就象苹果模块自动生成的工程那样。下面我的介绍你要注意了,因为这些概念将在我们开始纹理渲染的时候起倒作用(很快的)
在OpenGL ES中,可以为整体物体设计一个单一的颜色块, 或可用多色和渲染的颜色转移,以便通过频谱从一个颜色过渡到下一个。在我们的物体上渲染单一的颜色不是很复杂。
象OpenGL的所有事情一样,在OpenGL中改变颜色是一个“状态”,那就是说,(改变状态)之后,绘制操作将使用这个颜色。 即使我们调用我们的“reset”正在glLoadIdentity ( ) (这是因为glLoadIdentity ( )上只运行实际顶点) 。所以我们只需要增加一行代码,就可以将我们两个物体修改为任意的颜色;没有什么颜色比白色更糟糕了,现在我就来修改为蓝色的。
开启XCode并来到drawView,在第一个 glLoadIdentity()之后增加下面的:
glLoadIdentity();
glColor4f(0.0, 0.0, 0.8, 1.0);
glColor4f()告诉OpenGL开始使用蓝色这个颜色来绘制(填充)。参数如下:
glColor4f( GLfloat red,
GLfloat green,
GLfloat blue,
GLfloat alpha);
在OpenGL ES中,你必须使用四个参数来定义颜色(RGBA),这里不能使用RGB的颜色。这点你千万别忘了,alpha是透明度的值,1.0表示实体,0.0表示全透明。
那个red,green,blue这三个参数是颜色的浮点值,0.0表示没有强度,1.0表示全强度。
点击编译并运行,你可以看到下面的图片:
比白色的好的太多了,下面让我们看看苹果模板里那彩色的旋转物体是如何实现的。
多重颜色
将一个物体变为多重颜色不需要很多的工作。我们需要定义一个象我们使用过的顶点数组那样的数组,并且告诉OpenGL从这个数组中获得颜色。在数组中的每个颜色,都对应了顶点数组里的一个顶点。
让我更清楚的认识到用颜色去渲染矩形。看下面的代码,在这里,我定义了一个颜色数组对应着矩形数组。
const GLfloat squareVertices[] = { -1.0, 1.0, 0.0, // Top left -1.0, -1.0, 0.0, // Bottom left 1.0, -1.0, 0.0, // Bottom right 1.0, 1.0, 0.0 // Top right }; const GLfloat squareColours[] = { 1.0, 0.0, 0.0, 1.0,// Red - top left - colour for squareVertices[0] 0.0, 1.0, 0.0, 1.0, // Green - bottom left - squareVertices[1] 0.0, 0.0, 1.0, 1.0, // Blue - bottom right - squareVerticies[2] 0.5, 0.5, 0.5, 1.0 // Grey - top right- squareVerticies[3] }; |
我希望这表示了颜色数组的每个值都对应了矩形顶点中的一个值。在我们通过运行前,我们需要增加一些代码,为了矩形渲染。
glLoadIdentity(); glTranslatef(1.5, 0.0, -6.0); glRotatef(rota, 0.0, 0.0, -1.0); glVertexPointer(3, GL_FLOAT, 0, squareVertices); glEnableClientState(GL_VERTEX_ARRAY); glColorPointer(4, GL_FLOAT, 0, squareColours); // NEW glEnableClientState(GL_COLOR_ARRAY); // NEW glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glDisableClientState(GL_COLOR_ARRAY); // NEW |
这里有三行新的代码,让我们一行行的解释:
glColorPointer(4, GL_FLOAT, 0, squareColours);
这和我们建立矩形顶点数组是类似的,这四个参数是:
1.Size-数组中颜色的数目
2.Data Format-我们在这里使用GL_FLOAT,因为我们在顶点数组中使用了浮点数。你也可以使用0-255的整形来定义。
3.Stride-再次,这里告诉OpenGL在两个值之间跳多少个数字。
4.Arry Points-这里是数据存储的地方。
这里需要注意下数据格式,GL_FLOAT是告诉OpenGL是什么参数格式(是一个枚举类型),GLfloat是宣布在OpenGL中使用什么数据类型。
Ok,这个函数告诉OpenGL,数据在哪里,格式是什么。但是,就象坐标顶点数组需要告诉OpenGL对物体使用坐标,我们需要给OpenGL一个必要的状态,告诉OpenGL当渲染物体的使用要使用我们的颜色
这就是:
glEnableClientState(GL_COLOR_ARRAY);
这就能将这个状态添加到OpenGL引擎中。不是通过 GL_VERTEX_ARRAY ,我们只需要告诉OpenGL颜色数组用 GL_COLOR_ARRAY 。
下一步,我们正常的绘制矩形。在绘制矩形后,我们需要关闭颜色数组,如果我们不这样做,那下个时刻我们绘制三角形的时候,我们还会象矩形那样使用颜色渲染,所以我们调用:
glDisableClientState(GL_COLOR_ARRAY);
这需要关闭OpenGL当前的颜色数组状态。如果我们没有这样做,那么第一次调用drawView的时候将绘制一个蓝色的三角形,而第二次调用drawView的时候将用颜色数组来绘制三角形。 但是,目前只有3个顶点的三角形的统筹阵列( triangleVerticies [ ] ) ,它只会使用前三个颜色。
修改好,运行如下:
如果你喜欢,关闭掉之前的旋转函数,看清楚每个顶点对应的颜色数组。
着色
如何通知矩形绘制从一个颜色到下一个?OpenGL使用了着色。这里有两个着色模型可以在OpenGL使用:GL_FLAT&GL_SMOOTH。GL_SMOOTH是默认的渲染。
为了显示它们的不同,在矩形的 glLoadIdentity ()函数之前,插入下面这行:
glShadeModel(GL_FLAT);
这个 glShadeModel ()函数改变了OpenGL中来自平滑的着色模式里的平面着色模式的状态。同样的, OpenGL的改变它的状态并保持这种状态,直到您告诉它需要修改,所以你可以把这行代码放在setupView函数里的任意地方,只要你喜欢。
点击“Build and Go”,通过着色的矩形改变为下面样子:
让我来解释下这里发生了什么。
三角形的渲染是正常的。做为一个平面颜色,着色并不会影响三角形的绘制。在来看看矩形,你现在可以清楚的看到OpenGL是用两个三角形来组成一个矩形的。 由于平面着色模式,只使用OpenGL的最后肤色填补每一个三角形,那就是squareColours [ 2 ] (蓝色)和squareColours [ 3 ] (灰色) 。如果你不能确定组成矩形的两个三角形的最后顶点是那个,你可以查阅原来的教程。
做一个总结:GL_SMOOTH是一个平滑着色,这就意味着当你开始填充一个矩形的时候,OpenGL将使用在我们 squareColours[] 数组里的默认颜色去定义在 squareVertices[] 数组里的每个顶点。 使用插值中每个像素的面积之间的点,顺利改变颜色之间的四点。换句话说,这将是我们出现彩色的矩形。
GL_FLAT是使用物体的的最后一个顶点的颜色去填充整个图元。矩形是由两个三角形组成的,所以我们看到2块颜色的三角形。
结论
好吧,我希望这对你是有益的。在现实生活中,你可能只是想使用GL_SMOOTH 作为着色,除非你做其中的一个怀旧的3D游戏从C64 days。 GL_SMOOTH是预设的,因此您不必启用它。
另外,请注意,你上面使用的颜色分类,也可用于纹理映射,所以我回到这个教程,重新看这两个。
纹理映射是指日可待了。我要告诉您如何创建一个三维物体在今后的教学课程。这将是平面彩色不过这没关系,因为我们将开始纹理映射在下面的教程。