OpenGL 入门教程4

OpenGL 支持两种颜色模式:一种是 RGBA,一种是颜色索引模式。

无论哪种颜色模式,计算机都必须为每一个像素保存一些数据。不同的是,RGBA 模式中,数据直接就代

表了颜色;而颜色索引模式中,数据代表的是一个索引,要得到真正的颜色,还必须去查索引表。

1. RGBA 颜色

RGBA 模式中,每一个像素会保存以下数据:R 值(红色分量) 、G 值(绿色分量) 、B 值(蓝色分量)和

A 值(alpha 分量) 。其中红、绿、蓝三种颜色相组合,就可以得到我们所需要的各种颜色,而 alpha 不直接

影响颜色,它将留待以后介绍。

在 RGBA 模式下选择颜色是十分简单的事情,只需要一个函数就可以搞定。

glColor*系列函数可以用于设置颜色,其中三个参数的版本可以指定 R、G、B 的值,而A 值采用默认;四

个参数的版本可以分别指定 R、G、B、A 的值。例如:

void glColor3f(GLfloat red, GLfloat green, GLfloat blue);

void glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);

(还记得吗?3f 表示有三个浮点参数~请看第二课中关于 glVertex*函数的叙述。 )

将浮点数作为参数,其中 0.0 表示不使用该种颜色,而 1.0 表示将该种颜色用到最多。例如:

glColor3f(1.0f, 0.0f, 0.0f); 表示不使用绿、蓝色,而将红色使用最多,于是得到最纯净的红色。

glColor3f(0.0f, 1.0f, 1.0f); 表示使用绿、蓝色到最多,而不使用红色。混合的效果就是浅蓝色。

glColor3f(0.5f, 0.5f, 0.5f); 表示各种颜色使用一半,效果为灰色。

注意:浮点数可以精确到小数点后若干位,这并不表示计算机就可以显示如此多种颜色。实际上,计算机

可以显示的颜色种数将由硬件决定。如果 OpenGL 找不到精确的颜色,会进行类似“四舍五入”的处理。

大家可以通过改变下面代码中 glColor3f 的参数值,绘制不同颜色的矩形。

void myDisplay(void)

{

glClear(GL_COLOR_BUFFER_BIT);

glColor3f(0.0f, 1.0f, 1.0f);

glRectf(-0.5f, -0.5f, 0.5f, 0.5f);

glFlush();

}

注意:glColor 系列函数,在参数类型不同时,表示“最大”颜色的值也不同。

采用 f 和 d 做后缀的函数,以 1.0 表示最大的使用。

采用 b 做后缀的函数,以 127 表示最大的使用。

采用 ub 做后缀的函数,以 255 表示最大的使用。

采用 s 做后缀的函数,以 32767 表示最大的使用。

采用 us 做后缀的函数,以 65535 表示最大的使用。

这些规则看似麻烦,但熟悉后实际使用中不会有什么障碍。

2、索引颜色

在索引颜色模式中,OpenGL 需要一个颜色表。这个表就相当于画家的调色板:虽然可以调出很多种颜色,

但同时存在于调色板上的颜色种数将不会超过调色板的格数。试将颜色表的每一项想象成调色板上的一个

格子:它保存了一种颜色。

在使用索引颜色模式画图时,我说“我把第 i 种颜色设置为某某”,其实就相当于将调色板的第 i 格调为某某

颜色。“我需要第 k 种颜色来画图”,那么就用画笔去蘸一下第 k 格调色板。

颜色表的大小是很有限的, 一般在 256~4096 之间, 且总是 2 的整数次幂。 在使用索引颜色方式进行绘图时,

总是先设置颜色表,然后选择颜色。

2.1、选择颜色

使用 glIndex*系列函数可以在颜色表中选择颜色。其中最常用的可能是 glIndexi,它的参数是一个整形。

void glIndexi(GLint c);

是的,这的确很简单。

2.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 等下再讲,这里不提。

然后在循环中用 glVertex设置顶点,同时用 glIndexi 改变顶点代表的颜色。

最终得到的效果是八个相同形状、不同颜色的三角形。

索引颜色虽然讲得多了点。索引颜色的主要优势是占用空间小(每个像素不必单独保存自己的颜色,只用

很少的二进制位就可以代表其颜色在颜色表中的位置) ,花费系统资源少,图形运算速度快,但它编程稍稍

