2011年5月14日 星期六

作業4 3D場景悠遊

主題介紹

步行於元智的夜晚



過程與成果展示

這次的作業,參考了老師的範例17,載入物件的部分

但網路上可以用的obj實在太少了

不然就是可以用的都要錢...

最後我就參考了範例17裡面其中一個obj

然後慢慢修改,做出一到七館( building1.obj ~ building7.obj )

把.mtl的部分拿掉,讓顏色那些也自己設定

每個館都是用物件的方式載入

glMaterialfv(GL_FRONT, GL_DIFFUSE, matn_diffuse);
glPushMatrix();
       glTranslated(x,y,z);
       glRotatef(angle, 0.0, 1.0, 0.0);
       glCallList( list_idn );
    glPopMatrix();

使用gluLookAt讓程式可變化個角度來看元智

初始視角設在(20, 0, 0) 面對六館方向


延續上個作業用到的,加上光源與材質,我將光源設在(0, 10, 0)處

寫在prepare_lighting函式中

光是放上一到七館,就花了滿多時間了

可能是自己空間概念不夠好

加上Z軸之後,腦筋就一直轉不過來

幸好拿出紙筆標記在紙上之後

就解決這個困擾了


接著我在各館間的空隙處利用迴圈加上了樹

以及幫紅磚道上色,在二三館間加了恐龍蛋 (二一石)


後來我覺得,各館雖然都有自己的外型了

但是都是很光滑的同一色系,好像有點單調

看到很多人在作業一就運用了貼圖

於是我也開始學習要怎樣貼圖


參考了以上網頁以及老師的範例

根據網友的建議

以64*64,或256*256的bmp是最好的,接著我便開始收集圖片

本來想要貼上各館外觀的照片

可是貼上去變好醜


所以我就去網頁素材的網站,找了一些適合的圖

用小畫家改成64*64的bmp

先利用AUX_RGBImageRec 來開一個檔案

LoadGLTextures 將Load的檔案,轉換成Textures

glGenTextures 創造Textures

接著再產生Texture

利用glTexImage2D將圖片貼在物件上





貼圖的code是參考老師的範例的

在依照自己的需求做修改這樣


貼完圖之後,作業終於看起來比較順眼一點了

雖然看起來只是變個顏色而已

其實每個館貼的圖是有花紋的

不過可能我設得太小,所以看不太出來

如果將館放超級大的話,就可以看得比較明顯唷 :)




因為紅磚道上看起來有點空虛單調

所以我又載入了人的物件

他長得真的很壯欸,我一開始還放大三倍載入,結果自己嚇了一大跳 XD


縮小之後

再用Loop等,讓他各角度都產生行人

( 有些要進七館,有些往宿舍方向,有些要去一館... )


用俯視角來看看元智吧






最後在天空中加上了月亮,以及隨機產生星星

月亮是用上一個作業的 glutSolidSphere 做法畫出的

而星星也是用 glutSolidSphere 畫出,不過是將半徑設為 0.01

所以看起來很像一個小點點


以下是我這次作業的架構



KeyboardFunc( )的部分

a,d控制視野z方向

w,x控制視野x方向

q,e則可控制仰視及俯視

簡單來說

就是面對六館的時候 ( 初始 )

a,d可左右移動

w,x可前進後退

q,e可看仰視及俯視

為了方便起見

利用SpecialFunc( )

↑ , ↓ 控制視野z方向,也就是面對六館時可前進後退 

← , → 控制視野x方向,面對六館時可左右移動

最後加上按下Esc可關閉視窗


心得與討論

遇到最大的問題

一開始我是用Visual Studio 2008

在執行到 return auxDIBImageLoad(Filename); 這一行code會一直出錯

我幾乎是遍了所有網路上提供的方法

1. 改成 return auxDIBImageLoad(_L("xxx.bmp"));

2. 加入#pragma comment(lib, "glaux.lib")

3. 加入#define auxDIBImageLoad auxDIBImageLoadL

4. 專案→屬性→連結器→輸入→加入glaux.lib

5. 直接去下載glaux.lib到lib的資料夾內,在link

6. 不使用unicode




.
.
.

繁多不及備載


我試了一整個晚上,以上方法全部都不行!!!!!!

在這些過程中,為了載glaux.lib這個檔案

電腦還不知道怎麼了,瘋狂安裝很奇怪的東西

嗚嗚~千萬不要連不熟悉的網頁亂下載東西 QQ

就在我終於把亂安裝的東西都解除安裝之後

google到有一位網友說,glaux.lib在v5.0的資料夾內有...

當下真的很想乾脆不要貼圖直接交作業算了

但看到很多同學都會貼圖,自己真的也很希望可以嘗試成功

就在我快要絕望之際

看到了曾經修過圖學的同學上線

厚著臉皮問他我這個Error要怎麼辦

他告訴我,VS2008"似乎"沒有支援glaux,叫我改用VC6或Dev c++寫

他也很好心的提供了老師之前提供的CGMyDemo這份範例給我

於是,在Dev中安裝了glut,glaux套件之後

我終於搞定之前的Error了

這個當下,用痛哭流涕來形容真的一點都不為過



只是我真的很想知道,VS2008真的不能用嗎

因為有問到之前曾經修過的同學

他說他的VS2008只要Link lib就可以用了

