梅章明,張秀山
(海軍工程大學 計算機工程系,湖北 武漢 430033)
由于自然環境中大部分景物(如云彩、火焰、煙霧、瀑布、雪花等特效)具有不規則性、復雜性與隨機性,且隨著時間變化形狀會隨之變化,對其進行逼真的實時模擬十分困難,需要大量的計算量和數據量。在虛擬環境中,自然景物的視覺效果直接影響到觀察者對周圍環境的感知,所以開發一個既能滿足逼真度要求,又能實時顯示的粒子系統是非常必要的。自從OpenGL公布以來,有關圖形學方面的書籍、論文等資料就層出不窮,如何利用Open GL開發出具有一定水平的計算機圖形程序就成為眾多學者的追求目標。在Visual C++中,既可利用 Win32編程,也可利用 MFC編程,兩者各有特點,本文就如何利用Open GL在MFC中開發出一個簡單的噴泉模擬程序作一個簡單探討。
OpenGL是一個跨平臺的三維圖形庫,可在Windows、Unix和 Mac等平臺上運行。而 Visual C++完善的基本類庫MFC和應用向導AppWizard使得開發一個復雜的應用程序變得輕松自如。如果將兩者結合,便可開發出較高水平的Windows下三維圖形應用程序[1]。
在3D游戲的渲染過程中,傳統的建模方法一般只適用于外形比較規則的形體,對于那些像雨、雪、瀑布、噴泉以及火焰等沒有固定形狀,甚至要隨著外部環境或者其他因素的改變而改變的物質建模,傳統的方法就顯得無能為力了[2]。1983年REEVES W T提出了一種新的建模方法,稱為模糊物體建模,該方法就是粒子系統,它的出現正好解決了上述問題[3]。
OpenGL函數庫和操作系統無關,它有自己的獨特設計,與Windows的圖像設備接口GDI模型以及多數MFC應用程序的建立方法不太一致。在Windows系統中,這樣的一組函數稱為wiggle函數,每個wiggle函數的前綴是“wgl”。
在Win32下,首先必須重新設置畫圖窗口的像素格式,使其符合OpenGL對像素格式的需要。為此,聲明一個PIXELFORMATDESCRIPTOR結構的變量,并適當設置其結構成員的值,使其支持OpenGL及其顏色模式。再以此變量為參數調用 ChoosePixelFormat(),分配一個像素格式號,然后調用 SetPixelFormat()將其設置為當前像素格式。
完成了像素格式的重新設置后,需要為OpenGL建立繪制描述表 (Render Context)。繪制描述表的作用類似于Windows中的設備描述表(Device Context)。只有建立了繪制描述表RC后,OpenGL才能調用繪圖原語在窗口中做出圖形。Win32API提供了幾個操作繪制描述表的函數,包括建立、復制、使用、刪除和查詢等,它們都以wgl為詞頭。RC是以線程為單位的,每一個線程必須使用一個RC作為當前RC才能執行OpenGL繪圖原語。
wglCreateContext()是建立繪制描述表的函數,它以一個指向GDI設備描述表的句柄為參數,返回一個與此設備描述表相關聯的繪制描述表句柄。在以此2句柄為參數調用函數wglMakeCurrent(),使RC成為線程當前使用的RC,完成Windows下OpenGL繪圖環境的初始化過程[4]。
使用 Visual C++的 AppWizard和 Class Wizard可以很容易地生成一個使用MFC的OpenGL單文檔應用程序框架,名稱為MyFountain。

使視窗口具有WS_CLIPCHILDREN和WS_CLIPSIBLINGS風格,確保成功地設置像素格式。
利用MFC ClassWizard為CMySDOpenGLView類添加消息 WM_CREATE、WM_DESTROY、WM_SIZE 和WM_TIMER的響應函數。
光滑極限量規是具有以孔或軸的最大極限尺寸和最小極限尺寸為公稱尺寸的標準測量面[1],由于其結構簡單、檢驗效率高、能保證被檢工件在裝配中的互換性要求,因而在大批量生產中被廣泛使用。目前光滑極限量規的檢定項目包括尺寸、母線直線度、圓度和測量面表面粗糙度[2],其中圓度和母線的直線度測量主要分別使用圓度儀和輪廓儀,但這幾種儀器只適合在計量實驗室中使用,而且只能檢定一項,無法適合大批量的量規檢定[3],因此,有必要研究出一套機電一體化測量方案,可以通過一次裝夾即可自動測量塞規尺寸和形位誤差,可大大地提高檢定效率和數字化水平。
首先在OnCreate方法中初始化OpenGL,并設置定時器。
然后在OnTimer響應函數中添加定時器響應函數和場景更新命令,使得程序按照定時器設置的時間步長進行中斷,并調用OnDraw對場景進行更新、渲染。
第三步,添加OnSize函數對用戶進行窗口調整的消息進行響應,并即時調整窗口的大小[5]。
最后,當關閉窗口時,將值NULL(或0)賦值給wglMakeCurrent()的參數 hRC 后,調用 wglDeleteContext()刪除繪制描述表,并刪除調色板和定時器。
構造可視化系統的建模技術大致可以分為兩類:幾何建模和行為建模。幾何建模處理物體的幾何和形狀的表示,研究圖形數據結構等基本問題;行為建模處理物體運動和行為的描述。
一個粒子系統由大量稱為粒子的簡單體素構成。每個粒子有一組屬性,如位置、速度、顏色和生命期。一個粒子究竟有什么樣的屬性,主要取決于具體的應用。粒子的初值由隨機過程產生。粒子往往由位于空間的某個地方的粒子源產生。
粒子系統也利用了隨機過程,并常將物體的幾何和行為組合在一個有機模型中。
一個粒子系統是不斷進化的。在生命期的每一刻,都要完成以下4步工作:
(1)粒子源產生新粒子。產生任意數目的新粒子,它們的初始屬性由隨機過程控制。每個粒子都有一個生命期,如果某些粒子不應刪除,則可以賦予它無限長的生命期。
(2)更新現有粒子屬性。例如,若粒子有位置和速度屬性,在模擬重力場中的運動時,可以如下更新粒子的位置和速度屬性:

