視頻遊戲製作教程C++ win95 |
|
conundrum
尊榮會員 發表:893 回覆:1272 積分:643 註冊:2004-01-06 發送簡訊給我 |
http://www.gdi3d.com/txt/learn3.htm 視頻遊戲製作教程(一) Analyst 首先,講講初學者應該選擇哪些軟體? 一、編程語言:C 當然是首選。 二、C編譯器:這分三種環境,即DOS實模式、DOS保護模式、Win95 DirectX。 1.DOS實模式:我推薦使用Borland C 3.1 這是個十分成熟的版本。功能比Turbo C要強多了。 2.DOS保護模式:Watcom C是不錯的選擇。DJGPP也是個很好的編譯器,它最吸引人的地方是提供一個強大的遊戲/圖形庫:allegro。有關allegro的詳情可以去“風雲工作室”看看。 3.Win95 DirectX:當然是用Visual C 4.2以上版本。 這三種環境都各有優缺點。 DOS實模式:這種環境現在在商業遊戲製作中已徹底淘汰,主要原因是受DOS 64k記憶體段及640k基本記憶體的限制。但DOS對於我們來說非常透明、也很單純,可以深入硬體編程,對於初學者來說也很熟悉、容易入門。 DOS保護模式:在DirectX出現之前曾在商業遊製作中一度流行,沒有64k記憶體段及640k基本記憶體的限制,又可以對硬體編程,所以淘汰了DOS實模式。 Win95 DirectX:Windows本不適合運行視頻遊戲,因爲它不讓我們接觸硬體,而它的圖形用戶介面又慢如烏龜。但突然有一天,你一覺醒來,發現太陽高高地照耀著,鳥兒歡樂地歌唱著,同時許多遊戲在Win95上快速的運作著——Microsoft推出了DirectX。DirectX可以讓你比較自由的操縱顯存,這正是編寫快速視頻遊戲所要的。DirectX爲我們提供了設備無關性的奇妙特性,就是說我們無須爲每種硬體編寫驅動程式樂。這些使Win95成爲最熱門的視頻遊戲編程平臺。Windows徹底淘汰Dos的時代終於來臨了。 接下來講講初學者從哪里開始。 我將初學者分三類,然後給出我的建議。 第一類:剛開始學編程語言的,或是只會一點的。如果你屬這一類,則應先從C語言開始慢慢學起,暫時不要奢望能編遊戲。 第二類:已掌握了C語言,但使用BGI圖形庫作圖的。我的教程主要面向這一類讀者。有一定的基礎,需要開始瞭解一些視頻遊戲的原理,可以從DOS實模式開始,當然不反對直接從DOS保護模式開始,但不贊成用DirectX。 第三類:初步瞭解視頻遊戲的製作方法,並已有一些作品。(本人即屬這一類)我幫不上什麽忙。 [上一篇 | 返回 | 下一篇] Made by Zerone Studio 最後修改於( ) 視頻遊戲製作教程(二) Analyst 要編寫視頻遊戲就要有快速的視頻顯示,所以Borland C提供的BGI圖形庫是不適合的,我們需要編寫自己的圖形庫,其實並不困難。 現在,讓我們從DOS實模式 mode 13H(320*200*256c)最基本的開始,SVGA在原理上和它差不多(但稍繁一些),所以我以此爲基礎開始講解。 VGA mode 13h是個很好的顯示模式,因爲它是線性對應的,就是說一個象素對應一個位元組,在標準VGA顯示模式中是唯一特殊的一個。 如何設置顯示模式: void SetVideoMode(unsigned char mode) { union REGS in,out; in.h.ah=0; in.h.al=mode; int86(0x10,&in,&out); } /*以下是用行內彙編改寫的,功能一樣,只是讓大家知道有行內彙編這回事,以後會用到。*/ void SetVideoMode(unsigned char mode) { asm{ mov ah,0h mov al,mode int 10h } } /*以上程式爲我憑記憶寫的,沒有上機驗證,如上機通不過,請告訴我一聲。*/ 用SetVideoMode(0x13);進入mode 13h 用SetVideoMode(0x3);回到文本模式 視頻緩衝區中存放螢幕上每個象素,在螢幕作圖就是通過改變視頻緩衝區來實現的。 視頻緩衝區被映射到從A000:0000h到A000:FFFFh共64k這段地址中,就是說我們一次只能存取64K的顯存(現在的顯卡都帶1M以上的顯存,至於如何存取64K以外的顯存,有多種方法,以後再講)現在我們不必擔心無法存取64K以外的顯存,因爲mode 13h只用到320 * 200 * 1 = 64000 Bytes的顯存,地址範圍從A000:0000h到A000:F9FFh。 由於mode 13h是線性對應的,所以可以把視頻緩衝區想象成一個二維陣列。char video[320][200]; //video[x][y]對應螢幕上(x,y)這一點。 不過我們用一遠指標來存取視頻緩衝區,這和二維陣列差不多。 可以這麽定義: char far *video_buffer=(char far *)0xa0000000L; 向螢幕(0,0)畫點就是video_buffer[0]=color;//color爲顔色值。 下面給出畫點函數: #define SCREEN_WIDTH 320 #define SCREEN_HEIGHT 200 putpixel(int x,int y,char color) { video_buffer[y*SCREEN_WIDTH x]=color; } 下面用邏輯位移來優化畫點函數:(去掉了慢速的乘法運算) putpixel(int x,int y,char color) { video_buffer[((y<<8 (y<<6)) x]=color; } 下面給出清屏函數: void ClearScreen(char color) { fmemset(video_buffer,color,64000); //fmemset(video_buffer,color,SCREEN_WIDTH*SCREEN_HEIGHT 1); } 這些都很簡單,不是嗎?試著用這些函數寫個星空類比程式吧。 好了,我不想再講更多的有關畫線、畫圓、畫曲線的函數了,因爲它們在視頻遊戲中不常用,有興趣的話可以翻資料或是自己寫。 希望大家理解這一講的內容,下一講內容:調色板。 [上一篇 | 返回 | 下一篇] Made by Zerone Studio 最後修改於( ) 視頻遊戲製作教程(三) Analyst 今天講講調色板。 我們所使用的 PC 機的顯示器的顔色顯示採用的是 RGB 模式,就是說那繽紛的色彩都是由紅、綠、藍三種顔色構成的。最初的機器顯存昂貴,所以採用調色板機制來節省顯存。 使用的顯示模式便是我們所熟知的16色和256色模式。(標準 VGA 下的 0x13 模式即爲 256 色的) 在這個模式下所有的點由 64 級紅色,64 級綠色,64 級藍色構成。而將需要用到的 256 種顔色配好後放到調色板中, 而顯存裏則存放調色板的索引值(0~255)。用這種方式,我們可以得到豐富的色彩,又不必消耗太多的記憶體,在以前記憶體昂貴,硬體速度偏慢的年代,無疑是是一種既節約記憶體,又能提高處理圖形速度的好方法。而後來記憶體越來越多,能夠處理的資料量也比以前大的好幾倍;而 CPU 更能處理 32 位元資料,這樣 8 位(256色) 顯示模式簡直毫無優勢可言,高彩色和真彩色成爲標準。 所謂高彩色和真彩色即指16bit/15bit、24bit/32bit顯示模式。許多顯卡不是完全支援所有的這些顯示模式(這給我們的開發帶來了不少麻煩,比如要用16bit模式,我們就必須寫兩套函數來分別支援16bit/15bit模式)。這類顯示模式和256色模式是不同的,顯存裏存放的不再是調色板的索引值,而是直接存放RGB顔色值,也就是說,不再需要調色板了。 對於調色板,我經常懷著即愛又恨的心情。愛的是它能實現一些特效,比如淡入、淡出,調色板動畫等,而且它和16bit模式比起來,畫面質量差不多卻比較節省記憶體,速度較快。恨的是,在做美工時經常被調色板問題所困擾,調色板模式對美工要求是很高的。而且在一些特效中,如實時光影,半透明顯示、霧化等,顯得力不從心。 16bit模式和調色板模式孰優孰劣一直是有爭議的問題。對於要求大量光影的3D遊戲來說,16bit模式當然是首選。但對於2D遊戲來說,情況就不同了,調色板模式能極大的發揮程式師和美工的水平和想象力。就拿《星際爭霸》和《DIABLO》來說,這兩個遊戲對調色板的運用簡直是出神入化,比許多16bit模式的遊戲要精美的多,但這些都是建立在高超的技術和很大的耐心上的。對我們這些業餘的來說還是用16bit模式來的省力些。 好了,廢話說了一大堆,讓我們進入正題吧。 一、256色調色板的結構。 VGA卡有256個顔色寄存器,每個寄存器存儲R、G、B三原色。 R、G、B三原色分別占一個位元組,只使用低6bit,這樣就有2的18次方種組合,也就是說共有262144種顔色供我們挑選,R、G、B每種原色共有64級灰度。 二、如何存取調色板。 顔色寄存器是通過VGA卡上的I/O埠來存取的,一共要用到四個I/O埠: #define PALETTE_MAST 0x3c6 #define PALETTE_RD 0x3c7 #define PALETTE_WR 0x3c8 #define PALETTE_DATA 0x3c9 在存取調色板之前,我們先定義個調色板的資料結構: typedef struct RGB{ unsigned char R; unsigned char G; unsigned char B; }RGB_COLOR,*PALLETE; 下面是存取調色板的過程: 1、在PALETTE_MAST埠中寫入0xff,進入存取調色板狀態。 2、然後向PALETTE_RD(如果你要讀取調色板)或PALETTE_WR(如果你要改變調色板)寫入你要讀取/改變哪個顔色寄存器。 3、向PALETTE_DATA埠寫資料,一次讀/寫一個位元組,按R、G、B順序讀/寫,每讀/寫完一組RGB資料,VGA卡就指向下一個顔色寄存器,可以連續的讀/寫,直到把所有的資料都讀/寫完。注意:每次必須成組的讀/寫RGB資料,也就是必須讀/寫三個位元組的倍數,不然會……我也不知道會出現什麽情況。 下面給出四個存取調色板的函數: void set_all_pallete(PALLETE *pal) { int i; outportb(PALETTE_MAST,0xff); outportb(PALETTE_WR,0); /* for(i=0;i<256;i ) { outportb(PALETTE_DATA,pal[i]->R); outportb(PALETTE_DATA,pal[i]->G); outportb(PALETTE_DATA,pal[i]->B); } /* 這樣寫效率差了些,不過很好理解 下面用彙編寫,不過我沒調試過,不知行不行,僅供參考 asm{ lds si,pal mov cx,768 _next: lodsb out PALETTE_DATA,al sub cx jnz _next } */ } void get_all_pallete(PALLETE *pal) { int i; outportb(PALETTE_MAST,0xff); outportb(PALETTE_RD,0); for(i=0;i<256;i ) { pal[i]->R=inportb(PALETTE_DATA); pal[i]->G=inportb(PALETTE_DATA); pal[i]->B=inportb(PALETTE_DATA); } /* 這樣寫效率差了些,不過很好理解 下面用彙編寫,不過我沒調試過,不知行不行,僅供參考 asm{ lds si,pal mov cx,768 _next: in al,PALETTE_DATA stosb sub cx jnz _next } */ } void get_pallete(int index,PALETTE pal) { outportb(PALETTE_MAST,0xff); outportb(PALETTE_RD,index); pal->R=inportb(PALETTE_DATA); pal->G=inportb(PALETTE_DATA); pal->B=inportb(PALETTE_DATA); } void set_pallete(int index,PALETTE pal) { outportb(PALETTE_MAST,0xff); outportb(PALETTE_WR,index); outportb(PALETTE_DATA,pal->R); outportb(PALETTE_DATA,pal->G); outportb(PALETTE_DATA,pal->B); } 有了這幾個函數,我們就可以輕鬆駕禦調色板了。 下面是關於調色板的一些深入的專題: 一、調色板的應用: 1、fade out/fade in 這是在調色板中最常用的特效,實現起來和簡單。 fade out只要每次將R、G、B三原色分別乘以一個值(小於1),於是螢幕逐漸變成一片漆黑。 fade in則是個相反的過程。 2、調色板動畫 調色板可以實現許多難以實現的特效,而且速度很快。最簡單的例子,如燈光閃爍,只要迴圈改變燈光顔色所對應的調色板顔色的值,就可以了。迴圈改變一連串的調色板顔色的值,就可以實現水流、火焰等的效果。這需要充分發揮你的想象,合理的運用調色板。這裏就不多說了。 3、消除閃爍: 在大量寫調色板時,經常會發生螢幕閃爍現象,在fade out/fade in經常發生。這是由於在顯示卡刷新螢幕時寫調色板所造成的。因此,應該等待垂直回掃時寫調色板,這可以有效避免閃爍。只要使用如下代碼: void wait_vsync() { while(inportb(0x3da)&0x08); while(!inportb(0x3da)&0x08); } 好了,有關於調色板就說到這兒吧。 [上一篇 | 返回 | 下一篇] Made by Zerone Studio 最後修改於( ) |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |