4.4 優(yōu)化渲染
目前我們所討論的代碼在每次更新時是這樣渲染圖形的:
● 清空后臺緩沖區(qū)。
● 將所有游戲?qū)ο罄L制到后臺緩沖區(qū)中。
● 將后臺緩沖區(qū)呈現(xiàn)在屏幕上。
這種方式很簡單,但效率不高。設(shè)想一個俄羅斯方塊游戲:我們將玩家的方塊向屏幕底部降落,游戲區(qū)域已經(jīng)有了很多其他的方塊,這些方塊已經(jīng)是完全靜止的了。以我們現(xiàn)在所用的渲染步驟,需要在每次更新畫面時也對那些靜態(tài)的方塊進行重繪,即使它們與上一次畫面更新時相比沒有發(fā)生任何變化。如果能夠只對后臺緩沖區(qū)中那些實際發(fā)生了變化的一部分進行重繪,那么效率將會明顯地提高。
該如何做呢?需要下列步驟:
● 判斷前一幀繪制完成后,發(fā)生了移動的游戲?qū)ο笏嫉膮^(qū)域。
● 清空后臺緩沖區(qū),但只清空發(fā)生了移動的區(qū)域。
● 對與移動區(qū)域發(fā)生重疊的所有對象進行繪制。
● 將移動區(qū)域繪制到屏幕上,保留該區(qū)域以外的所有圖形不變。
實現(xiàn)這個改進后能使引擎的表現(xiàn)有實質(zhì)性的改善。尤其是在那種包含了很多靜態(tài)元素的游戲中,通??梢员苊夂芏嗖槐匾闹乩L。
實現(xiàn)此優(yōu)化所需要進行的改動都發(fā)生在CGameEngineGDIBase類中,主要是其Render函數(shù)。首先要做的是判斷上次繪圖完成后發(fā)生了移動的區(qū)域。
這個區(qū)域?qū)嶋H上包含了進入了對象的區(qū)域(需要渲染移入對象的區(qū)域)以及移出對象的區(qū)域(也需要被重繪,這樣背景或者在該位置的其他任何對象才能重新顯示)。對象移出區(qū)域的渲染是很重要的,否則舊的對象會在后面形成拖尾。
注意:
在我們的實現(xiàn)中,將只計算游戲的單個移動區(qū)域。還有一種方法是計算許多類似的小移動區(qū)域,甚至是對每個對象的移動區(qū)域都進行計算。在大多數(shù)情況下,優(yōu)化渲染時使用單個區(qū)域?qū)嶋H上是一個效率比較高的方法,因為GDI不必對多個單獨的小區(qū)域進行記錄。該技術(shù)所用的代碼會簡單很多,它將Render函數(shù)的復(fù)雜度降到了最低。
示意圖4-4的對小球的移動區(qū)域進行了標注,上一次調(diào)用Render函數(shù)時該區(qū)域的位置為灰色,本次調(diào)用時該區(qū)域為黑色。于是我們需要對方框中原來被小球遮擋了的方框以及該區(qū)域的背景進行重繪。被虛線矩形標注出來的區(qū)域為移動區(qū)域。