計算機(jī)圖形學(xué)課程設(shè)計_第1頁
計算機(jī)圖形學(xué)課程設(shè)計_第2頁
計算機(jī)圖形學(xué)課程設(shè)計_第3頁
計算機(jī)圖形學(xué)課程設(shè)計_第4頁
計算機(jī)圖形學(xué)課程設(shè)計_第5頁
已閱讀5頁,還剩37頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

1、計算機(jī)圖形學(xué)課程設(shè)計(2015-2016學(xué)年第二學(xué)期) 學(xué) 院 專業(yè)班級 學(xué) 號 學(xué)生姓名 老 師 編寫日期:2016年xx月xx日 41 / 42目 錄真實感游戲場景繪制3一實驗?zāi)康?二實驗內(nèi)容3三實驗分工3四理論基礎(chǔ)41霧化模型42顏色模型53光照模型64紋理模型6五系統(tǒng)描述131墻壁、地面、箱子132石柱、雪人143玻璃球154天空17六心得體會19七附錄:程序源代碼19計算機(jī)圖形學(xué) 真實感游戲場景繪制【摘要】本次課程設(shè)計繪制了一個真實感的三維場景,并實現(xiàn)場景漫游。主要繪制了墻壁與地面、天空、石柱、箱子、玻璃球、雪人、霧等對象。以Visual Studio2012為平臺用OpenGL基礎(chǔ)

2、知識實現(xiàn)此真實感場景的繪制。一 實驗?zāi)康?熟悉OpenGL基礎(chǔ)函數(shù),并了解其用法。2通過程序模擬真實感游戲場景,掌握圖形綜合展示效果,基于專業(yè)背景,結(jié)合實驗課內(nèi)容與課程設(shè)計要求,使用OpenGL繪制簡單的3D真實感游戲場景,包括光柵化算法、多邊形裁剪計算以及消隱算法在場景繪制中的應(yīng)用。二 實驗內(nèi)容和效果光柵化算法、多邊形裁剪計算以及消隱算法在場景繪制中的應(yīng)用,其中真實感場景繪制包括顏色模型、紋理模型、霧化模型、運動模型以及環(huán)境光、漫反射、鏡面反射等光照模型設(shè)置。 圖1 游戲場景整體效果三 實驗分工 本次課程設(shè)計實驗,小組成員齊心協(xié)力。首先從自己嘗試編寫沒有成功到后來的各種搜集資料,尋找3D游戲

3、場景的繪制代碼,到最后小組成員分工解析代碼并注釋,做PPT,演講PPT等,大家合作都很用心。這次的實驗中我們小組每個成員在每一個環(huán)節(jié)都參與任務(wù),因代碼過多,也都參與到代碼解析中。具體安排如下:姓名任務(wù)xxx搜集資料,代碼解析注釋,做PPT,PPT演講xxx 搜集資料,代碼解析并注釋,做PPT,PPT演講xxx搜集資料,代碼解析注釋,做PPT,PPT演講xxx搜集資料,代碼解析注釋,做PPT,PPT演講四 理論基礎(chǔ)1 霧化模型OpenGL中提供了完整的霧化接口,我們只需要選擇合適的霧氣的混合因子、密度、顏色、起始位置等。在OpenGL中,霧的工作模式有兩種:線性模式和指數(shù)模式。這兩種模式是根據(jù)霧

4、的濃度變化來區(qū)分的。在線性模式下,只需要提供一個距離視點的開始位置和結(jié)束位置。從開始位置到結(jié)束位置之間,霧的濃度越來越高,濃度的變化和距離成正比。在指數(shù)模式下,霧的濃度隨著距離的增加呈指數(shù)增長。這種模式通常用來用于煙霧、煙幕等效果。glFogf(GL_FOG_START, 1.0f)確定了霧的開始初離屏幕有多近。glFogf(GL_FOG_END, 5.0),它告訴OpenGL霧能離開屏幕有多遠(yuǎn)glHint(GL_FOG_HINT, GL_DONT_CARE)確定了霧的渲染方式,使用GL_DONT_CARE是因為并不關(guān)心建議值。這個項的不同值之間的區(qū)別: GK_DONT_CARE:讓OPENG

