freepeople性欧美熟妇, 色戒完整版无删减158分钟hd, 无码精品国产vα在线观看DVD, 丰满少妇伦精品无码专区在线观看,艾栗栗与纹身男宾馆3p50分钟,国产AV片在线观看,黑人与美女高潮,18岁女RAPPERDISSSUBS,国产手机在机看影片

正文內(nèi)容

opengl游戲程序設(shè)計(編輯修改稿)

2025-02-05 01:51 本頁面
 

【文章內(nèi)容簡介】 使用 glOrtho函數(shù)可以將當前的可視空間設(shè)置為正投影空間。其參數(shù)的意義如下圖: 如果繪制的圖形空間本身就是二維的,可以使用 gluOrtho2D。他的使用類似于glOrgho。 視口變換 當一切工作已經(jīng)就緒,只需要把像素繪制到屏幕上了。這時候還剩最后一個問題:應(yīng)該把像素繪制到窗口的哪個區(qū)域呢?通常情況下,默認是完整的填充整個窗口,但我們完全可以只填充一半。(即:把整個圖象填充到一半的窗口內(nèi)) 使用 glViewport來定義視口。其中前兩個參數(shù)定義了視口的左下腳( 0,0表示最左下方),后兩個參數(shù)分別是寬度和高度。 操作矩陣堆棧 我們在進行矩陣操作時,有可能需要先保存某個矩陣,過一段時間再恢復(fù)它。當我們需要保存時,調(diào)用glPushMatrix函數(shù),它相當于把矩陣(相當于盤子)放到堆棧上。當需要恢復(fù)最近一次的保存時,調(diào)用glPopMatrix函數(shù),它相當于把矩陣從堆棧上取下。OpenGL規(guī)定堆棧的容量至少可以容納 32個矩陣,某些OpenGL實現(xiàn)中,堆棧的容量實際上超過了 32個。因此不必過于擔(dān)心矩陣的容量問題。 通常,用這種先保存后恢復(fù)的措施,比先變換再逆變換要更方便,更快速。 注意:模型視圖矩陣和投影矩陣都有相應(yīng)的堆棧。使用 glMatrixMode來指定當前操作的究竟是模型視圖矩陣還是投影矩陣。 綜合舉例( ) 第六章 動畫 想必大家都知道電影和動畫的工作原理吧?是的,快速的把看似連續(xù)的畫面一幅幅的呈現(xiàn)在人們面前。一旦每秒鐘呈現(xiàn)的畫面超過 24幅,人們就會錯以為它是連續(xù)的。 我們通常觀看的電視,每秒播放 25或 30幅畫面。但對于計算機來說,它可以播放更多的畫面,以達到更平滑的效果。如果速度過慢,畫面不夠平滑。如果速度過快,則人眼未必就能反應(yīng)得過來。對于一個正常人來說,每秒 60~120幅圖畫是比較合適的。具體的數(shù)值因人而異。 假設(shè)某動畫一共有 n幅畫面,則它的工作步驟就是: 顯示第 1幅畫面,然后等待一小段時間,直到下一個1/24秒 顯示第 2幅畫面,然后等待一小段時間,直到下一個1/24秒 …… 顯示第 n幅畫面,然后等待一小段時間,直到下一個1/24秒 結(jié)束 如果用 C語言偽代碼來描述這一過程,就是: for(i=0。 in。 ++i) { DrawScene(i)。 Wait()。 } 雙緩沖技術(shù) 在計算機上的動畫與實際的動畫有些不同:實際的動畫都是先畫好了,播放的時候直接拿出來顯示就行。計算機動畫則是畫一張,就拿出來一張,再畫下一張,再拿出來。如果所需要繪制的圖形很簡單,那么這樣也沒什么問題。但一旦圖形比較復(fù)雜,繪制需要的時間較長,問題就會變得突出。 讓我們把計算機想象成一個畫圖比較快的人,假如他直接在屏幕上畫圖,而圖形比較復(fù)雜,則有可能在他只畫了某幅圖的一半的時候就被觀眾看到。而后面雖然他把畫補全了,但觀眾的眼睛卻又沒有反應(yīng)過來,還停留在原來那個殘缺的畫面上。也就是說,有時候觀眾看到完整的圖象,有時卻又只看到殘缺的圖象,這樣就造成了屏幕的閃爍。 如何解決這一問題呢?我們設(shè)想有兩塊畫板,畫圖的人在旁邊畫,畫好以后把他手里的畫板與掛在屏幕上的畫板相交換。這樣以來,觀眾就不會看到殘缺的畫了。這一技術(shù)被應(yīng)用到計算機圖形中,稱為雙緩沖技術(shù)。即:在存儲器(很有可能是顯存)中開辟兩塊區(qū)域,一塊作為發(fā)送到顯示器的數(shù)據(jù),一塊作為繪畫的區(qū)域,在適當?shù)臅r候交換它們。由于交換兩塊內(nèi)存區(qū)域?qū)嶋H上只需要交換兩個指針,這一方法效率非常高,所以被廣泛的采用。 注意:雖然絕大多數(shù)平臺都支持雙緩沖技術(shù),但這一技術(shù)并不是 OpenGL標準中的內(nèi)容。 OpenGL為了保證更好的可移植性,允許在實現(xiàn)時不使用雙緩沖技術(shù)。當然,我們常用的 PC都是支持雙緩沖技術(shù)的。 要啟動雙緩沖功能,最簡單的辦法就是使用GLUT工具包。我們以前在 main函數(shù)里面寫: glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE)。 其中 GLUT_SINGLE表示單緩沖,如果改成GLUT_DOUBLE就是雙緩沖了。 當然還有需要更改的地方 —— 每次繪制完成時,我們需要交換兩個緩沖區(qū),把繪制好的信息用于屏幕顯示(否則無論怎么繪制,還是什么都看不到)。如果使用 GLUT工具包,也可以很輕松的完成這一工作,只要在繪制完成時簡單的調(diào)用 glutSwapBuffers函數(shù)就可以了。 實現(xiàn)連續(xù)動畫 似乎沒有任何疑問,我們應(yīng)該把繪制動畫的代碼寫成下面這個樣子: for(i=0。 in。 ++i) { DrawScene(i)。 glutSwapBuffers()。 Wait()。 } 但事實上,這樣做不太符合窗口系統(tǒng)的程序設(shè)計思路。還記得我們的第一個 OpenGL程序嗎?我們在 main函數(shù)里寫:glutDisplayFunc(amp。myDisplay)。 glutDisplayFunc(amp。myDisplay)意思是對系統(tǒng)說:如果你需要繪制窗口了,請調(diào)用 myDisplay這個函數(shù)。為什么我們不直接調(diào)用 myDisplay,而要采用這種看似“舍近求遠”的做法呢?原因在于 —— 我們自己的程序無法掌握究竟什么時候該繪制窗口。因為一般的窗口系統(tǒng) —— 拿我們熟悉一點的來說 —— Windows和 X窗口系統(tǒng),都是支持同時顯示多個窗口的。假如你的程序窗口碰巧被別的窗口遮住了,后來用戶又把原來遮住的窗口移開,這時你的窗口需要重新繪制。很不幸的,你無法知道這一事件發(fā)生的具體時間。因此這一切只好委托操作系統(tǒng)來辦了。 現(xiàn)在我們再看上面那個循環(huán)。既然 DrawScene都可以交給操作系統(tǒng)來代辦了,那讓整個循環(huán)運行起來的工作是否也可以交給操作系統(tǒng)呢?答案是肯定的。我們先前的思路是:繪制,然后等待一段時間;再繪制,再等待一段時間。但如果去掉等待的時間,就變成了繪制,繪制, …… ,不停的繪制。 —— 當然了,資源是公用的嘛,殺毒軟件總要工作吧?我的下載不能停下來吧?我的 mp3播放還不能給耽擱了。總不能因為我們的動畫,讓其他的工作都停下來。因此,我們需要在 CPU空閑的時間繪制。 這里的“在 CPU空閑的時間繪制”和我們在第一課講的“在需要繪制的時候繪制”有些共通,都是“在 XX時間做 XX事”, GLUT工具包也提供了一個比較類似的函數(shù): glutIdleFunc,表示在 CPU空閑的時間調(diào)用某一函數(shù)。其實GLUT還提供了一些別的函數(shù),例如“在鍵盤按下時做某事”等。 到現(xiàn)在,我們已經(jīng)可以初步開始制作動畫了。好的,就拿上次那個“太陽、地球和月亮”的程序開刀,讓地球和月亮自己動起來。 include GL/ // 太陽、地球和月亮 // 假設(shè)每個月都是 30天 // 一年 12個月,共是 360天 static int day = 200。 // day的變化:從 0到 359 void myDisplay(void) { /**************************************************** 這里的內(nèi)容照搬上一課的,只因為使用了雙緩沖,補上最后這句 *****************************************************/ glutSwapBuffers()。 } void myIdle(void) { /* 新的函數(shù),在空閑時調(diào)用,作用是把日期往后移動一天并重新繪制,達到動畫效果 */ ++day。 if( day = 360 ) day = 0。 myDisplay()。 } int main(int argc, char *argv[]) { glutInit(amp。argc, argv)。 glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE)。 // 修改了參數(shù)為 GLUT_DOUBLE glutInitWindowPosition(100, 100)。 glutInitWindowSize(400, 400)。 glutCreateWindow(太陽,地球和月亮 )。 // 改了窗口標題 glutDisplayFunc(amp。myDisplay)。 glutIdleFunc(amp。myIdle)。 // 新加入了這句 glutMainLoop()。 return 0。 } 關(guān)于垂直同步 代碼是寫好了,但相信大家還有疑問。某些朋友可能在運行時發(fā)現(xiàn),雖然 CPU幾乎都用上了,但運動速度很快,根本看不清楚,另一些朋友在運行時發(fā)現(xiàn)CPU使用率很低,根本就沒有把空閑時間完全利用起來。但對于上面那段代碼來說,這些現(xiàn)象都是合理的。這里就牽涉到關(guān)于垂直同步的問題。 大家知道顯示器的刷新率是比較有限的,一般為60~120Hz,也就是一秒鐘刷新 60~120次。但如果叫計算機繪制一個簡單的畫面,例如只有一個三角形,則一秒鐘可以繪制成千上萬次。因此,如果最大限度的利用計算機的處理能力,繪制很多幅畫面,但顯示器的刷新速度卻跟不上,這不僅造成性能的浪費,還可能帶來一些負面影響(例如,顯示器只刷新到一半時,需要繪制的內(nèi)容卻變化了,由于顯示器是逐行刷新的,于是顯示器上半部分和下半部分實際上是來自兩幅畫面)。 采用垂直同步技術(shù)可以解決這一問題。即,只有在顯示器刷新時,才把繪制好的圖象傳輸出去供顯示。這樣一來,計算機就不必去繪制大量的根本就用不到的圖象了。如果顯示器的刷新率為 85Hz,則計算機一秒鐘只需要繪制 85幅圖象就足夠,如果場景足夠簡單,就會造成比較多的 CPU空閑。 幾乎所有的顯卡都支持“垂直同步”這一功能。 垂直同步也有它的問題。如果刷新頻率為 60Hz,則在繪制比較簡單的場景時,繪制一幅圖畫需要的時間很段,幀速可以恒定在 60FPS(即 60幀 /秒)。如果場景變得復(fù)雜,繪制一幅圖畫的時間超過了 1/60秒,則幀速將急劇下降。 如果繪制一幅圖畫的時間為 1/50,則在第一個1/60秒時,顯示器需要刷新了,但由于新的圖畫沒有畫好,所以只能顯示原來的圖畫,等到下一個 1/60秒時才顯示新的圖畫。于是顯示一幅圖畫實際上用了 1/30秒,幀速為 30FPS。(如果不采用垂直同步,則幀速應(yīng)該是 50FPS) 如果繪制一幅圖畫的時間更長,則下降的趨勢就是階梯狀的: 60FPS, 30FPS, 20FPS, ……( 60/1, 60/2, 60/3, …… ) 如果每一幅圖畫的復(fù)雜程度是不一致的,且繪制它們需要的時間都在 1/60上下。則在 1/60時間內(nèi)畫完時,幀速為 60FPS,在 1/60時間未完成時,幀速為 30FPS,這就造成了幀速的跳動。這是很麻煩的事情,需要避免它 —— 要么想辦法簡化每一畫面的繪制時間,要么都延遲一小段時間,以作到統(tǒng)一。 計算幀速 不知道大家玩過 3D Mark這個軟件沒有,它可以運行各種場景,測出幀速,并且為你的系統(tǒng)給出評分。這里我也介紹一個計算幀速的方法。 根據(jù)定義,幀速就是一秒鐘內(nèi)播放的畫面數(shù)目( FPS)。我們可以先測量繪制兩幅畫面之間時間 t,然后求它的倒數(shù)即可。假如 t=,則 FPS的值就是 1/=20。 理論上是如此了,可是如何得到這個時間呢?通常 C語言的 time函數(shù)精確度一般只到
點擊復(fù)制文檔內(nèi)容
教學(xué)課件相關(guān)推薦
文庫吧 www.dybbs8.com
備案圖片鄂ICP備17016276號-1