2012年6月18日 星期一

[作業五 整合練習]


主題介紹 - 動物賽跑

       在喧嚷的城市中,豬與牛悠閒的在道路中賽跑,究竟是好吃懶做的豬會獲勝,還是西班牙鬥牛會獲勝呢?

讓我們仔細的看下去

程式設計與寫作方法、執行結果呈現

        這次的程式結合本學期課程所學,3D空間游走、3D model匯入、視角切換等等

從跑道的繪製,設置3D model的位置,旋轉角度等等,每一個步驟都是精心策劃

為的就是讓動物們真的在跑道上逼真的移動。另外在程式中按下O可以切換自動視角,有點像是看電影一般的感

覺,這個使用到的函式是gluLookatfun(); 以前都不知道這個這麼好用。其實這次的作品成熟度已經有了,如果

在加上滑鼠事件、碰撞偵測、還有移動的model細部的動作的話就更加完美了。

不過也學到了一件事情,就是隨著model的load 越來越多,程式執行就會越來越慢,所以要想辦法避免不必要

的讀取。

         最後一樣附上作品影片





  
心得與討論


        我自己覺得這次的作業算是蠻有趣的,整個場景看起來有點像是常玩的大富翁,可以蓋房子,又有動物在

跑道上移動,也許如果以後有機會的話可以從這個當做出發點,做個有趣的遊戲提供大家玩,最後我要感謝這

學期老師教了我們許多,讓我們可以寫做出這麼棒的程式。





2012年6月11日 星期一

[作業四 擬真3D空間場景-元智校園]


主題介紹 - 海洋動物園

       在廣闊的校園中,可愛的小豬、聰明伶俐的海豚與驕傲的老鷹活動於元智校園之中,校園的周圍禁是一望無

際的海洋,給人廣闊無邊的感覺。



程式設計與寫作方法、執行結果呈現

         這次的程式主要的重點就是學會如何讀取OBJ

首先,就是要先畫出3D模型,利用Audodesk 的 3ds Max 就可以設計出不錯的模型

再來,利用glm所提供的函式就可以成功的讀取OBJ。

程式代碼大致如下:

{
    GLMmodel *glm_model_pig;
     glm_model_pig= glmReadOBJ( "model/pig.obj" );
     glmUnitize( glm_model_pig );
     glmScale( glm_model_pig, 5 );
     glmFacetNormals( glm_model_pig );
     glmVertexNormals( glm_model_pig, 90 );

     list_id[0] = glmList( glm_model_pig, GLM_MATERIAL | GLM_SMOOTH );

     glmDelete( glm_model_pig );
}

如此就可以將OBJ成功的讀入程式中

再利用glCallList繪出

    glPushMatrix();
glDisable(GL_TEXTURE_2D);
glTranslatef(-5.0f,-5.0f,-20.0f);
    glCallList( list_id[0] );
glPopMatrix();

此外,我在這次的程式還加入的skybox,這個要實作也不困難,

首先一樣利用glm讀入bmp檔,然後再利用texture貼圖

程式碼大致上如下

首先是讀取bmp檔

bool Load_Texture(unsigned int & aTexture, char * fileName) {

if(!fileName) return false; //if no file name is given return

FILE *aFile = NULL;
AUX_RGBImageRec *image_record = NULL;

if((aFile = fopen(fileName, "rb")) == NULL) return false;
WCHAR wsz[64];
swprintf(wsz, L"%S", fileName);
LPCWSTR p = wsz;
image_record = auxDIBImageLoad(p); //Function to load BMP

if(!image_record) return false; //check that BMP loaded

glGenTextures(1, &aTexture); //generates 1 texture name

glPixelStorei (GL_UNPACK_ALIGNMENT, 1); //sets how the pixels of the texture are stored

glBindTexture(GL_TEXTURE_2D, aTexture); //binds the name to the target

//build prefiltered textures at different resolutions
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, image_record->sizeX, 
 image_record->sizeY, GL_RGB, GL_UNSIGNED_BYTE, image_record->data);

