OpenGL 支持两种颜色模式:一种是RGBA,一种是颜色索引模式。无论哪种颜色模式,计算机都必须为每一个像素保存一些数据。不同的是,RGBA模式中,数据直接代表了颜色;而颜色索引模式中,数据代表的是一个索引,要得到真正的颜色,还须差索引表。RGBA模式中,每一个像素会保存以下数据:R值(红色分量)、G值(绿色分量)、B值(蓝色分量)和A值(alpha分量)。
1、glClearColor ( )设置颜色缓存的清除值
glClearColor ( ) 就是用来设置这个 “ 底色 ” 的,即所谓的背景颜色。glClearColor ( ) 只起到Set 的作用,并不Clear 任何。
void glClearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); //红、绿、蓝和 alpha 值,指定值范围均为[ 0.0f,1.0f ]
2、glClear ( ) 将缓存清除为预先的设置值
glClear ( ) 是用来清除屏幕颜色,即将屏幕的所有像素点都还原为 “底色 ”。
void glClear(GLbitfield mask);
mask 对指定需要清除的缓存进行按位或屏蔽操作,值如下表:
mask 说明 GL_COLOR_BUFFER_BIT 指定当前被激活为写操作的颜色缓存 GL_DEPTH_BUFFER_BIT 指定深度缓存 GL_ACCUM_BUFFER_BIT 指定累加缓存 GL_STENCIL_BUFFER_BIT 指定模板缓存
3、glColor ( )
glColor ( ) 是用来设置画笔的颜色,即绘图颜色。属于RGBA模式。
void glcolor3b(GLbyte red,GLbyte green,GLbyte blue); void glcolor3d(GLdouble red,GLdouble green,GLdouble blue); void glcolor3f(GLfloat red,GLfloat green,GLfloat blue); void glcolor3i(GLint red,GLint green,GLint blue); void glcolor3s(GLshort red,GLshort green,GLshort blue); void glcolor3ub(GLubyte red,GLubyte green,GLubyte blue); void glcolor3ui(GLuint red,GLuint green,GLuint blue); void glcolor3us(GLushort red,GLushort green,GLushort blue); void glcolor4b(GLbyte red,GLbyte green,GLbyte blue,GLbyte alpha); void glcolor4d(GLdouble red,GLdouble green,GLdouble blue,GLdouble alpha); void glcolor4f(GLfloat red,GLfloat green,GLfloat blue,GLfloat alpha); void glcolor4i(GLint red,GLint green,GLint blue,GLint alpha); void glcolor4s(GLshort red,GLshort green,GLshort blue,GLshort alpha); void glcolor4ub(GLubyte red,GLubyte green,GLubyte blue,GLubyte alpha); void glcolor4ui(GLuint red,GLuint green,GLuint blue,GLuint alpha); void glcolor4us(GLushort red,GLushort green,GLushort blue,GLushort alpha); void glcolor3bv(const GLbyte *v); void glcolor3dv(const GLdouble *v); void glcolor3fv(const GLfloat *v); void glcolor3iv(const GLint *v); void glcolor3sv(const GLshort *v); void glcolor3ubv(const GLubyte *v); void glcolor3uiv(const GLuint *v); void glcolor3usv(const GLushort *v); void glcolor4bv(const GLbyte *v); void glcolor4dv(const GLdouble *v); void glcolor4fv(const GLfloat *v); void glcolor4iv(const GLint *v); void glcolor4sv(const GLshort *v); void glcolor4ubv(const GLubyte *v); void glcolor4uiv(const GLuint *v); void glcolor4usv(const GLushort *v);
参数:
red,green,blue 指定当前颜色中的红、绿和蓝色成分。
alpha 指定颜色中的α成分。只有在glColor4函数带4个变量时才指定此参数。
*v 指定一个指向包含红、绿、蓝和alpha值的数组指针。
说明:
本函数通过指定红、绿、蓝的颜色成分来设置当前的颜色,同时部分函数可以接受α成分。每个成分亮度的表示范围是从零(0.0)到全光强(1.0),当指定了非浮点类型时,该类型从0到最大值的表示法与浮点类型范围的0.0到1.0相映射。
glColor系列函数中,在参数类型不同时,表示“最大”颜色的值也不同。
采用 f 和 d 做后缀的函数,以 1.0 表示最大的使用。
采用 b 做后缀的函数,以 127 表示最大的使用。
采用 ub 做后缀的函数,以255 表示最大的使用。
采用 s 做后缀的函数,以 32767 表示最大的使用。
采用 us 做后缀的函数,以65535 表示最大的使用。
4、glClearColor ( ) 的作用
glClearColor ( ) 的作用是指定刷新颜色缓冲区时所用的颜色,所以完成一个刷新的过程是要 glClearColor ( COLOR) 与glClear ( GL_COLOR_BUFFER_BIT) 配合使用。
glClearColor(1.0, 0.0, 0.0, 1.0);//红色 glClear(GL_COLOR_BUFFER_BIT); //GL_COLOR_BUFFER_BIT 是缓冲标志位,表明需要清除的缓冲是颜色缓冲
注:
在 RGBA 模式下,使用 glClearColor 来指定“清除”的颜色,它需要四个参数,其参数的意义跟 glColor4f 相似。
在索引颜色模式下,使用 glClearIndex 来指定“清除”的颜色所在的索引,它需要一个参数,其意义跟 glIndexi 相似。
5、清除颜色缓冲区的作用
清除颜色缓冲区的作用是防止缓冲区中原有的颜色信息影响本次绘图(注意:即使认为可以直接覆盖原值,也是有可能会有影响),当绘图区域为整个窗口时,就是通常看到的,颜色缓冲区的清除值就是窗口的背景颜色。所以,这两条清除指令并不是必须的,比如对于静态画面只需设置一次,比如不需要背景色 / 背景色为白色。
另外,glClear ( ) 比手动涂抹一个背景画布效率高且省力,所以通常使用这种方式。
6、 glShadeModel ( )
glShadeModel ( ) 函数用于控制 opengl 中绘制指定两点间其他点颜色的过渡模式。
参数一般为 GL_SMOOLH ( 默认 ) 或 GL_FLAT。
如果两点的颜色相同,则使用这两个参数效果相同;
如果两点颜色不同,GL_SMOOLH 会出现过渡效果; GL_FLAT 则以指定的某一点的单一色绘制其他所有点,如下图:
7、glClearDepth ( ) 设置深度缓存的清除值
void glClearDepth(GLclampd depth);
depth 指定清除深度缓存时使用的深度值,值范围在[ 0 , 1 ] 之间,初始值为1。该值将被用于glClear ( ) 函数清理深度缓冲区
8、glDepthFunc ( ) 指定用于深度缓冲的比较值
void glDepthFunc (int func)
func指定深度比较函数。值如下:
func值 含义 GL_NEVER 不通过(输入的深度值不取代参考值) GL_LESS 如果输入的深度值小于参考值,则通过 GL_EQUAL 如果输入的深度值等于参考值,则通过 GL_LEQUAL 如果输入的深度值小于或等于参考值,则通过 GL_GREATER 如果输入的深度值大于参考值,则通过 GL_NOTE_QUAL 如果输入的深度值不等于参考值,则通过 GL_GEQUAL 如果输入的深度值大于或等于参考值,则通过 GL_ALWAYS 总是通过(输入的深度值取代参考值)
9、索引颜色
在索引颜色模式中,OpenGL需要一个颜色表。这个表就相当于画家的调色板:虽然可以调出很多种颜色,但同时存在于调色板上的颜色种数将不会超过调色板的格数。试将颜色表的每一项想象成调色板上的一个格子:它保存了一种颜色。
在使用索引颜色模式画图时,我说“我把第 i 种颜色设置为某某”,其实就相当于将调色板的第 i 格调为某某颜色。“我需要第 k 种颜色来画图”,那么就用画笔去蘸一下第 k 格调色板。
颜色表的大小是很有限的,一般在256~4096之间,且总是2的整数次幂。在使用索引颜色方式进行绘图时,总是先设置颜色表,然后选择颜色。
9.1、选择颜色
使用 glIndex* 系列函数可以在颜色表中选择颜色。其中最常用的可能是glIndexi,它的参数是一个整形。void glIndexi(GLint c);
9.2、设置颜色表
OpenGL 并直接没有提供设置颜色表的方法,因此设置颜色表需要使用操作系统的支持。我们所用的Windows和其他大多数图形操作系统都具有这个功能,但所使用的 函数却不相同。正如我没有讲述如何自己写代码在Windows下建立一个窗口,这里我也不会讲述如何在Windows下设置颜色表。
GLUT工具 包提供了设置颜色表的函数 glutSetColor ,但我测试始终有问题。现在为了让大家体验一下索引颜色,我向大家介绍另一个OpenGL工具包: aux。这个工具包是VisualStudio自带的,不必另外安装,但它已经过时,这里仅仅是体验一下,大家不必深入。
#include <windows.h> #include <GL/gl.h> #include <GL/glaux.h> #pragma comment (lib, "opengl32.lib") #pragma comment (lib, "glaux.lib") #include <math.h> const GLdouble Pi = 3.1415926536; void myDisplay(void) { int i; for(i=0; i<8; ++i) auxSetOneColor(i, (float)(i&0x04), (float)(i&0x02), (float)(i&0x01)); glShadeModel(GL_FLAT); glClear(GL_COLOR_BUFFER_BIT); glBegin(GL_TRIANGLE_FAN); glVertex2f(0.0f, 0.0f); for(i=0; i<=8; ++i) { glIndexi(i); glVertex2f(cos(i*Pi/4), sin(i*Pi/4)); } glEnd(); glFlush(); } int main(void) { auxInitDisplayMode(AUX_SINGLE|AUX_INDEX); auxInitPosition(0, 0, 400, 400); auxInitWindow(L""); myDisplay(); Sleep(10 * 1000); return 0; }
其它部分大家都可以不管,只看 myDisplay 函数就可以了。首先,使用 auxSetOneColor 设置颜色表中的一格。循环八次就可以设置八格。
glShadeModel ( GL_FLAT ) 采用单色着色模式。
然后在循环中用 glVertex 设置顶点,同时用 glIndexi 改变顶点代表的颜色。
最终得到的效果是八个相同形状、不同颜色的三角形。
索引颜色的主要优势是占用空间小(每个像素不必单独保存自己的颜色,只用很少的二进制位就可以代表其颜色在颜色表中的位置),花费系统资源少,图形运算速度快,但它编程稍稍显得不是那么方便,并且画面效果也会比RGB颜色差一些。“星际争霸”可能代表了256色的颜色表的画面效果,虽然它在一台很烂的PC上也可以运行很流畅,但以目前的眼光来看,其画面效果就显得不足了。
目前的PC机性能已经足够在各种场合下使用RGB颜色,因此PC程序开发中,使用索引颜色已经不是主流。当然,一些小型设备例如GBA、手机等,索引颜色还是有它的用武之地。