1. 程式人生 > >圖形學實驗三 圖形幾何變換

圖形學實驗三 圖形幾何變換

實驗三 圖形幾何變換

實驗型別:設計型   實驗學時: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;
}

實驗結果即為實驗要求!