方開紅, 張新林
(羅定職業(yè)技術(shù)學(xué)院 電子信息系,廣東 羅定 527200)
隨著計算機(jī)技術(shù)的不斷發(fā)展進(jìn)步,計算機(jī)應(yīng)用不斷滲透到人們的學(xué)習(xí)、生活、工作及娛樂等各行各業(yè)之中。據(jù)了解,目前計算機(jī)應(yīng)用中的娛樂游戲,已成為生活中不同群體最受歡迎的娛樂之一。在娛樂游戲的選擇上,游戲的圖形畫面顯示效果往往是游戲玩家是否接受該游戲的決定因素之一,也是游戲開發(fā)中必須重點考慮并處理好的問題。比如,游戲中圖形畫面的閃爍就是游戲開發(fā)中必須解決的問題之一。本文就這一問題的解決辦法提出一種解決方案,供各位游戲開發(fā)人員參考借鑒。
VC++游戲開發(fā)中圖形編程主要采用的是Windows系統(tǒng)中的圖形系統(tǒng)的結(jié)構(gòu)體系。由于計算機(jī)輸出設(shè)備和顯示設(shè)備種類繁多,每種設(shè)備又包含許多種不同的型號,Windows系統(tǒng)提供了GDI(Graphics Device Interface,圖形設(shè)備接口)的概念,實現(xiàn)應(yīng)用程序的設(shè)備無關(guān)性。所謂設(shè)備無關(guān)性,就是操作系統(tǒng)屏蔽了硬件設(shè)備的差異,外部設(shè)備的驅(qū)動程序由操作系統(tǒng)管理,使用戶編程時無需考慮特殊的硬件設(shè)置,通過設(shè)備描述表DC(Device context)建立與應(yīng)用程序的關(guān)聯(lián)。
所謂GDI指的是Windows系統(tǒng)中的一個子系統(tǒng),它主要負(fù)責(zé)在顯示器或打印機(jī)等圖形輸出設(shè)備上輸出圖形,Windows系統(tǒng)中所有的圖形處理都是通過GDI來完成的。GDI中封裝了一系列用于圖形處理的函數(shù)和一些相關(guān)的數(shù)據(jù)結(jié)構(gòu)、宏和結(jié)構(gòu),可以很方便地來繪制點、線、矩形、橢圓、多邊形和位圖等圖形對象。使用GDI可以很容易的實現(xiàn)對圖形處理,而不必去考慮圖形具體是如何繪制出來的,無論是在屏幕上還是打印機(jī)上,都可以用同樣的方法進(jìn)行圖形的繪制。GDI是Windows圖形界面程序與實際物理設(shè)備之間的橋梁,使得用戶無需具體關(guān)注具體設(shè)備的細(xì)節(jié),只需在一個虛擬的環(huán)境中進(jìn)行操作。GDI會自動將用戶通過調(diào)用GDI將邏輯空間的操作轉(zhuǎn)化為對具體設(shè)備驅(qū)動程序的調(diào)用。GDI能夠自動檢測物理設(shè)備,并依據(jù)物理設(shè)備以最優(yōu)方式驅(qū)動這些設(shè)備,完成真是的圖形顯示。具體繪圖的原理流程圖如圖1所示。
圖1 繪圖原理流程圖
用VC++開發(fā)應(yīng)用程序,實質(zhì)就是對應(yīng)用程序的各種消息進(jìn)行響應(yīng)處理,對圖形進(jìn)行繪制也是如此。在程序代碼中,一般將繪制圖形的代碼放在OnPaint或OnDraw消息響應(yīng)函數(shù)中,當(dāng)系統(tǒng)產(chǎn)生WM_PAINT消息時,上述函數(shù)會自動進(jìn)行消息響應(yīng)并處理,從而實現(xiàn)圖形的繪制。在游戲程序圖形很少改變或者游戲程序窗口很少刷新時,采用這樣方式處理沒有任何問題,但是如果游戲程序窗體的內(nèi)容經(jīng)常需要刷新,圖形就會出現(xiàn)閃爍現(xiàn)象。因此,很多人認(rèn)為出現(xiàn)這樣的現(xiàn)象是圖形刷新速度過快而造成的。實際上,在游戲程序中,比如最小化或最大化游戲窗口,移動游戲窗口,覆蓋游戲窗口等等都會引起游戲窗口里的圖形的重繪。通過大量實驗我們發(fā)現(xiàn),刷新速度快并不是造成游戲中圖形閃爍的最根本的原因,造成圖形閃爍的直接原因?qū)嶋H上是相鄰兩幀圖像之間存在的巨大差異,造成這一差異的原因是由于VC++本身的圖形處理機(jī)制所導(dǎo)致的。在VC++開發(fā)中,應(yīng)用程序窗口每次刷新時,將自動調(diào)用OnEraseBkgnd擦除背景函數(shù),該函數(shù)的作用是利用系統(tǒng)背景色填充窗體繪圖區(qū),在填充完了之后,系統(tǒng)才會重新調(diào)用繪圖代碼對窗口進(jìn)行重繪。當(dāng)WM_PAINT繪圖響應(yīng)函數(shù)的響應(yīng)很頻繁的時,于是我們就看到了游戲中圖形的閃爍現(xiàn)象。出現(xiàn)這種現(xiàn)象的原因是游戲程序在每次執(zhí)行繪圖任時,都是在重復(fù)繪制背景,而且所有的繪制圖形都是直接在屏幕上顯示的,這種行為導(dǎo)致游戲屏幕不停的執(zhí)行“擦除背景-重繪背景”工作,使得我們?nèi)庋劭雌饋沓霈F(xiàn)了閃爍現(xiàn)象。
通過上述分析可知,之所以出現(xiàn)閃爍是由于繪圖時響應(yīng)繪圖函數(shù)然后直接把圖形在物理設(shè)備如顯示屏上顯示出來,如果繪圖響應(yīng)非常頻繁,就產(chǎn)生了閃爍現(xiàn)象,具體表示如圖2所示。
圖2 直接繪圖
雙緩沖技術(shù)就是在計算機(jī)內(nèi)存中創(chuàng)建一個兼容設(shè)備環(huán)境,一次游戲循環(huán)中的所有繪圖任務(wù)都繪制到該內(nèi)存設(shè)備環(huán)境中,當(dāng)所有繪圖任務(wù)完成后,一次性將內(nèi)存設(shè)備環(huán)境中的內(nèi)容繪制到物理設(shè)備環(huán)境最后在顯示屏幕顯示出來(具體表示如圖3所示)。通過分析閃爍原因可知,當(dāng)發(fā)生n次繪圖時,直接繪圖方式在物理設(shè)備環(huán)境及顯示屏上直接執(zhí)行“擦除-重繪”n次,所以產(chǎn)生閃爍。雙緩沖技術(shù)繪圖是將n次繪圖的內(nèi)容繪制到內(nèi)存設(shè)備環(huán)境,完成后一次性繪制到物理設(shè)備環(huán)境然后在屏幕上顯示出來,因此圖形不會產(chǎn)生閃爍現(xiàn)象。
圖3 雙緩沖繪圖
在VC++游戲開發(fā)中,實現(xiàn)雙緩沖技術(shù)的方法很多。下面介紹一種最常見的方法,就是使用一個全局內(nèi)存設(shè)備環(huán)境變量來實現(xiàn)雙緩沖。具體設(shè)計步驟如下:
(1)定義一個全局內(nèi)存設(shè)備環(huán)境,例如:
(2)在游戲初始化時,將全局內(nèi)存設(shè)備變量(如g_h(yuǎn)MemDC)創(chuàng)建為兼容的設(shè)備環(huán)境(DC),將全局內(nèi)存位圖變量(如g_h(yuǎn)bmMen)創(chuàng)建為兼容位圖,并選入全局內(nèi)存設(shè)備變量(如g_h(yuǎn)MemDC),以便在該內(nèi)存位圖中繪圖。
(3)在需要將繪圖內(nèi)容顯示出來時,把全局內(nèi)存設(shè)備變量存放的圖形繪制到物理設(shè)備并顯示到顯示屏上。
(4)當(dāng)不需要在使用全局內(nèi)存設(shè)備環(huán)境是,記得將其占用資源釋放以便其他需要。
用VC++實現(xiàn)雙緩沖技術(shù)的具體代碼如下:
在VC++游戲開發(fā)過程中,圖形圖像處理是一個非常重要的技術(shù)環(huán)節(jié)。比如,我在指導(dǎo)學(xué)生用VC++開發(fā)一個簡單的游戲卡片對對碰游戲時,學(xué)生做出來的游戲畫面效果都是出現(xiàn)很明顯的閃爍現(xiàn)象,使得游戲失去了吸引力。卡片對對碰游戲界面如圖4所示。于是,我詳細(xì)給學(xué)生分析了產(chǎn)生畫面產(chǎn)生閃爍的原因,之后教會了他們一種改進(jìn)游戲畫面閃爍的方法,這種方法就是采用上面所講到的雙緩沖實現(xiàn)技術(shù)。學(xué)生按照我的指導(dǎo)思想對游戲進(jìn)行改進(jìn),在繪圖部分并采用了雙緩沖技術(shù)的實現(xiàn)方法,最后做出來的游戲畫面效果都沒有再出現(xiàn)畫面閃爍現(xiàn)象。另外,我在其他游戲的開發(fā)過程中,也利用雙緩沖技術(shù)來處理游戲畫面閃爍問題,多次實踐證明,雙緩沖技術(shù)確實是處理游戲畫面閃爍問題的一種簡單實用的好辦法。
圖4 卡片對對碰游戲界面圖
通過卡片對對碰游戲及其他游戲開發(fā)的實踐證明:未使用雙緩沖技術(shù)之前,游戲中的許多畫面都能感覺到明顯的閃爍現(xiàn)象,采用了雙緩沖技術(shù)之后,游戲中的許多畫面閃爍幾乎消失。對游戲中的圖形閃爍處理現(xiàn)象運(yùn)用雙緩沖技術(shù)原理簡單,實現(xiàn)起來方便容易,并且處理效果非常理想,幾乎能完美解決游戲中圖形閃爍的問題。因此 雙緩沖技術(shù)是使用VC++進(jìn)行游戲圖形繪制時必不可少的技術(shù)之一,值得所有從事游戲開發(fā)的人員學(xué)習(xí)借鑒及使用。
[1]侯捷.深入淺出 MFC[M].武漢:華中科技大學(xué)出版社,2001.
[2]吳星,沈琳.MFC如何實現(xiàn)繪圖功能[J].福建電腦,2002(12):44-45.
[3]沈大林.C++游戲設(shè)計案例教程[M].北京:電子工業(yè)出版社,2009.
[4]潘愛民.王國印 VC++技術(shù)內(nèi)幕[M].4版.北京:清華大學(xué)出版社,2009.
[5]張磊.基于 VC++的高效繪圖——雙緩沖技術(shù)[J].硅谷,2009(20):61.
[6]張亮.基于雙緩沖技術(shù)的VC++圖形刷新技術(shù)的原理和實現(xiàn)[J].福建電腦,2010(6):110(137).
[7]張哲源,熊慶國,李文翔.基于雙緩沖技術(shù)解決游戲開發(fā)中畫面更新問題[J].信息技術(shù),2011(8):17-19.