




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
第1章OpenGL基礎(chǔ)知識
☆掌握圖形學(xué)編程的基本概念☆了解OpenGL基本功能與操作☆學(xué)習(xí)圖形系統(tǒng)和模型的基本原理、結(jié)構(gòu)1.1OpenGL概述
1.1.1直觀的三維圖形開發(fā)環(huán)境
OpenGL是美國SGI公司為圖形工作站開發(fā)的一種功能強(qiáng)大的三維圖形機(jī)制,其目的是將用戶從具體的硬件系統(tǒng)和操作系統(tǒng)中解放出來,可以完全不去理解這些系統(tǒng)的結(jié)構(gòu)和指令系統(tǒng),只要按規(guī)定的格式書寫應(yīng)用程序就可以在任何支持該語言的硬件平臺上運(yùn)行。 OpenGL實(shí)際上是一種圖形與硬件的接口。它包括了幾百個指令和函數(shù),開發(fā)者可以用這些函數(shù)來建立三維模型和進(jìn)行三維實(shí)時交互。與其他圖形程序設(shè)計(jì)接口不同,OpenGL提供了十分清晰明了的圖形函數(shù)。1.1.2三維圖形開發(fā)標(biāo)準(zhǔn)
許多計(jì)算機(jī)公司已經(jīng)把OpenGL集成到各種窗口和操作系統(tǒng)中,其中操作系統(tǒng)包括UNIX、WindowsNT、DOS等,窗口系統(tǒng)有X窗口、Windows等。為了實(shí)現(xiàn)一個完整功能的圖形處理系統(tǒng),設(shè)計(jì)一個與OpenGL相關(guān)的系統(tǒng)結(jié)構(gòu)為:其最底層是圖形硬件,第二層為操作系統(tǒng),第三層為窗口系統(tǒng),第四層為OpenGL,第五層為應(yīng)用軟件。OpenGL是網(wǎng)絡(luò)透明的,在客戶—服務(wù)器(Client-Server)體系結(jié)構(gòu)中,OpenGL允許本地和遠(yuǎn)程繪圖。所以在網(wǎng)絡(luò)系統(tǒng)中,OpenGL在X窗口、Windows或其它窗口系統(tǒng)下都可以以一個獨(dú)立的圖形窗口出現(xiàn)。1.1.3OpenGL基本功能與操作
OpenGL能夠?qū)φ麄€三維模型進(jìn)行渲染著色,從而繪制出與客觀世界十分類似的三維景象。另外OpenGL還可以進(jìn)行三維交互、動作模擬等。具體的功能主要有以下這些內(nèi)容。(1)模型繪制(2)模型觀察(3)顏色模式的指定(4)光照應(yīng)用(5)圖象效果增強(qiáng)(6)位圖和圖象處理OpenGL還提供了專門對位圖和圖象進(jìn)行操作的函數(shù)。(7)紋理映射(8)實(shí)時動畫(9)交互技術(shù)1.1.4OpenGL的體系結(jié)構(gòu)
OpenGL是一個獨(dú)立于硬件的高效接口,其中沒有執(zhí)行窗口任務(wù)或獲取用戶輸入的函數(shù),程序員必須通過窗口系統(tǒng)來控制硬件。因此在三維圖形的繪制過程中,應(yīng)用程序需要利用OpenGL與操作系統(tǒng)的基本指令,使窗口系統(tǒng)與操作系統(tǒng)進(jìn)行交互控制,通過硬件驅(qū)動程序操作各個圖形硬件,進(jìn)而完成三維圖形的繪制。應(yīng)用軟件OpenGL窗口系統(tǒng)操作系統(tǒng)圖形硬件
網(wǎng)絡(luò)下的OpenGL體系結(jié)構(gòu),在實(shí)際操作中,應(yīng)用程序發(fā)出OpenGL命令,由動態(tài)鏈接庫OpenGL32.dll接受打包后,發(fā)送到服務(wù)器端的WINSRV.DLL,然后由它通過DDI層發(fā)往視頻顯示驅(qū)動程序。如果系統(tǒng)安裝了硬件加速器,則由硬件相關(guān)的DDI來處理。
應(yīng)用程序OpenGL32.DLLGDI32.DLL可安裝的客戶端驅(qū)動程序WINSRV.DLL相關(guān)DDIWIN32.DDI視頻顯示驅(qū)動程序
1.1.5創(chuàng)建OpenGL控制臺應(yīng)用程序框架
1)OpenGL安裝(以VisualStudio.Net2008為例)2)OpenGL工程配置與測試3)OpenGL程序測試
1.1.6VisualC++6.0環(huán)境下OpenGL單文檔應(yīng)用程序框架
1)OpenGL安裝(以VisualStudio6.0為例)1、下載OpenGL類庫/source/274113(這個是1.4版本的),也可以到OpenGL官網(wǎng)下載其他版本。將下載的文件解壓到一個臨時文件夾中。2、將解壓文件中的所有.h頭文件拷貝到C:\ProgramFiles\MicrosoftVisualStudio6.0\VC\include\GL目錄中(沒有GL目錄就自己創(chuàng)建一個,這里的具體路徑看電腦上VisualStudio6.0安裝的位置而定);將.lib文件拷貝到C:\ProgramFiles\MicrosoftVisualStudio6.0\VC\lib目錄中;將.dll文件拷貝到C:\Windows\System32目錄中。2)OpenGL工程配置與測試啟動VC6,新建一個Win32ConsoleApplication1、按照如下順序選擇:Project→Settings→Link選項(xiàng)卡然后,在Object/librarymodules下面的文本框的最前面添加如下庫文件內(nèi)容:Opengl32.libglut32.libGLAUX.LIBGlu32.lib最后,在ProjectOptions中修改subsystem:console修改為subsystem:windows。2、再按照如下順序選擇:Project→Settings→C/C++選項(xiàng)卡將Preprocessordefinitions中的_CONSOLE修改為_WINDOWS。這樣可以進(jìn)行OpenGL應(yīng)用程序的測試了。1.2OpenGL圖形的實(shí)現(xiàn)方式
1.2.1設(shè)備上下文DC與渲染上下文RC
OpenGL的繪圖方式與Windows的一般的繪圖方式是不同的,其區(qū)別主要表現(xiàn)在以下3個方面:①Windows采用的是GDI繪圖。②OpenGL采用的是渲染上下文RC(RenderContext,又稱渲染描述表)繪圖。③OpenGL使用的是特殊的像素格式。在Windows中使用GDI繪圖時必須指定在哪個設(shè)備上下文(DeviceContext,又稱設(shè)備描述表)中繪制。同樣地,在使用OpenGL函數(shù)時也必須指定一個所謂的渲染上下文。正如設(shè)備上下文DC要存儲GDI的繪制環(huán)境信息如筆、刷和字體等,渲染上下文RC也必須存儲OpenGL所需的渲染信息如像素格式等。
兩種管理RC與DC的方法。
方法1:RC由WM_CREATE消息響應(yīng)時創(chuàng)建,創(chuàng)建后立即釋放DC;當(dāng)WM_PAINT消息到來時,程序再獲取DC句柄,并與RC關(guān)聯(lián)起來,繪圖完成后,立即解除RC與DC的關(guān)聯(lián),并釋放DC;當(dāng)WM_DESTROY消息到來時,程序只需簡單地刪除RC即可,如圖1.9所示。
方法2:RC在程序開始時創(chuàng)建并使之成為現(xiàn)行RC。它將保持為現(xiàn)行RC直至程序結(jié)束。相應(yīng)地,GetDC在程序開始時調(diào)用,ReleaseDC在程序結(jié)束時才調(diào)用。
1.2.3OpenGL圖形處理流程
OpenGL的工作流程如圖所示:1.2.4OpenGL圖形繪制方式
OpenGL中的模型繪制過程就多種多樣,內(nèi)容十分豐富,OpenGL提供了以下的對三維物體的繪制方式:(1)線框繪制方式(Wireframe):繪制三維物體的網(wǎng)格輪廓線。(2)深度優(yōu)先線框繪制方式(Depthcued):(3)反走樣線框繪制方式(Antialiased):(4)平面明暗處理方式(Flatshading):(5)光滑明暗處理方式(Smoothshading):(6)加陰影和紋理的方式(ShadowandTexture):(7)運(yùn)動模糊繪制方式(Motionblured):(8)大氣環(huán)境效果(Atmosphereeffects):(9)深度域效果(Depthofeffects):1.2.5OpenGL程序的運(yùn)行方式
運(yùn)行OpenGL主要有以下3種方式:1)OpenGL硬件加速方式2)三維圖形加速模式3)純軟件模式1.3OpenGL圖形開發(fā)庫
1.3.1開發(fā)庫的組成
OpenGL函數(shù)庫相關(guān)的API有核心庫(gl)、實(shí)用庫(glu)、輔助庫(aux)、實(shí)用工具庫(glut)、窗口庫(glx、agl、wgl)和擴(kuò)展函數(shù)庫等。從圖1可以看出,gl是核心,glu是對gl的部分封裝。glx、agl、wgl是針對不同窗口系統(tǒng)的函數(shù)。glut是為跨平臺的OpenGL程序的工具包,比aux功能強(qiáng)大。擴(kuò)展函數(shù)庫是硬件廠商為實(shí)現(xiàn)硬件更新利用OpenGL的擴(kuò)展機(jī)制開發(fā)的函數(shù)。1.3.2基本數(shù)據(jù)類型
OpenGL是一個跨平臺的API,數(shù)據(jù)類型的大小會隨使用的編程語言以及處理器(64位,32位,16位)等的不同而不同,所以O(shè)penGL定義了自己的數(shù)據(jù)類型。
1.3.3OpenGL庫函數(shù)命名規(guī)則
所有OpenGL函數(shù)采用了以下格式:
<庫前綴><根命令><可選的參數(shù)個數(shù)><可選的參數(shù)類型>
庫前綴有g(shù)l、glu、aux、glut、wgl、glx等等,分別表示該函數(shù)屬于OpenGL某開發(fā)庫等,從函數(shù)名后面中還可以看出需要多少個參數(shù)以及參數(shù)的類型。I代表int型,f代表float型,d代表double型,u代表無符號整型。注意,有的函數(shù)參數(shù)類型后綴前帶有數(shù)字2、3、4。2代表二維,3代表三維,4代表alpha值(以后介紹)。有些OpenGL函數(shù)最后帶一個字母v,表示函數(shù)參數(shù)可用一個指針指向一個向量(或數(shù)組)來替代一系列單個參數(shù)值。1.4基于OpenGL的高層圖形庫
除了基于底層三維圖形庫的OpenGL之外,目前還出現(xiàn)了許多高層的三維圖形開發(fā)庫。當(dāng)前支持實(shí)時三維圖形開發(fā)的軟件包包括IRISPerformer,MultiGen-ParadigmVega,CG2Vtree,SoftRealitySoftVR,CarmelAppliedTechnologyX-IG,Reality2Tiepolo,ThomsonTrainingSimulationSPACEMagic,LockedMartinSE/ViewQuantum3DOpenGVS等等。
1.5OpenGL應(yīng)用程序框架
1、Window32控制臺程序框架用OpenGL編寫的程序結(jié)構(gòu)類似于用其他語言編寫的程序。實(shí)際上,OpenGL是一個豐富的三維圖形函數(shù)庫,編寫OpenGL程序并非難事,只需在基本程序語言中調(diào)用這些函數(shù),用法基本類似,但也有部分不同之處。對于簡單的控制臺程序,只需按以下步驟即可進(jìn)行OpenGL編程:①創(chuàng)建一個新工程。②設(shè)置包含文件和庫文件路徑。③加入OpenGL庫。2.Win32SDK程序框架Win32軟件開發(fā)包(SDK)是在Windows32位機(jī)平臺下的軟件開發(fā)包,包含了各類API函數(shù)及其相關(guān)套件。Win32程序總是依托于窗口,采用事件驅(qū)動方式,基于消息機(jī)制。1)WM_CREATE消息的響應(yīng)2)WM_PAINT消息響應(yīng)3、MFC程序框架MFC是一套面向?qū)ο蟮暮瘮?shù)庫,以類的方式提供給開發(fā)者,它將WindowsAPI函數(shù)封裝到類中。所以MFC的底層還是Win32程序。每個Win32應(yīng)用程序都要完成固定的任務(wù),MFC也不例外,比如要定義一個窗口類,注冊窗口類,要創(chuàng)建窗口,進(jìn)行消息循環(huán)、窗口過程定義等。但是MFC的工程代碼里找不到這些明顯的定義代碼,因?yàn)镸FC底層框架類中封裝了這些部分,只有當(dāng)程序編譯鏈接時,由鏈接器將那些基本的函數(shù)鏈接到MFC程序中,同時,MFC基于消息映射機(jī)制,可能跟Win32程序的直接消息處理方法上有所不同,但是本質(zhì)是一樣的。
1.6開發(fā)實(shí)例:基本二維幾何物體繪制
這個例子我們可以看到OpenGL可以做什么,當(dāng)然這個例子只做了很簡單的一件事--繪制一個彩色的三角形。除此以外,我們還可以看到典型的OpenGL程序結(jié)構(gòu)及openGL的運(yùn)行順序。
1.7本章小結(jié)與習(xí)題
第2章OpenGL建模技術(shù)
☆圖形顯示控制☆點(diǎn)、線段、多邊形的繪制☆規(guī)則三維物體繪制函數(shù)☆曲線、樣條曲線、樣條曲面、NURBS曲線和曲面繪制☆二次曲面☆顯示列表概念、創(chuàng)建、執(zhí)行、索引和嵌套
2.1基本圖元及規(guī)則物體繪制
任何復(fù)雜的圖形模型都是由基本的幾何圖元———點(diǎn)、線段和多邊形組成的,基本幾何圖元的構(gòu)造是OpenGL一切后續(xù)處理的基礎(chǔ)。這一節(jié)講述OpenGL中的基本圖元操作,在這之前,必須熟悉OpenGL圖形的基本顯示控制。
2.1.1圖形顯示控制
1.刷新窗口在一般情況下,在繪制一幅圖形之前,需要將計(jì)算機(jī)內(nèi)存中的原始內(nèi)容清除掉,用戶可以自行設(shè)置清除的背景顏色值。OpenGL之所以提供清除窗口函數(shù),是因?yàn)樗壤L制一個覆蓋整個窗口的顏色矩形要更有效也更快;OpenGL允許用戶設(shè)置坐標(biāo)系統(tǒng)、視點(diǎn)和視角,而此時要給出相應(yīng)覆蓋窗口矩形的位置和大小比較困難;如果使用OpenGL的消隱技術(shù)(后面目標(biāo)會被前面目標(biāo)遮住),則當(dāng)使用清除窗口多邊形作為背景時,必須保證它處在其他物體的后面。這在任意坐標(biāo)和視點(diǎn)的情況下很難保證;最后,大多數(shù)計(jì)算機(jī)上除了像素顏色緩存區(qū)外還有其他一些圖形硬件支持的緩沖區(qū),這些緩沖區(qū)也必須逐次清除。。
2.指定繪圖顏色在OpenGL中的幾何體和顏色是分開的。不論什么時候要繪制幾何模型時,都使用當(dāng)前指定的顏色來繪制,OpenGL程序首先設(shè)置顏色,然后繪制目標(biāo)。除非重新設(shè)置了顏色,否則所有物體都將用該顏色來繪制。此方法與不存儲當(dāng)前顏色相比,可以獲得更高的繪制效率。在OpenGL中,指定當(dāng)前繪圖顏色的函數(shù)原型如下:voidglColor3{b,d,f,s,i,ub,ui,us}(TYPEred,TYPEgreen,TYPEblue);voidglColor4{b,d,f,s,i,ub,ui,us}(TYPEred,TYPEgreen,TYPEblue,TYPEalpha);voidglColor3{b,d,f,s,i,ub,ui,us}v(constTYPE*v);voidglColor3{b,d,f,s,i,ub,ui,us}v(constTYPE*v);
3.強(qiáng)制繪圖完成在高檔體系結(jié)構(gòu)中,每種操作是由圖形硬件的不同部分分別執(zhí)行的,CPU負(fù)責(zé)控制,這樣才可以保證計(jì)算機(jī)資源的充分利用,提高作圖質(zhì)量和速度。在這個協(xié)調(diào)工作的計(jì)算機(jī)系統(tǒng)中,CPU并不是把命令一條一條地分送給作圖硬件,而是把命令放在一個緩沖區(qū)中,成批成批地分送到執(zhí)行硬件中。這就存在著一個如果緩沖區(qū)未滿的情況下,強(qiáng)行讓硬件操作的問題。在特殊的情況下,可以要求作圖硬件系統(tǒng)完成某項(xiàng)操作后,CPU才可以繼續(xù)做其他的事情。在OpenGL提供了兩個解決這個問題的函數(shù),函數(shù)的原型如下:voidglFinish(void)功能:在有限時間內(nèi)強(qiáng)制執(zhí)行OpenGL命令。
4.消隱在三維空間中,一些物體遮擋另一些物體是很自然的一件事情,而且這種遮擋關(guān)系隨視點(diǎn)的不同而不同。清除一個物體被其他物體擋住的部分的操作稱為消隱。OpenGL中,消隱操作是由深度buffer(Z-buffer)來實(shí)現(xiàn)的,深度buffer為窗口的每個點(diǎn)保留一個深度值,這個深度值記錄了視點(diǎn)到占有該像素的目標(biāo)的垂直距離,然后根據(jù)組成物體像素點(diǎn)的不同深度值,決定該點(diǎn)是否需要顯示到屏幕上。在OpenGL中,設(shè)置深度緩存的清除值的函數(shù)原型如下:voidglClearDepth(Glclampddepth);功能:指定深度緩沖區(qū)的清除值。
5.構(gòu)造圖形在OpenGL中繪制一組頂點(diǎn)、線段或多邊形,必須使用一個函數(shù)對glBegin()和glEnd()。傳遞給glBegin()函數(shù)的參數(shù)惟一確定了繪制哪些幾何圖元,在函數(shù)對gl-Begin()和glEnd()中給出了這些頂點(diǎn)的定義,該函數(shù)的原型如下:voidglBegin(GLenummode);voidglEnd(void);功能:指定一個或一組相似圖元的頂點(diǎn)。參數(shù)說明:mode指定由函數(shù)對glBegin和gIEnd提供的頂點(diǎn)所要創(chuàng)建的圖元類型。
2.1.2點(diǎn)的繪制
OpenGL中的點(diǎn)由一組數(shù)來定義的。在一般情況下,所有的內(nèi)部計(jì)算均以三維方式進(jìn)行的。當(dāng)用戶只定義(x,y)二維數(shù)據(jù)時,OpenGL會自動將z軸坐標(biāo)賦值0。OpenGL運(yùn)用三維投影坐標(biāo)系進(jìn)行計(jì)算時,x,y,z三者是均勻等比例的,因此在內(nèi)部計(jì)算時,所有頂點(diǎn)用4個浮點(diǎn)來表示(x,y,z,w),如果w不為0,則該坐標(biāo)對應(yīng)于歐幾里德三維點(diǎn)(x/w,y/w,z/w)。在程序中可以使用OpenGL命令指定w坐標(biāo),如果沒有指定w坐標(biāo),則其默認(rèn)值為1.0。在OpenGL中,對點(diǎn)這個基本圖元有如下操作:
1.定義頂點(diǎn)坐標(biāo)在OpenGL中,定義頂點(diǎn)坐標(biāo)的函數(shù)是glVertex(),該函數(shù)的原型如下:voidglVertex{234}{sidf}[v](TYPEcoords);功能:指定一個頂點(diǎn)。參數(shù)說明:{234}指定頂點(diǎn)的維數(shù),即點(diǎn)是二維的,或者是三維的或者是四維的。{sidf}指定點(diǎn)的數(shù)據(jù)類型,即點(diǎn)的數(shù)據(jù)是雙精度的,或者是浮點(diǎn)精度的,或者是整形精度的,或者是短整形精度的。[v]是可選的,指定一個指向二元、三元或者是四元數(shù)組的指針。二元數(shù)組中包含的元素是x和y,三元數(shù)組中包含的元素是x,y和z,四元數(shù)組中包含的元素是x,y,z和w。2.設(shè)定點(diǎn)的大小在OpenGL中,設(shè)定點(diǎn)的大小的函數(shù)是glPointSize(),該函數(shù)的原型如下:voidglPointSize(GLfloatsize);功能:指定光柵化的點(diǎn)的直徑。參數(shù)說明:size指定光柵化的點(diǎn)的直徑,它的初始值是1。
2.1.3線段的繪制
OpenGL中的線段與幾何中定義的略有不同,分為三種不同的類型:1.線段線段是由空間上兩個點(diǎn)決定的一條直線,glBegin()函數(shù)中mode的取值為GLLINES。2.折線折線是由空間上一系列的點(diǎn)決定的,第一個點(diǎn)的坐標(biāo)是折線和第一條線段的起點(diǎn)坐標(biāo),第二個點(diǎn)的坐標(biāo)是第一條線段的終點(diǎn)坐標(biāo)也是第二條線段的起點(diǎn)坐標(biāo),其后各點(diǎn)依次類推。3.封閉線除最后一個點(diǎn)自動與第一個點(diǎn)相連外,封閉線與折線沒有其他的區(qū)別。(1)設(shè)定線寬在OpenGL中,設(shè)定線寬的函數(shù)是glLineWidth(),該函數(shù)的原型如下:voidglLineWidth(GLfloatwidth);功能:指定光柵化線的寬度。(2)設(shè)定線型在OpenGL中,設(shè)定線型的函數(shù)是glLineStipple(),該函數(shù)的原型如下:
voidglLineStipple(GLintfactor,GLushortpattern);功能:指定線的點(diǎn)畫繪制模板。
2.1.4多邊形的繪制
多邊形是指封閉曲線圍成的區(qū)域。在OpenGL中可以描述的多邊形有兩點(diǎn)限制:1、多邊形的邊和邊除了多邊形的頂點(diǎn)外不可以相交。2、多邊形必須是凸多邊形,所謂凸多邊形是指多邊形任意非相鄰的兩點(diǎn)的連線位于多邊形的內(nèi)部。在OpenGL中,多邊形的繪制分為三角形、四邊形、多邊形、相連三角形、扇形三角形和相連四邊形等6種。
2.1.5規(guī)則三維物體繪制函數(shù)
在OpenGL的輔助庫中,提供了繪制11種基本幾何圖形的函數(shù),每一種圖形又包括線框體和實(shí)心體兩種形式,因此共有22個函數(shù).如:voidauxWireSphere(GLdoubleradius);
voidauxSolidSphere(GLdoubleradius);功能:繪制一個球體的線框圖和實(shí)體圖。參數(shù)說明:radius指定所繪制球體的半徑。voidauxWireBox(GLdoublewidth,GLdoubleheight,GLdoubledepth);voidauxSolidBox(GLdoublewidth,GLdoubleheight,GLdoubledepth);功能:繪制一個長方體線框圖和實(shí)體圖。
2.1.6開發(fā)實(shí)例:基本三維幾何物體繪制
下面介紹一個實(shí)例,通過它介紹如何繪制各種基本圖元,以及如何設(shè)置繪圖的顏色,其中有些函數(shù)目前還沒有介紹,但是并不影響對程序的理解,這些函數(shù)將在后面的章節(jié)陸續(xù)介紹。規(guī)則三維物體如球體、圓錐等的繪制技術(shù)的實(shí)例,與基本圖元的繪制技術(shù)類似,請讀者自行參考第1章。該應(yīng)用程序是基于控制臺運(yùn)行模式。
2.2曲線與曲面繪制
2.2.1曲線的基本理論
1)參數(shù)曲線最常用的曲線表現(xiàn)形式是顯式參數(shù)形式,這也是OpenGL所使用的形式。還有其他一些表現(xiàn)形式,如隱含式和代數(shù)式等。2)多項(xiàng)式曲線曲線在數(shù)學(xué)上可以表示為多項(xiàng)式。下面的表達(dá)式表示x和y作為u的三次多項(xiàng)式函數(shù)。x(u)=a0+a1u1+a2u2+a3u3y(u)=b0+b1u1+b2u2+b3u3式中ai和bi稱為參數(shù)。3)參數(shù)樣條曲線將多個多項(xiàng)式合起來形成一個分段多項(xiàng)式,分段多項(xiàng)式使曲線的造型具有更大的靈活性,這樣的分段多項(xiàng)式稱為樣條函數(shù)。樣條函數(shù)的階定義為各多項(xiàng)式中階數(shù)最高的那個多項(xiàng)式的階(階=多項(xiàng)式次數(shù)+1)。一般情況下,樣條函數(shù)中每個多項(xiàng)式都具有相同的界。多項(xiàng)式曲線段相連處的斷點(diǎn)稱為節(jié)點(diǎn)。4)B樣條曲線B樣條是分段多項(xiàng)式的一種簡單表示。B樣條曲線的節(jié)點(diǎn)是一個多項(xiàng)式線段結(jié)束而另一個多項(xiàng)式線段開始的地方。下面介紹B樣條曲線的形狀是如何控制的。(1)控制點(diǎn)(2)基函數(shù)基函數(shù)定義控制點(diǎn)對曲線的影響程度,哪些控制點(diǎn)影響曲線以及在什么地方曲線受哪個控制點(diǎn)的影響。(3)節(jié)點(diǎn)節(jié)點(diǎn)決定如何以及在什么地方定義基函數(shù)。(4)加權(quán)假定要使某個控制點(diǎn)對曲線的影響力大于其他控制點(diǎn),可以為該節(jié)點(diǎn)賦予一個較大的權(quán)值以改變該點(diǎn)對曲線的影響力。(5)NURBS曲線NURBS曲線是由分段有理B樣條多項(xiàng)式基函數(shù)定義的,具有許多有用的性質(zhì)。例如,可以用NURBS準(zhǔn)確地表示圓、拋物線、橢圓、雙曲線等二次曲線。
2.2.2樣條曲線的繪制
在OpenGL中,為了繪制一條樣條曲線,必須先定義求值器,然后才能計(jì)算曲線上點(diǎn)的坐標(biāo)并完成曲線的繪制。1)定義求值器在OpenGL中,定義一維求值器的函數(shù)是glMap1(),該函數(shù)的原型如下:
voidglMap1{fd}(GLenumtarget,GLfloatu1,GLfloatu2,GLintstride,GLintorder,constGLdouble*points);功能:定義一個一維求值器。參數(shù)說明:target指定由求值器所生成的值的種類。2)計(jì)算曲線坐標(biāo)在OpenGL中,計(jì)算曲線坐標(biāo)的函數(shù)是glEvalCoord1(),該函數(shù)的原型如下:voidglEvalCoord1{fd}[v](TYPEu);功能:求取有效的一維映射值。
參數(shù)說明:指定一個由函數(shù)glMap1定義的基礎(chǔ)函數(shù)的域坐標(biāo)u的值。此函數(shù)計(jì)算曲線上頂點(diǎn)的坐標(biāo),并將此坐標(biāo)設(shè)置為該頂點(diǎn)的當(dāng)前坐標(biāo)。該函數(shù)每調(diào)用一次只產(chǎn)生一個頂點(diǎn)的坐標(biāo)值。3)計(jì)算均勻間隔坐標(biāo)在使用函數(shù)glEvalCoord1()時,由于u的取值可以是定義域中的任意值,因此得到的坐標(biāo)也是任意的。在通常情況下,計(jì)算曲線坐標(biāo)時,采用均勻分割定義域的方法。要得到均勻分割后的坐標(biāo)值,OpenGL提供了兩個函數(shù)glMapGrid1()和glE-valMesh1(),函數(shù)原型分別介紹如下:voidglMapGrid1{fd}(GLintun,TYPEu1,TYPEu2);
功能:定義一個一維的網(wǎng)格。
參數(shù)說明:un指定網(wǎng)格范圍[u1,u2]之間的等份數(shù)。它必須是正整數(shù)。u1,u2指定整形網(wǎng)格域值i=0和i=un的映射值。
2.2.3樣條曲面的繪制
樣條曲面的繪制方法在原理上與樣條曲線基本相同,所不同的是曲面使用二維求值器,并且控制點(diǎn)連接起來形成一個網(wǎng)格。1)定義求值器
對于曲面,求值器函數(shù)除了使用兩個參數(shù)u和v外,其余與一維求值器基本相同。頂點(diǎn)坐標(biāo)、顏色、法線矢量和紋理坐標(biāo)都對應(yīng)于曲面而不是曲線。在OpenGL中,定義二維求值器的函數(shù)是glMap2(),該函數(shù)的原型如下:voidglMap2{fd}(GLenumtarget,TYPEu1,TYPEu2,GLintus-tride,GLintuorder,TYPEv1,TYPEv2,GLintvstrideGLintvorder,constTYPE*points);功能:定義一個二維求值器。參數(shù)說明:target指定求值器所生成的值的種類,其取值及其意義與一維求值器類似。2)計(jì)算曲面坐標(biāo)在OpenGL中,計(jì)算曲面坐標(biāo)的函數(shù)是glEvalCoord2(),該函數(shù)的原型如下:voidglEvalCoord2{fd}[v](TYPEu,TYPEv);
功能:求取有效的二維映射值。參數(shù)說明:u,v指定已經(jīng)由函數(shù)glMap2定義的基礎(chǔ)函數(shù)的域坐標(biāo)u和v的值。此函數(shù)計(jì)算曲面上頂點(diǎn)的坐標(biāo),并將此坐標(biāo)設(shè)置為該頂點(diǎn)的當(dāng)前坐標(biāo)。3)計(jì)算均勻曲面坐標(biāo)與一維曲線情況類似,對于二維情況,同樣可以使用兩個類似的函數(shù)自動生成等間隔的坐標(biāo)值。在OpenGL中,計(jì)算均勻曲面坐標(biāo)的函數(shù)是glMapGrid2()和glEvalMesh2(),兩函數(shù)的原型如下:voidglMapGrid2{fd}(GLintnu,TYPEu1,TYPEu2,GLintnv,TYPEv1,TYPEv2);voidglEvalMesh2{fd}(GLenummode,GLinti1,GLinti2,GLintj1,GLintj2)功能:定義和計(jì)算二維網(wǎng)格的坐標(biāo)值。參數(shù)說明:un,vn指定網(wǎng)格范圍[u1,u2]和[v1,v2]之間的等份數(shù)。它們必須是正整數(shù)。
2.2.4NURBS曲線和曲面繪制
基于求值器的曲線和曲面繪制方法是OpenGL基本函數(shù)庫中惟一直接繪制曲線和曲面的方法,可以得到硬件圖形加速器的支持。OpenGL的實(shí)用函數(shù)庫(GLU)提供了另外一種曲線、曲面繪圖接口,即NURBS接口。這一接口同樣是建立在求值器的基礎(chǔ)上的,但更靈活,使用起來也更方便。1)NURBS的使用在OpenGL中,NURBS曲線和曲面的使用較簡單,進(jìn)行光照處理和紋理映射也很方便。NURBS曲線或曲面的繪制步驟如下:①如果要對曲面進(jìn)行光照處理,首先要指定法線矢量。可以調(diào)glEnable(GL_AUTO_NORMAL)讓OpenGL自動生成,也可以顯式地指定。
②創(chuàng)建一個指向NURBS對象的指針,這個指針在創(chuàng)建NURBS曲線或曲面時要用到。
在OpenGL中,創(chuàng)建NURBS對象的函數(shù)是gluNewNurbsRenderer(),該函數(shù)的原型如下GLUnurbs*gluNewNurbsRenderer(void)
功能:該函數(shù)用來建立并返回一個指向新的NURBS對象的指針。
當(dāng)調(diào)用NURBS的繪圖和控制函數(shù)時,必須提供這個對象。當(dāng)返回值是NUL時,表示沒有足夠的內(nèi)存空間來存放這個對象
。
③設(shè)置NURBS對象的屬性。
在OpenGL中,設(shè)置NURBS對象的函數(shù)是gluNurbsProperty(),該函數(shù)的原型如下:
voidgluNurbsProperty(GLUnurbs*nurb,GLenumproperty,GL-floatvalue);
功能:設(shè)置一條NURBS對象的屬性。
參數(shù)說明:nurb指定NURBS對象。property指定要設(shè)置的屬性。
2.2.5二次曲面
OpenGL實(shí)用函數(shù)庫中提供了一些利用二次曲面技術(shù)繪制幾何圖形(如球體、圓柱體等)的函數(shù),下面介紹幾個比較常用的函數(shù):1)創(chuàng)建二次曲面在OpenGL中,創(chuàng)建二次曲面的函數(shù)是gluNewQuadric(),該函數(shù)的原型如下:CLUquadric*gluNewQuadric(void);功能:創(chuàng)建一個二次曲面對象。該函數(shù)用來建立并返回一個指向新的二次曲面對象的指針。當(dāng)調(diào)用二次曲面的繪圖和控制函數(shù)時,必須提供這個對象。當(dāng)返回值是NULL時,表示沒有足夠的內(nèi)存空間來存放這個對象。該對象使用完成后應(yīng)該調(diào)用gluDeleteQuadric()函數(shù)將其刪除以便釋放所占用的資源。2)二次曲面對象①繪制圓柱體。②繪制圓盤。③繪制盤形的圓弧。④繪制球體。
2.3顯示列表
OpenGL的顯示列表(DisplayList)是由一組預(yù)先定義并儲存起來可以在以后執(zhí)行的OpenGL函數(shù)組成。當(dāng)調(diào)用這個顯示列表時,顯示列表中的函數(shù)被依次執(zhí)行。另外一種繪圖方式是立即方式,就是給出繪圖命令后,OpenGL立即執(zhí)行的方式。
2.3.1顯示列表概念
OpenGL定義顯示列表的目的是提高應(yīng)用程序的運(yùn)行性能,特別是網(wǎng)絡(luò)的性能。顯示列表被設(shè)計(jì)成高速的命令緩存,而不是動態(tài)的數(shù)據(jù)緩存。因此,顯示列表一旦創(chuàng)建,就只能刪除和運(yùn)行,不能修改。從而減少了管理、搜索的開銷,提高了運(yùn)行的性能。采用顯示列表方式,通常會比立即方式要快。
在網(wǎng)絡(luò)環(huán)境下,由于創(chuàng)建好的顯示列表駐留在服務(wù)器上,因此當(dāng)應(yīng)用程序調(diào)用顯示列表時,對網(wǎng)絡(luò)通訊的壓力與立即方式相比要小得多。
在單機(jī)環(huán)境下,顯示列表的優(yōu)勢同樣明顯。下列場合如果應(yīng)用顯示列表,將有可能充分發(fā)揮顯示列表的優(yōu)勢:1)矩陣操作
2)光柵位圖和圖像3)光、材質(zhì)和光照模型4)紋理5)多邊形的圖案填充模式
2.3.2顯示列表的創(chuàng)建
顯示列表必須在創(chuàng)建之后才能使用,這是和函數(shù)定義不一樣的地方。函數(shù)只要聲明和定義之后,在需要使用的地方調(diào)用它即可;而顯示列表不僅需要定義繪制代碼,而且在使用之前需要調(diào)用這段建立顯示列表的程序。 OpenGL提供類似于描述基本圖元的格式,即函數(shù)glBegin()和函數(shù)glEnd()的成對形式來創(chuàng)建顯示列表。OpenGL創(chuàng)建顯示列表使用的函數(shù)是glNewList()和glEndList(),相應(yīng)的函數(shù)原型如下:voidglNewList(Gluintlist,GLenummode);功能:建立或替換一個顯示列表。
2.3.3顯示列表的執(zhí)行
一旦成功地創(chuàng)建了一個顯示列表,就可以在后續(xù)的程序中多調(diào)用該顯示列表。調(diào)用顯示列表的函數(shù)是glCallList(),該函數(shù)的原型如下:voidglCallList(Gluintlist);功能:執(zhí)行一個顯示列表。參數(shù)說明:list指定要執(zhí)行的顯示列表的名稱。如果list所標(biāo)識的顯示列表沒有定義,則不產(chǎn)生任何操作。
2.3.4多重顯示列表
OpenGL提供了一種有效的機(jī)制來依次執(zhí)行多個顯示列表。這種機(jī)制需要將顯示列表索引放入一個數(shù)組中,并調(diào)用glCallLists()函數(shù)。當(dāng)顯示列表索引與有意義的值相對應(yīng)時,就可以使用多重顯示列表來進(jìn)行處理。
在創(chuàng)建多重顯示列表時,需要知道不同顯示列表的正確索引值。OpenGL提供了函數(shù)glListBase()來指定顯示列表的初始索引,該函數(shù)的原型如下:voidglListBase(GLuintbase);功能:為函數(shù)glCallLists設(shè)置顯示列表的基值。
2.3.5顯示列表索引
如果需要刪除某個特定的顯示列表,則可以使用glDeleteLists()函數(shù)。函數(shù)的原型分別介紹如下:GLuintglGenLists(GLsizeirange);功能:建立一組連續(xù)的空顯示列表。參數(shù)說明:range指定要產(chǎn)生的連續(xù)的空顯示列表的數(shù)目。
2.3.6顯示列表的嵌套
顯示列表的嵌套,就是在一個顯示列表中調(diào)用另一個顯示列表,即在函數(shù)glNewList()與函數(shù)glEndList()之間,調(diào)用了函數(shù)glCallList()。顯示列表的嵌套對于構(gòu)造由多個元件組成的物體非常有用,尤其是某些元件需要重復(fù)使用的時候。為了避免陷入無限遞歸,顯示列表的嵌套深度限制為64層(不同平臺的定義略有不同),可以通過調(diào)用函數(shù)glGetIntegerv()來獲取顯示列表的最大嵌套深度。
2.3.7實(shí)例介紹
下面介紹一個如何使用顯示列表的實(shí)例,該實(shí)例是基于控制臺運(yùn)行模式的,在該程序中首先利用顯示列表繪制若干個三角形,然后繪制一條直線。
2.4位圖、圖像與文本繪制
在OpenGL中,除了基本圖元(點(diǎn)、線段和多邊形)外,還有另外兩種圖元類型:位圖和圖像。文本繪制基本上就是上述兩種圖元的擴(kuò)展。這兩種圖元數(shù)據(jù)都是以像素矩陣的形式存儲,即通過一個像素的矩陣數(shù)組來表示一個位圖或圖像。兩者的不同之處在于,位圖包含每個像素的一位信息,而圖像數(shù)據(jù)一般包括每個像素的多位信息(例如:紅、綠、藍(lán)和alpha值);另外,位圖類似于掩碼,可用于遮掩其他的已經(jīng)存在的圖像,而圖像數(shù)據(jù)則簡單地覆蓋原先已經(jīng)存在的數(shù)據(jù)或者與之融合。
2.4.1位圖
一幅位圖是窗口上一塊矩形區(qū)域中的像素,位圖數(shù)據(jù)是一個由0和1組成的二維數(shù)組,每一位對應(yīng)位圖中一個像素。當(dāng)位圖數(shù)據(jù)中的某位為1時,窗口上相應(yīng)位置的像素以當(dāng)前顏色顯示出來;當(dāng)某位為0時,相應(yīng)的像素不變。1)數(shù)據(jù)格式位圖數(shù)據(jù)的格式使用OpenGL的像素存儲格式,控制像素存儲格式的函數(shù)是glPixelStore(),該函數(shù)的原型如下:voidglPixelStore{fi}(GLenumpname,TYPEparam);功能:設(shè)置像素存儲模式。2)光柵坐標(biāo)位圖按光柵圖像的方式繪制,其坐標(biāo)為光柵坐標(biāo)。為了使光柵坐標(biāo)與屏幕上的像素相對應(yīng),OpenGL提供了最底層的函數(shù)glRasterPos(),該函數(shù)的原型如下:voidglRasterPos{234}{sifd}[v](TYPEx,TYPEy,TYPEz,TYPEw);功能:指定像素操作的光柵位置。3)繪制位圖當(dāng)設(shè)置了光柵位置后,就可以調(diào)用函數(shù)glBitmap()來顯示位圖,該函數(shù)的原型如下:glBitmap的函數(shù)原型如下: voidglBitmap(GLsizeiwidth,GLsizeiheight,GLfloatxorig,GLfloatyorig,GLfloatxmove,GLfloatymove,constGlubyte*bitmap);
功能:繪制一個位圖。
參數(shù)說明:width,height指定一個位圖的寬度和高度。
2.4.2圖像
圖像與位圖的不同之處在于:圖像的每一個像素不止用一位表示。例如,對于RGBA顏色模式下的彩色圖像,其中的每一個像素都存儲有完整的RGB信息。
在OpenGL中,可以直接操作幀緩沖區(qū)和內(nèi)存中的圖像數(shù)據(jù)。主要的操作有:從幀緩沖區(qū)中讀取圖像,向幀緩沖區(qū)中繪制圖像,從幀緩沖區(qū)中復(fù)制圖像以及縮放圖像。1)像素讀取OpenGL提供了函數(shù)glReadPixels()進(jìn)行最基本的像素讀取操作,該函數(shù)的原型如下:voidglReadPixels(GLintx,GLinty,GLsizeiwidth,GLsizeiheight,GLenumformat,GLenumtype,GLvoid*pixels);功能:從幀緩沖區(qū)中讀出一個像素塊。2)像素繪制OpenGL提供了函數(shù)glDrawPixels()進(jìn)行最基本像素繪制操作,該函數(shù)的原型如下:voidglDrawPixels(GLsizeiwidth,GLsizeiheight,GLenumformat,GLenumtype,GLvoid*pixels);功能:向幀緩沖區(qū)寫入一個像素塊。參數(shù)說明:width,height指定要寫入幀緩沖區(qū)中的像素矩形的尺寸。3)像素復(fù)制OpenGL提供了函數(shù)glCopyPixels()進(jìn)行最基本像素復(fù)制操作,該函數(shù)的原型如下:voidglCopyPixels(GLintx,GLinty,GLsizeiwidth,GLsizeiheight,GLenumtype);功能:向幀緩沖區(qū)中拷貝像素。參數(shù)說明:x,y指定被拷貝的像素矩形區(qū)域的左下角的窗口坐標(biāo)。4)像素縮放
一般情況下,圖像中的每一個像素對應(yīng)窗口中的一個點(diǎn)。也可以任意地縮小和放大圖像。OpenGL提供了函數(shù)glPixelZoom()進(jìn)行像素縮放操作,該函數(shù)的原型如下:voidglPixelZoom(GLfloatxfactor,GLfloatyfactor);功能:指定像素的縮放比例因子。參數(shù)說明:xfactor,yfactor指定對像素進(jìn)行寫操作時的x和y縮放比例因子。
2.4.3文本
在雙顏色緩沖區(qū)模式下,不能在OpenGL繪圖設(shè)備上使用Windows的GDI字體管理和文本輸出函數(shù),因此也就無法實(shí)現(xiàn)字符串的顯示。為了解決這個問題,WGL提供了兩個函數(shù)wglUseFontBitmaps()和wglUseFontOutlines()分別用于位圖文本和輪廓文本的輸出。由于這兩個函數(shù)是Win32函數(shù),必須使用Windows的窗口系統(tǒng)進(jìn)行編程。1)位圖文本
在雙緩沖區(qū)模式下顯示文本的方法是:將文本中的每一個字符當(dāng)做一個普通的OpenGL物體看待和處理,顯示字符之前,先為每個字符創(chuàng)建一個顯示列表,然后通過執(zhí)行顯示列表完成字符的輸出。OpenGL提供創(chuàng)建位圖字符顯示列表的函數(shù)是wglUseFontBitmaps()BOOLwglUseFontBitmaps(HDChdc,DWORDfirst,DWORDcount,DWORDlistBase);功能:為從first(字符編碼)開始的count個字符分別創(chuàng)建一個顯示列表。2)輪廓文本在雙緩沖區(qū)模式下顯示輪廓文本的方法與顯示位圖文本基本相同。與位圖文本不同的是,輪廓文本是使用二次B樣條曲線描述的。OpenGL提供創(chuàng)建輪廓字符顯示列表的函數(shù)是wglUseFontOutlines(),該函數(shù)的原型如下:BOOLwglUseFontOutlines(HDChdc,DWORDfirst,DWORDcount,DWORDlistBase,FLOATdeviation,FLOATextrusion,intformat,LPGLYPHMETRICSFLOATlpgmf);功能:為從first(字符編碼)開始的count個字符分別創(chuàng)建一個顯示列表。3)實(shí)例介紹
利用輪廓文本很容易實(shí)現(xiàn)3d文本的顯示,下面介紹一個簡單的實(shí)例來顯示一個3d的字符串,該程序是基于Win32運(yùn)行模式的,這一部分代碼的框架可以參考第1章的1.5.3節(jié)。
2.5本章小結(jié)與習(xí)題
2.5.1重點(diǎn)回顧圖元是各類圖形構(gòu)成的基礎(chǔ)。OpenGL中提供了各類基礎(chǔ)圖元構(gòu)建的方法。通過實(shí)踐掌握OpenGL圖元各函數(shù)功能、作用及函數(shù)參數(shù)的意義。2.5.2課后練習(xí)1、OpenGL圖形構(gòu)建的方式有那些?2、OpenGL顏色控制模式及定義?2.5.3實(shí)訓(xùn)技能訓(xùn)練目的:進(jìn)一步熟悉OpenGL的開發(fā)環(huán)境配置方法掌握OpenGL基礎(chǔ)圖元的構(gòu)建模式熟悉VC/VC.net的程序框架與流程技能訓(xùn)練內(nèi)容使用OpenGL繪制一個地球、月亮和太陽的模型。建議通過查資料用MFC來實(shí)現(xiàn)。
第3章
坐標(biāo)變換
☆學(xué)習(xí)三維模型在繪制到二維屏幕之前如何進(jìn)行變換。☆學(xué)習(xí)坐標(biāo)系與坐標(biāo)變換☆學(xué)習(xí)矩陣操作、平移變換、旋轉(zhuǎn)變換、縮放變換、變換次序等☆學(xué)習(xí)控制這些變換的方法,顯示模型的特定視圖。
OpenGL提供了計(jì)算機(jī)圖形學(xué)中最基本的三維變換,包括:視點(diǎn)變換、模型變換、投影變換、剪取變換(附加裁剪面)和視口變換等。同時OpenGL還有針對性地提供了一些特殊的變換和用法,如矩陣堆棧等。
3.1從三維圖形到二維圖像
3.1.1三維圖形的輸出過程
在現(xiàn)實(shí)世界中,觀察到的所有物體對象都具有三維特征。但是在計(jì)算機(jī)屏幕上只能表現(xiàn)二維圖像。那么,在三維圖形到二維平面之間,需要什么樣的變換,才能真實(shí)地反映現(xiàn)實(shí)世界呢?
3.1.2坐標(biāo)系與坐標(biāo)變換
為了能在計(jì)算機(jī)上顯示三維圖形,必須使其適應(yīng)計(jì)算機(jī)。因?yàn)橛?jì)算機(jī)只能處理數(shù)據(jù),因此必須將三維圖形與數(shù)據(jù)相聯(lián)系。而將數(shù)據(jù)與三維圖形聯(lián)系在一起的惟一紐帶,就是坐標(biāo)。從現(xiàn)實(shí)三維世界中獲取的三維對象,本身是包含了現(xiàn)實(shí)世界的坐標(biāo)形式。這個坐標(biāo)系稱之為世界坐標(biāo)系。而屏幕上的二維平面本身又定義了一個坐標(biāo)系,稱為屏幕坐標(biāo)系。三維圖形映射到二維平面上,最重要的一環(huán)就是投影。投影分為透視投影和正交投影兩種。投影平面對應(yīng)的三維空間稱為三維視景體(ViewingVolume)。只有在視景體內(nèi)的三維物體才可能投影到二維平面上。在屏幕坐標(biāo)系中,可以定義一個矩形,稱為視口,視景體投影后的圖形就在視口中顯示出來。視口的坐標(biāo)系與物理設(shè)備的坐標(biāo)系之間可能還存在差異,因此還需要做一些適應(yīng)物理設(shè)備的坐標(biāo)變換。物理設(shè)備的坐標(biāo)系稱為物理設(shè)備坐標(biāo)系。
3.1.3矩陣操作
OpenGL提供了豐富的三維變換函數(shù),用戶可以運(yùn)用這些三維變換函數(shù)自如地進(jìn)行三維圖形操作,同時OpenGL還提供了一系列矩陣操作函數(shù),幫助用戶自己定義變換。下面先介紹這些矩陣操作函數(shù)。1)設(shè)置矩陣類在OpenGL中,設(shè)置矩陣類型的函數(shù)是glMatrixMode(),該函數(shù)的原型如下:voidglMatrixMode(GLenummode);功能:設(shè)置當(dāng)前矩陣。2)裝入矩陣在OpenGL中,裝入矩陣的函數(shù)是glLoadMatrix(),該函數(shù)的原型如下:voidglLoadMatrix{fd}(TYPE*m);功能:用指定的矩陣替換當(dāng)前矩陣。3)裝入單位矩陣在OpenGL中,裝入單位矩陣的函數(shù)是glLoadIdentity(),該函數(shù)的原型如下:voidglLoadIdentity(void);功能:用單位矩陣替換當(dāng)前的矩陣。4)矩陣相乘在OpenGL中,矩陣相乘的函數(shù)是glMultMatrix(),該函數(shù)的原型如下:voidglMultMatrix{fd}(TYPE*m);功能:用指定的矩陣乘以當(dāng)前的矩陣。
3.2幾何變換
幾何變換是指三維場景中的物體運(yùn)動姿態(tài)的變化,包括物體的平移、旋轉(zhuǎn)和縮放。在OenGL中提供了3個命令函數(shù)來實(shí)現(xiàn)平移、旋轉(zhuǎn)和縮放,它們是glTranslate(),glRotate(),glScale(),從而可以確定一個物體在場景中的位置、旋轉(zhuǎn)角度和縮放比例。直接使用OpenGL中的矩陣操作函數(shù)可以實(shí)現(xiàn)幾何變換,但是使用OpenGL中的變換函數(shù),變換的速度要快得多。
3.2.1平移變換
為了便于建模,通常以物體坐標(biāo)系缺省的原點(diǎn)作為模型的初始位置,建模完成后再將物體移至它在場景中應(yīng)處的位置。在OpenGL中,物體的移動是用平移變換函數(shù)glTranslate()來完成的,函數(shù)原型如下:voidglTranslate{fd}(TYPEx,TYPEy,TYPEz);功能:把當(dāng)前矩陣乘上一個平移矩陣。glTranslate()函數(shù)可以作用于幾何矩陣、投影矩陣和紋理坐標(biāo)變換矩陣。如果當(dāng)前矩陣為幾何矩陣,函數(shù)的功能則是將物體坐標(biāo)系的原點(diǎn)移到(x,y,z)所指的位置,形成新的物體坐標(biāo)系。調(diào)用此函數(shù)之后的所有頂點(diǎn)的坐標(biāo)都以新的位置作為原點(diǎn)。換句話說,平移之后所畫的幾何物體都做了相同的平移。glTranslate()函數(shù)平移的是坐標(biāo)系而不是物體,如圖3.2所示。該函數(shù)僅影響在它被調(diào)用之后所繪的物體。如果使用(0,0,0)作為參數(shù)調(diào)用該函數(shù),則不產(chǎn)生任何平移。
3.2.2旋轉(zhuǎn)變換
在OpenGL中,進(jìn)行旋轉(zhuǎn)變換的函數(shù)是glRotate(),該函數(shù)的原型如下:voidglRotate{fd}(TYPEangle,TYPEx,TYPEy,TYPEz);功能:把當(dāng)前矩陣乘上一個旋轉(zhuǎn)矩陣。參數(shù)說明:angle指定旋轉(zhuǎn)角度,其單位是“度”(°)。X,y,z分別指定一個向量的x,y和z坐標(biāo)。函數(shù)glRotate()的作用是繞向量(x,y,z)產(chǎn)生一個angle角度的旋轉(zhuǎn)。當(dāng)前矩陣將被它與一個旋轉(zhuǎn)矩陣相乘后所得的矩陣所替代。
3.2.3縮放變換
在OpenGL中,進(jìn)行縮放變換的函數(shù)是glScale(),該函數(shù)的原型如下:voidglScale{fd}(TYPEx,TYPEy,TYPEz);功能:當(dāng)前矩陣乘以一個普通的縮放矩陣。參數(shù)說明:x,y,z分別指定沿x,y和z軸方向的縮放因子。當(dāng)前矩陣將被它與這個縮放矩陣相乘的結(jié)果所替換。
3.2.4變換次序
在OpenGL中,平移、旋轉(zhuǎn)和縮放變換的組合使用會產(chǎn)生復(fù)雜的變換效果,但是必須注意變換的先后次序,因?yàn)椴煌淖儞Q次序會導(dǎo)致不同的效果。
3.2.5實(shí)例介紹
下面介紹一個應(yīng)用幾何變換的例子,從該例子中可以清晰地分辨出,對一個三角形實(shí)施的平移變換、縮放變換和旋轉(zhuǎn)變換的痕跡。
3.3投影變換投影變換的目的是將三維場景中的物體投影到二維平面上,這個二維平面就是顯示窗口。投影變換定義一個取景器,該取景器決定物體是如何投影到窗口平面上的,并且它還定義了哪些對象或物體的哪些部分從最終的圖像中剪切出去。投影變換同樣是使用矩陣變換來實(shí)現(xiàn)的,與幾何變換不同的是它使用投影矩陣,因此在進(jìn)行投影變換之前必須調(diào)用glMatrixMode(GL_PROJECTION)函數(shù)將當(dāng)前矩陣的類型設(shè)置為投影矩陣。投影變換有兩種,一種是透視投影,這種投影得到的效果與人眼觀察世界的效果相同;另一種是正交投影,它的最大特點(diǎn)是無論物體距離視點(diǎn)多遠(yuǎn),投影后的尺寸不變。在執(zhí)行投影變換命令之前,必須調(diào)用下面的函數(shù),將變換矩陣設(shè)置為投影變換矩陣:glMatrixMode(GL_PROJECTION);//陣模式為投影變換矩陣glLoadIdentity();
3.3.1透視投影
透視投影的取景器被設(shè)計(jì)成一個被截去了頂?shù)乃拿驽F體,因此取景器又稱為觀察錐。落在取景器內(nèi)的物體朝著觀察錐的頂點(diǎn)的方向投影,觀察錐的頂點(diǎn)就是視點(diǎn),靠近視點(diǎn)的平面稱為近剪切面,觀察錐的底稱為遠(yuǎn)剪切面。觀察錐的底平行于xOy平面,并向z軸負(fù)方向延伸。同樣尺寸的物體,離視點(diǎn)越近就顯得越大,這是因?yàn)樗鼈儽饶切┻h(yuǎn)處的物體占據(jù)的取景器空間的比例更大。這種投影方式與人眼的工作方式相似,因此常被用于動畫、視覺模擬等場合。在OpenGL中,定義取景器有2個函數(shù):glFrustum()和gluPerspective()。1)glFrustum()在OpenGL中,glFrustum()的函數(shù)原型如下:voidglFrustum(GLdoubleleft,GLdoubleright,GLdoublebottom,GLdoubletop,GLdoublezNear,GLdoublezFar);功能:用一個透視矩陣乘以當(dāng)前的矩陣。參數(shù)說明:left,right指定左、右垂直剪切平面的坐標(biāo)。bottom,top指定下、上水平剪切平面的坐標(biāo)。zNear,zFar指定視點(diǎn)到最近和最遠(yuǎn)深度剪切平面的距離。二者必須是正數(shù)。2)gluPerspective()在OpenGL中,luPerspective()函數(shù)的原型如下:voidgluPerspective(GLdoublefovy,GLdoubleaspect,GLdoublezNear,GLdoublezFar);功能:立一個透視投影矩陣。參數(shù)說明:ovy指定y方向的取景區(qū)域的角度,值范圍為[0°,180°]。aspect指定x方向的用來確定取景區(qū)域的高寬比。高寬比是x(寬度)與y(高度)的比率。zNear指定視點(diǎn)到最近的裁剪平面的距離(它必須是正數(shù))。zFar指定視點(diǎn)到最遠(yuǎn)的裁剪平面的距離(它必須是正數(shù))。
3.3.2正交投影
正交投影的取景器是一個封閉的平行六面體。與透視投影不同,從一端到另一端,取景器的大小不改變,因此同樣尺寸的物體,距離視點(diǎn)近的物體與離視點(diǎn)遠(yuǎn)的物體經(jīng)投影后,它們的大小仍然是相同的。這類投影通常用于CAD等領(lǐng)域。在OpenGL中設(shè)置正交投影的函數(shù)是glOrtho(),該函數(shù)的原型如下:voidglOrtho(GLdoubleleft,GLdoubleright,GLdoublebottom,GLdoubletop,GLdoublezNear,GLdoublezFar);功能:一個正交矩陣乘以當(dāng)前矩陣。
3.4視窗變換視窗變換類似于照片沖洗過程中的照片裁剪。在計(jì)算機(jī)圖形學(xué)中,視窗是繪制圖像的矩形區(qū)域。視窗以窗口坐標(biāo)來定義,它表示圖像相對于窗口左下角的位置。進(jìn)行視窗變換時,所有頂點(diǎn)都已經(jīng)過幾何變換和投影變換,并且位于取景器之外的圖像已被剪切掉了。
3.4.1定義視窗
打開一個窗口時,系統(tǒng)自動地將視口設(shè)置為整個窗口的大小。在OpenGL中可以用glViewport()函數(shù)來設(shè)置一個較小的繪圖區(qū),該函數(shù)的原型如下:voidglViewport(GLintx,clinty,GLsizeiwidth,GLsizeiheight);功能:設(shè)置視口。視口的寬度和高度被默認(rèn)地截斷到一定的范圍,具體范圍值由所處環(huán)境決定??烧{(diào)用函數(shù)glGet(GL_MAX_VIEWPORT_DIMS)查詢這一范圍值。視口的高寬比一般應(yīng)與投影取景器的高寬比相同,否則會造成圖像的變形。在程序的運(yùn)行過程中,可能會改變窗口的大小,因此程序應(yīng)該能夠檢測到這種變化,并作相應(yīng)的處理。
3.4.2變換z坐標(biāo)
在視口變換中,z坐標(biāo)或深度坐標(biāo)被編碼并被存儲起來。在OpenGL中可以使用glDepthRange()函數(shù)縮放z坐標(biāo)的值,使它位于所要求的范圍內(nèi)。該函數(shù)的原型如下:voidglDepthRange(GLclampedzNear,GLclampedzFar);功能:指定一種從歸一化深度坐標(biāo)到窗口深度坐標(biāo)的映射方法。
3.5附加裁剪面
附加裁剪面可用于顯示物體的剖面圖等情況。每個裁剪面是通過指定方程Ax+By+Cz+D=0中的系數(shù)來確定。裁剪面通過模型和視點(diǎn)變換自動進(jìn)行相應(yīng)的變換。最后的裁剪體成為視圖體和附加裁剪面所定義的半空間的交集。OpenGL會適當(dāng)?shù)刂亟ū蛔詣蛹羟械亩噙呅蔚倪?。在OpenGL中,定義附加裁剪面的函數(shù)是glClipPlane()。該函數(shù)的原型如下:voidglClipPlane(GLenumplane,constGLdouble*equation);功能:指定一個剪切幾何體所用的平面。
3.6矩陣堆棧
堆棧在計(jì)算機(jī)中表示先入后出的內(nèi)存區(qū)域。而OpenGL中的矩陣堆棧,也是以這種方式管理的,專門用于存儲矩陣的內(nèi)存區(qū)域,只不過該堆棧中存放的數(shù)據(jù)單元是矩陣。OpenGL中管理內(nèi)存堆棧的函數(shù)是glPushMatrix()和glPopMatrix(),函數(shù)的原型如下:voidglPushMatrix(void);voidglPopMatrix(void);功能:壓入和彈出當(dāng)前矩陣堆棧。下面介紹一個3個齒輪相互嚙合運(yùn)動的實(shí)例,說明了矩陣堆棧的用法。該實(shí)例基于控制臺運(yùn)行模式,詳細(xì)的源代碼請參考本書,部分關(guān)鍵源代碼介紹如下:1)齒輪繪制函數(shù)。該函數(shù)主要根據(jù)齒輪的參數(shù),如內(nèi)孔直徑、最大外徑和齒輪寬度進(jìn)行齒輪的繪制。2)場景繪制函數(shù)。在該函數(shù)中主要通過調(diào)用顯示列表的模式繪制出3個齒輪,為了控制不同齒輪的繪制位置,采用了壓入和彈出矩陣堆棧的形式。3)空閑響應(yīng)函數(shù)。在該函數(shù)中使齒輪的角度遞增,從而產(chǎn)生動畫效果。4)鍵盤響應(yīng)函數(shù)。在該函數(shù)中主要處理了z和Z鍵以及LEFT,RIGHT,UP,DOWN鍵的響應(yīng)代碼。
第4章OpenGL顏色
☆RGBA顯示模式☆顏色索引模式☆RGBA模式與顏色索引模式的對比☆抖動操作
☆指定陰影模型
OpenGL是用來描述真實(shí)三維世界的,沒有了顏色也就不可能真實(shí)地再現(xiàn)現(xiàn)實(shí)世界。顏色是一門非常復(fù)雜的學(xué)科,涉及到數(shù)學(xué)、物理學(xué)、心理學(xué)和美學(xué)等多個領(lǐng)域。這里僅討論與計(jì)算機(jī)圖形學(xué)有關(guān)的部分。
物體的顏色不僅取決于物體本身,它還與光源、周圍環(huán)境的顏色,以及觀察者的視覺系統(tǒng)都有關(guān)系。
4.1RGBA模式與顏色索引模式
4.1.1RGBA模式與顏色索引模式的對比
在一臺計(jì)算機(jī)彩色顯示器上,電子槍使熒屏上的每個像素發(fā)出不同量的紅、綠、藍(lán)光,稱為R,G,B值。這些值通常被組裝在一起(有時加入第4個值,稱為alpha),合起來稱為RGB(或RGBA)值。每個像素的顏色信息,可以用RGB(或RGBA)方式存儲,也可以用顏色索引方式存儲。顏色索引方式指每個像素的顏色信息存儲單個值(稱為顏色索引)。每個顏色索引定義一組R,G,B值,作為表中的一項(xiàng)。這種表稱為查色表,表中的值可以改變。準(zhǔn)確地回憶顏色對于每個人來說都是很困難的,即使對非常了解的對象的顏色也是如此。光照的位置或強(qiáng)度不同時,顏色也會不同。為了清楚起見,一種顏色通??梢杂盟?種屬性來描述:色調(diào)(hue)、飽和度(saturation)和亮度(lightness)。在OpenGL中通常使用2種顏色模式,即RGBA模式和顏色索引模式。在顏色索引模式下,對每個像素存儲一定數(shù)量的顏色數(shù)據(jù)。這個量是由幀緩存中的位平面數(shù)所確定的,也就是通常說的多少位顏色。如果有8個顏色位平面,則每個像素有8個顏色位,從而對像素可以存儲2=256種不同的顏色。現(xiàn)在的圖形硬件,一般都支持高達(dá)32位顏色位面,通常對R,G,B,A都分配8位,但并非一定得如此??梢哉{(diào)用glGetIntegerv()函數(shù),將參數(shù)分別設(shè)置為:GL_RED_BITS,GL_GREEN_BITS,GL_BLUE_BITS,GL_ALPHA_BITS,GL_INDEX_BITS,來查詢有關(guān)R,G,B,A或顏色索引值的位面數(shù)。
4.1.2RGBA顯示模式
在RGBA顏色模式中,每個像素的R,G,B,A分量被分別保存,其中A分量稱為alpha,主要用于圖像的融合和深度控制。為了適應(yīng)不同的圖形硬件,OpenGL使用浮點(diǎn)數(shù)表示RGBA各分量的值,取值范圍從0.0或-1.0到1.0。這種表示方式的好處是不必考慮位面的數(shù)目,0.0表示該分量的最小強(qiáng)度,1.0表示最大強(qiáng)度。圖形硬件系統(tǒng)只需簡單地乘上位面數(shù)就可以將浮點(diǎn)數(shù)表示的強(qiáng)度值轉(zhuǎn)換成電子束的強(qiáng)度值。在OpenGL中,系統(tǒng)時刻保存著系統(tǒng)使用的當(dāng)前顏色,并且只使用當(dāng)前顏色繪圖。缺省的當(dāng)前顏色為白色(1.0,1.0,1.0),可以使用glColor()函數(shù)改變當(dāng)前的顏色,該函數(shù)的原型如下:voidglColor3{bsifdubusui}(TYPEred,TYPEgreen,TYPEblue);voidglColor4{bsifdubusui}(TYPEred,TYPEgreen,TYPEblue,TYPEalpha);voidglColor3{bsifdubusui}v(constTYPE*v);voidglColor4{bsifdubusui}v(constTYPE*v);功能:設(shè)置當(dāng)前的繪圖顏色。
4.1.3抖動操作
有些圖形硬件使用抖動來增加可以顯示的顏色數(shù)量。為了說明拉動的工作原理,假定系統(tǒng)分別只用1個位來表示RG和B。這樣,它一共可以顯示8種顏色:黑、白、紅、藍(lán)、綠、黃、青和洋紅。為了一塊粉紅色的區(qū)域,圖形硬件仍然采用前面那種棋盤模式的方法,用紅色和白色交替對像素進(jìn)行著色。如果眼睛距離屏幕足夠遠(yuǎn),不能看到單獨(dú)的像素,這塊區(qū)域看上去就是粉紅色的,也就是紅色和白色的均值。深一點(diǎn)的粉紅色可以通過提高紅色像素的比例來實(shí)現(xiàn),淡一點(diǎn)的粉紅色可以通過提高白色像素的比例來實(shí)現(xiàn)。
4.1.4顏色索引顯示模式
在顏色索引模式中,每個像素只保存一個顏色索引號,系統(tǒng)有一張顏色索引表,該表保存每一個索引號和與之對應(yīng)顏色的R,G,B值。這樣的顏色索引表稱為顏色映射(ColorMap)。在OpenGL中的顏色索引模式下,指定顏色的函數(shù)是glIndex(),該函數(shù)的原型如下:voidglIndex{sifdub}(TYPEc
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 濮陽科技職業(yè)學(xué)院《大數(shù)據(jù)統(tǒng)計(jì)模型實(shí)驗(yàn)》2023-2024學(xué)年第二學(xué)期期末試卷
- 喀什大學(xué)《數(shù)字影像工程》2023-2024學(xué)年第二學(xué)期期末試卷
- 安徽工業(yè)經(jīng)濟(jì)職業(yè)技術(shù)學(xué)院《流行音樂經(jīng)典作品分析(2)》2023-2024學(xué)年第二學(xué)期期末試卷
- 公章的管理制度
- 公司章程中內(nèi)控的內(nèi)容
- 公共交通線路調(diào)整管理制度
- 工程施工隊(duì)每周進(jìn)度計(jì)劃表格
- 頁巖磚砌體施工方案
- 【2025年二手房行業(yè)資訊:深圳周錄1812套再創(chuàng)新高】
- 江西省上饒市2024-2025學(xué)年高二上學(xué)期1月期末英語試題【含答案】
- (一模)東北三省三校2025年高三第一次聯(lián)合模擬考試 生物試卷(含答案)
- 污水處理廠工程設(shè)備安裝施工方案及技術(shù)措施
- 2025年海南??谑兴畡?wù)局招聘事業(yè)單位人員35人歷年高頻重點(diǎn)模擬試卷提升(共500題附帶答案詳解)
- 交警大隊(duì)合同范本
- COP生產(chǎn)一致性控制計(jì)劃
- 產(chǎn)業(yè)轉(zhuǎn)移課件-2024-2025學(xué)年高三一輪復(fù)習(xí)人教版(2019)地理選擇性必修2
- 2025年02月中國科協(xié)所屬單位公開招聘社會在職人員14人筆試歷年典型考題(歷年真題考點(diǎn))解題思路附帶答案詳解
- 2025-2030年中國電動滑板車市場運(yùn)行動態(tài)及發(fā)展規(guī)劃分析報告
- 中考英語專題總復(fù)習(xí)-題型9省公開課一等獎百校聯(lián)賽賽課微課獲獎?wù)n件
- 2025年電力人工智能多模態(tài)大模型創(chuàng)新技術(shù)及應(yīng)用報告-西安交通大學(xué)
- 天津2025年天津市機(jī)關(guān)后勤事務(wù)服務(wù)中心分支機(jī)構(gòu)天津市迎賓館招聘2人筆試歷年參考題庫附帶答案詳解
評論
0/150
提交評論