在該步中,粒子的生命期遞減一個時間步。
(3)刪除“死”粒子。檢查粒子的生命期,若為 0則將粒子從系統中刪除。
(4)繪制粒子。顯示粒子系統中所有現存的粒子。
在一般情況下,粒子的幾何特征十分簡單,可以采用一個像素或小的多邊形來代表[6]。
粒子數據結構的定義如下:

3.2.1 先構造一個場景
由于重點是噴泉,因此簡單構造一個模擬的地面能突出噴泉就可以了。實現代碼如下:

3.2.2 噴泉的渲染處理
噴泉的渲染處理過程主要是利用了OpenGL的特征函數[7]和方法,主要進行了兩方面的處理:(1)將噴泉模型渲染成紋理文件[8];(2)采用透明紋理渲染技術[9]。
3.2.3 噴泉的實現
在構造了簡單的地面場景后,取以原點為中心的圓周上的均勻點序列作為噴泉的噴射點,按照上述提到的繪制方法[10]即完成了噴泉的動態模擬。噴泉系統模擬的主要關鍵代碼在于向內存中添加渲染粒子,即函數AddParticles(),之后粒子將按照預定的軌道運行,其主要實現代碼如下:

噴泉的效果顯示如圖1所示。
通過改變程序中alpha(圓的內接正多邊形圓心角)的值,可以改變噴泉粒子流的股數。噴泉的粒子流粗細可通過改變矢量的乘積來實現,通過改變“vectl.x*=5;vectl.y*=5;vectl.z*=5;”等式右邊的數值可以控制,圖 1就是改為“5;3;2;”的結果。

圖1 噴泉的效果顯示
通過上述的試驗比較可知,噴泉粒子流的股數和每股粒子流的粒子數目都會影響到噴泉模擬效果的真實感[11]。越來越多的人注意到使用Visual C++和OpenGL開發三維圖形動畫軟件的有利之處,但是有關OpenGL的資料大多都是介紹基本的編程指南或者一些基礎的原理或方法,卻很少有大型的與應用有關的編程案例,而且有也大多都是基于Win32的類來實現一些簡單的圖形功能,介紹MFC與OpenGL連接的資料卻少之又少,
本文主要是在MFC下實現了一個簡單的噴泉模擬程序,主要的創新點是分析了MFC下消息響應的內部機制,所以希望本次的探索能對以后利用MFC開發出更高效的程序有所幫助。
[1]和平鴿工作室.OpenGl高級編程與可視化系統開發(高級編程篇)[M].北京:中國水利水電出版社,2007.
[2]徐明亮,盧紅星,王琬.OpenGl游戲編程[M].北京:機械工業出版社,2008.
[3]REEVES W T.Particle systems-a technique for modeling a class of fuzzy objects[J].ACM Transations on Graphics(TOG), 1983,2(2):359-376.
[4]周建龍,肖春.計算機圖形學理論與OpenGl編程實踐[M].廣州:華南理工大學出版社,2007.
[5]孫鑫,余安萍.VC++深入詳解[M].北京:電子工業出版社,2008.
[6]雷曉,胡倩.基于 Direct3D的粒子系統設計[J].微計算機信息,2010(11-1).
[7]張芹,吳慧中,謝雋毅.基于粒子系統的火焰模型及其生產方法研究 [J].計算機輔助設計與圖形學報,2001,13(1):78-82.
[8]PHONG B T.Illunimation for computer generated pictures[J].Communications of the ACM,1975,18(6):311-317.
[9]侯陽,迪克.三維圖形動畫編程實例[M].海洋出版社,1993.
[10]楊春雨.基于粒子系統的噴泉動畫模擬[J].長春:吉林大學出版社,2008.
[11]凌云,儲林波.用 Visual C++中的 MFC和 OpenGl建立三維圖形應用環境[J].微型機與應用,1998,17(4):8-10.