OpenGL从1.0开始--颜色调和

一、图元属性

任何影响图元显示方法的参数一般称为属性参数。OpenGL将属性选择加入图形软件包的方法是提供一张系统当前属性值表,并使用包含在图形软件包中的独立函数来为属性表设置当前值。维护属性和其他参数当前值表的图形系统称为状态系统或状态机。输出图元的属性和当前帧缓存位置等其他参数称为状态变量或状态参数。在给一个或几个状态参数赋值时,系统进入一个特定状态。该状态一直保留到状态参数的值再次改变。
属性值和其他参数设置由定义当前OpenGL状态的独立函数指定。OpenGL中状态变量有颜色和其他图元属性、当前矩阵模式、模型观察矩阵的元素、缓存当前位置和和场景光照效果参数等。

二、颜色函数

颜色是所有图元的一个基本属性。相信大家通过前面的学习对颜色函数已经不再陌生,我们再通过一个示例来给大家看看颜色世界的变幻无穷。

#include <Gl/glut.h>
void init()
{
    glClearColor(1.0, 1.0, 1.0, 0.0);//设置显示窗口颜色为白色
    glMatrixMode(GL_PROJECTION);
    gluOrtho2D(0.0, 200.0, 0.0, 150.0);
    glColor3f(0.0, 0.4, 0.2);//设置绘制所使用颜色(绿色)
}
void lineSegment()
{
    glClear(GL_COLOR_BUFFER_BIT);//用当前缓冲区(glClearColor)清除值(GL_COLOR_BUFFER_BIT)
    glBegin(GL_LINES);开始绘制线段
    glVertex2i(180, 15);
    glVertex2i(10, 145);
    glEnd();
    glColor3f(0.0, 0.4, 0.2);//设置绘制所使用颜色(绿色)
    glRecti(0, 0, 50, 50);//绘制矩形
    glColor3f(1.0, 0.4, 0.2);
    glRecti(30, 30, 100, 100);
    glFlush();
}
void main(int argc, char**argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);//设置显示模式:单缓存、RGB模式
    glutInitWindowPosition(50, 100);
    glutInitWindowSize(400, 300);
    glutCreateWindow("An Example OpenGL Program");
    init();
    glutDisplayFunc(lineSegment);
    glutMainLoop();
}

这里写图片描述
每一段完整的OpenGL代码首先都需要设定颜色显示模式。

glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);

该函数中指定了RGB模式,也是OpenGL的默认模式,使用红绿蓝三个颜色分量描述图元颜色属性。除了最常用的RGB模式外,还有一种四维的颜色描述模式被称为RGBA模式,在RGB模式的基础上增加了称为α系数的第四个分量,用来控制颜色调和。
在RGB(或RGBA)模式中,使用下面的函数来选择当前颜色分量:

glColor*(colorComponents);

颜色分量的浮点数范围从0.0到1.0.默认颜色分量为(1.0,1.0,1.0,1.0),即颜色为白色,不需要颜色调和。

三、颜色调和

在我们上面的例子中,我们先后绘制了三个图元。我们很容易就会发现,因为我们采用不调和的设置,所有图元按照绘制顺序依次叠加。状态机设置颜色属性时在第三次时设定为了橙色,随后绘制了一个橙色的正方形叠加在前一个正方形和直线之上。
我们现在尝试实现透明效果,使两张照片能够混合在一起。
我们在第二个矩形绘制函数之前加上如下一段代码:

    glEnable(GL_BLEND);
    glBlendFunc(GL_DST_ALPHA, GL_SRC_ALPHA);

这里写图片描述
橙色正方形不见了!
我们来分析一下新增的代码在玩什么花样。
在OpenGL中,通过先将第一个对象装载进帧缓存,再将第二个对象的颜色与帧缓存颜色相混合来实现两个对象颜色的调和。当前帧缓存颜色称为OpenGL目标颜色,而第二个对象的颜色称为OpenGL源颜色。要在应用中进行颜色调和,必须先使用下面的函数激活这个OpenGL特性:

glEnable(GL_BLEND);

颜色可按要达到的效果进行多种调和,通过指定两组调和因子来生成不同的颜色效果。假设源颜色向量为S,目标颜色向量为D,对应的调和因子分别为A和B,则将要装入帧缓存的新的调和颜色等于A*S+B*D。
使用下列函数可选择调和因子的值:

glBlendFunc(sFactor, dFactor);

函数的参数即源和目标因子,例如常量GL_ZERO表示调和因子(0.0,0.0,0.0,0.0),GL_ONE表示(1.0,1.0,1.0,1.0),GL_DST_ALPHA表示目标α值,GL_SRC_ALPHA表示源α值。其他常用的常量还有GL_ONE_MINUS_DST_ALPHA,GL_ONE_MINUS_SRC_ALPHA, GL_DST_COLOR,GL_SRC_COLOR,这些调和因子常用来模拟透明性,以后还会再次讲到。
我们再来分析一下我们的示例代码发生了什么。我们的示例代码在绘制第二个正方形时启动了颜色调和,也就是说在这之前绘制的背景和绿色正方形、直线都作为目标颜色,使用了目标颜色的α值,橙色正方形作为源颜色,使用了源颜色的α值。所以结果中橙色正方形和背景呈现了混合的效果,其中和绿色正方形重叠的地方渲染成了黄色(绿+橙),而和背景重叠的地方渲染成了白色,这是因为调和颜色的取值范围为0-1,而大于1的颜色取值为0,所以和白色重叠的地方取值为白色。

四、OpenGL颜色数组

和顶点数组类似,也可以用颜色数组来优化颜色属性的指定。
下面给大家看一段代码做一个简单的示范。

typedef GLint vertex3[3];
vertex3 verpt[8] = { { 0, 0, 0 }, { 0, 1, 0 }, { 1, 0, 0 }, { 1, 1, 0 }, { 0, 0, 1 }, {0, 1, 1}, { 1, 0, 1 }, { 1, 1, 1 } };
vertex3 colorpt[8] = { { 0, 0, 0 }, { 0, 1, 0 }, { 1, 0, 0 }, { 1, 1, 0 }, { 0, 0, 1 }, {0, 1, 1}, { 1, 0, 1 }, { 1, 1, 1 } };
glEnableClientState(GL_VERTEX_ARRAY);//激活OpengL顶点数组特性
glEnableClientState(GL_COLOR_ARRAY);//激活OpengL颜色数组特性
glVertexPointer(3, GL_INT, 0, pt);//指定顶点坐标位置和数据格式
glColorPointer(3, GL_INT, 0, pt);//指定颜色属性和数据格式
GLubyte vertIndex[] = { 6, 2, 3, 7, 5, 1, 0, 4, 7, 3, 1, 5, 4, 0, 2, 6, 2, 0, 1, 3, 7, 5, 4, 6 };//指定顶点索引的数组
GLubyte colorIndex[] = { 6, 2, 3, 7, 5, 1, 0, 4, 7, 3, 1, 5, 4, 0, 2, 6, 2, 0, 1, 3, 7, 5, 4, 6 };//指定颜色索引的数组

从上面这段代码可以看出颜色数组和顶点数组的使用方式如出一辙,我们会在以后再通过具体的实例让大家加深理解。

其他OpenGL颜色函数

这一节都是大家或多或少遇见过的函数,不过我们还是希望通过这一节的集中讲解加深大家的理解。下面我们再看两个非常熟悉的颜色函数。
指定所有颜色缓存的颜色,即为显示窗口选择颜色分量:

glclear(red,green,blue,alpha);

将净颜色用于这些颜色缓存

glclear(GL_COLOR_BUFFER_BIT);
阅读更多
文章标签: opengl
个人分类: OpenGL
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