显得不是那么方便,并且画面效果也会比 RGB 颜色差一些。“星际争霸”可能代表了 256 色的颜色表的画面

效果,虽然它在一台很烂的 PC 上也可以运行很流畅,但以目前的眼光来看,其画面效果就显得不足了。

目前的 PC 机性能已经足够在各种场合下使用 RGB 颜色,因此 PC 程序开发中,使用索引颜色已经不是主

流。当然,一些小型设备例如 GBA、手机等,索引颜色还是有它的用武之地。

3、指定清除屏幕用的颜色

我们写:glClear(GL_COLOR_BUFFER_BIT);意思是把屏幕上的颜色清空。

但实际上什么才叫“空”呢?在宇宙中,黑色代表了“空”;在一张白纸上,白色代表了“空”;在信封上,信

封的颜色才是“空”。

OpenGL 用下面的函数来定义清楚屏幕后屏幕所拥有的颜色。

在 RGB 模式下,使用 glClearColor 来指定“空”的颜色,它需要四个参数,其参数的意义跟 glColor4f 相似。

在索引颜色模式下,使用 glClearIndex来指定“空”的颜色所在的索引,它需要一个参数,其意义跟 glIndexi

相似。

void myDisplay(void)

{

glClearColor(1.0f, 0.0f, 0.0f, 0.0f);

glClear(GL_COLOR_BUFFER_BIT);

glFlush();

}

呵,这个还真简单~

4、指定着色模型

OpenGL 允许为同一多边形的不同顶点指定不同的颜色。例如:

#include <math.h>

const GLdouble Pi = 3.1415926536;

void myDisplay(void)

{

int i;

// glShadeModel(GL_FLAT);

glClear(GL_COLOR_BUFFER_BIT);

glBegin(GL_TRIANGLE_FAN);

glColor3f(1.0f, 1.0f, 1.0f);

glVertex2f(0.0f, 0.0f);

for(i=0; i<=8; ++i)

{

glColor3f(i&0x04, i&0x02, i&0x01);

glVertex2f(cos(i*Pi/4), sin(i*Pi/4));

}

glEnd();

glFlush();

}

在默认情况下,OpenGL 会计算两点顶点之间的其它点,并为它们填上“合适”的颜色,使相邻的点的颜色值

都比较接近。如果使用的是 RGB 模式,看起来就具有渐变的效果。如果是使用颜色索引模式,则其相邻点

的索引值是接近的,如果将颜色表中接近的项设置成接近的颜色,则看起来也是渐变的效果。但如果颜色

表中接近的项颜色却差距很大,则看起来可能是很奇怪的效果。

使用 glShadeModel 函数可以关闭这种计算,如果顶点的颜色不同,则将顶点之间的其它点全部设置为与某

一个点相同。 (直线以后指定的点的颜色为准,而多边形将以任意顶点的颜色为准,由实现决定。 )为了避

免这个不确定性,尽量在多边形中使用同一种颜色。

glShadeModel 的使用方法:

glShadeModel(GL_SMOOTH); // 平滑方式,这也是默认方式

glShadeModel(GL_FLAT); // 单色方式

小结:

本课学习了如何设置颜色。其中 RGB 颜色方式是目前 PC 机上的常用方式。

可以设置 glClear 清除后屏幕所剩的颜色。

可以设置颜色填充方式:平滑方式或单色方式

时间: 2024-10-09 17:25:14

OpenGL 入门教程4的相关文章

OpenGL 入门教程5

在前面绘制几何图形的时候,大家是否觉得我们绘图的范围太狭隘了呢?坐标只能从-1 到 1,还只能是 X 轴向右,Y轴向上,Z 轴垂直屏幕.这些限制给我们的绘图带来了很多不便. 我们生活在一个三维的世界--如果要观察一个物体,我们可以: 1.从不同的位置去观察它. (视图变换) 2.移动或者旋转它,当然了,如果它只是计算机里面的物体,我们还可以放大或缩小它. (模型变换) 3.如果把物体画下来,我们可以选择:是否需要一种"近大远小"的透视效果.另外,我们可能只希望看到 物体的一部分,而不是

OPENGL入门教程

OpenGL入门学习1:编写第一个OpenGL程序http://www.c3dn.net/forum.php?mo ... d=20&extra=page%3D3OpenGL入门学习2:点.直线和多边形http://www.c3dn.net/forum.php?mo ... id%3D5%26typeid%3D5OpenGL入门学习3:绘制几何图形的细节http://www.c3dn.net/forum.php?mo ... id%3D5%26typeid%3D5OpenGL入门学习4:颜色的选