5、L自己來確定霧的渲染方式,每頂點或是每像素。GL_NICEST:對每一像素進(jìn)行霧的渲染,它看起來是極棒的。GL_FASTEST:對每一頂點進(jìn)行霧的渲染,它速度較快,但是不夠美麗我們的霧氣設(shè)置如下:修改函數(shù)里面的參數(shù)改變霧的顏色和濃度: 圖2 改變顏色(藍(lán)色)和濃度的霧氣2 顏色模型OpenGL支持兩種顏色模式:一種是RGBA,一種是顏色索引模式。不同的是,RGBA模式中,數(shù)據(jù)直接就代表了顏色;而顏色索引模式中,數(shù)據(jù)代表的是一個索引,要得到真正的顏色,還必須去查索引表。RGBA顏色RGBA模式中,每一個像素會保存以下數(shù)據(jù):R值(紅色分量)、G值(綠色分量)、B值(藍(lán)色分量)和A值(alpha分量

6、)。其中紅、綠、藍(lán)三種顏色相組合,就可以得到我們所需要的各種顏色,而alpha不直接影響顏色。3 光照模型光照模型包括許多因素,如物體的類型,物體相對光源與其他物體的位置以及場景中所設(shè)置的光源屬性,物體的透明度,物體的表面光亮程度,甚至物體的各種表面紋理等。光照到物體表面時,物體對光會發(fā)生反射、透射、吸收、衍射、折射和干涉。通常觀察不透明、不發(fā)光的物體,人眼所觀察到的是從物體表面的得到的反射光,它是由場景中的光源和其他物體表面的反射光共同作用產(chǎn)生的。簡單光照明模型模擬物體表面對直接光照的反射作用,包括鏡面反射和漫反射,而物體間的光反射作用沒有被充分考慮到,僅僅用一個與物體周圍和視點、光源位置都

7、無關(guān)的環(huán)境光常量來近似表示??梢杂萌缦卤磉_(dá)式表示:入射光=環(huán)境光+漫反射+鏡面反射光4 紋理模型(因為我們的場景大量使用了紋理模型,且我主要也負(fù)責(zé)紋理模型,因此處會詳細(xì)解釋。) 我們都知道物體表面通常并不是具有簡單顏色的平滑面,而是有著花紋圖案等豐富細(xì)節(jié)的。計算機(jī)三維圖形通過給面貼紋理來表現(xiàn)表面細(xì)節(jié)。OpenGL默認(rèn)設(shè)置是關(guān)閉貼紋理的,所以必須先用命令打開紋理計算。glEnable(GL_TEXTURE_2D); / 啟用二維紋理glDisable(GL_TEXTURE_2D); / 禁用二維紋理1、啟用紋理和載入紋理如同我們曾經(jīng)學(xué)習(xí)過的OpenGL光照、混合等功能一樣。在使用紋理前,必須啟用

8、它。OpenGL支持一維紋理、二維紋理、三維紋理和四維紋理。 一般情況下使用二維紋理即可。使用紋理前,必須載入紋理。利用glTexImage2D函數(shù)可以載入一個二維的紋理,該函數(shù)有多達(dá)九個參數(shù),glTexImage2D(GL_TEXTURE_2D,Glint level,Glint components, Glsizei width,Glsizei Height,Glint order,Glenum ype,const Glvoid *pixels)詳細(xì)說明如下:第一個參數(shù)為指定的目標(biāo),在我們的入門教材中,這個參數(shù)將始終使用GL_TEXTURE_2D。第二個參數(shù)為“多重細(xì)節(jié)層次”,現(xiàn)在我們并不

9、考慮多重紋理細(xì)節(jié),因此這個參數(shù)設(shè)置為零。第三個參數(shù)有兩種用法。在OpenGL最初的版本中,使用整數(shù)來表示顏色分量數(shù)目,例如:像素數(shù)據(jù)用RGB顏色表示,總共有紅、綠、藍(lán)三個值,因此參數(shù)設(shè)置為3,而如果像素數(shù)據(jù)是用RGBA顏色表示,總共有紅、綠、藍(lán)、alpha四個值,因此參數(shù)設(shè)置為4。而在后來的版本中,可以直接使用GL_RGB或GL_RGBA來表示以上情況,顯得更直觀。注意:雖然我們使用Windows的BMP文件作為紋理時,一般是藍(lán)色的像素在最前,其真實的格式為GL_BGR而不是GL_RGB,在數(shù)據(jù)的順序上有所不同,但因為同樣是紅、綠、藍(lán)三種顏色,因此這里仍然使用GL_RGB。如果使用GL_BGR

