一、实验原理
1、视口
(1)定义
视口是程序窗口中的一个矩形绘图区(如下图所示),在屏幕上打开一个窗口时,自动把视口设置为整个程序窗口的大小。可以定义一个比程序窗口小的视口,也可以在一个程序窗口中定义多个视口,达到分屏显示的目的。
(2)函数说明
void glViewport(int left, int bottom, int width, int height)
①功能:设置视口在程序窗口中的位置和大小。
②参数:(left, bottom)是视口左下角在窗口中的坐标;(width, height)是视口的宽和高。
③说明:坐标原点位于程序窗口左下角,以像素为单位。默认视口为(0, 0, W, H),其中W、H分别表示程序窗口的宽和高。
2、光源属性
(1)环境光成分
glLightfv(GLenum light, GL_ AMBIENT, float *params)
glLightiv(GLenum light, GL_ AMBIENT, int *params)
①功能:用于指定环境光成分的RGBA强度。
②说明:默认值为(0, 0, 0, 1),表示没有环境光。
(2)漫反射成分
glLightfv(GLenum light, GL_ DIFFUSE, float *params)
glLightiv(GLenum light, GL_ DIFFUSE, int *params)
①功能:用于指定漫反射成分的RGBA强度。
②说明:对于GL_LIGHT0,默认值为(1, 1, 1, 1),对于其他光源,默认值为(0, 0, 0, 0)。
(3)镜面反射成分
glLightfv(GLenum light, GL_ SPECULAR, float *params)
glLightiv(GLenum light, GL_ SPECULAR, int *params)
①功能:用于指定镜面反射成分的RGBA强度。
②说明:对于GL_LIGHT0,默认值为(1, 1, 1, 1),对于其他光源,默认值为(0, 0, 0, 0)。
(4)位置
glLightfv(GLenum light, GL_POSITION, float *params)
glLightiv(GLenum light, GL_POSITION, int *params)
①功能:用于指定光源位置的齐次坐标(x, y, z, w) 。
②说明:若w≠0,表示该光源是位置光源,距离场景较近,位置用齐次坐标(x, y, z, w)表示;若w=0,表示该光源是方向光源,距离场景无限远,方向用从(x, y, z)到坐标原点的射线方向表示。(x, y, z, w) 的默认值为(0, 0, 1, 0)。
3、材质属性
(1)漫反射系数
glMaterialfv(GLenum face, GL_ DIFFUSE, float *params)
①功能:用于定义物体对光源漫反射成分的反射系数。
②说明:漫反射系数对物体的颜色起最重要的作用,默认值为(0.8, 0.8, 0.8, 1)。
(2)环境光反射系数
glMaterialfv(GLenum face, GL_AMBIENT, float *params)
①功能:用于定义物体对环境光的反射系数。
②说明:环境光反射系数影响物体的整体颜色,因为直射到物体上的漫反射光最亮,而没有被直射的物体的环境光反射最明显。物体的环境光反射强度受全局环境光和光源环境光成分的双重影响。默认值为(0.2, 0.2, 0.2, 1)。
(3)同时指定漫反射、环境光反射系数
glMaterialfv(GLenum face, GL_AMBIENT_AND_DIFFUSE, float *params)
①功能:用于同时指定漫反射系数和环境光反射系数。
②说明:默认值为(0.8, 0.8, 0.8, 1)。
(4)镜面反射系数
glMaterialfv(GLenum face, GL_SPECULAR, float *params)
①功能:用于定义物体对光源镜面反射成分的反射系数,即亮斑的颜色。
②说明:默认值为(0, 0, 0, 1)。
(5)镜面反射指数
glMaterialf(GLenum face, GL_SHINESS, float param)
glMaterialfv(GLenum face, GL_SHINESS, float *params)
①功能:用于控制亮斑的大小和亮度,称为镜面反射指数或光洁度。
②说明:取值范围为[0, 128],值越大,亮斑的尺寸越小且亮度越高,默认值为0。
(6)发光
glMaterialfv(GLenum face, GL_EMISSION, float *params)
功能:用于定义发光体的发光强度,默认值为(0, 0, 0, 1)。
4、光照处理部分相关函数
(1)光源和光照效果
glEnable(GL_LIGHTi) //开启i 号光源(0≤i≤8)
glDisable(GL_LIGHTi) //关闭i 号光源(0≤i≤8)
glEnable(GL_LIGHTING) //启用光照效果
glDisable(GL_LIGHTING) //禁止光照效果
(2)明暗模式
glShadeModel(GL_SMOOTH) //光滑明暗模式,使用Gouraud算法
glShadeModel(GL_FLAT) //平面明暗模式,用其中一个顶点的颜色填充
二、算法程序
1、使用OpenGL、GLU和GLUT编写一个多视口演示程序。要求:
(1)屏幕窗口左下角1/4部分显示红色的填充矩形,该矩形的一对对角顶点是(0, 0)和(1, 1);
(2)屏幕窗口右下角1/4部分显示绿色的填充犹他茶壶,茶壶半径为0.4,并向右、上各移动0.5;
(3)屏幕窗口上部居中1/4部分显示蓝色的填充正三角形,该正三角形的左下角顶点是(0, 0),右下角顶点是(1, 0);
(4)裁剪窗口均为(-0.1, -0.1)~(1.1, 1.1),程序窗口的大小为(200, 200),背景为黑色,标题为“多视口演示”。
#include<GL/freeglut.h>
#include<math.h>
void Viewport(int x, int y, int w, int h) {
glViewport(x, y, w, h);
glLoadIdentity();
gluOrtho2D(-0.1, 1.1, -0.1, 1.1);
}
void Triangle() {
glBegin(GL_TRIANGLES);
glVertex2f(0, 0);
glVertex2f(1.0, 0);
glVertex2f(0.5 , sqrt(3) / 2);
glEnd();
}
void Paint() {
int w = glutGet(GLUT_WINDOW_WIDTH) / 2;
int h = glutGet(GLUT_WINDOW_HEIGHT) / 2;
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT);
Viewport(0, 0, w, h);
glColor3f(1, 0, 0);
glRectf(0, 0, 1, 1);
Viewport(w, 0, w, h);
glTranslatef(0.5, 0.5, 0);
glColor3f(0, 1, 0);
glutSolidTeapot(0.4);
Viewport(w / 2, h, w, h);
glColor3f(0, 0, 1);
Triangle();
glFlush();
}
int main(int argc, char *argv[]) {
glutInit(&argc, argv);
glutInitWindowSize(200, 200);
glutCreateWindow("多视口演示");
glutDisplayFunc(Paint);
glutMainLoop();
return 0;
}
2、已知在一个空旷的场景中有一个粗糙的紫色球体,球体的右上角方向放置了一个白色的点光源,请使用OpenGL和GLUT编写一个程序模拟出球面上的光照效果(不考虑环境光)。
#include <GL/glut.h>
void Light() {
float pos[] = {200, 200, 0, 1};
glLightfv(GL_LIGHT0, GL_POSITION, pos);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHTING);
}
void Material() {
float mater[] = {1, 0, 1, 1};
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, mater);
}
void Paint() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
gluPerspective(60, 1, 1, 1000);
glTranslatef(0, 0, -2);
glutSolidSphere(0.95, 100, 50);
glFlush();
}
int main(int argc, char* argv[]) {
glutInit(&argc, argv);
glutInitWindowSize(300, 300);
glutCreateWindow("粗糙的紫色球体");
glutDisplayFunc(Paint);
Light(), Material();
glutMainLoop();
}
三、结果演示
1、多视口演示
2、粗糙的紫色球体