绘图工具箱。在这个工具箱中,有用来绘图的工具。
正常画家的工具箱中会有画笔,画刷,铅笔,橡皮等。
在OpenGL绘图工具箱中,有清除窗口的工具,指定绘图颜色的工具,强制完成绘图的工具,描述坐标系统的工具。而这些工具,其实就是一些函数。
清除窗口
如果把窗口比喻成一块黑板,那么清除窗口,就是擦黑板。但是不同的是,这个清除窗口,可以把窗口清除为某种特定背景色,比如绿色。
要以指定的颜色清除窗口,先要来了解颜色在OpenGL中的表示。在OpenGL中,颜色有两种表示方法,RGBA颜色模式和索引模式。
RGBA颜色模式就是通过指定组成颜色的三种基本颜色,红绿蓝的颜色值,然后通过这三种基本颜色组合成一种混合颜色。至于RGBA中的A,这个表示透明度,在以后颜色混合时再用到。
而颜色索引模式,就是事先定义了一些颜色,把这些颜色保存起来,然后通过索引对这些颜色进行访问,有点类似于通过数组下标去访问数组中的元素。
在OpenGL中,指定清除窗口,有两个相关的函数,一个函数用来指定清除窗口的颜色,这个函数叫glClearColor,一个函数用来执行实际清除操作,这个函数叫glClear。
下面两行代码把一个RGBA模式的窗口清除为黑色:
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
glClearColor的作用就是指定窗口清除颜色,其中四个参数分别是RGBA的值。RGBA这几个分量的取值范围限定在[0, 1]之间。默认的清除颜色是(0.0, 0.0, 0.0, 0.0), 也就是黑色。
glClear,清除指定的缓冲区,参数表示要清除哪个缓冲区,可以是几个缓冲区的组合。主要有4个缓冲区,如下表所示:
缓冲区 | 名称 |
---|---|
颜色缓冲区 | GL_COLOR_BUFFER_BIT |
深度缓冲区 | GL_DEPTH_BUFFER_BIT |
累积缓冲区 | GL_ACCUM_BUFFER_BIT |
模板缓冲区 | GL_STENCIL_BUFFER_BIT |
如果要同时清除颜色缓冲区和深度缓冲区,则可以这样用
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
指定颜色
上面已经知道了,颜色在OpenGL有两种表示方法,RGBA表示 或者 颜色索引表示。
在OpenGL中,要绘制一个红色矩形,只需要先指定绘制颜色,然后在绘制物体,就可以了。
指定绘制颜色,RGBA模式下是通过glColor*函数来设置的, 颜色索引模式下是通过glIndex*来设置的 ,但是这个颜色索引模式通常不怎么用。比如指定绘制颜色为红色,代码如下:
glColor3f(1.0, 0.0, 0.0);//红色分量为1,绿色和蓝色分量为0
指定完绘制颜色之后,直接绘制物体就可以了。比如下面的伪代码,画一个红色的A和一个绿色的B。
glColor3f(1.0, 0.0, 0.0);
draw_object(A);
glColor3f(0.0, 1.0, 0.0);//绿色分量为1
draw_object(B);
好,就这样。指定绘制物体的颜色,然后绘制物体即可。
强制完成绘图操作
为什么要强制完成绘图操作呢?因为我们指定的OpenGL函数的绘图操作,只是告诉硬件,你去完成这些绘图操作。但是硬件并不保证很快就能完成,硬件可能因为其他的一些事情,耽误了绘图操作。而强制完成绘图操作,就是告诉硬件,我这些绘图操作很重要,你立刻给我绘图。
有两个函数,用来强制完成绘图操作。一个叫glFlush,一个叫glFinish。这两个的区别就是,glFlush是异步的,而glFinish是同步的。说白一点,就是glFlush是去催硬件赶紧完成绘图,但是催完之后,自己又不管了,该干啥干啥。而glFinish则是催硬件赶紧完成绘图操作,催完之后,自己在那里等着,直到硬件完成绘图操作。
坐标系统工具箱
坐标系统,有两个要素,坐标原点和坐标轴。而OpenGL中,坐标轴的方向,其实已经定了。OpenGL使用的是右手坐标系。至于坐标原点,以及坐标的大小设置,则是通过函数gluOrtho2d来实现的,这里只指2维坐标系统。
由于窗口的大小发生改变时,需要使用新的窗口,作为OpenGL的画布。画布大小的改变,导致我们需要绘画的区域的范围变化,为了让画布大小,与我们绘制物体的大小对应起来,通常在reshape函数中,重新定义坐标系统。
GLUT使用glutReshapeFunc(reshape)注册reshape函数,当窗口大小发生变化时,会调用reshape函数。然后在reshape函数中,可以重新指定画布大小,重新指定坐标系统,如下所示:
void reshape(int w, int h)
{
glViewPort(0, 0, (GLsize)w, (GLsize) h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, (GLdouble) w, 0.0, (GLdouble) h);
}
总感觉这一小节 理解起来有点牵强,先这样了。