Exercise 3:光照
要求:
1. 绘制带有光照效果的场景;
2. 场景包含3个茶壶,通过键盘1,2,3可以分别选中三个茶壶,然后用鼠标对每个茶壶进行分别的旋转;
3. 使用点光源,点光源为白色,以白色的球体表示;
4. 使用3个不同的点光源
i. 光源1的坐标设置在世界坐标系中,并围绕着三个茶壶的中心进行圆周运动;
ii. 光源2 的坐标 设置在观察坐标系,不发生变化;
iii. 光源3的坐标设置在茶壶1的物体坐标系中,当茶壶1被选中进行旋转时,光源3要跟随茶壶1 做相同的旋转;
考察目的:
1. OpenGL中光源的使用;
2. 如何在OpenGL中通过回调函数实现简单的动画(光源1需要自动围绕茶壶做圆周运动);
3. 通过设置光源的不同时机,将光源设置在不同的坐标系下;
by/scu xx
/*
世界坐标系:是将每一个模型共享在一个场景中的坐标系,它通常用来描述我们期望呈现的各个模型之间的联系关系。
观察坐标系:有时候我们也叫做摄影坐标系,这个有点像世界坐标系那样,只不过世界坐标系是用来描述整个场景的,
而观察坐标系的原点在观察着的眼睛或摄像机。观察坐标系的Z轴就是眼睛看到的前方,Y轴相当于眼睛的上
方,X轴位于右方。
颜色缓冲区(COLOR_BUFFER)就是帧缓冲区(FRAME_BUFFER),你需要渲染的场景最终每一个像素都要写入该缓冲区,然后由它在渲染到屏幕上显示.
深度缓冲区(DEPTH_BUFFER)与帧缓冲区对应,用于记录上面每个像素的深度值,通过深度缓冲区,我们可以进行深度测试,从而确定像素的遮挡关系,保证渲染正确.
模版缓冲(STENCIL_BUFFER)与深度缓冲大小相同,通过设置模版缓冲每个像素的值,我们可以指定在渲染的时候只渲染某些像素,从而可以达到一些特殊的效果.
环境光是一种无处不在的光。环境光源放出的光线被认为来自任何方向。因此,当你仅为场景指定环境光时,所有的物体无论法向量如何,都将表现为同样的明暗程度。
点光源放出的光线来自同一点,且方向辐射自四面八方。
平行光又称镜面光,这种光线是互相平行的。从手电筒、太阳等物体射出的光线都属于平行光。
聚光灯光线从一个锥体中射出,在被照射的物体上产生聚光的效果。使用这种光源需要指定光的射出方向以及锥体的顶角α。
*/
#include <iostream>
#include <gl\glew.h>
#define GLUT_DISABLE_ATEXIT_HACK//若没有这一句会出现无法解析外部符号的错误,在glut.h前加上这一句就正确了
#include <glut.h>
#pragma comment(lib,"glew32.lib")
using namespace std;
bool isRotatef[4]; // 控制要旋转的茶壶或旋转视图
bool isLightOpen[3]; //定义光源是否打开的bool值
float lightRotatefSpeed = 0; //第一个光源绕三个茶壶的中心旋转的速度(是一个角度)
GLfloat LightPosition1[] = {0.0f, 0.0f, 0.0f, 1.0f}; //第一个点光源的位置
GLfloat LightPosition2[] = {4.0f, 4.0f, 6.0f, 1.0f}; //第二个点光源的位置
GLfloat LightPosition3[] = {-1.0f, 1.0f, 2.0f, 1.0f}; //第三个点光源的位置
static int mousePosX = 0,mousePosY = 0, tempX, tempY;
bool isMosDownMove = false;//鼠标移动时的判断变量
struct simpleCamera
{
float camera[3];
float lookat[3];
float cam[3];
};
simpleCamera camera;
void display();
void init();
void keyboard(unsignedchar key,int x, int y);
void motion(int x,int z);
void mouse(int button,int state,int x,int z);
void reshape(int w,int h);
void createLight();
void init(void)
{
glClearColor(0.7f,0.7f, 0.7f, 0.0f);
//用当前的缓冲区清除值清除指定的缓冲区(缓冲