实验三 图形几何变换
实验类型:设计型 实验学时:2实验要求:必修
一、实验目的
理解掌握OpenGL二维平移、旋转、缩放变换的方法。
二、实验内容
1阅读实验原理,运行示范实验代码,掌握OpenGL程序平移、旋转、缩放变换的方法;
2 根据示范代码,尝试完成实验作业;
三、实验原理
在OpenGL的核心库中,每一种几何变换都有一个独立的函数,所有变换都在三维空间中定义。
平移矩阵构造函数为glTranslate<f,d>(tx, ty, tz),作用是把当前矩阵和一个表示移动物体的矩阵相乘。tx, ty,tz指定这个移动物体的矩阵,它们可以是任意的实数值,后缀为f(单精度浮点float)或d(双精度浮点double),对于二维应用来说,tz=0.0。
旋转矩阵构造函数为glRotate<f,d>(theta, vx, vy, vz),作用是把当前矩阵和一个表示旋转物体的矩阵相乘。theta, vx, vy, vz指定这个旋转物体的矩阵,物体将绕着(0,0,0)到(x,y,z)的直线以逆时针旋转,参数theta表示旋转的角度。向量v=(vx, vy,vz)的分量可以是任意的实数值,该向量用于定义通过坐标原点的旋转轴的方向,后缀为f(单精度浮点float)或d(双精度浮点double),对于二维旋转来说,vx=0.0,vy=0.0,vz=1.0。
缩放矩阵构造函数为glScale<f,d>(sx, sy, sz),作用是把当前矩阵和一个表示缩放物体的矩阵相乘。sx, sy,sz指定这个缩放物体的矩阵,分别表示在x,y,z方向上的缩放比例,它们可以是任意的实数值,当缩放参数为负值时,该函数为反射矩阵,缩放相对于原点进行,后缀为f(单精度浮点float)或d(双精度浮点double)。
由于模型和视图的变换都通过矩阵运算来实现,在进行变换前,应先设置当前操作的矩阵为“模型视图矩阵”。设置的方法是以GL_MODELVIEW为参数调用glMatrixMode函数,像这样:
glMatrixMode(GL_MODELVIEW);
该语句指定一个4×4的建模矩阵作为当前矩阵。
通常,我们需要在进行变换前把当前矩阵设置为单位矩阵。把当前矩阵设置为单位矩阵的函数为:
glLoadIdentity();
我们在进行矩阵操作时,有可能需要先保存某个矩阵,过一段时间再恢复它。当我们需要保存时,调用glPushMatrix()函数,它相当于把当前矩阵压入堆栈。当需要恢复最近一次的保存时,调用glPopMatrix()函数,它相当于从堆栈栈顶弹出一个矩阵为当前矩阵。OpenGL规定堆栈的容量至少可以容纳32个矩阵,某些OpenGL实现中,堆栈的容量实际上超过了32个。因此不必过于担心矩阵的容量问题。
通常,用这种先保存后恢复的措施,比先变换再逆变换要更方便,更快速。注意:模型视图矩阵和投影矩阵都有相应的堆栈。使用glMatrixMode来指定当前操作的究竟是模型视图矩阵还是投影矩阵。
四、实验示范代码(略)
五、实验步骤
1 在Windows xp/win7操作环境下,启动VC;
2 建立W32 Console Application 的应用工程;
3 建立源程序编辑环境,进行编辑源程序。
4 调试运行程序,完成实验。
六、实验结果处理
演示结果并保存相关文件。
七、实验注意事项
注意编程环境的配置,即在Windows环境下,OpenGL扩展库相关文件的配置,把头文件“GL.H”、库文件“OPENGL32.LIB”和动态链接库“OPENGL32.DLL”配置到相应的目录下。
八、预习与思考题
预习:阅读课本相关内容,仔细阅读示范代码。
思考题:如何通过点击鼠标左右键实现图形颜色的改变。
九、实验报告要求
1、实验报告中应包括相关操作步骤和程序代码和运行效果截图。
2.书写实验报告时要结构合理,层次分明,在分析描述的时候,需要注意语言的流畅。
基础:
升级1要求实现鼠标控制四棱锥旋转,鼠标左键加速,鼠标右键减速,鼠标滑轮部分推出程序;
基础代码:
#include "pch.h"
#include <iostream>
using namespace std;
#include<GL/glut.h>
float rtri;//金字塔旋转角度
void init(void)
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glShadeModel(GL_SMOOTH);
glEnable(GL_DEPTH_TEST);//激活深度测试
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(-1.5, 0.0, -6.0);
glRotatef(rtri, 0.0, 1.0, 0.0);
glBegin(GL_TRIANGLES);
glColor3f(1.0f, 0.0f, 0.0f);
glVertex3f(0.0f, 1.0f, 0.0f);
glColor3f(0.0f, 1.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glColor3f(0.0f, 0.0f, 1.0f);
glVertex3f(1.0f, -1.0f, 1.0f);
glColor3f(1.0f, 0.0f, 0.0f);
glVertex3f(0.0f, 1.0f, 0.0f);
glColor3f(0.0f, 0.0f, 1.0f);
glVertex3f(1.0f, -1.0f, 1.0f);
glColor3f(0.0f, 1.0f, 0.0f);
glVertex3f(1.0f, -1.0f, -1.0f);
glColor3f(1.0f, 0.0f, 0.0f);
glVertex3f(0.0f, 1.0f, 0.0f);
glColor3f(0.0f, 1.0f, 0.0f);
glVertex3f(1.0f, -1.0f, -1.0f);
glColor3f(0.0f, 0.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glColor3f(1.0f, 0.0f, 0.0f);
glVertex3f(0.0f, 1.0f, 0.0f);
glColor3f(0.0f, 0.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glColor3f(0.0f, 1.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glEnd();
rtri += 0.1;
glutSwapBuffers();
}
void reshape(int width, int height)
{
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, (GLfloat)width / (GLfloat)height, 0.1, 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void keyboard(unsigned char key, int x, int y)
{
switch (key)
{
case'x':
exit(0);
break;
default:
break;
}
}
int main(int argc ,char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowSize(640, 480);
glutInitWindowPosition(100, 100);
glutCreateWindow("Transform2");
init();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);
glutIdleFunc(display);//
glutMainLoop();
return 0;
}
升级1:
#include "pch.h"
#include <iostream>
using namespace std;
#include<GL/glut.h>
#include <windows.h>
float rtri=0.1,a=0.1;//金字塔旋转角度
void init(void)
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glShadeModel(GL_SMOOTH);
glEnable(GL_DEPTH_TEST);//激活深度测试
}
void mymouse(GLint button, GLint state, GLint wx, GLint wy)
{
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
a += 0.2;
if (button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN)
if (rtri > 0) a -= 0.1;
if (button == GLUT_MIDDLE_BUTTON && state == GLUT_DOWN)
exit(0);
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(-1.5, 0.0, -6);
glRotatef(rtri, 0.0, 1.0, 0.0);//x,y,z谁不为0绕谁转,正数逆时针
glBegin(GL_TRIANGLES);//绘制四棱锥
glColor3f(1.0f, 0.0f, 0.0f);
glVertex3f(0.0f, 1.0f, 0.0f);
glColor3f(0.0f, 1.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glColor3f(0.0f, 0.0f, 1.0f);
glVertex3f(1.0f, -1.0f, 1.0f);
glColor3f(1.0f, 0.0f, 0.0f);
glVertex3f(0.0f, 1.0f, 0.0f);
glColor3f(0.0f, 0.0f, 1.0f);
glVertex3f(1.0f, -1.0f, 1.0f);
glColor3f(0.0f, 1.0f, 0.0f);
glVertex3f(1.0f, -1.0f, -1.0f);
glColor3f(1.0f, 0.0f, 0.0f);
glVertex3f(0.0f, 1.0f, 0.0f);
glColor3f(0.0f, 1.0f, 0.0f);
glVertex3f(1.0f, -1.0f, -1.0f);
glColor3f(0.0f, 0.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glColor3f(1.0f, 0.0f, 0.0f);
glVertex3f(0.0f, 1.0f, 0.0f);
glColor3f(0.0f, 0.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glColor3f(0.0f, 1.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glEnd();
rtri +=a;
glutSwapBuffers();
}
void reshape(int width, int height)
{
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, (GLfloat)width / (GLfloat)height, 0.1, 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void keyboard(unsigned char key, int x, int y)
{
switch (key)
{
case'x':
exit(0);
break;
default:
break;
}
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowSize(640, 480);
glutInitWindowPosition(100, 100);
glutCreateWindow("Transform2");
init();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);
glutMouseFunc(mymouse);
glutIdleFunc(display);
glutMainLoop();
return 0;
}
实验结果即为实验要求!