圖形學實驗三 圖形幾何變換
實驗三 圖形幾何變換
實驗型別:設計型 實驗學時: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;
}
實驗結果即為實驗要求!