




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)
文檔簡介
實驗二結(jié)合MFC與OpenGL實現(xiàn)三維應(yīng)用程序的顯示實驗?zāi)康氖煜penGL的編程環(huán)境設(shè)置熟悉MFC的基本編程框架MFC與OpenGL混合編程的設(shè)置OpenGL中基本圖元的繪制實驗內(nèi)容創(chuàng)建MFC+OpenGL的編程環(huán)境?利用三角形和四邊形等基本圖元繪制底面圓圓心在坐標(biāo)原點,半徑為r,高為h,方向沿z軸方向的圓柱實驗指導(dǎo)MFC應(yīng)用程序框架在VisualC++2.0以后的版本中,Microsoft公司推出了MFC(MicrosoftFoundationClass)類庫。MFC類庫是用來編寫Windows程序的C++類集。使用MFC類庫,可以簡化應(yīng)用程序的開發(fā),從而縮短開發(fā)周期,而且代碼的可靠性和可重用性也大大提高。MFC應(yīng)用程序的文檔/視圖結(jié)構(gòu)概述MFC提供了一個典型且實用的基于文檔與視圖的應(yīng)用程序框架模板,按照其應(yīng)用程序生成向?qū)У膶?dǎo)引步驟(MFCAppWizard)就可以創(chuàng)建一個基于文檔/視圖結(jié)構(gòu)的MFC應(yīng)用程序框架。在此框架的基礎(chǔ)上,設(shè)計和插入相關(guān)的對象,就可以實現(xiàn)交互式的用戶界面、幾何模型的管理和操作、圖形圖像的顯示,以及其他
各種專業(yè)功能。在MFC的文檔/視圖結(jié)構(gòu)的應(yīng)用程序框架中,文檔類和視圖類是成對出現(xiàn)的。文檔用于管理應(yīng)用程序的數(shù)據(jù);而視圖用于顯示文檔中的數(shù)據(jù),并處理與用戶的交互信息。MFC通過文檔類和視圖類的劃分,使數(shù)據(jù)的存儲和顯示既相對獨立又相互關(guān)聯(lián)。在MFC所提供的框架結(jié)構(gòu)中,文檔與視圖的關(guān)系可以由圖0.1簡要表示。MFC中的視圖和文檔是由視圖類(CViewClass)和文檔類(CDocumentClass)分別表示的。視圖類可以調(diào)用其本身的成員函數(shù)GetDocument(),獲得一個指向文檔類的指針,從而能夠訪問文檔類中的數(shù)據(jù)。例如:在視圖類中的OnDraw()函數(shù)中,視圖類通過調(diào)用GetDocument()函數(shù)獲得一個指向文檔累的指針,然后通過這個指針獲取文檔類中的數(shù)據(jù),并使用CDC類(負(fù)責(zé)處理應(yīng)用程序顯示設(shè)備接口的MFC類)中的函數(shù)將這些數(shù)據(jù)繪制在視圖窗口中。視圖可以通過圖形、圖像、文字、表格等多種方式以視圖對象(CViewObject)來顯示實際的文檔(CDocumentObject)中的數(shù)據(jù)。同時,視圖對象也負(fù)責(zé)接收鼠標(biāo)、鍵盤等用戶輸入信息,并通過這些與用戶之間的交互信息來操作和修改文檔中的數(shù)據(jù)。CDocumentCViewCView圖0.1文檔與視圖的關(guān)系CDocumentCViewCView3.1.2文檔與多個視圖的關(guān)聯(lián)使用MFCAppWizard自動創(chuàng)建的MFC應(yīng)用程序中,為每個文檔類的對象創(chuàng)建并關(guān)聯(lián)了一個視圖類的對對象。實際上,文檔和視圖的關(guān)系可以使一對一或一對多,即一個文檔可以關(guān)聯(lián)一個或一個以上的視圖,也就是可以用多個視圖來顯示和操作文檔中的數(shù)據(jù)時。通常,設(shè)計不同的視圖時為了以不同的方式來顯示文檔內(nèi)容,如圖形、圖表、結(jié)構(gòu)、文字等。如圖0.1所示,一個文檔對象就同時關(guān)聯(lián)了多個視圖對象。當(dāng)在一個視圖類對象中對文檔數(shù)據(jù)做了修改后,可以調(diào)用文檔類的UpdateAllViews()函數(shù)來更新所有與文檔相關(guān)聯(lián)的視圖類對象的顯示,以此來保持所有視圖對同一文檔數(shù)據(jù)變化的同步顯示。一個文檔關(guān)聯(lián)多個視圖為應(yīng)用程序提供了很多的方便。例如:程序中使用兩個視圖,分別以表格和圖形的方式來顯示文檔中的數(shù)據(jù),圖形顯示給用戶直觀的感覺,而用戶可以通過表格來訪問和操作文檔中的具體數(shù)據(jù)。3.1.3文檔模板及主要組成類MFC中,文檔/視圖的結(jié)構(gòu)關(guān)系是由文檔模板(DocumentTemplate)定義的。文檔模板用于存放與應(yīng)用程序文檔、視圖和框架窗口有關(guān)的信息。MFC類庫提供有兩種文檔模板類,即用于單文檔(SDI)應(yīng)用程序的CSingleDocTemplate和用于多文檔(MDI)應(yīng)用程序的CMultiDocTemplate。CSingleDocTemplate每次只能創(chuàng)建并管理一個文檔,而CMultiDocTemplate可以創(chuàng)建并管理多個文檔。圖0.2、圖0.3分別顯示了基于MFC單文檔和多文檔的模板結(jié)構(gòu)。圖0.2MFC的單文檔應(yīng)用程序結(jié)構(gòu)圖0.3MFC的多文檔應(yīng)用程序結(jié)構(gòu)文檔模板的創(chuàng)建和維護是在MFC的應(yīng)用程序類CWinApp的對象中實現(xiàn)的。在類CWinApp調(diào)用成員函數(shù)InitInstance()進行初始化時,必須為應(yīng)用程序創(chuàng)建一個文檔模板對象,并使用AddDocTemplate()向新創(chuàng)建的應(yīng)用程序加載這個模板。在應(yīng)用程序?qū)ο笾?,也可以?chuàng)建并加載多個文檔模板。下面列出的代碼是在應(yīng)用程序類CTeapotApp(CWinApp的派生類)的成員函數(shù)InitInstance()中創(chuàng)建并加載一個單文檔模板的例子,該部分代碼由應(yīng)用程序向?qū)ё詣由?。BOOLCTeapotApp::InitInstance(){//Registertheapplication'sdocumenttemplates.Documenttemplates//serveastheconnectionbetweendocuments,framewindowsandviewsCSingleDocTemplate*pDocTemplate;pDocTemplate=newCSingleDocTemplate(IDR_MAINFRAME,RUNTIME_CLASS(CTeapotDoc),RUNTIME_CLASS(CMainFrame),//mainSDIframewindowRUNTIME_CLASS(CTeapotView));if(!pDocTemplate)returnFALSE;AddDocTemplate(pDocTemplate);}由文檔模板定義的MFC文檔和視圖程序框架包含四個主要的類:
文檔類CTeapotDoc。其對應(yīng)的文件為TeapotDoc.h和TeapotDoc.cpp。視圖類CTeapotView。其對應(yīng)的文件為TeapotView.h和TeapotView.cpp。主框架類CMainFrame。其對應(yīng)的文件為MainFrm.h和MainFrm.cpp。應(yīng)用程序類CTeapotApp。其對應(yīng)的文件為Teapot.h和Teapot.cpp。應(yīng)用程序的主要功能實現(xiàn)分配在這四個主要的類中。MFCAppWizard為每個類自動生成了源文件。以此為基礎(chǔ),開發(fā)人員進一步在這些類中插入需要的代碼和對象,就可以實現(xiàn)軟件的專業(yè)功能。這四個類的主要功能如圖0.4所示。CTeapotAppCTeapotDocCTeapotViewCMainFrame程序的初始化(文檔/視圖結(jié)構(gòu)的
建立、主窗口的創(chuàng)
建)程序關(guān)閉時的清除工
作數(shù)據(jù)的存放與磁盤文件的交互(文件IO)數(shù)據(jù)的顯示用戶交互CTeapotAppCTeapotDocCTeapotViewCMainFrame程序的初始化(文檔/視圖結(jié)構(gòu)的
建立、主窗口的創(chuàng)
建)程序關(guān)閉時的清除工
作數(shù)據(jù)的存放與磁盤文件的交互(文件IO)數(shù)據(jù)的顯示用戶交互(鍵盤輸入、鼠標(biāo)輸入、菜單以及工具欄命令)用戶界面對象的管理(菜單、工具條、狀
態(tài)欄)視窗的管理⑴應(yīng)用程序類。應(yīng)用程序類由MFC提供的程序基類CWinApp所派生,負(fù)責(zé)從總體上實現(xiàn)對程序的管理,管理從程序開始到結(jié)束的全過程。MFC的文檔/視圖結(jié)構(gòu)、程序的主窗口都在應(yīng)用程序類中定義和創(chuàng)建。每個MFC應(yīng)用程序都必須生成一個CWinApp派生類的對象。⑵文檔類。文檔類是由MFC提供的文檔基類CDocument派生,負(fù)責(zé)存放應(yīng)用程序的數(shù)據(jù),并管理程序和磁盤文件之間的存儲和讀取。文檔類把數(shù)據(jù)處理從界面中分離出來,同時提供一個與其他對象交互的接口。⑶視圖類。視圖類由MFC基類CView所派生,負(fù)責(zé)顯示文檔類中的數(shù)據(jù)。顯示的設(shè)備可以使計算機屏幕,也可以是打印機或其他設(shè)備。視圖類還負(fù)責(zé)處理用戶的交互輸入,如鍵盤輸入、鼠標(biāo)輸入、菜單以及工具欄命令等。視圖類可以通過GetDocument()函數(shù)來獲取文檔指針,用于讀取和操作文檔中的數(shù)據(jù),從而實現(xiàn)文檔數(shù)據(jù)的修改。當(dāng)文檔數(shù)據(jù)發(fā)生變化時,也可通過調(diào)用CDocument::UpdateAllViews()函數(shù)來更新視圖的顯示內(nèi)容。⑷主框架類。主框架窗口也就是應(yīng)用程序的主窗口,是由主框架類管理。如圖0.2、圖0.3所示,單文檔應(yīng)用程序和多文檔應(yīng)用程序的主框架類的MFC基類是不同的。對單文檔應(yīng)用程序(SDI),主框架窗口的基類為CFrameWnd類;而在多文檔應(yīng)用程序(MDI)的情況下,其框架窗口所繼承的類為CMDIFrameWnd類,文檔框架窗口所繼承的類則為CMDIChildWnd類,每個文檔都有一個文檔框架窗口。在用戶界面上,一個文檔框架窗口至少含有一個視圖以顯示該文檔數(shù)據(jù)。主框架窗口還負(fù)責(zé)管理用戶界面對象,如菜單、工具條、狀態(tài)欄等。每個框架窗口管理一個可選的加速鍵表,這樣可以方便的定義調(diào)用菜單命令的加速鍵。主框架窗口同時管理所有的視圖窗口,并跟蹤當(dāng)前活動的視圖。當(dāng)框架窗口含有多個視圖窗口時,當(dāng)前視圖即使最近使用的視圖。當(dāng)視圖活動改變時,框架窗口通過調(diào)用CView::OnActiveView()來通知當(dāng)前視圖。3.2OpenGL動態(tài)庫OpenGL介紹OpenGL(OpenGraphicsLibrary)是一個與硬件無關(guān)的圖形編程接口,可以在不同的硬件平臺上實現(xiàn)。使用OpenGL可以繪制出真實感很強的三維圖形,且由于越來越多的高檔圖形加速卡支持OpenGL,所以使用OpenGL繪圖可以獲得很快的執(zhí)行速度。OpenGL最初是SGI公司為其圖形工作站開發(fā)的可獨立于窗口操作系統(tǒng)和硬件設(shè)備的圖形開發(fā)環(huán)境,其目的是將用戶從具體的硬件環(huán)境和操作系統(tǒng)中解放出來,而可以完全不去理這些系統(tǒng)的結(jié)構(gòu)和指令系統(tǒng)。由于它在三維真實感圖形制作中具有優(yōu)秀的性能,目前OpenGL已被廣泛接受,成為事實上高性能圖形和交互視景處理的工業(yè)標(biāo)準(zhǔn)。作為圖形軟件接口,OpenGL由幾百個函數(shù)組成,用于訪問和操作圖形硬件所提供的各種功能。OpenGL本身不提供高級的造型命令,而是通過基本的幾何圖元一一點、線和多邊形來建立幾何模型。用戶則是通過這些基本圖元來建立高級的幾何模型。歸納起來,OpenGL提供的功能包括以下幾個方面:?圖形繪制。OpenGL使用基本圖元一一點、線、多邊形來繪制三維圖形和場景。用戶定義的高級模型和場景都可以通過這些基本圖元組成。?變換操作。OpenGL提供了一系列基本的變換操作:使用投影變換定義了一個視景體;幾何變換可以使物體在三維場景中平移、旋轉(zhuǎn)和縮放;視點變換可以使得用戶從不同角度去觀察物體;裁剪變換可以定義裁剪平面;視口變換決定怎樣把圖形映射到平面上。?顏色模式。OpenGL提供兩種可供選擇的顏色模式:RGBA模式和顏色索引模式。光照。光照是生成真實感圖形的重要環(huán)節(jié)。OpenGL可以通過配置如下四種光,即環(huán)境光、漫反射光、輻射光和鏡面光,來定義一個光源。用戶可以在應(yīng)用程序中定義多個光源,以及他們的位置和屬性,以達到需要的光照效果。?圖像效果增強。OpenGL通過反走樣、融合、霧化來增強圖像的效果。反走樣改善圖像中兩個面交界處的鋸齒效果;融合可以產(chǎn)生半透明的效果;霧化則可以模擬場景,使場景更逼真。位圖和圖像。OpenGL提供了一系列的函數(shù)來實現(xiàn)位圖顯示與操作。?紋理映射。紋理映射是增強三維真實感圖形效果的重要工具。當(dāng)顯示一個三角形對象時,在模型表面貼上模擬自然界的紋理,可以使三維圖形顯得更逼真、更自然。交互與動畫。OpenGL提供的選擇模式(SELECT)和反饋模式(FEEDBACK)方便了圖形和用戶之間交互功能的實現(xiàn)。OpenGL的雙緩存技術(shù)能夠使圖像幀與幀之間平滑的過渡,為實現(xiàn)圖形的動畫效果提供了可能。OpenGL函數(shù)庫OpenGL提供了四個函數(shù)庫,它們是基本庫(OpenGLLibrary)、實用庫(UtilityLibrary)、實用工具庫(UtilityToolkit)和輔助庫(AuxiliaryLibrary):⑴OpenGL基本庫是OpenGL的核心庫,在這個函數(shù)庫中,提供了一百多個函數(shù),實現(xiàn)了OpenGL的所有基本功能,如:創(chuàng)建二維和三維幾何形體、設(shè)置視點、幾何變換、設(shè)置顏色及材質(zhì)、設(shè)置光源、紋理映射等。這些函數(shù)以gl開頭,在opengl32.dll中實現(xiàn),并在頭文件gl.h中聲明。(2)OpenGL實用庫的作用在于提供一些更方便于用戶使用的函數(shù),如繪制球(Sphere)、圓柱(Cylinder)等復(fù)雜形狀。這些函數(shù)都由OpenGL基本庫中的函數(shù)實現(xiàn),能夠在所有支持OpenGL規(guī)范的平臺上使用。實用庫在glu32.dll中輸出,在頭文件glu.h中聲明,所有函數(shù)以glu為前綴。⑶OpenGL輔助庫實際上不能算OpenGL規(guī)范的一部分。它更是一個工具包,提供一些獨立于平臺的框架,從而可以方便的調(diào)用OpenGL的函數(shù)。如在輔助庫中,提供了一些基本的窗口處理函數(shù)、事件處理函數(shù)和簡單的模型那個制作函數(shù)。輔助庫的函數(shù)在glaux.dll中輸出,在頭文件glaux.h中聲明,函數(shù)以aux為前綴。⑷OpenGL實用工具庫不屬于OpenGL規(guī)范的一部分,提供更高層次的功能調(diào)用,如繪制猶他茶壺的函數(shù)glutSolidTeapot(),非常適合于算法研究。實用工具庫的函數(shù)在glut32.dll中輸出,在頭文件glut.h中聲明,函數(shù)以glut為前綴。OpenGL函數(shù)的命名方式為:3.2.3OpenGL動態(tài)庫的使用在Windows中,OpenGL的相關(guān)功能以動態(tài)鏈接庫(dll,Dynamic-LinkLibrary)的形式存在,因此,其使用方法和基本的動態(tài)鏈接庫一樣,需要將相應(yīng)的頭文件、lib文件、動態(tài)鏈接庫放在適當(dāng)?shù)穆窂较?,以便編譯器能夠找到相應(yīng)的文件。頭文件用以編譯時檢查函數(shù)調(diào)用的語法,lib文件用于編譯器鏈接時將調(diào)用函數(shù)的入口地址鏈接到目標(biāo)代碼中,dll文件只是在程序運行時才需要,在編譯的階段并不需要。這個適當(dāng)?shù)穆窂剑布淳幾g器能夠找到的路徑,包括:⑴應(yīng)用程序的當(dāng)前路徑;⑵系統(tǒng)路徑及PATH環(huán)境變量所定義的路徑,可通過右鍵桌面->【屬性】->【高級】->【環(huán)境變量】進行設(shè)置,如圖0.5所示;⑶編譯器中所指定的路徑。編譯器指定的路徑包括兩種:一種是針對于所有工程的設(shè)置,通過【Tools】->【Options】指定,頭文件路徑和lib文件路勁的設(shè)定分別如圖0.6、圖0.7所示;一種是針對本項目的設(shè)置,通過[Project!->[Settings!設(shè)定,頭文件路徑和lib文件路徑的設(shè)定分別如圖0.8、圖0.9所示。因此,通常只將一些適用于絕大部分工程的系統(tǒng)性的文件路徑通過前一種方式設(shè)定,如MFC的路徑設(shè)置,其他情況下則通過后一種方式設(shè)置。因此,我們在使用動態(tài)鏈接庫時可以將對應(yīng)的頭文件、lib文件放在上述三種方式指定的路徑下面。SyslcniPropcrtici;I?X|SystemRe±loreAlJtDfTI池口UpdatMRemitGeneralComplcrNanBHtfdwsrcAdvairedYourYiLHl-beloggedonAdoninishr-akrInmakema±lofIhewchanges.圖0.5環(huán)境變量PATH的設(shè)置5!區(qū)日6EdtytwInsertEropctWadyrot-AAicrDRcftVisualvakire£hape{GL£lzelw,GLsLeih)Ln42,Col2voidr?tiape(GL3Ed燦h)CancelXsqu-i-i.azn;/14EdilurTaLt*f口札典CumptilibilityBuildDirrdurirt:Suurue|~[7V7inJ7Dlrecturlei;:CAHrDuramFiks^MicrosoftVisualStudi<^VC9^MFqUBPlatform:區(qū)BleEdt&CW[pstrfcPjejectBet1四區(qū)1甘錨.sharpFilcsIiMicjDEDft:VisualStudiMier-D5?flVisualC**-[1eapoi,cpp]IO'ptians/J-I-U3\i-ci-Il-iIIIndn:m-,■\:irnj-*圖0.7針對所有工程的lib文件路徑的設(shè)定indgGRE-Micswf*VisualC++-[L;L?.Isriniew..&pp]*1wrdowProjcclSclthi^Win32PseudaRelsI度忡uriFrinn1副FbeGeoMadel劇MyMGREcral。前114〔£廈++_jLijik|HesdufcceCategoiResetPreprmcciissoirdlsfioniians:|wiNJy._ULUJU._WINUU17S._AfXDLL._MbCSUndefinedsymbolsIUndeliriEallsymbolicKHeaifyLnzji/,con45MtUUULUVIiKHeaifyLnzji/,con45MtUUULUVIi^riologofMDM3"X區(qū)UOdJI1.V^ReGeoMDdel!\Mndefl|VoliJmeVlnc,a".U"/".AFramcW'/l,4呷口的伽伽時』"頑門函/1Csnc^l圖0.8針對當(dāng)前工程的頭文件路徑的設(shè)定CalegcifIGRE+I-!hGhiiMiii1hI■ggtariTiK?|D^buigjHesouirces1MI|igilu32.|[i)bg^NlibJib9。材叩弓eirJibkwnairJibmgiimigJS.libcIgnorelibiranic^:]gmiQrcalldetou]tlibraries|lIHC.lih,IIHCD.lihForceBymholrefEireraces!1廠OblBcitfUibrarymofiliulles:rarypath:J.iy30WPEcucloRele:3SE!tuut^R^GcGModeHth[i[rdpiysrc'||liE圖0.9針對當(dāng)前項目的lib文件路徑的設(shè)定msimgjE.llbopengl32.libReGeoModel.libOpenGL基本庫、實用庫由Windows自帶,因此,opengl32.dll、glu32.dll已經(jīng)在系統(tǒng)目錄下了,如C:/Windows/System32,如果安裝了VisualStudio6.0的話,其對應(yīng)的頭文件和lib庫文件分別在C:\ProgramFiles\MicrosoftVisualStudio\VC98\Include\GL和C:\ProgramFiles\MicrosoftVisualStudio\VC98\Lib中,其中:\ProgramFiles\MicrosoftVisualStudio為VisualStudio6.0的安裝路徑。如果要使用實用工具庫,則需要從網(wǎng)上下載相應(yīng)的頭文件、lib文件,將其放置在上述三種方式中某種方式所指定的路徑下,通??梢詫⑵浞胖迷诋?dāng)前工程路徑下或者系統(tǒng)路徑下。除了設(shè)定相應(yīng)的路徑外,我們還需提供編譯器鏈接所需的lib庫的名稱,如圖0.10所示。
lidTwJsWjndowHdp函DeEditVpwI阪丈羿cd^Jjj|回風(fēng)唐I攜Lsharp3id1IgnoreallIgnorelibraries:UBC.lib.LIBCD.libFarcesymbollreferences:H幽NGRERcs+lidTwJsWjndowHdp函DeEditVpwI阪丈羿cd^Jjj|回風(fēng)唐I攜Lsharp3id1IgnoreallIgnorelibraries:UBC.lib.LIBCD.libFarcesymbollreferences:H幽NGRERcs+|=3ReGeoMDdel+囹wmwSindIGREr~~;ProjieclOptions:glu32JIbopeng!32JlbgludZJIb^nologojVergion:1.0jsubsystEm^winddwsfincrememtsI:yesjpdb:"PscudoRdcast^SindyNGHE.pdh"MebugOKCnuf.rArteamyLnzjir.cui圖0.10lib文件的設(shè)定3.3在Windows環(huán)境下使用OpenGL3.3.1OpenGL與GDI在利用MFC開發(fā)Windows應(yīng)用程序的時候,大多習(xí)慣于使用GDI(GraphicalDeviceInterface)函數(shù),即圖形設(shè)備接口函數(shù)來繪制圖形。GDI是Windows體系結(jié)構(gòu)中的重要組件,他為Windows提供了所有基本的繪圖函數(shù)。GDI與Windows系統(tǒng)中的圖形設(shè)備驅(qū)動程序連接,通過調(diào)用驅(qū)動程序中的相應(yīng)功能,以響應(yīng)Windows圖形函數(shù)的調(diào)用。這樣,程序員只需要將繪制代碼是先到GDI函數(shù)這個層次上,而不必去關(guān)心具體的硬件設(shè)備。GDI與Windows窗口的關(guān)聯(lián)靠一個設(shè)備上下文對象(DeviceContext)來實現(xiàn)。在Windows窗口中使用GDI時,需要創(chuàng)建一個設(shè)備上下文對象。設(shè)備上下文指定了許多如何在窗口上顯示圖形的信息,例如指定畫筆和畫刷的顏色、設(shè)置繪圖模式、調(diào)色板、映射模式和其他圖形模式。該上下文作為一個參數(shù)被發(fā)送到GDI函數(shù)中。如CView::OnDraw(CDC*pDC){CPen*pPen=newCPen(PS_SOLID,1,COLORREF(255,0,0));pDC->SelectObject(pPen);pDC->LineTo(250,250);???}每個Windows窗口都有一個設(shè)備上下文用于圖形輸出,而每個GDI函數(shù)都需要一個設(shè)備上下文,用來標(biāo)識這個函數(shù)將向哪一個窗口輸出。一個程序中可以存在多個設(shè)備上下文,但每個窗口只有一個它自己的設(shè)備上下文。任何時候,圖形繪制到顯示器或者打印機時,它必須使用GDI函數(shù)。GDI函數(shù)可以繪制點、直線、矩形、多邊形、橢圓、位圖、文本。OpenGLWindows應(yīng)用程序不使用GDI函數(shù),而是直接使用OpenGLAPI函數(shù)進行圖形繪制。OpenGL與GDI的關(guān)系如圖0.11所示。圖0.11OpenGL工作結(jié)構(gòu)Micorsoft還提供了一套"Wiggle”函數(shù),用于OpenGLAPI和MicrosoftWindowsGDI的連接。與使用GDI在Windows下繪圖不同,使用OpenGL繪圖后,GDI中的畫筆(Pens)、畫刷(Brushes)、字體(Fonts)以及其他GDI對象將不再起作用。正如GDI使用設(shè)備上下文(DeviceContext)用于控制Windows中的圖形繪制,OpenGL使用了一個渲染上下文(RenderingContext)。這個渲染上下文通過與設(shè)備上下文相關(guān)聯(lián),從而實現(xiàn)了與窗口的關(guān)聯(lián)。渲染上下文(RenderingContext)渲染上下文和設(shè)備上下文正如使用GDI繪圖時,每個Windows程序的窗口中都擁有一個設(shè)備上下文(DeviceContext),用于窗口中的圖形繪制。使用OpenGL在Windows窗口中繪制圖形時,也需要在每個窗口中嵌入一個渲染上下文(RenderingContext)。渲染上下文保存了與OpenGL發(fā)生聯(lián)系的信息,負(fù)責(zé)處理應(yīng)用程序發(fā)出的OpenGL命令。所以在發(fā)出OpenGL命令之前,必須首先為該窗口創(chuàng)建一個渲染上下文。一個應(yīng)用程序可以具有一個或多個渲染上下文,但同時只能有一個渲染上下文被設(shè)為當(dāng)前的渲染上下文(CurrentRenderingContext)。程序中發(fā)出的OpenGL命令只輸出給當(dāng)前的渲染上下文。例如在MDI的應(yīng)用程序中同時打開了兩個窗口,當(dāng)程序中發(fā)出一個OpenGL命令時,系統(tǒng)如何知道這個命令是傳給哪一個窗口的呢?為了使系統(tǒng)知道當(dāng)前命令將發(fā)給哪一個窗口,所以在一個應(yīng)用程序中(嚴(yán)格的說是在一個線程中)只能同時存在一個當(dāng)前化的渲染上下文。當(dāng)一個渲染上下文被設(shè)為當(dāng)前上下文后,由于該渲染上下文關(guān)聯(lián)了一個Windows的設(shè)備上下文,從而能找到它所關(guān)聯(lián)的窗口,于是OpenGL向該窗口繪制圖像。Wiggle函數(shù)對渲染上下文的操作嚴(yán)格的說,渲染上下文不屬于OpenGL的概念,而更是Windows窗口中一個附加的概念,以支持窗口與OpenGL的連接。WindowsAPI中增加Wiggle函數(shù)的目的在于增加Windows窗口對OpenGL的支持。這些函數(shù)都以wgl為其前綴,其中最常用的幾個與渲染上下文相關(guān)的Wiggle函數(shù)是:HGLRCwglCreateContext(HDC);該函數(shù)輸入一個GDI的設(shè)備上下文的句柄,創(chuàng)建與這個設(shè)備上下文相關(guān)聯(lián)的渲染上下文。在調(diào)用這個函數(shù)創(chuàng)建渲染上下文之前,必須先調(diào)用函數(shù)SetPixelFormat()設(shè)置與設(shè)備上下文相匹配的像素格式。BOOLwglDeleteContext(HGLRC);該函數(shù)用于刪除一個渲染上下文。所創(chuàng)建的渲染上下文在用完之后需要將它刪除。HGLRCwglGetCurrentContext(VOID);該函數(shù)獲得線程中當(dāng)前的渲染上下文。HDCwglGetCurrentDC(VOID);該函數(shù)獲得與當(dāng)前渲染上下文相關(guān)聯(lián)的設(shè)備上下文。BOOLwglMakeCurrent(HDC,HGLRC);該函數(shù)用于當(dāng)前化一個渲染上下文,即將一個渲染上下文設(shè)置為線程的當(dāng)前上下文。線程中一旦當(dāng)前化了一個渲染上下文,所有隨后的OpenGL命令都發(fā)往這個當(dāng)前的渲染上下文中處理,并通過與該渲染上下文關(guān)聯(lián)的設(shè)備上下文實現(xiàn)窗口的場景繪制。3.3.3像素格式要在一個窗口中使用OpenGL,還需要為它選擇一個合適的像素格式(PixelFormat)。和渲染上下文的概念類似,像素格式并不屬于OpenGL的概念。它作為WindowsAPI的一個擴展,用于支持Windows下的OpenGL的功能。在OpenGL的圖形操作步驟中,最終的環(huán)節(jié)是將圖形光柵化,即把圖形轉(zhuǎn)化成可以在計算機屏幕上顯示的像素信息,并將這些像素寫到幀緩存中以實現(xiàn)屏幕顯示。像素格式為設(shè)備上下文設(shè)置一些與OpenGL相關(guān)的屬性。在像素格式中規(guī)定了和像素操作有關(guān)的信息,諸如:像素緩存是單緩存還是雙緩存;像素的顏色模式是RGBA模式還是索引模式;顏色的位數(shù);深度緩存的位數(shù)等。因而在創(chuàng)建一個渲染上下文之前,需要首先為窗口的設(shè)備上下文設(shè)置一個像素格式。Windows中,使用結(jié)構(gòu)PIXELFORMATDESCRIPTOR來設(shè)置像素格式,并提供了四個函數(shù)用于操作像素格式:intChoosePixelFormat(HDChdc,constPIXELFORMATDESCRIPTOR*ppfd);該函數(shù)返回與所定義的像素結(jié)構(gòu)最匹配的線程中當(dāng)前的渲染上下文。BOOLSetPixelFormat(HDChdc,intformat,constPIXELFORMATDESCRIPTOR*ppfd);該函數(shù)為指定的設(shè)備上下文設(shè)置像素格式。intDescribePixelFormat(HDChdc,intiPixelFormat,UINTnBytes,LPPIXELFORMATDESCRIPTORppfd);該函數(shù)獲得被PixelFormat指定的像素格式的信息。intGetPixelFormat(HDChdc);該函數(shù)返回設(shè)備上下文中被指定的像素格式的索引號。設(shè)置像素格式的步驟如下:第一步:根據(jù)需要,填寫結(jié)構(gòu)PIXELFORMATDESCRIPTOR,因為像素格式是用這個結(jié)構(gòu)來描述的,第二步:調(diào)用函數(shù)ChoosePixelFormat(),將填寫好的像素格式傳遞給該函數(shù),函數(shù)ChoosePixelFormat()返回一個整形的序號。這個序號標(biāo)識一個當(dāng)前設(shè)備上下
文中所能提供的,且與所要求的像素格式最為匹配的像素格式;第三步:將這個返回的像素格式序號傳遞給函數(shù)SetPixelFormat(),使之成為設(shè)備上下文的像素格式。PIXELFORMATDESCRIPTOR的結(jié)構(gòu)定義如下:/*Pixelformatdescriptor*/typedefstructtagPIXELFORMATDESCRIPTOR{WORDnSize;WORDWORDnSize;WORDnVersion;DWORDdwFlags;//亥結(jié)構(gòu)的版本號,現(xiàn)在應(yīng)設(shè)為1//像素緩存的屬性,包括:PFD_DOUBLE_BUFFER,PFD_DRAW_TO_WINDOWPFD_SUPPORT_GDI等BYTEiPixelType;//顏色模式,包括RGBA模式(PFD_TYPE_RGBA)和顏色索引模式(PFD_TYPE_COLORINDEX)BYTEcColorBits;//顏色位數(shù),如8位代表256色,24位代表真彩色BYTEcRedBits;//通常不使用,置為0BYTEBYTEIcRedShift;cGreenBits;BYTEcGreenShift;BYTEcBlueBits;BYTEcBlueShift;BYTEcAlphaBits;BYTEcAlphaShift;BYTEcAccumBits;/累計緩存的位數(shù)BYTEcAccumRedBits;/一般置為0BYTEcAccumGreenBits;BYTEcAccumBlueBits;BYTEcAccumAlphaBits;BYTEcDepthBits;/深度緩存的位數(shù)BYTEcStencilBits;/模板緩存的位數(shù)BYTEcAuxBuffers;/輔助緩存的位數(shù)BYTEiLayerType;/現(xiàn)巳不用,可忽略,置為0BYTEbReserved;/必須為0DWORDdwLayerMask;//N下不支持,設(shè)為0DWORDdwVisibleMask;DWORDdwDamageMask;}PIXELFORMATDESCRIPTOR下面給出一個設(shè)置像素格式的主要操作過程的程序清單staticPIXELFORMATDESCRIPTORpfd={
sizeof(PIXELFORMATDESCRIPTOR),//sizeofthispfd//versionnumberPFD_DRAW_TO_WINDOW|//supportwindowPFD_SUPPORT_OPENGL|//supportOpenGLPFD_DOUBLEBUFFER,//doublebufferedPFD_TYPE_RGBA,//RGBAtype24,//24-bitcolordepth0,0,0,0,0,0,//colorbitsignored0,//noalphabuffer0,//shiftbitignored0,//noaccumulationbuffer0,0,0,0,//accumbitsignored16,//16-bitz-buffer0,//nostencilbuffer0,//noauxiliarybufferPFD_MAIN_PLANE,//mainlayer0,//reserved0,0,0//layermasksignored};//選擇一個最匹配的像素格式intnPixelFormat=ChoosePixelFormat(m_pDC->GetSafeHdc(),&pfd);//為設(shè)備上下文設(shè)置像素格式SetPixelFormat(m_pDC->GetSafeHdc(),nPixelFormat,&pfd);在開始使用OpenGL繪制之前,程序中必須先完成像素格式的設(shè)置和渲染上下文的創(chuàng)建。由于設(shè)備像素格式需要設(shè)備上下文,所以這個過程必須在窗口創(chuàng)建完成之后進行。通常在Windows消息WM_CREATE的映射函數(shù)OnCreate()中進行像素格式的設(shè)置和渲染上下文的創(chuàng)建。對于創(chuàng)建的渲染上下文,最后還應(yīng)該在Windows消息WM_DESTROY的映射函數(shù)OnDestroy()函數(shù)中予以刪除。圖0.12顯示了在Windows窗口的有關(guān)環(huán)節(jié)中創(chuàng)建和使用渲染上下文。圖0.12創(chuàng)建和使用渲染上下文的環(huán)節(jié)3.3.4典型實現(xiàn)如圖0.12所示,各消息響應(yīng)函數(shù)的典型實現(xiàn)為:OnCreate()的典型實現(xiàn):建立像素格式和繪制上下文來初始化OpenGL。在IntializeOpenGL()中創(chuàng)建一個設(shè)備上下文(DC),為這個DC選擇一個像素格式,創(chuàng)建和這個DC相關(guān)的繪制上下文(RC),然后選擇這個RC(通過wglMakeCurrent()實現(xiàn))。intCTeapotView::OnCreate(LPCREATESTRUCTIpCreateStruct){if(CView::OnCreate(lpCreateStruct)==-1)return-1;//TODO:Addyourspecializedcreationcodehere//InitializeOpenGLHereInitializeOpenGL();return0;}BOOLCTeapotView::InitializeOpenGL(){//GetaDCfortheClientAreampDC=newCClientDC(this);//FailuretoGetDCifmpDC==NULL)AfxMessageBox(T("ErrorObtainingDC"));returnFALSE;}//Failuretosetthepixelformatif:!SetupPixelFormat())returnFALSE;//CreateRenderingContextmhRC=::wglCreateContext(mpDC->GetSafeHdc());//FailuretoCreateRenderingContextif(mhRC==0)MessageBox(_T("ErrorCreatingRC"));returnFALSE;}//MaketheRCCurrentif(::wglMakeCurrent(mpDC->GetSafeHdc(),mhRC)==FALSE)MessageBox(T("ErrormakingRCCurrent"));returnFALSE;//SpecifyBlackastheclearcolor::glClearColor(0.0f,0.0f,0.0f,1.0f);//Specifythebackofthebufferascleardepth::glClearDepth(1.0f);//EnableDepthTesting::glEnable(GL_DEPTH_TEST);//enablelightingglEnable(GL_LIGHTING);glEnable(GLLIGHT0);returnTRUE;}//SetupPixelFormat/////////////////////////////////////////////////////////////////////////////BOOLCTeapotView::SetupPixelFormat(){staticPIXELFORMATDESCRIPTORpfd={sizeof(PIXELFORMATDESCRIPTOR),//sizeofthispfd1,//versionnumberPFD_DRAW_TO_WINDOW|//supportwindowPFD_SUPPORT_OPENGL|//supportOpenGLPFD_DOUBLEBUFFER,//doublebufferedPFD_TYPE_RGBA,//RGBAtype24,//24-bitcolordepth0,0,0,0,0,0,//colorbitsignored0,//noalphabuffer0,//shiftbitignored0,//noaccumulationbuffer0,0,0,0,//accumbitsignored16,//16-bitz-buffer0,//nostencilbuffer0,//noauxiliarybufferPFD_MAIN_PLANE,//mainlayer0,//reserved0,0,0//layermasksignored};intnPixelFormat=::ChoosePixelFormat(m_pDC->GetSafeHdc(),&pfd);if(nPixelFormat==0)■{returnFALSE;}if(::SetPixelFormat(m_pDC->GetSafeHdc(),nPixelFormat,&pfd)==FALSE)■{returnFALSE;■}returnTRUE;}OnSizeO的典型實現(xiàn):設(shè)置視口和視景體,因為這些是和窗口大小相關(guān)的。基本操作包括設(shè)置視口、選擇投影矩陣、設(shè)置模型視圖矩陣。voidCTeapotView::OnSize(UINTnType,intcx,intcy){CView::OnSize(nType,cx,cy);//TODO:Addyourmessagehandlercodehereif(0>=cx||0>=cy)return;■}//selectthefullclientareaglViewport(0,0,cx,cy);//computetheaspectratio//thiswillkeepalldimensionscalesequalGLdoubleaspect_ratio=(GLdouble)cx/(GLdouble)cy;//selecttheprojectionmatrixandclearitglMatrixMode(GL_PROJECTION);glLoadIdentity();//selecttheviewingvolumegluPerspective(60.0f,aspect_ratio,.1f,200.0f);//glFrustum(-1,1,-1,1,1,3);//glOrtho(-1,1,-1,1,-1,1);//switchbacktothemodelviewmatrixandclearitglMatrixMode(GL_MODELVIEW);glLoadIdentity();gluLookAt(0,0,2,0,0,0,0,1,0);}OnDraw()的典型實現(xiàn):繪制具體場景,一般包括如下步驟:清空緩存繪制場景Flush掉渲染流水線若設(shè)置了雙緩沖,則交換前后臺緩沖區(qū)voidCTeapotView::OnDraw(CDC*/*pDC*/){CTeapotDoc*pDoc=GetDocument();ASSERT_VALID(pDoc);if(!pDoc)return;//TODO:adddrawcodefornativedatahere//Clearoutthecolor&depthbuffersglClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);RenderScene();//TellOpenGLtoflushitspipelineglFinish();//NowSwapthebuffersSwapBuffers(m_pDC->GetSafeHdc());}voidCTeapotView::RenderScene(){//glEnable(GL_COLOR_MATERIAL);glColor3f(1.0f,0.0f,0.0f);glutSolidTeapot(0.5);}OnDestroy()的典型實現(xiàn):釋放設(shè)備上下文(DC)和渲染上下文(RC),從而避免內(nèi)存泄露。voidCTeapotView::OnDestroy(){CView::OnDestroy();//TODO:Addyourmessagehandlercodehere//MaketheRCnon-cur
溫馨提示
- 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)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- TSHAEPI 014-2024 溫室氣體(二氧化碳和甲烷)走航監(jiān)測技術(shù)規(guī)范
- 二零二五年度網(wǎng)絡(luò)安全就業(yè)協(xié)議書協(xié)議內(nèi)容詳盡規(guī)范
- 二零二五年度股權(quán)投資公司股東合作協(xié)議
- 2025年度軟裝行業(yè)市場監(jiān)測與風(fēng)險評估合同
- 二零二五年度廣東省房屋租賃合同租賃保險合作協(xié)議
- 二零二五年度娛樂產(chǎn)業(yè)動漫IP授權(quán)使用勞動合同
- 二零二五年度店鋪轉(zhuǎn)讓定金及品牌授權(quán)使用合同
- 二零二五年度商業(yè)空間合租租賃及稅務(wù)咨詢合同
- 二零二五年度旅游度假村裝修合同終止書
- 2025年度防火門市場調(diào)研與銷售預(yù)測合同
- 2023年湖南食品藥品職業(yè)學(xué)院高職單招(英語)試題庫含答案解析
- GB/T 39096-2020石油天然氣工業(yè)油氣井油管用鋁合金管
- 爐外精煉說課
- GB/T 23111-2008非自動衡器
- GB/T 18877-2020有機無機復(fù)混肥料
- 三大構(gòu)成之立體構(gòu)成-課件
- DB11 938-2022 綠色建筑設(shè)計標(biāo)準(zhǔn)
- 最新家政服務(wù)員培訓(xùn)課件
- 2022譯林版新教材高一英語必修二單詞表及默寫表
- 全國青少年機器人技術(shù)等級考試:二級培訓(xùn)全套課件
- TB T2075-《電氣化鐵道接觸網(wǎng)零部件》
評論
0/150
提交評論