//give the texture its attributes
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

// Now we need to free the image data that we loaded since openGL stored it as a texture
if (image_record) { //if we stored data then free the memory
if (image_record->data) { //check if there is any data
// free(image_record->data); //free the memory
}
// free(image_record); //free the image record
}

return true; //everything should have worked so return true
}

然後再設置Texture

void skyboxInit() 
{

Load_Texture(texture[0],"texture/left.bmp");
Load_Texture(texture[1],"texture/front.bmp");
Load_Texture(texture[2],"texture/right.bmp");
Load_Texture(texture[3],"texture/back.bmp");
Load_Texture(texture[4],"texture/down.bmp");
Load_Texture(texture[5],"texture/up.bmp");
}

然後再呼叫繪出

void skybox()
{
glPushMatrix();
glDisable (GL_LIGHTING);
glColor3f(1.0f,1.0f,1.0f);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture[0]);
glBegin (GL_QUADS);
glNormal3d (0.0,0.0,1.0); glTexCoord2d (0.0 ,0.0 );
                glVertex3d (-100.0,-10.0,100.0);
                
glNormal3d (0.0,0.0,1.0); glTexCoord2d (1.0 ,0.0 );
                glVertex3d (-100.0,-10.0,-100.0);
                
                glNormal3d (0.0,0.0,1.0);
glTexCoord2d (1.0 ,1.0 );
                glVertex3d (-100.0,100.0,-100.0);
glTexCoord2d (0.0 ,1.0 );
                glVertex3d (-100.0,100.0,100.0);
glEnd ();
glBindTexture(GL_TEXTURE_2D, texture[1]);
glBegin (GL_QUADS);
glNormal3d (0.0,0.0,1.0); glTexCoord2d (0.0 ,0.0 );
                glVertex3d (-100.0,-10.0,100.0);
                
glNormal3d (0.0,0.0,1.0); glTexCoord2d (1.0 ,0.0 );
                glVertex3d (100.0,-10.0,100.0);
                
                glNormal3d (0.0,0.0,1.0);
glTexCoord2d (1.0 ,1.0 );
                glVertex3d (100.0,100.0,100.0);
glTexCoord2d (0.0 ,1.0 );
                glVertex3d (-100.0,100.0,100.0);
glEnd ();
glBindTexture(GL_TEXTURE_2D, texture[3]);
glBegin (GL_QUADS);
glNormal3d (0.0,0.0,1.0); glTexCoord2d (0.0 ,0.0 );
                glVertex3d (-100.0,-10.0,-100.0);
                
glNormal3d (0.0,0.0,1.0); glTexCoord2d (1.0 ,0.0 );
                glVertex3d (100.0,-10.0,-100.0);
                
                glNormal3d (0.0,0.0,1.0);
glTexCoord2d (1.0 ,1.0 );
                glVertex3d (100.0,100.0,-100.0);
glTexCoord2d (0.0 ,1.0 );
                glVertex3d (-100.0,100.0,-100.0);
glEnd ();
glBindTexture(GL_TEXTURE_2D, texture[3]);
glBegin (GL_QUADS);
glNormal3d (0.0,0.0,1.0); glTexCoord2d (0.0 ,0.0 );
                glVertex3d (100.0,-10.0,100.0);
                
glNormal3d (0.0,0.0,1.0); glTexCoord2d (1.0 ,0.0 );
                glVertex3d (100.0,-10.0,-100.0);
                
                glNormal3d (0.0,0.0,1.0);
glTexCoord2d (1.0 ,1.0 );
                glVertex3d (100.0,100.0,-100.0);
glTexCoord2d (0.0 ,1.0 );
                glVertex3d (100.0,100.0,100.0);
glEnd ();
glPopMatrix();

}

如此一來就可以做出不錯的3D立體空間

         一樣附上作品影片


  
心得與討論


        作業四讀入OBJ檔後又加入的天空盒的texture,讓整個程式空間都完整了。


不過在讀取texture的時候,有一些型態的轉換要注意,例如"LPCWSTR",