10、,OpenGL將無法識別這個參數(shù),造成錯誤。第四、五個參數(shù)是二維紋理像素的寬度和高度。在使用紋理時要特別注意其大小,必須使用大小為2的整數(shù)次方的紋理。在很長一段時間內(nèi),很多圖形程序都喜歡使用256*256大小的紋理,不僅因為256是2的整數(shù)次方,也因為某些硬件可以使用8位的整數(shù)來表示紋理坐標(biāo),2的8次方正好是256,這一巧妙的組合為處理紋理坐標(biāo)時的硬件優(yōu)化創(chuàng)造了一些不錯的條件。第六個參數(shù)是紋理邊框的大小。最后三個參數(shù)分別是紋理的圖像數(shù)據(jù)格式,數(shù)據(jù)類型和紋理圖像的像素數(shù)據(jù)的存儲地址。舉個例子,如果有一幅大小為width*height,格式為Windows系統(tǒng)中使用最普遍的24位BGR,保存在pi

11、xels中的像素圖像。則把這樣一幅圖像載入為紋理可使用以下代碼:glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_BGR_EXT, GL_UNSIGNED_BYTE, pixels);下面一段為我們的游戲場景中的載入紋理的代碼:/對于指定的多個紋理,要根據(jù)自己的需要映射到不同的面上,需要對位圖創(chuàng)建一個數(shù)組,/用來存儲位圖的名稱,然后在初始化OpenGL的時候,可以讀取這些位圖,然后生成多個紋理存儲到一個紋理數(shù)組中,接著就可以指定繪制的某個面,對該指定的面進(jìn)行紋理映射/加載位圖AUX_RGBImageRec *LoadBMP(

12、char *Filename)/ 根據(jù)位圖文件的名稱進(jìn)行加載。 AUX_RGBImageRec定義紋理數(shù)據(jù)的格式FILE *File=NULL; / 文件指針if (!Filename)/確保文件名已提供return NULL;/如果沒有提供,返回nullFile=fopen(Filename,r); / 根據(jù)指定的位圖文件名稱,打開該位圖文件if (File)/ 如果位圖文件存在fclose(File);/ 關(guān)閉句柄。 因為只是需要判斷問題是否存在,而不需要對位圖文件進(jìn)行寫操作,所以關(guān)閉位圖文件return auxDIBImageLoad(Filename); /載入位圖并返回指針(其實,只

13、需要一個真正存在的位圖文件的名稱,實現(xiàn)加載位圖文件,并返回)return NULL;首先,AUX_RGBImageRec類型是一個RGB圖像結(jié)構(gòu)類型。該結(jié)構(gòu)定義了三個成員:sizeX 圖像的寬度;sizeY 圖像的高度;data; 圖形所包含的數(shù)據(jù),其實也就是該圖形在內(nèi)存中的像素數(shù)據(jù)的一個指針。AUX_RGBImageRec類型的變量描述了一幅圖像的特征。上述函數(shù)中,調(diào)用了glaux.h庫文件中的auxDIBImageLoad函數(shù),其實它是一個宏,函數(shù)原型為auxRGBImageLoadW(LPCWSTR)或者auxRGBImageLoadA(LPCSTR),可以在該庫文件中找到它的定義,如下

14、所示:/* AUX_RGBImageRec * APIENTRY auxRGBImageLoad(LPCTSTR); */#ifdef UNICODE#define auxRGBImageLoad auxRGBImageLoadW#else#define auxRGBImageLoad auxRGBImageLoadA#endifAUX_RGBImageRec * APIENTRY auxRGBImageLoadA(LPCSTR);AUX_RGBImageRec * APIENTRY auxRGBImageLoadW(LPCWSTR);#ifdef UNICODE#define auxDIBI