到底為什麼我的不行 QAQ

這個問題真的是我這次作業的最大難題了

也耗了最多時間在解決



另外遇到的問題就是

不知道為什麼

如果我把Mydisplay裡面的一館到七館

移到Mydisplay最前面,紅磚道會因為鍵盤中任何一個觸發點而變成黑磚道

但放在後面就可以正常顯示

這個奇怪的問題還要再花時間想想辦法吧



作業越來越多元,做出來也越來越有成就感

雖然跟其他同學比起來還是差了一截

但希望自己可以保有這種感覺

讓作業慢慢上手

:)

========================
後記

作業是在家中完成的,但家裡電腦CPU不夠好

變成動得很慢

想說到學校來再把畫面拍成影片上傳

結果一打開

變成....


真不知道是不是因為我沒有裝顯卡,直接用內顯的關係

所以行人就變成沒有穿褲子了

好害羞 >///<

為了大家好,就不拍成影片了 

:P

2011年5月13日 星期五

作業3 太陽系



主題介紹

轉動吧,九大行星



過程與成果展示

因為要畫成立體的,所以上網找了很多資料

其中,這個網頁 OpenGL入门学习

真的是個好幫手

透過這個網站的講解

我學會了設定光源和材質

裡面有很詳細的解說,透過幾次的測試之後

就發現使用的很得心應手了

另外也去查詢了類似MFC中Timer功能的函式

是利用 glutGet(GLUT_ELAPSED_TIME) 


Glut函式說明2


這裡面有很多glut的函式


只要找要適合的,再去另外google用法就好了,超方便的 :P


用此函式取得的毫秒值,再去除除除,除到差不多適合的速度


我是先除1000再乘20,這個速度我覺得看起來比較順眼  = =



設定好光源和材質後

就開始畫九大行星與衛星(月亮)

一開始以原尺寸畫了一顆太陽,結果整個視窗都是黃的,完全被擋住

故我將太陽縮小了很多倍(以不擋住其他星球為原則)

九大行星互相之間是維持原始比例

而月亮則為了方便觀看起見,也不是照原比例

去維基百科搜尋了九大行星的各軸旋轉角度、半徑大小、公轉自轉周期等

如下表所示:


每顆星球的Matrix大致如下
  
以地球為標準算出各變數  

glRotated(X,0,1,0);  //以太陽為中心公轉,公轉週期 angle/行星的公轉週期(年)
glTranslated(XX,XX,XX);
glRotated(90,1,0,0);  //X軸角度
glRotated(XXX,0,1,0);  //赤道傾斜角度
glRotated(XXX,0,0,1);  //自轉週期,以10天為基準
glutSolidSphere(XXX,20,20);  //半徑大小,與地球比較

其中glutSolidSphere用來畫"球體"

而 glutSolidTorus用來畫"面"

也就是土星的環

一開始我就直接將太陽放在原點,這樣公轉的時候就可以直接繞原點

省了很多麻煩

但...

將個星球依序畫下去

會出現幾顆星球因體積較大而互相遮蓋的問題


所以我後來


將土星與海王星移到-x的位置上


雖然不像wiki上的圖,是成一直線的


但為了方便看清楚各星球,我想,做這樣的調整應該是OK的

以下是我這次作業的程式架構


看了學長的網誌之後,我也增加了鍵盤控制的部分

分為兩部分:

KeyboardFunc()的部分

按下 x,X 可旋轉x軸

按下 y,Y 可旋轉y軸

按下 z,Z 可旋轉z軸

因要旋轉各軸
故我寫入了

    glRotatef(x, 0.0, 1.0, 0.0);
    glRotatef(y, 1.0, 0.0, 0.0);
    glRotatef(z, 0.0, 0.0, 1.0);

來作旋轉

按下 + 可加快轉動速度

按下 - 可減緩轉動速度

而SpecialFunc()的部分

按下 ↑ 可放大地球與月亮的體積

按下 ↓ 可減小地球與月亮的體積

此功能是利用glScalef來完成

主要是為了方便觀看衛星繞地球而增加的

最後在加上,按下Esc可關閉視窗

因為每次測試都要用滑鼠點視窗右上角的X

增加了這個功能之後就可以稍微偷懶一下不要用滑鼠




以下影片為作業展示


心得與討論

一開始在研究光源與材質時

吃了很多苦頭

常常因為光源位置設錯

導致顏色變得很奇怪

甚至轉個角度,星球就消失了

經過這個作業的練習

對於光源與材質的運用算是熟練了

希望在往後的作業可以多多運用到這次所學習到的知識





另外一個遇到的問題就是在算個星球公轉自轉週期等計算

雖然wiki上的表格都有列出週期

但轉換成可以應用在作業上的角度時間時,常常鬼打牆一直算錯

導致轉得很奇怪





這次作業耗最多時間就是在理解

glTranslated和glRotated 

誰先誰後造成的差異

寫到最後變得有點似懂非懂

都用測試的方法把它做到對

自己接下來會在多花一點時間去理解他








本來想用貼圖貼在星球上,使他看起來更逼真


但怎麼貼都不成功


上網查了很多資料,似乎是VS2008不支援glaux.lib


網友們提共了很多解決方法,但我都不適用

希望能盡快解決這個問題

下一個作業就可以應用這項技巧了