OpenGL 入门教程1

说起编程作图,大概还有很多人想起 TC 的#include <graphics.h>吧? 但是各位是否想过,那些画面绚丽的 PC 游戏是如何编写出来的?就靠 TC 那可怜的 640*480 分辨率.16 色来做吗?显然是不行的. 本帖的目的是让大家放弃 TC 的老旧图形接口,让大家接触一些新事物. OpenGL 作为当前主流的图形 API 之一,它在一些场合具有比 DirectX 更优越的特性. 1.与 C 语言紧密结合. OpenGL 命令最初就是用 C 语言函数来进行描述的,对于学习过 C

OpenGL 入门教程2

说明一下 csdn 写文章的代码端 不用 本次课程所要讲的是绘制简单的几何图形,在实际绘制之前,让我们先熟悉一些概念. 一.点.直线和多边形 我们知道数学(具体的说,是几何学)中有点.直线和多边形的概念,但这些概念在计算机中会有所不同. 数学上的点,只有位置,没有大小.但在计算机中,无论计算精度如何提高,始终不能表示一个无穷小的 点.另一方面,无论图形输出设备(例如,显示器)如何精确,始终不能输出一个无穷小的点.一般情况 下,OpenGL 中的点将被画成单个的像素(像素的概念,请自己搜索之~)

OpenGL 入门教程3

点的大小默认为 1 个像素,但也可以改变之.改变的命令为 glPointSize,其函数原型如下: void glPointSize(GLfloat size); size 必须大于 0.0f,默认值为 1.0f,单位为"像素". 注意:对于具体的 OpenGL 实现,点的大小都有个限度的,如果设置的 size 超过最大值,则设置可能会有 问题. 例子 void myDisplay(void) { glClear(GL_COLOR_BUFFER_BIT); glPointSize(5.

转:openGL入门(1)

                    OpenGL入门教程 第一课: 说起编程作图,大概还有很多人想起TC的#include <graphics.h>吧? 但是各位是否想过,那些画面绚丽的PC游戏是如何编写出来的?就靠TC那可怜的640*480分辨率.16色来做吗?显然是不行的. 本帖的目的是让大家放弃TC的老旧图形接口,让大家接触一些新事物. OpenGL作为当前主流的图形API之一,它在一些场合具有比DirectX更优越的特性. 1.与C语言紧密结合. OpenGL命令最初就是用C语言函

【OpenCV入门教程之三】 图像的载入,显示和输出 一站式完全解析

了解过之前老版本OpenCV的童鞋们都应该清楚,对于OpenCV1.0时代的基于 C 语言接口而建的图像存储格式IplImage*,如果在退出前忘记release掉的话,就会造成内存泄露.而且用起来超级麻烦,我们往往在debug的时候,很大一部分时间在纠结手动释放内存的问题.虽然对于小型的程序来说手动管理内存不是问题,但一旦我们写的代码变得越来越庞大,我们便会开始越来越多地纠缠于内存管理的问题,而不是着力解决你的开发目标. 这,就有些舍本逐末的感觉了. 而自从OpenCV踏入2.0时代,用Mat

iOS开发入门教程_iOS开发视频教程

iOS开发入门教程 (Object-C.网络编程.多线程.蓝牙.二维码.Cocos2D.OpenGL)适合人群:初级课时数量:34课时用到技术:IOS,Object-C,OpenGL,XCode,Cocos 2D涉及项目:Cocos+2D.Game Kit蓝牙数据处理等咨询QQ:1840215592 iOS开发入门教程详细查看:http://www.ibeifeng.com/goods-471.html1.1.课程目标iOS开发入门教程内容的目标是初学者入门,让入门者提高,让所有人符合企业招聘的

OpenGL入门学习

说起编程作图,大概还有很多人想起TC的#include <graphics.h>吧? 但是各位是否想过,那些画面绚丽的PC游戏是如何编写出来的?就靠TC那可怜的640*480分辨率.16色来做吗?显然是不行的. 本帖的目的是让大家放弃TC的老旧图形接口,让大家接触一些新事物. OpenGL作为当前主流的图形API之一,它在一些场合具有比DirectX更优越的特性. 1.与C语言紧密结合. OpenGL命令最初就是用C语言函数来进行描述的,对于学习过C语言的人来讲,OpenGL是容易理解和学习的