15、mageLoad auxDIBImageLoadW#else#define auxDIBImageLoad auxDIBImageLoadA#endifAUX_RGBImageRec * APIENTRY auxDIBImageLoadA(LPCSTR);AUX_RGBImageRec * APIENTRY auxDIBImageLoadW(LPCWSTR);宏auxDIBImageLoad實現(xiàn)的功能就是:根據(jù)指定的位圖名稱,將該位圖的信息加載到內(nèi)存中,以便用來創(chuàng)建成為紋理。/加載紋理int LoadGLTextures()/用于創(chuàng)建并加載紋理的函數(shù)為LoadGLTexturesint Sta

16、tus=FALSE;/很多函數(shù)的返回類型都是Status,這里Status是用typedef定義的intl類型 即:typedef int Status;AUX_RGBImageRec *TextureImage10;/創(chuàng)建一個紋理圖像數(shù)組,這里指定數(shù)組大小為10memset(TextureImage,0,sizeof(void *)*10); / 創(chuàng)建一個紋理圖像數(shù)組,這里指定數(shù)組大小為10/創(chuàng)建的位圖名稱數(shù)組,對應(yīng)10幅位圖if(TextureImage0=LoadBMP(Data/Floor.bmp)&(TextureImage1=LoadBMP(Data/Wall.bmp)&(Text

17、ureImage2=LoadBMP(Data/Door.bmp)&(TextureImage3=LoadBMP(Data/Box.bmp)&(TextureImage4=LoadBMP(Data/Hat.bmp)&(TextureImage5=LoadBMP(Data/Cylinder.bmp)&(TextureImage6=LoadBMP(Data/Star.bmp)&(TextureImage7=LoadBMP(Data/Mask.bmp)&(TextureImage8=LoadBMP(Data/Sky.bmp)&(TextureImage9=LoadBMP(Data/Lightning.

18、bmp)Status=TRUE;/加載位圖成功,修改狀態(tài)標(biāo)志變量Status為TRUEglGenTextures(10, &texture0);/紋理標(biāo)識for(int loop=0;loopsizeX, TextureImageloop-sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImageloop-data);/生成紋理for (int loop=0; loopdata!=NULL)free(TextureImageloop-data);free(TextureImageloop);return Status; / 創(chuàng)建紋理并加載,返回成功或者失敗

19、的標(biāo)志Status2、紋理控制 OpenGL的紋理控制實質(zhì)上就是定義紋理如何包裹物體的表面的,因為紋理的外形并不總是與物體一致,比如紋理通常是矩形的,但會被映射到一個多邊形或曲面上,在被變換到屏幕坐標(biāo)后,紋理的單個紋素很難與屏幕上的像素對應(yīng)。根據(jù)所使用的變換和所用的紋理的映射方式,屏幕上的單個像素可能對應(yīng)紋理單元中單個紋素的一部分,即放大濾波或?qū)?yīng)于多個紋素的,即縮小濾波。而控制縮小和放大濾波的是采用glTexParameter函數(shù)來實現(xiàn)的。 3、紋理坐標(biāo)紋理的使用只要指定每一個頂點在紋理圖像中所對應(yīng)的像素位置,OpenGL就會自動計算頂點以外的其它點在紋理圖像中所對應(yīng)的像素位置。例如:在繪制

20、一條線段時,我們設(shè)置其中一個端點為紅色,另一個端點為綠色,則OpenGL會自動計算線段中其它各像素的顏色,如果是使用glShadeMode(GL_SMOOTH);,則最終會形成一種漸變的效果(例如線段中點,就是紅色和綠色的中間色)。類似的,在繪制一條線段時,我們設(shè)置其中一個端點使用“紋理圖像中最左下角的顏色”作為它的顏色,另一個端點使用“紋理圖像中最右上角的顏色”作為它的顏色,則OpenGL會自動在紋理圖像中選擇合適位置的顏色,填充到線段的各個像素(例如線段中點,可能就是選擇紋理圖像中央的那個像素的顏色)。使用glTexCoord*系列函數(shù)來指定紋理坐標(biāo)。這些函數(shù)的用法與使用glVertex*

21、系列函數(shù)來指定頂點坐標(biāo)十分相似。例如:glTexCoord2f(0.0f, 0.0f);指定使用(0, 0)紋理坐標(biāo)。通常,每個頂點使用不同的紋理,于是下面這樣形式的代碼是比較常見的。glBegin( /* . */ ); glTexCoord2f( /* . */ ); glVertex3f( /* . */ ); glTexCoord2f( /* . */ ); glVertex3f( /* . */ ); /* . */glEnd();我們的代碼中使用的紋理坐標(biāo):五 系統(tǒng)描述本實驗繪制的游戲場景可以使用按鍵、或W、S、A、D控制運動方向,PgDn和PgUp可以改變觀察者的高度,鼠標(biāo)控制轉(zhuǎn)

22、向,按鍵F可以打開和關(guān)閉“霧氣”,Esc退出程序。主要繪制了墻壁與地面、天空、石柱、箱子、玻璃球、雪人、霧等對象下面將依次分析它們的設(shè)計思路,這里將使用相同繪制技術(shù)的對象放到一起說明。1 墻壁、地面、箱子它們的基本操作對四邊形的紋理映射,將一幅紋理圖的四個頂點坐標(biāo)分別映射到四邊形的四個頂點上即可。OpenGL就自動通過插值填充多邊形內(nèi)部的紋理。由于在OpenGL中紋理坐標(biāo)是一個點的屬性,故需要在繪制點之前指定該點的紋理坐標(biāo)。另外在繪制四邊形時要保證繪制順序的一致,這里統(tǒng)一采用逆時針順序繪制。紋理坐標(biāo)范圍在0,1之間,坐標(biāo)超過1則采用重復(fù)的方式(OpenGL默認(rèn)處理方式)。這樣可以在映射時按四邊

23、形的比例設(shè)置紋理坐標(biāo),從而防止紋理圖過度拉伸造成的變形。一個四邊形的紋理映射步驟為:glBindTexture(GL_TEXTURE_2D,texture0); glBegin(GL_QUADS); glTexCoord2f(0.0f, 0.0f); glVertex3f(30.0f,0.0f, -170.0f);glTexCoord2f(1.0f, 0.0f); glVertex3f(30.0f,0.0f, -150.0f);glTexCoord2f(1.0f, 1.0f); glVertex3f(30.0f,20.0f,-150.0f);glTexCoord2f(0.0f, 1.0f);

24、glVertex3f(30.0f,20.0f,-170.0f);glEnd();實驗效果圖如下:圖3 墻壁 地面 箱子2 石柱、雪人石柱和雪人都屬于二次幾何體的繪制和紋理映射,其中雪人由圓柱、球體、圓盤、圓錐構(gòu)成。OpenGL提供了這些基本幾何體的繪制函數(shù),而且在紋理映射時我們采用自動生成紋理坐標(biāo)的方法,所以這一部分工作量其實很少。另外,為了給雪人的身體、鼻子等部位設(shè)置顏色時,我們需要關(guān)閉紋理映射、并更改材質(zhì)的屬性(物體的顏色是由光源和材質(zhì)共同作用的結(jié)果)。對于石柱,我們加上了繞自身局部坐標(biāo)Y軸的勻速旋轉(zhuǎn)。我們使用Glut庫提供的如下函數(shù)繪制二次幾何體:gluCylinder:繪制圓柱和圓柱g

25、luSphere:繪制球體gluDisk:繪制圓盤使用gluQuadricTexture設(shè)置自動計算紋理坐標(biāo)。實驗效果如下: 圖4 雪人和石柱3 玻璃球在繪制玻璃球時,為了在球面上反射出周圍的場景,我們使用了環(huán)境映射。由于我們能夠在三維場景中漫游,這就需要球面上反射出的場景是隨著視點移動而變化的,這一需求可以利用“渲染到紋理”(RTT)技術(shù)實現(xiàn)。其基本思想是:首先繪制出環(huán)境中的所有物體(除了該玻璃球),接著將繪制得到的場景圖制作成紋理,在繪制該玻璃球時將此紋理圖貼在球面上即可。該場景使用的核心函數(shù)是glCopyTexImage2D,該函數(shù)可以將幀緩存中的顏色值復(fù)制到紋理緩存中。實驗發(fā)現(xiàn)該函數(shù)性

26、能較低,會拖慢整個程序的速度,為了平衡繪制質(zhì)量和速度,可以只拷貝一部分像素值。實驗效果如下:圖5 玻璃球4、 霧氣OpenGL中提供了完整的霧化接口,我們只需要選擇合適的霧氣的混合因子、密度、顏色、起始位置等。該場景的霧氣設(shè)置如下:GLfloat fogColor4=0.5f, 0.5f, 0.5f, 0.5f; glFogi(GL_FOG_MODE,GL_EXP2);/模式glFogfv(GL_FOG_COLOR,fogColor);/顏色glFogf(GL_FOG_DENSITY, 0.004f);/密度glFogf(GL_FOG_START, 5.0f);/開始距離glFogf(GL_F

27、OG_END, 300.0f);/結(jié)束距離glHint(GL_FOG_HINT,GL_NICEST);/霧化效果實驗效果如下:圖6 霧氣4 天空天空包含云、星星、閃電三個對象。我們要實現(xiàn)的目標(biāo)是:云在空中飄動、且能夠遮蓋住空中的星星,每間隔一段時間都會有閃電和雷聲。天空的繪制主要使用了顏色混合技術(shù)。首先將星星的紋理圖映射到天空,為了實現(xiàn)云朵覆蓋住星星,我們使用了如下技巧:制作一個關(guān)于云圖(圖6)的二值圖像(圖7),其中有云的部分為黑色、無云的部分為白色。將該二值圖像作為“掩?!迸c星星圖進(jìn)行混合,并設(shè)置混合因子glBlendFunc (GL_DST_COLOR,GL_ZERO),該設(shè)置可以將星星

28、圖中對應(yīng)“掩?!焙谏牟糠种脼楹谏?yīng)“掩?!卑咨牟糠直A粼?。接著再將云圖映射至天空,并更改混合因子glBlendFunc(GL_ONE, GL_ONE),該設(shè)置實現(xiàn)源色與目的色相加。至此已經(jīng)實現(xiàn)云對星星的遮蓋,另外,在進(jìn)行顏色混合時需要打開OpenGL的顏色混合功能,且要關(guān)閉深度測試功能。為了實現(xiàn)云的飄動,我們在設(shè)置云圖紋理坐標(biāo)時添加一個變量,該變量從0遞增至1,超過1時做減1操作,這樣就可以模擬云的移動。如下的roll即為該變量:glBegin(GL_QUADS); glTexCoord2f(0.0f, 3.0f-roll);glVertex3f(-50.0f, 100.0f, -3

29、00.0f);glTexCoord2f(1.0f, 3.0f-roll);glVertex3f( 50.0f, 100.0f, -300.0f);glTexCoord2f(1.0f, 0.0f-roll);glVertex3f( 50.0f, 100.0f, 300.0f);glTexCoord2f(0.0f, 0.0f-roll);glVertex3f(-50.0f, 100.0f, 300.0f);glEnd(); 圖7 云圖和云的二值圖圖8 天空六 心得體會這次的課程設(shè)計不僅考察了書上所學(xué)知識點,將所學(xué)融合在一起。過程中雖然剛開始感覺有些難,也遇到很多困難,比如電腦配置問題等等,但遇到困

30、難不可怕,重要的是解決困難的過程,我們的游戲場景的繪制,因工程量很大,且代碼很多,在實驗過程中,我不斷查資料,看書去理解各種模型代碼,從來不敢相信自己能將看完并理解這么多代碼。但是這次我做到了,雖然我重點講的是紋理模型,其他模型也都去認(rèn)真學(xué)習(xí)了一遍。在這個過程中真的學(xué)到很多,而大學(xué)鍛煉的也就是這種自學(xué)能力。七 附錄:程序源代碼#include #include#include#include #include #pragma comment( lib, opengl32.lib) #pragma comment( lib, glu32.lib) #pragma comment( lib, gl

31、aux.lib) #define KEY_DOWN(vk_code)(GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)HDChDC=NULL;HGLRChRC=NULL;HWNDhWnd=NULL;HINSTANCEhInstance;boolkeys256;boolactive=TRUE;boolfullscreen=TRUE;int SCREEN_WIDTH =800;/屏幕寬 int SCREEN_HEIGHT =600;/屏幕高GLfloat theta = 0.0f; /左右旋轉(zhuǎn)角度GLfloat viewUp = 0.0f;/向上和向下程度G

32、Lfloat speed = 0.23f;/運動速度GLfloat dis=10;/碰撞檢測保留距離GLfloat viewAtPosition3;/觀察目標(biāo)位置GLfloat eyePosition3 = 0.0f, 40.0f, 0.0f; /視點初始位置 GLfloat Matblack= 0.0f, 0.0f, 0.0f, 1.0f;GLfloat Matwhite= 0.7f, 0.7f, 0.7f, 1.0f;GLfloat Matred= 0.6f, 0.0f, 0.0f, 1.0f;GLfloat LightAmbient= 0.8f, 0.8f, 0.8f, 1.0f; GL

33、float LightDiffuse= 1.0f, 1.0f, 1.0f, 1.0f;GLfloat LightPosition=1.0f, 1.0f, 1.0f, 0.0f;GLfloat mat_specular =1.0f, 1.0f, 1.0f, 1.0f;GLfloat mat_shininess = 100; /高光度GLfloat fogColor4= 0.5f, 0.5f, 0.5f, 0.5f;/霧氣顏色GLuinttexture10;/紋理標(biāo)識GLUquadricObj *quadratic=gluNewQuadric();/二次幾何體GLfloat rotate=0.0f

34、;/石柱旋轉(zhuǎn)角度GLfloat roll=0;/云層移動量GLfloat lightning=0;bool thunder=true;/是否打雷GLboolean fog=false;/是否開啟霧化bool fp;/F鍵是否按下GLuintEnvTexture;/環(huán)境紋理/*/接口集void CollDetec(GLfloat &x,GLfloat &z);void SetViewByMouse();void Camera();AUX_RGBImageRec *LoadBMP(char *Filename);int LoadGLTextures();GLuint EmptyTexture();

35、int InitGL(GLvoid);void DrawCave();void DrawBox();void DrawSnowMan();void Drawcylinder();void DrawGlassBall();void DrawSky();int DrawGLScene(GLvoid);GLvoid ReSizeGLScene(GLsizei width, GLsizei height);GLvoid KillGLWindow(GLvoid);BOOL CreateGLWindow(char* title, int width, int height, int bits, bool

36、fullscreenflag);LRESULTCALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);/*/改變寬口大小GLvoid ReSizeGLScene(GLsizei width, GLsizei height)if (height=0)height=1;/下面函數(shù)是定義視圖窗口在畫布上的大小和位置glViewport(0,0,width,height);/設(shè)置為投影矩陣glMatrixMode(GL_PROJECTION);/當(dāng)前矩陣設(shè)置為單位矩陣glLoadIdentity();/角度視,景體的寬高比,沿z軸方向的兩裁面之間的距離的近處,/沿z軸

37、方向的兩裁面之間的距離的遠(yuǎn)處gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,1000.0f);/模型視圖應(yīng)用這個參數(shù)后,表示接下來的矩陣操作都是針對模型視景矩陣堆棧 , /直到下一次調(diào)用這個函數(shù)并更改參數(shù)為止。glMatrixMode(GL_MODELVIEW);/當(dāng)前矩陣設(shè)置為單位矩陣glLoadIdentity();/碰撞檢測,防止視點穿過物體,是極為簡單的最小外包矩形進(jìn)行碰撞檢測void CollDetec(GLfloat &x,GLfloat &z)if (x (50-dis)x= 50-dis;if (z (300-d

38、is)z= 300-dis;if (z=-170&z(30-dis)&eyePosition1=30&z=-170&z-(150-dis)&eyePosition1=30&z-(170+dis)&eyePosition1=150&z=170&x-(30-dis)&eyePosition1=55) x=-(30-dis);/雪人if (x=-30&z(150-dis)&eyePosition1=55)z=(150-dis);if (x=150&z(170+dis)&eyePosition1=55)z=(170+dis);if (z(30-dis)x=30-dis;/石柱if (z=-280&x=

39、30&z-(280-dis)z=-(280-dis);if (x=-30&z360) theta=0.0f; if (viewUp0.6f)viewUp = 0.6f; if (viewUp-0.6f)viewUp =-0.6f; if (KEY_DOWN(VK_UP)|KEY_DOWN(W)/前進(jìn)eyePosition0+= (viewAtPosition0-eyePosition0)*speed;eyePosition2+= (viewAtPosition2-eyePosition2)*speed;if(KEY_DOWN(VK_DOWN)|KEY_DOWN(S) /后退 eyePositi

40、on0-= (viewAtPosition0-eyePosition0)*speed;eyePosition2-= (viewAtPosition2-eyePosition2)*speed;if(KEY_DOWN(F) /后退 fog = true;/*eyePosition0-= (viewAtPosition0-eyePosition0)*speed;eyePosition2-= (viewAtPosition2-eyePosition2)*speed;*/if(KEY_DOWN(G) /后退 fog = false;/*eyePosition0-= (viewAtPosition0-ey

41、ePosition0)*speed;eyePosition2-= (viewAtPosition2-eyePosition2)*speed;*/if(KEY_DOWN(VK_PRIOR)&eyePosition130.0f) /向下eyePosition1-=0.5*speed;CollDetec(eyePosition0,eyePosition2);viewAtPosition0 = eyePosition0 + cos(theta);/ 新的參考點的位置 viewAtPosition2 = eyePosition2 + sin(theta);viewAtPosition1 = eyePos

42、ition1;gluLookAt( eyePosition0,eyePosition1 ,eyePosition2, / 視點位置viewAtPosition0, viewAtPosition1 + viewUp, viewAtPosition2 , /參考點位置0.0,1.0,0.0); /向上方向return ;/加載位圖AUX_RGBImageRec *LoadBMP(char *Filename)/ 根據(jù)位圖文件的名稱進(jìn)行加載。 AUX_RGBImageRec定義紋理數(shù)據(jù)的格式FILE *File=NULL; / 文件指針if (!Filename)/確保文件名已提供return NU

43、LL;/如果沒有提供,返回nullFile=fopen(Filename,r); / 根據(jù)指定的位圖文件名稱,打開該位圖文件if (File)/ 如果位圖文件存在fclose(File);/ 關(guān)閉句柄。 因為只是需要判斷問題是否存在,而不需要對位圖文件進(jìn)行寫操作,所以關(guān)閉位圖文件return auxDIBImageLoad(Filename); /載入位圖并返回指針(其實,只需要一個真正存在的位圖文件的名稱,實現(xiàn)加載位圖文件,并返回)return NULL;/加載紋理int LoadGLTextures()/用于創(chuàng)建并加載紋理的函數(shù)為LoadGLTexturesint Status=FALSE

44、;/很多函數(shù)的返回類型都是Status,這里Status是用typedef定義的intl類型 即:typedef int Status;AUX_RGBImageRec *TextureImage10;/創(chuàng)建一個紋理圖像數(shù)組,這里指定數(shù)組大小為10memset(TextureImage,0,sizeof(void *)*10); / 創(chuàng)建一個紋理圖像數(shù)組,這里指定數(shù)組大小為6/創(chuàng)建的位圖名稱數(shù)組,對應(yīng)6幅位圖if (TextureImage0=LoadBMP(Data/Floor.bmp)&(TextureImage1=LoadBMP(Data/Wall.bmp)&(TextureImage2=

45、LoadBMP(Data/Door.bmp)&(TextureImage3=LoadBMP(Data/Box.bmp)&(TextureImage4=LoadBMP(Data/Hat.bmp)&(TextureImage5=LoadBMP(Data/Cylinder.bmp)&(TextureImage6=LoadBMP(Data/Star.bmp)&(TextureImage7=LoadBMP(Data/Mask.bmp)&(TextureImage8=LoadBMP(Data/Sky.bmp)&(TextureImage9=LoadBMP(Data/Lightning.bmp)Status=TRUE;/加載位圖成功,修改狀態(tài)標(biāo)志變量Status為TRUEglGenTextures(10, &texture0);/紋理標(biāo)識for(int loop=0;loopsizeX, TextureImageloop-sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImageloop-data);/生成紋理for (int loop=0; loopdata!=NULL)free(TextureImageloop-data);free(TextureImageloop);return

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論