OpenGL入门学习(四)
http://blog.csdn.net/sun6255028/article/details/5090055
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清除后屏幕所剩的颜色。
可以设置颜色填充方式:平滑方式或单色方式。
OpenGL入门学习(四)的更多相关文章
- SCARA——OpenGL入门学习四(颜色)
OpenGL入门学习[四] 本次学习的是颜色的选择.终于要走出黑白的世界了~~ OpenGL支持两种颜色模式:一种是RGBA,一种是颜色索引模式. 无论哪种颜色模式,计算机都必须为每一个像素保存一些数 ...
- opengl入门学习
OpenGL入门学习 说起编程作图,大概还有很多人想起TC的#include <graphics.h>吧? 但是各位是否想过,那些画面绚丽的PC游戏是如何编写出来的?就靠TC那可怜的640 ...
- OpenGL入门学习(转)
OpenGL入门学习 http://www.cppblog.com/doing5552/archive/2009/01/08/71532.html 说起编程作图,大概还有很多人想起TC的#includ ...
- OpenGL入门学习(转载)
说起编程作图,大概还有很多人想起TC的#include <graphics.h>吧? 但是各位是否想过,那些画面绚丽的PC游戏是如何编写出来的?就靠TC那可怜的640*480分辨率.16色 ...
- SCARA——OpenGL入门学习三
OpenGL入门学习[三] 在第二课中,我们学习了如何绘制几何图形,但大家如果多写几个程序,就会发现其实还是有些郁闷之处.例如:点太小,难以看清楚:直线也太细,不舒服:或者想画虚线,但不知道方法只能用 ...
- OpenGL入门学习(三)
http://developer.178.com/201103/94954704639.html 在第二课中,我们学习了如何绘制几何图形,但大家如果多写几个程序,就会发现其实还是有些郁闷之处.例如:点 ...
- SCARA——OpenGL入门学习五六(三维变换、动画)
OpenGL入门学习(五) 此课为三维变换的内容,比较枯燥.主要是因为很多函数在单独使用时都不好描述其效果, 在前面绘制几何图形的时候,大家是否觉得我们绘图的范围太狭隘了呢?坐标只能从-1到1,还只能 ...
- SCARA——OpenGL入门学习一、二
参考博客:http://www.cppblog.com/doing5552/archive/2009/01/08/71532.html 简介 最近开始一个机械手臂的安装调试,平面关节型机器人又称SCA ...
- OpenGL入门学习(七)(转)
http://blog.chinaunix.net/uid-20622737-id-1912803.html 今天要讲的是OpenGL光照的基本知识.虽然内容显得有点多,但条理还算比较清晰,理解起来应 ...
随机推荐
- Java实现Avl树
Avl树即左右子树的深度[高度]相差不可超过1,所以在插入key的时候,就会出现需要旋转[更改根节点]的操作 下面是源代码: /* the define of avltree's node */ cl ...
- 牛客暑假多校第二场J-farm
一.题意 White Rabbit has a rectangular farmland of n*m. In each of the grid there is a kind of plant. T ...
- 关于学习less后一些感悟
学习了一天的less发现,自己被自己弄的晕头转向,好在是学明白了! 一.写自己的第一个less css样式编程: 网址:http://www.1024i.com/demo/less/document. ...
- PHP.15-mysqli
从PHP5.0开始可以使用mysql(i), 是一个面向对象的技术(新加功能都会以对象形式添加) i:表示改进,1. 功能增加了, 2,效率大大增加(以后的PHP项目改成mysqli),3,更稳定 m ...
- ansible-3
setup ansible_all_ipv4_addresses # ipv4的所有地址 ansible_all_ipv6_addresses # ipv6的所有地址 ansible_date_tim ...
- P3819 松江1843路(洛谷月赛)
P3819 松江1843路 题目描述 涞坊路是一条长L米的道路,道路上的坐标范围从0到L,路上有N座房子,第i座房子建在坐标为x[i]的地方,其中住了r[i]人. 松江1843路公交车要在这条路上建一 ...
- 让菜鸡讲一讲网络流(isap)
让我先讲一个故事吧. 一些小精灵要准备从银月城(S)迁徙到Nibel山(T). 这两个地方之间的道路构成了一个网络. 每个道路都有它自己的容量,这决定了每天有多少小精灵可以同时从这儿通过. 现在它们想 ...
- 自己定义的TryParse()
out 参数的练习,自己定义的TryParse()... 一开始写错了,错在:判断str[i] >= '0'&& str[i]<='9'时,把str[i]当数字去判断了.. ...
- 滑动菜单栏之开源项目SlidingMenu的使用
一.SlidingMenu简介 相信大家对SlidingMenu都不陌生了,它是一种比较新的设置界面或配置界面的效果,在主界面左滑或者右滑出现设置界面效果,能方便的进行各种操作.很多优秀的应用都采用了 ...
- Pytest+allure+jenkins生成测试报告
allure集成jenkins下载地址.下载相关版本的allure包 http://updates.jenkins-ci.org/download/plugins/allure-jenkins-plu ...