王曉松+徐妍+田董煒+劉志強(qiáng)+胡夢濤
摘要:目前沒有在C#中開發(fā)OpenGL的標(biāo)準(zhǔn),在.NET Framework中也沒有OpenGL API接口。為此,研究了在C#中聯(lián)合SharpGL編寫三維建模算法,闡述了三維建模關(guān)鍵步驟,并且實(shí)例化例子。相比較C++,在動態(tài)鏈接庫SharpGL.dll支持下,在C#中進(jìn)行SharpGL三維建模代碼可讀性強(qiáng),開發(fā)變得更簡潔,程序可移植性佳。
關(guān)鍵詞:SharpGL;C#;動態(tài)鏈接庫;三維建模
中圖分類號:TP317.4
文獻(xiàn)標(biāo)識碼:A
文章編號:16727800(2017)004020503
0引言
SharpGL是進(jìn)行三維顯示的函數(shù)庫,其運(yùn)行環(huán)境與平臺無關(guān),能在Windows、Linux及Mac OS等操作系統(tǒng)上運(yùn)行,故其在硬件、窗口及操作系統(tǒng)方面是相互獨(dú)立的,SharpGL能不依賴于任何硬件或操作系統(tǒng)即可運(yùn)行。SharpGL本身只定義了一個標(biāo)準(zhǔn),因此只要符合定義標(biāo)準(zhǔn)的函數(shù)庫,都可以稱為SharpGL標(biāo)準(zhǔn)函數(shù)庫。ATT、UNIX軟件實(shí)驗室、IBM等著名企業(yè)都采用OpenGL標(biāo)準(zhǔn)。SharpGL標(biāo)準(zhǔn)定義的函數(shù)庫分為4個部分:SharpGL核心庫、SharpGL實(shí)用庫、SharpGL輔助庫、SharpGL工具庫。SharpGL函數(shù)庫是一個實(shí)時渲染函數(shù)庫,能夠在短時間進(jìn)行實(shí)時交互繪制。DirectX與其相似,但只能在Windows操作系統(tǒng)上執(zhí)行。 C#是微軟公司早在2000年就開始推出的一種高級編程語言,這種高級編程語言運(yùn)行在.NET CLR環(huán)境上,并基于.NET Framework框架創(chuàng)作。C#是從C與C++語言派生出的,吸收了C與C++的優(yōu)點(diǎn),并彌補(bǔ)了C與C++的缺點(diǎn),從而產(chǎn)生功能強(qiáng)大、類型安全、更簡單的面向?qū)ο笳Z言。C#代碼框架具有面向?qū)ο?、引用類等概念,幾乎囊括所有軟件開發(fā)與工程研究的最新成果。相比較C與C++而言,C#具有語法簡單易學(xué)、配置與調(diào)制簡單、程序開發(fā)周期短等優(yōu)點(diǎn),廣泛應(yīng)用于當(dāng)今工程開發(fā)。本文將C#和SharpGL聯(lián)合,開發(fā)三維物體模型程序以提高效率。
1SharpGL函數(shù)庫
1.1SharpGL核心庫
SharpGL動態(tài)鏈接庫——核心庫包含約115個可以被調(diào)用的函數(shù),統(tǒng)一將函數(shù)名的前綴命名為gl。核心庫函數(shù)用于常規(guī)圖形處理,應(yīng)用范圍較廣。同一個功能函數(shù)輸入不同類型的參數(shù),從基本的115個函數(shù)中派生出來的函數(shù)表達(dá)式約有300個。
1.2SharpGL實(shí)用庫
SharpGL動態(tài)鏈接庫——實(shí)用庫包含約43個可調(diào)用函數(shù),統(tǒng)一將函數(shù)名的前綴命名為glu。SharpGL提供了豐富的繪圖函數(shù)命令,但所有圖形繪制都由點(diǎn)、線、面元素組合而成。glu函數(shù)通過調(diào)用核心庫函數(shù),為軟件開發(fā)提供了相對簡單的用法,可實(shí)現(xiàn)較為復(fù)雜的操作[1]。
1.3SharpGL輔助庫
SharpGL動態(tài)鏈接庫——輔助庫包含約31個可調(diào)用函數(shù),統(tǒng)一將函數(shù)名的前綴命名為aux。輔助庫函數(shù)提供面向?qū)ο蟮臄?shù)據(jù)輸入輸出處理、窗口操作以及繪制一些簡單的三維物體。
〗1.4SharpGL工具庫
SharpGL動態(tài)鏈接庫——工具庫包含約30個可調(diào)用函數(shù),統(tǒng)一將函數(shù)名的前綴命名為glut。glut是不依賴于任何操作系統(tǒng)平臺的SharpGL函數(shù)庫,用途是隱藏不同操作系統(tǒng)接口難題。工具庫函數(shù)以glut開頭,提供更為復(fù)雜的繪圖功能[2]。由于glut中的面向?qū)ο蟠翱诠芾砗瘮?shù)不依賴任何運(yùn)行環(huán)境,因此SharpGL中的工具庫可以在各種操作系統(tǒng)中執(zhí)行命令[3]。
2SharpGL建模環(huán)境創(chuàng)建
2.1添加SharpGL引用
在Visual Studio 2012中建立C#應(yīng)用程序過程很簡單:在Visual Studio 2012編譯器環(huán)境中選擇新建項目——Visual C#--Windows窗體應(yīng)用程序,輸入項目名稱與解決方案名稱,然后保存在適當(dāng)路徑位置,點(diǎn)擊確定,就成功創(chuàng)建了WindowsForms應(yīng)用程序。此時Visual Studio 2012會根據(jù)上一步的輸入,自動創(chuàng)建一個程序命名空間、一個窗體組建 (Form1)以及程序的主入口函數(shù) Main(string[] args)。 到此,Visual Studio 2012只是創(chuàng)建了應(yīng)用程序主體,即編譯環(huán)境,使用SharpGL還必須添加SharpGL的動態(tài)鏈接庫引用。在C#中,引用是通過using關(guān)鍵字實(shí)現(xiàn)的,在編寫代碼窗口上部輸入代碼: using SharpGL; 至此,SharpGL的動態(tài)鏈接庫引用工作完成,下一步工作就可使用SharpGL函數(shù)繪制三維物體模型了。
2.2創(chuàng)建SharpGL設(shè)備環(huán)境
使用SharpGL相關(guān)代碼開發(fā)三維物體模型時,必須先建立繪制設(shè)備環(huán)境。先拖拉一個可視化組件,用于顯示三維模型繪制。在Visual Studio 2012項目名稱中添加一個組件,命名為SharpGLControl,然后為創(chuàng)建的組件類進(jìn)行對象實(shí)例化,編寫如下代碼:
// Get the SharpGL object. SharpGL gl = SharpGLControl.SharpGL;
為了在SharpGLControl對象組件上繪制三維物體模型,必須先進(jìn)行初始化設(shè)置,這一點(diǎn)與其它程序語言不同。SharpGLControl加載如下:
//Clear the color and depth buffer. gl.Clear(SharpGL.GL_COLOR_BUFFER_BIT | SharpGL.GL_DEPTH_BUFFER_BIT); //Load the identity matrix. gl.LoadIdentity();
2.3建立SharpGL繪制環(huán)境
由于SharpGL直接使用繪制環(huán)境,與設(shè)備環(huán)境沒有關(guān)聯(lián)。因此,還需要建立一個SharpGL繪制環(huán)境,否則SharpGL函數(shù)不能調(diào)用。在SharpGLControl_SharpGLDraw中定義了繪制環(huán)境相關(guān)函數(shù),無需重寫這個函數(shù)就能直接調(diào)用。由于SharpGLControl_SharpGLDraw是由SharpGL類派生出來的,因而它具有Control類的全部屬性和功能。 SharpGL具有多種函數(shù),繪制環(huán)境如下:
// Get the SharpGL object. SharpGL gl = SharpGLControl.SharpGL; //Set the projection matrix. gl.MatrixMode(SharpGL.GL_PROJECTION); //Load the identity. gl.LoadIdentity(); //Create a perspective transformation. gl.Perspective(60.0f,(double)Width / (double)Height,0.01,100.0); //Use the 'look at' helper function to position and aim the camera. gl.LookAt(-5,5,-5,0,0,0,0,1,0); //Set the modelview matrix. gl.MatrixMode(SharpGL.GL_MODELVIEW);
通過以上步驟操作,SharpGL繪制環(huán)境創(chuàng)建工作就全部完成,在這個程序代碼環(huán)境中即可進(jìn)行三維建模。SharpGL中創(chuàng)建的所有三維物體模型,如三維建筑物、家具、山峰等,都是用頂點(diǎn)描述的,因此三維物體模型繪制操作都可針對每個特征點(diǎn)進(jìn)行計算,然后通過內(nèi)核矩陣函數(shù)進(jìn)行光柵化形成二維像素。SharpGL的另一個核心模塊是矩陣算法變換,就是把三維物體模型轉(zhuǎn)換為二維圖像。
3三維建模算法
隨著計算機(jī)技術(shù)的不斷進(jìn)步,在圖像、VR、游戲系統(tǒng)、醫(yī)療系統(tǒng)等領(lǐng)域構(gòu)造和使用的模型越來越復(fù)雜、越來越精細(xì)。這些復(fù)雜的物體模型,不但對計算機(jī)的處理速度以及存儲容量提出了更高要求,而且成為實(shí)時繪制物體模型、通信傳輸?shù)钠款i,因此物體模型簡化研究成為非常重要的科研課題。物體模型簡化指在保持原有模型基本不畸變的條件下,采用適當(dāng)?shù)暮瘮?shù)算法減少該物體模型的三角面數(shù)、邊數(shù)、頂點(diǎn)數(shù)[3]。 三維物體模型因其表面凹凸不平,呈現(xiàn)一種連續(xù)變化的曲面,這種曲面無法用平面地圖確切表示。單元三角形是三維物體模型的基本組建單元圖,為真實(shí)表現(xiàn)三維物體模型,每個單元三角形需要包括3個頂點(diǎn)和單元三角形的法向量,以此確定一個最小單位表面,不管多么復(fù)雜的三維物體模型都可以化解成多個單元三角形組合。對于同一物體,三維物體模型上的單元三角形并非獨(dú)立存在,而是所有單元三角形都是相互關(guān)聯(lián)的,這些關(guān)聯(lián)信息主要體現(xiàn)在以下兩方面:①鄰接關(guān)系即共邊與共頂點(diǎn);②同一個單元三角形,法向量相等、法向量共面。通過上述單元三角形之間的聯(lián)系進(jìn)行分類,即可組成不同的三維曲面模型。 三維物體模型三角網(wǎng)算法可通過兩個步驟實(shí)現(xiàn):①在三維物體模型包含的所有點(diǎn)云數(shù)據(jù)中搜索符合單元三角形條件的點(diǎn),建立單元三角形;②判斷搜索到的單元三角形是否有共邊關(guān)系,如果滿足條件,就將單元三角形添加到三維物體模型的表面,如果沒有則進(jìn)行其它搜索。 SharpGL算法類定義如下:
public class Vertex public class Triangle ...... public class Mesh public void Compute(List
三維物體模型的噪點(diǎn)數(shù)據(jù),必須去除點(diǎn)云數(shù)據(jù)的離群孤立點(diǎn),編寫相關(guān)算法,設(shè)定除噪閾值。閾值參數(shù)為噪聲點(diǎn)閾值,小于這個值的點(diǎn)會刪除,否則就參與計算。 其它相關(guān)定義如下: 定義1:三維物體模型中任意兩個單元三角形共邊,則稱這兩個單元三角形相鄰; 定義2:三維物體模型中任意兩個單元三角形共頂點(diǎn),則稱這兩個單元三角形相接; 定義3:如果存在一組單元三角形具有相接關(guān)系,且兩個單元三角形法向量相等,則這一組單元三角形在同一平面上; 定義4:如果存在一組單元三角形具有相接關(guān)系,且兩個單元三角形的法向量處于某個平面上,則這組單元三角形在同一個柱面上。
4建模關(guān)鍵環(huán)節(jié)
4.1SharpGL渲染流程
在使用SharpGL繪制過程中,需要完成的加載任務(wù)有:設(shè)置各種緩存,如顏色、深度等,加載場景物體表面貼膜紋理,設(shè)置光照與陰影模式,建立景物顯示列表、圖像質(zhì)量和材料性質(zhì)等[4]。SharpGL渲染步驟如下: ①輸入三維物體模型要渲染的點(diǎn)的云數(shù)據(jù)等相關(guān)信息;②設(shè)置攝像頭的位置和視角,調(diào)整視覺角度,把三維物體模型安置到三維場景合適的位置;③設(shè)置投影光照位置、方向、顏色、類型等屬性; ④設(shè)置三維物體模型顏色、紋理貼圖等材質(zhì)參數(shù); ⑤將上述三維信息轉(zhuǎn)化為二維圖像。 SharpGL另一個重要模塊是三維矩陣模塊,據(jù)此進(jìn)行三維物體模型的移動、旋轉(zhuǎn)和縮放。
4.2紋理映射
對三維物體模型進(jìn)行渲染,為了得到現(xiàn)實(shí)感效果,常用技術(shù)是模型表面貼圖。通過紋理貼圖,可使三維物體模型顏色不再是單一色彩,而是具有各種風(fēng)格。 三維物體模型貼圖原理:給每個三維物體模型頂點(diǎn)對應(yīng)一個二維圖形坐標(biāo),這樣在顯示三維物體模型頂點(diǎn)時可采用二維圖像上相應(yīng)像素的顏色值。三維物體模型位于三維空間,每個頂點(diǎn)的坐標(biāo)是(x,y,z)三個分量,而二維圖像位于二維空間,每個坐標(biāo)是(u,v)兩個分量,每個坐標(biāo)稱為頂點(diǎn)的紋理坐標(biāo)[5]。三維物體模型制作時是沒有紋理坐標(biāo)的,需要經(jīng)過專門的參數(shù)化過程來生成紋理坐標(biāo)。如果一個三維物體模型沒有紋理坐標(biāo)就無法使用紋理貼圖技術(shù)來渲染物體模型表面,因此,不是每個三維物體模型都可以顯示紋理貼圖,必須先生成紋理坐標(biāo)才可進(jìn)行貼圖渲染。三維物體模型的紋理坐標(biāo)對應(yīng)的是二維空間像素位置,而不是像素的具體顏色,因此同一個三維物體模型只要更換貼圖圖像,就可顯示不同的渲染效果。
4.3SharpGL三維坐標(biāo)變換
SharpGL三維物體模型變換和二維變換類似,其實(shí)質(zhì)就是在二維變換的基礎(chǔ)上增加z坐標(biāo)值得到。三維物體模型基本變換有模型平移、旋轉(zhuǎn)、比例縮放、切錯、對稱等。對于三維空間坐標(biāo)系,需要采用齊次坐標(biāo)系,其數(shù)學(xué)變換矩陣是4×4階矩陣。三維物體模型平移變換,指物體模型在空間坐標(biāo)系中沿著指定方向移動一段距離而形狀和大小保持不變的過程。平移變換作用在點(diǎn)上,向量沒有位置屬性變化,因此向量的平移對變換沒有意義。已知三維坐標(biāo)系中一個點(diǎn)的坐標(biāo)是P(x,y,z),沿X軸、Y軸、Z軸方向分別平移tx、ty、tz后,得到新的坐標(biāo)P'(x',y',z')的函數(shù)表達(dá)式為:
三維物體模型空間旋轉(zhuǎn)變換是個復(fù)雜的數(shù)學(xué)矩陣模型變化,通常認(rèn)為物體模型繞某軸逆時針方向旋轉(zhuǎn)時角度為正,順時針方向旋轉(zhuǎn)時角度為負(fù)。三維物體模型作旋轉(zhuǎn)變換時,需要兩個必不可少的條件,即旋轉(zhuǎn)軸和旋轉(zhuǎn)角度。旋轉(zhuǎn)前后三維物體模型的大小和形狀沒有變化,變化的只是空間點(diǎn)的位置坐標(biāo)。其中繞坐標(biāo)軸旋轉(zhuǎn)變換是最簡單的變換,當(dāng)三維物體模型繞某一坐標(biāo)軸旋轉(zhuǎn)時,物體模型上各點(diǎn)在此軸的坐標(biāo)值不變,而在另兩個坐標(biāo)軸組成的坐標(biāo)面上的坐標(biāo)相當(dāng)于一個二維的旋轉(zhuǎn)變換[6]。筆者使用三維數(shù)據(jù),最終形成三維物體模型顯示結(jié)果如圖1所示。5結(jié)語
本文闡述了在C#中實(shí)現(xiàn)SharpGL三維物體建模的幾個關(guān)鍵步驟。從最終成型結(jié)果可知,在動態(tài)鏈接庫SharpGL.dll支持下,使用C#進(jìn)行SharpGL三維物體建模可操作性強(qiáng)、代碼簡潔易讀。與C++比較,C#省去了很多工作,譬如像素格式設(shè)置、設(shè)備環(huán)境、繪制環(huán)境的激活與去活、前后臺緩存交換等,本文方法僅僅需要考慮的是如何在三維建模關(guān)鍵步驟中組織好SharpGL函數(shù)調(diào)用命令。
參考文獻(xiàn):
[1]蔡振鋒,密長林,王榮華,等.基于OpenGL的地下管線三維緩沖分析算法研究及應(yīng)用[J].山東國土資源,2016(9):6064.[2]高士娟,毛先成,張寶一,等.基于平面地質(zhì)圖的地質(zhì)體三維建模[J].地質(zhì)找礦論叢,2015(5):594601.
[3]閔芳,張志先,楊功廷.基于OpenGL的三維建筑可視化研究與仿真[J].現(xiàn)代電子技術(shù),2016(2):7881.
[4]李春林,曹宇,朱德華,等.激光加工工藝軟件的三維圖形層次化拾取方法[J].激光,2016(7):5861.
[5]田明銀,蘭一麟濤.基于分形算法的三維地形可視化應(yīng)用[J].電子設(shè)計工程,2016(14):2026.
[6]董鴻鵬,姜本清,方偉.基于OpenGL的三維模型渲染技術(shù)研究[J].艦船電子工程,2015(10):114128.
[7]劉韜.基于OpenGL噴泉粒子系統(tǒng)設(shè)計與實(shí)現(xiàn)[J].科技視界,2016(11):287288.
[8]梁春艷,李志雄,蘇清茂.六自由度機(jī)器人3D建模仿真研究[J].西南科技大學(xué)學(xué)報,2016(2):8186.
(責(zé)任編輯:杜能鋼)