1.实验目的:
- 通过示范代码1的立方体实例,理解巩固点的透视投影变换知识;
- 通过示范代码1的立方体实例,了解OpenGL实体显示的基本原理与方法;
- 通过示范代码2的立方体实例,学习OpenGL观察变换函数、投影变换函数的设置与使用方法;
2.实验内容:
在示范代码1基础上,按以下要求修改:
(1) 修改代码,让立方体平移和旋转,产生两点透视和三点透视,将两种透视图结果存为图1-2,与对应修改的代码一起保存至word实验文档中(20分钟);
(2) 参考教材代码7.3.5,将代码中的立方体改为四棱锥,将测试结果存为图3,与对应修改的代码一起保存至word实验文档中(20分钟);
在示范代码2基础上,按以下要求修改:
(3) 学习OpenGL观察变换函数gluLookAt的设置与使用方法,并在代码中修改参数产生两点透视和三点透视,将两种透视图结果存为图4-5,与对应修改的代码一起保存至word实验文档中(20分钟);
(4)学习OpenGL投影变换函数gluPerspective和glOrtho的设置与使用方法,启用gluPerspective函数并修改参数得到不同的透视图6-7,将图和代码保存;启用glOrtho并修改参数得到不同的正交投影图8-9,将图和代码保存(20分钟);
(5) 整理word实验文档,将其命名为“序号-姓名-Prj5.doc”,电子版提交至雨课堂,A4打印稿下一次课前或实验课前提交。
3.实验原理:
在OpenGL程序中,观察变换必须出现在模型变换之前,但可以在绘图之前的任何时候执行投影变换和视口变换。
(1)在给定的观察变换之前,应该使用glLoadIdentity函数把当前矩阵设置为单位矩阵。
(2)在载入单位矩阵之后,使用gluLookAt函数指定观察变换。如果程序没有调用gluLookAt(),那么照相机会设定为一个默认的位置和方向。在默认的情况下,照相机位于原点,指向z轴负方向,朝上向量为(0,1,0)。
(3)一般而言,display函数包括:观察变换 + 模型变换 + 绘制图形的函数(如ColorCube)。display会在窗口被移动或者原来先遮住这个窗口的东西被移开时,被重复调用,并经过适当变换,保证绘制的图形是按照希望的方式进行绘制。
(4)在调用gluPerspective设置投影变换之前,在reshape函数中有一些准备工作:视口变换 + 投影变换 + 观察变换 + 模型变换。由于投影变换,视口变换共同决定了场景是如何映射到计算机的屏幕上的,而且它们都与屏幕的宽度、高度密切相关,因此应该放在reshape函数中。reshape函数会在窗口初次创建,移动或改变时被调用。
总结起来,OpenGL中矩阵坐标之间的关系为:物体世界坐标→观察坐标→投影坐标→透视除法→规范化设备坐标→窗口坐标。
(1)用观察变换函数gluLookAt(0.0,0.0,5.0,0.0,0.0,0.0,0.0,1.0,0.0)设置照相机的位置。把照相机放在(0,0,5),镜头瞄准(0,0,0),朝上向量定为(0,1,0),朝上向量为照相机指定了一个唯一的方向。如果没有调用gluLookAt函数,照相机就设定一个默认的位置和方向,如上所述。glLoadIdentity函数把当前矩阵设置为单位矩阵。
(2)使用模型变换的目的是设置模型的位置和方向。
(3)投影变换,指定投影变换类似于为照相机选择镜头,可以认为这种变换的目的是确定视野,并因此确定哪些物体位于视野之内以及它们能够被看到的程度。除了考虑视野之外,投影变换确定物体如何投影到屏幕上,OpenGL提供了两种基本类型的投影:(i)透视投影:远大近小;(ii)正投影:不影响相对大小,一般用于工程当中。
(4)视口变换。视口变换指定一个图像在屏幕上所占的区域,可参考OpenGL的glViewport视口变换函数详解。
(5)绘制场景。
4.示范代码:
(1) 示范代码1-通过透视投影变换计算投影点来显示立方体投影图
1 | // Projection.cpp : Defines the entry point for the console application. |
程序运行结果:
图1
(2) 示范代码2-通过OpenGL观察变换和投影变换函数来显示立方体投影图
1 | #include <gl/glut.h> |
程序运行结果:
图2
5.实验思考
在示范代码2中,若将gluPerspective(90.0f, (GLfloat)width / (GLfloat)height, 0.1f, 100.0f)
代码改为如下:
gluPerspective(90.0f, (GLfloat)width / (GLfloat)height, 0.0f, 100.0f)
,
点击按键1和2,切换显示方式,观察下显示效果有何不同,试解释原因。