版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
實驗二結合MFC與OpenGL實現三維應用程序的顯示實驗目的熟悉OpenGL的編程環(huán)境設置熟悉MFC的基本編程框架MFC與OpenGL混合編程的設置OpenGL中基本圖元的繪制實驗內容創(chuàng)建MFC+OpenGL的編程環(huán)境?利用三角形和四邊形等基本圖元繪制底面圓圓心在坐標原點,半徑為r,高為h,方向沿z軸方向的圓柱實驗指導MFC應用程序框架在VisualC++2.0以后的版本中,Microsoft公司推出了MFC(MicrosoftFoundationClass)類庫。MFC類庫是用來編寫Windows程序的C++類集。使用MFC類庫,可以簡化應用程序的開發(fā),從而縮短開發(fā)周期,而且代碼的可靠性和可重用性也大大提高。MFC應用程序的文檔/視圖結構概述MFC提供了一個典型且實用的基于文檔與視圖的應用程序框架模板,按照其應用程序生成向導的導引步驟(MFCAppWizard)就可以創(chuàng)建一個基于文檔/視圖結構的MFC應用程序框架。在此框架的基礎上,設計和插入相關的對象,就可以實現交互式的用戶界面、幾何模型的管理和操作、圖形圖像的顯示,以及其他
各種專業(yè)功能。在MFC的文檔/視圖結構的應用程序框架中,文檔類和視圖類是成對出現的。文檔用于管理應用程序的數據;而視圖用于顯示文檔中的數據,并處理與用戶的交互信息。MFC通過文檔類和視圖類的劃分,使數據的存儲和顯示既相對獨立又相互關聯。在MFC所提供的框架結構中,文檔與視圖的關系可以由圖0.1簡要表示。MFC中的視圖和文檔是由視圖類(CViewClass)和文檔類(CDocumentClass)分別表示的。視圖類可以調用其本身的成員函數GetDocument(),獲得一個指向文檔類的指針,從而能夠訪問文檔類中的數據。例如:在視圖類中的OnDraw()函數中,視圖類通過調用GetDocument()函數獲得一個指向文檔累的指針,然后通過這個指針獲取文檔類中的數據,并使用CDC類(負責處理應用程序顯示設備接口的MFC類)中的函數將這些數據繪制在視圖窗口中。視圖可以通過圖形、圖像、文字、表格等多種方式以視圖對象(CViewObject)來顯示實際的文檔(CDocumentObject)中的數據。同時,視圖對象也負責接收鼠標、鍵盤等用戶輸入信息,并通過這些與用戶之間的交互信息來操作和修改文檔中的數據。CDocumentCViewCView圖0.1文檔與視圖的關系CDocumentCViewCView3.1.2文檔與多個視圖的關聯使用MFCAppWizard自動創(chuàng)建的MFC應用程序中,為每個文檔類的對象創(chuàng)建并關聯了一個視圖類的對對象。實際上,文檔和視圖的關系可以使一對一或一對多,即一個文檔可以關聯一個或一個以上的視圖,也就是可以用多個視圖來顯示和操作文檔中的數據時。通常,設計不同的視圖時為了以不同的方式來顯示文檔內容,如圖形、圖表、結構、文字等。如圖0.1所示,一個文檔對象就同時關聯了多個視圖對象。當在一個視圖類對象中對文檔數據做了修改后,可以調用文檔類的UpdateAllViews()函數來更新所有與文檔相關聯的視圖類對象的顯示,以此來保持所有視圖對同一文檔數據變化的同步顯示。一個文檔關聯多個視圖為應用程序提供了很多的方便。例如:程序中使用兩個視圖,分別以表格和圖形的方式來顯示文檔中的數據,圖形顯示給用戶直觀的感覺,而用戶可以通過表格來訪問和操作文檔中的具體數據。3.1.3文檔模板及主要組成類MFC中,文檔/視圖的結構關系是由文檔模板(DocumentTemplate)定義的。文檔模板用于存放與應用程序文檔、視圖和框架窗口有關的信息。MFC類庫提供有兩種文檔模板類,即用于單文檔(SDI)應用程序的CSingleDocTemplate和用于多文檔(MDI)應用程序的CMultiDocTemplate。CSingleDocTemplate每次只能創(chuàng)建并管理一個文檔,而CMultiDocTemplate可以創(chuàng)建并管理多個文檔。圖0.2、圖0.3分別顯示了基于MFC單文檔和多文檔的模板結構。圖0.2MFC的單文檔應用程序結構圖0.3MFC的多文檔應用程序結構文檔模板的創(chuàng)建和維護是在MFC的應用程序類CWinApp的對象中實現的。在類CWinApp調用成員函數InitInstance()進行初始化時,必須為應用程序創(chuàng)建一個文檔模板對象,并使用AddDocTemplate()向新創(chuàng)建的應用程序加載這個模板。在應用程序對象中,也可以創(chuàng)建并加載多個文檔模板。下面列出的代碼是在應用程序類CTeapotApp(CWinApp的派生類)的成員函數InitInstance()中創(chuàng)建并加載一個單文檔模板的例子,該部分代碼由應用程序向導自動生成。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。其對應的文件為TeapotDoc.h和TeapotDoc.cpp。視圖類CTeapotView。其對應的文件為TeapotView.h和TeapotView.cpp。主框架類CMainFrame。其對應的文件為MainFrm.h和MainFrm.cpp。應用程序類CTeapotApp。其對應的文件為Teapot.h和Teapot.cpp。應用程序的主要功能實現分配在這四個主要的類中。MFCAppWizard為每個類自動生成了源文件。以此為基礎,開發(fā)人員進一步在這些類中插入需要的代碼和對象,就可以實現軟件的專業(yè)功能。這四個類的主要功能如圖0.4所示。CTeapotAppCTeapotDocCTeapotViewCMainFrame程序的初始化(文檔/視圖結構的
建立、主窗口的創(chuàng)
建)程序關閉時的清除工
作數據的存放與磁盤文件的交互(文件IO)數據的顯示用戶交互CTeapotAppCTeapotDocCTeapotViewCMainFrame程序的初始化(文檔/視圖結構的
建立、主窗口的創(chuàng)
建)程序關閉時的清除工
作數據的存放與磁盤文件的交互(文件IO)數據的顯示用戶交互(鍵盤輸入、鼠標輸入、菜單以及工具欄命令)用戶界面對象的管理(菜單、工具條、狀
態(tài)欄)視窗的管理⑴應用程序類。應用程序類由MFC提供的程序基類CWinApp所派生,負責從總體上實現對程序的管理,管理從程序開始到結束的全過程。MFC的文檔/視圖結構、程序的主窗口都在應用程序類中定義和創(chuàng)建。每個MFC應用程序都必須生成一個CWinApp派生類的對象。⑵文檔類。文檔類是由MFC提供的文檔基類CDocument派生,負責存放應用程序的數據,并管理程序和磁盤文件之間的存儲和讀取。文檔類把數據處理從界面中分離出來,同時提供一個與其他對象交互的接口。⑶視圖類。視圖類由MFC基類CView所派生,負責顯示文檔類中的數據。顯示的設備可以使計算機屏幕,也可以是打印機或其他設備。視圖類還負責處理用戶的交互輸入,如鍵盤輸入、鼠標輸入、菜單以及工具欄命令等。視圖類可以通過GetDocument()函數來獲取文檔指針,用于讀取和操作文檔中的數據,從而實現文檔數據的修改。當文檔數據發(fā)生變化時,也可通過調用CDocument::UpdateAllViews()函數來更新視圖的顯示內容。⑷主框架類。主框架窗口也就是應用程序的主窗口,是由主框架類管理。如圖0.2、圖0.3所示,單文檔應用程序和多文檔應用程序的主框架類的MFC基類是不同的。對單文檔應用程序(SDI),主框架窗口的基類為CFrameWnd類;而在多文檔應用程序(MDI)的情況下,其框架窗口所繼承的類為CMDIFrameWnd類,文檔框架窗口所繼承的類則為CMDIChildWnd類,每個文檔都有一個文檔框架窗口。在用戶界面上,一個文檔框架窗口至少含有一個視圖以顯示該文檔數據。主框架窗口還負責管理用戶界面對象,如菜單、工具條、狀態(tài)欄等。每個框架窗口管理一個可選的加速鍵表,這樣可以方便的定義調用菜單命令的加速鍵。主框架窗口同時管理所有的視圖窗口,并跟蹤當前活動的視圖。當框架窗口含有多個視圖窗口時,當前視圖即使最近使用的視圖。當視圖活動改變時,框架窗口通過調用CView::OnActiveView()來通知當前視圖。3.2OpenGL動態(tài)庫OpenGL介紹OpenGL(OpenGraphicsLibrary)是一個與硬件無關的圖形編程接口,可以在不同的硬件平臺上實現。使用OpenGL可以繪制出真實感很強的三維圖形,且由于越來越多的高檔圖形加速卡支持OpenGL,所以使用OpenGL繪圖可以獲得很快的執(zhí)行速度。OpenGL最初是SGI公司為其圖形工作站開發(fā)的可獨立于窗口操作系統和硬件設備的圖形開發(fā)環(huán)境,其目的是將用戶從具體的硬件環(huán)境和操作系統中解放出來,而可以完全不去理這些系統的結構和指令系統。由于它在三維真實感圖形制作中具有優(yōu)秀的性能,目前OpenGL已被廣泛接受,成為事實上高性能圖形和交互視景處理的工業(yè)標準。作為圖形軟件接口,OpenGL由幾百個函數組成,用于訪問和操作圖形硬件所提供的各種功能。OpenGL本身不提供高級的造型命令,而是通過基本的幾何圖元一一點、線和多邊形來建立幾何模型。用戶則是通過這些基本圖元來建立高級的幾何模型。歸納起來,OpenGL提供的功能包括以下幾個方面:?圖形繪制。OpenGL使用基本圖元一一點、線、多邊形來繪制三維圖形和場景。用戶定義的高級模型和場景都可以通過這些基本圖元組成。?變換操作。OpenGL提供了一系列基本的變換操作:使用投影變換定義了一個視景體;幾何變換可以使物體在三維場景中平移、旋轉和縮放;視點變換可以使得用戶從不同角度去觀察物體;裁剪變換可以定義裁剪平面;視口變換決定怎樣把圖形映射到平面上。?顏色模式。OpenGL提供兩種可供選擇的顏色模式:RGBA模式和顏色索引模式。光照。光照是生成真實感圖形的重要環(huán)節(jié)。OpenGL可以通過配置如下四種光,即環(huán)境光、漫反射光、輻射光和鏡面光,來定義一個光源。用戶可以在應用程序中定義多個光源,以及他們的位置和屬性,以達到需要的光照效果。?圖像效果增強。OpenGL通過反走樣、融合、霧化來增強圖像的效果。反走樣改善圖像中兩個面交界處的鋸齒效果;融合可以產生半透明的效果;霧化則可以模擬場景,使場景更逼真。位圖和圖像。OpenGL提供了一系列的函數來實現位圖顯示與操作。?紋理映射。紋理映射是增強三維真實感圖形效果的重要工具。當顯示一個三角形對象時,在模型表面貼上模擬自然界的紋理,可以使三維圖形顯得更逼真、更自然。交互與動畫。OpenGL提供的選擇模式(SELECT)和反饋模式(FEEDBACK)方便了圖形和用戶之間交互功能的實現。OpenGL的雙緩存技術能夠使圖像幀與幀之間平滑的過渡,為實現圖形的動畫效果提供了可能。OpenGL函數庫OpenGL提供了四個函數庫,它們是基本庫(OpenGLLibrary)、實用庫(UtilityLibrary)、實用工具庫(UtilityToolkit)和輔助庫(AuxiliaryLibrary):⑴OpenGL基本庫是OpenGL的核心庫,在這個函數庫中,提供了一百多個函數,實現了OpenGL的所有基本功能,如:創(chuàng)建二維和三維幾何形體、設置視點、幾何變換、設置顏色及材質、設置光源、紋理映射等。這些函數以gl開頭,在opengl32.dll中實現,并在頭文件gl.h中聲明。(2)OpenGL實用庫的作用在于提供一些更方便于用戶使用的函數,如繪制球(Sphere)、圓柱(Cylinder)等復雜形狀。這些函數都由OpenGL基本庫中的函數實現,能夠在所有支持OpenGL規(guī)范的平臺上使用。實用庫在glu32.dll中輸出,在頭文件glu.h中聲明,所有函數以glu為前綴。⑶OpenGL輔助庫實際上不能算OpenGL規(guī)范的一部分。它更是一個工具包,提供一些獨立于平臺的框架,從而可以方便的調用OpenGL的函數。如在輔助庫中,提供了一些基本的窗口處理函數、事件處理函數和簡單的模型那個制作函數。輔助庫的函數在glaux.dll中輸出,在頭文件glaux.h中聲明,函數以aux為前綴。⑷OpenGL實用工具庫不屬于OpenGL規(guī)范的一部分,提供更高層次的功能調用,如繪制猶他茶壺的函數glutSolidTeapot(),非常適合于算法研究。實用工具庫的函數在glut32.dll中輸出,在頭文件glut.h中聲明,函數以glut為前綴。OpenGL函數的命名方式為:3.2.3OpenGL動態(tài)庫的使用在Windows中,OpenGL的相關功能以動態(tài)鏈接庫(dll,Dynamic-LinkLibrary)的形式存在,因此,其使用方法和基本的動態(tài)鏈接庫一樣,需要將相應的頭文件、lib文件、動態(tài)鏈接庫放在適當的路徑下,以便編譯器能夠找到相應的文件。頭文件用以編譯時檢查函數調用的語法,lib文件用于編譯器鏈接時將調用函數的入口地址鏈接到目標代碼中,dll文件只是在程序運行時才需要,在編譯的階段并不需要。這個適當的路徑,也即編譯器能夠找到的路徑,包括:⑴應用程序的當前路徑;⑵系統路徑及PATH環(huán)境變量所定義的路徑,可通過右鍵桌面->【屬性】->【高級】->【環(huán)境變量】進行設置,如圖0.5所示;⑶編譯器中所指定的路徑。編譯器指定的路徑包括兩種:一種是針對于所有工程的設置,通過【Tools】->【Options】指定,頭文件路徑和lib文件路勁的設定分別如圖0.6、圖0.7所示;一種是針對本項目的設置,通過[Project!->[Settings!設定,頭文件路徑和lib文件路徑的設定分別如圖0.8、圖0.9所示。因此,通常只將一些適用于絕大部分工程的系統性的文件路徑通過前一種方式設定,如MFC的路徑設置,其他情況下則通過后一種方式設置。因此,我們在使用動態(tài)鏈接庫時可以將對應的頭文件、lib文件放在上述三種方式指定的路徑下面。SyslcniPropcrtici;I?X|SystemRe±loreAlJtDfTI池口UpdatMRemitGeneralComplcrNanBHtfdwsrcAdvairedYourYiLHl-beloggedonAdoninishr-akrInmakema±lofIhewchanges.圖0.5環(huán)境變量PATH的設置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文件路徑的設定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針對當前工程的頭文件路徑的設定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針對當前項目的lib文件路徑的設定msimgjE.llbopengl32.libReGeoModel.libOpenGL基本庫、實用庫由Windows自帶,因此,opengl32.dll、glu32.dll已經在系統目錄下了,如C:/Windows/System32,如果安裝了VisualStudio6.0的話,其對應的頭文件和lib庫文件分別在C:\ProgramFiles\MicrosoftVisualStudio\VC98\Include\GL和C:\ProgramFiles\MicrosoftVisualStudio\VC98\Lib中,其中:\ProgramFiles\MicrosoftVisualStudio為VisualStudio6.0的安裝路徑。如果要使用實用工具庫,則需要從網上下載相應的頭文件、lib文件,將其放置在上述三種方式中某種方式所指定的路徑下,通??梢詫⑵浞胖迷诋斍肮こ搪窂较禄蛘呦到y路徑下。除了設定相應的路徑外,我們還需提供編譯器鏈接所需的lib庫的名稱,如圖0.10所示。
lidTwJsWjndowHdp函DeEditVpwI阪丈羿cd^Jjj|回風唐I攜Lsharp3id1IgnoreallIgnorelibraries:UBC.lib.LIBCD.libFarcesymbollreferences:H幽NGRERcs+lidTwJsWjndowHdp函DeEditVpwI阪丈羿cd^Jjj|回風唐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文件的設定3.3在Windows環(huán)境下使用OpenGL3.3.1OpenGL與GDI在利用MFC開發(fā)Windows應用程序的時候,大多習慣于使用GDI(GraphicalDeviceInterface)函數,即圖形設備接口函數來繪制圖形。GDI是Windows體系結構中的重要組件,他為Windows提供了所有基本的繪圖函數。GDI與Windows系統中的圖形設備驅動程序連接,通過調用驅動程序中的相應功能,以響應Windows圖形函數的調用。這樣,程序員只需要將繪制代碼是先到GDI函數這個層次上,而不必去關心具體的硬件設備。GDI與Windows窗口的關聯靠一個設備上下文對象(DeviceContext)來實現。在Windows窗口中使用GDI時,需要創(chuàng)建一個設備上下文對象。設備上下文指定了許多如何在窗口上顯示圖形的信息,例如指定畫筆和畫刷的顏色、設置繪圖模式、調色板、映射模式和其他圖形模式。該上下文作為一個參數被發(fā)送到GDI函數中。如CView::OnDraw(CDC*pDC){CPen*pPen=newCPen(PS_SOLID,1,COLORREF(255,0,0));pDC->SelectObject(pPen);pDC->LineTo(250,250);???}每個Windows窗口都有一個設備上下文用于圖形輸出,而每個GDI函數都需要一個設備上下文,用來標識這個函數將向哪一個窗口輸出。一個程序中可以存在多個設備上下文,但每個窗口只有一個它自己的設備上下文。任何時候,圖形繪制到顯示器或者打印機時,它必須使用GDI函數。GDI函數可以繪制點、直線、矩形、多邊形、橢圓、位圖、文本。OpenGLWindows應用程序不使用GDI函數,而是直接使用OpenGLAPI函數進行圖形繪制。OpenGL與GDI的關系如圖0.11所示。圖0.11OpenGL工作結構Micorsoft還提供了一套"Wiggle”函數,用于OpenGLAPI和MicrosoftWindowsGDI的連接。與使用GDI在Windows下繪圖不同,使用OpenGL繪圖后,GDI中的畫筆(Pens)、畫刷(Brushes)、字體(Fonts)以及其他GDI對象將不再起作用。正如GDI使用設備上下文(DeviceContext)用于控制Windows中的圖形繪制,OpenGL使用了一個渲染上下文(RenderingContext)。這個渲染上下文通過與設備上下文相關聯,從而實現了與窗口的關聯。渲染上下文(RenderingContext)渲染上下文和設備上下文正如使用GDI繪圖時,每個Windows程序的窗口中都擁有一個設備上下文(DeviceContext),用于窗口中的圖形繪制。使用OpenGL在Windows窗口中繪制圖形時,也需要在每個窗口中嵌入一個渲染上下文(RenderingContext)。渲染上下文保存了與OpenGL發(fā)生聯系的信息,負責處理應用程序發(fā)出的OpenGL命令。所以在發(fā)出OpenGL命令之前,必須首先為該窗口創(chuàng)建一個渲染上下文。一個應用程序可以具有一個或多個渲染上下文,但同時只能有一個渲染上下文被設為當前的渲染上下文(CurrentRenderingContext)。程序中發(fā)出的OpenGL命令只輸出給當前的渲染上下文。例如在MDI的應用程序中同時打開了兩個窗口,當程序中發(fā)出一個OpenGL命令時,系統如何知道這個命令是傳給哪一個窗口的呢?為了使系統知道當前命令將發(fā)給哪一個窗口,所以在一個應用程序中(嚴格的說是在一個線程中)只能同時存在一個當前化的渲染上下文。當一個渲染上下文被設為當前上下文后,由于該渲染上下文關聯了一個Windows的設備上下文,從而能找到它所關聯的窗口,于是OpenGL向該窗口繪制圖像。Wiggle函數對渲染上下文的操作嚴格的說,渲染上下文不屬于OpenGL的概念,而更是Windows窗口中一個附加的概念,以支持窗口與OpenGL的連接。WindowsAPI中增加Wiggle函數的目的在于增加Windows窗口對OpenGL的支持。這些函數都以wgl為其前綴,其中最常用的幾個與渲染上下文相關的Wiggle函數是:HGLRCwglCreateContext(HDC);該函數輸入一個GDI的設備上下文的句柄,創(chuàng)建與這個設備上下文相關聯的渲染上下文。在調用這個函數創(chuàng)建渲染上下文之前,必須先調用函數SetPixelFormat()設置與設備上下文相匹配的像素格式。BOOLwglDeleteContext(HGLRC);該函數用于刪除一個渲染上下文。所創(chuàng)建的渲染上下文在用完之后需要將它刪除。HGLRCwglGetCurrentContext(VOID);該函數獲得線程中當前的渲染上下文。HDCwglGetCurrentDC(VOID);該函數獲得與當前渲染上下文相關聯的設備上下文。BOOLwglMakeCurrent(HDC,HGLRC);該函數用于當前化一個渲染上下文,即將一個渲染上下文設置為線程的當前上下文。線程中一旦當前化了一個渲染上下文,所有隨后的OpenGL命令都發(fā)往這個當前的渲染上下文中處理,并通過與該渲染上下文關聯的設備上下文實現窗口的場景繪制。3.3.3像素格式要在一個窗口中使用OpenGL,還需要為它選擇一個合適的像素格式(PixelFormat)。和渲染上下文的概念類似,像素格式并不屬于OpenGL的概念。它作為WindowsAPI的一個擴展,用于支持Windows下的OpenGL的功能。在OpenGL的圖形操作步驟中,最終的環(huán)節(jié)是將圖形光柵化,即把圖形轉化成可以在計算機屏幕上顯示的像素信息,并將這些像素寫到幀緩存中以實現屏幕顯示。像素格式為設備上下文設置一些與OpenGL相關的屬性。在像素格式中規(guī)定了和像素操作有關的信息,諸如:像素緩存是單緩存還是雙緩存;像素的顏色模式是RGBA模式還是索引模式;顏色的位數;深度緩存的位數等。因而在創(chuàng)建一個渲染上下文之前,需要首先為窗口的設備上下文設置一個像素格式。Windows中,使用結構PIXELFORMATDESCRIPTOR來設置像素格式,并提供了四個函數用于操作像素格式:intChoosePixelFormat(HDChdc,constPIXELFORMATDESCRIPTOR*ppfd);該函數返回與所定義的像素結構最匹配的線程中當前的渲染上下文。BOOLSetPixelFormat(HDChdc,intformat,constPIXELFORMATDESCRIPTOR*ppfd);該函數為指定的設備上下文設置像素格式。intDescribePixelFormat(HDChdc,intiPixelFormat,UINTnBytes,LPPIXELFORMATDESCRIPTORppfd);該函數獲得被PixelFormat指定的像素格式的信息。intGetPixelFormat(HDChdc);該函數返回設備上下文中被指定的像素格式的索引號。設置像素格式的步驟如下:第一步:根據需要,填寫結構PIXELFORMATDESCRIPTOR,因為像素格式是用這個結構來描述的,第二步:調用函數ChoosePixelFormat(),將填寫好的像素格式傳遞給該函數,函數ChoosePixelFormat()返回一個整形的序號。這個序號標識一個當前設備上下
文中所能提供的,且與所要求的像素格式最為匹配的像素格式;第三步:將這個返回的像素格式序號傳遞給函數SetPixelFormat(),使之成為設備上下文的像素格式。PIXELFORMATDESCRIPTOR的結構定義如下:/*Pixelformatdescriptor*/typedefstructtagPIXELFORMATDESCRIPTOR{WORDnSize;WORDWORDnSize;WORDnVersion;DWORDdwFlags;//亥結構的版本號,現在應設為1//像素緩存的屬性,包括:PFD_DOUBLE_BUFFER,PFD_DRAW_TO_WINDOWPFD_SUPPORT_GDI等BYTEiPixelType;//顏色模式,包括RGBA模式(PFD_TYPE_RGBA)和顏色索引模式(PFD_TYPE_COLORINDEX)BYTEcColorBits;//顏色位數,如8位代表256色,24位代表真彩色BYTEcRedBits;//通常不使用,置為0BYTEBYTEIcRedShift;cGreenBits;BYTEcGreenShift;BYTEcBlueBits;BYTEcBlueShift;BYTEcAlphaBits;BYTEcAlphaShift;BYTEcAccumBits;/累計緩存的位數BYTEcAccumRedBits;/一般置為0BYTEcAccumGreenBits;BYTEcAccumBlueBits;BYTEcAccumAlphaBits;BYTEcDepthBits;/深度緩存的位數BYTEcStencilBits;/模板緩存的位數BYTEcAuxBuffers;/輔助緩存的位數BYTEiLayerType;/現巳不用,可忽略,置為0BYTEbReserved;/必須為0DWORDdwLayerMask;//N下不支持,設為0DWORDdwVisibleMask;DWORDdwDamageMask;}PIXELFORMATDESCRIPTOR下面給出一個設置像素格式的主要操作過程的程序清單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);//為設備上下文設置像素格式SetPixelFormat(m_pDC->GetSafeHdc(),nPixelFormat,&pfd);在開始使用OpenGL繪制之前,程序中必須先完成像素格式的設置和渲染上下文的創(chuàng)建。由于設備像素格式需要設備上下文,所以這個過程必須在窗口創(chuàng)建完成之后進行。通常在Windows消息WM_CREATE的映射函數OnCreate()中進行像素格式的設置和渲染上下文的創(chuàng)建。對于創(chuàng)建的渲染上下文,最后還應該在Windows消息WM_DESTROY的映射函數OnDestroy()函數中予以刪除。圖0.12顯示了在Windows窗口的有關環(huán)節(jié)中創(chuàng)建和使用渲染上下文。圖0.12創(chuàng)建和使用渲染上下文的環(huán)節(jié)3.3.4典型實現如圖0.12所示,各消息響應函數的典型實現為:OnCreate()的典型實現:建立像素格式和繪制上下文來初始化OpenGL。在IntializeOpenGL()中創(chuàng)建一個設備上下文(DC),為這個DC選擇一個像素格式,創(chuàng)建和這個DC相關的繪制上下文(RC),然后選擇這個RC(通過wglMakeCurrent()實現)。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的典型實現:設置視口和視景體,因為這些是和窗口大小相關的?;静僮靼ㄔO置視口、選擇投影矩陣、設置模型視圖矩陣。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()的典型實現:繪制具體場景,一般包括如下步驟:清空緩存繪制場景Flush掉渲染流水線若設置了雙緩沖,則交換前后臺緩沖區(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()的典型實現:釋放設備上下文(DC)和渲染上下文(RC),從而避免內存泄露。voidCTeapotView::OnDestroy(){CView::OnDestroy();//TODO:Addyourmessagehandlercodehere//MaketheRCnon-cur
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 專業(yè)選擇講座模板
- 2025年度茶葉產品溯源體系建設合同范本4篇
- 2025年度場化項目服務類采購項目合同附件定制版4篇
- 2025年度電競主題商鋪租賃合作協議4篇
- 2025年度生態(tài)環(huán)保園區(qū)場地委托出租與環(huán)保技術服務合同樣本4篇
- 專業(yè)技能提升課程2024培訓協議
- 人教版九年級化學上冊第1章開啟化學之門《第2節(jié) 化學研究什么》公開示范課教學課件
- 二零二四事業(yè)單位聘用合同四種類別適用范圍與條件3篇
- 2025年度文化演藝中心場地租用協議范本4篇
- 2025年度城市綜合體項目場地購置合同示范文本4篇
- 瀝青路面施工安全培訓
- 機電設備安裝施工及驗收規(guī)范
- 倉庫安全培訓考試題及答案
- 中國大百科全書(第二版全32冊)08
- 初中古詩文言文背誦內容
- 天然氣分子篩脫水裝置吸附計算書
- 檔案管理項目 投標方案(技術方案)
- 蘇教版六年級上冊100道口算題(全冊完整版)
- 2024年大學試題(宗教學)-佛教文化筆試考試歷年典型考題及考點含含答案
- 計算機輔助設計智慧樹知到期末考試答案章節(jié)答案2024年青島城市學院
- 知識庫管理規(guī)范大全
評論
0/150
提交評論