satanupup 喜歡上這裡的冒險者
註冊時間: 2007-05-29 文章: 80
68.10 果凍幣
|
發表於: 2007-6-28, PM 2:12 星期四 文章主題: [轉貼自程式設計俱樂部]glut 教學 - 使用 OBJ 立體模型 |
|
|
作者 : ma_hty(白老鼠(Gary))
在上一次教學, 我們利用 glut 內建的函式繪圖了一個 茶壺, 並為之打燈,
但是, 只有茶壺是不足夠吧. 我們需要更豐富的立體模型. 而 立體模型 的設計, 與編程的關係並不是十分大, 反而, 要設計 立體模型, 除了需要專業的 立體模型設計軟體 ( 例如 3D Max 或 Maya ), 更重要的, 是需要你的美工 ( 噢... 美工... ).
立體模型設計完畢後, 你會把它儲存成 立體模型 的檔案, 好像圖檔一般, 我們有很多很多已經成熟 立體模型 的檔案格式, 例如, WaveFront 的 OBJ 檔, DirectX 的 X 檔, VRML 的 WRI 檔, OpenGL 的 .c 檔 ... ... 我們只要能正確的應用其中一個就可以了.
而我最常用的, 就是 WaveFront 的 OBJ 檔, 因此, 我也就介紹它的應用吧.
好, 我們去秀 OBJ 檔 吧.
-------------------------
讀取 OBJ 檔, 其實是一件頗煩瑣 ( 注意, 是煩瑣, 並不是困難 ). 為了簡化這個煩瑣的工序, 我們應用別人已經寫好的函式吧.
在 http://www.xmission.com/~nate/smooth.html 之內, 有一個 link
http://www.xmission.com/~nate/smooth/smooth.zip
這個 zip 之內, 有兩個檔案, glm.h 和 glm.c, 把它解壓出來到你的專案資料夾, 然後把 glm.c 更名成 glm.cpp, 然後把 glm.h 和 glm.cpp 都加到你的專案.
--------------------------
/////////////////////////
// glutTest08.cpp
//
// Created by Gary Ho, ma_hty@hotmail.com, 2005
//
#include <stdio.h>
#include <math.h>
#include "glut.h"
#include "glm.h"
#define G_PI 3.14159265358979323846f
void prepare_lighting();
void display();
void keyboard(unsigned char key, int x, int y);
float theta, phi;
GLuint list_id;
void main()
{
theta = G_PI/2;
phi = -G_PI/2;
glutInitDisplayMode( GLUT_DOUBLE | GLUT_DEPTH | GLUT_RGB );
glutInitWindowSize( 640, 640 );
glutCreateWindow( "glutTest08" );
glutDisplayFunc(display);
glutKeyboardFunc( keyboard );
{
GLMmodel *glm_model;
glm_model= glmReadOBJ( "castle.obj" );
glmUnitize( glm_model );
glmScale( glm_model, .1 );
glmFacetNormals( glm_model );
glmVertexNormals( glm_model, 90 );
list_id = glmList( glm_model, GLM_MATERIAL | GLM_SMOOTH );
glmDelete( glm_model );
}
prepare_lighting();
glutMainLoop();
}
void keyboard(unsigned char key, int x, int y)
{
switch( key )
{
case 'w':
theta -= .05;
prepare_lighting();
glutPostRedisplay();
break;
case 's':
theta += .05;
prepare_lighting();
glutPostRedisplay();
break;
case 'a':
phi -= .05;
prepare_lighting();
glutPostRedisplay();
break;
case 'd':
phi += .05;
prepare_lighting();
glutPostRedisplay();
break;
};
}
void display()
{
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective( 20, 1, 0.1, 10 );
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(
0,0,1,
0,0,0,
0,1,0 );
glEnable( GL_LIGHTING );
glEnable( GL_DEPTH_TEST );
glCallList( list_id );
glutSwapBuffers();
}
void prepare_lighting()
{
theta = fmodf( theta, 2*G_PI );
phi = fmodf( phi, 2*G_PI );
float light_diffuse[4] = {1.0, 1.0, 1.0, 1.0};
float mat_diffuse[4] = {1.0, 1.0, 1.0, 1.0};
float light_position[4] = { sinf(theta) * cosf(phi), cosf(theta), -sinf(theta) * sinf(phi), 0 };
//glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glEnable( GL_LIGHT0 );
}
-----------------------
glutTest08.cpp 其實跟上一次教學差不多是完全一樣的, 分別只是, 上一次我們畫 glut茶壺, 而這次, 我們先利用 glm.cpp 準備出一條 display list ( list_id ), 然後應用 glCallList( list_id ) 把它畫出來.
---------------------
應用 glm.cpp 去準備 display list 的部份
{
GLMmodel *glm_model;
glm_model= glmReadOBJ( "castle.obj" );
glmUnitize( glm_model );
glmScale( glm_model, .1 );
glmFacetNormals( glm_model );
glmVertexNormals( glm_model, 90 );
list_id = glmList( glm_model, GLM_MATERIAL | GLM_SMOOTH );
glmDelete( glm_model );
}
---------------------
繪畫 display list 的部份
void display()
{
//...
glCallList( list_id );
//...
}
------------------
OBJ 檔的檔案格式, 我暫不詳細交代, 但是, 有一事必需提醒你的, 構成一個完整的 OBJ 立體模型, 除了 .obj 檔, 你還有可能需要一些 .mtl 檔 和 一些圖檔. 因此, 如果你想應用 .obj 檔, 你需要額外的注意會否忘記了這些附加的檔案.
-------------------
上面的程式, 會在你的專案資料夾, 讀取一個叫 castle.obj 的 obj 檔, 你可以在上文說及的 smooth.zip 之內的 data 資料夾, 找到 castle.obj 和 castle.mtl.
請緊記, castle 這個 立體模型, 需要兩個檔案, 分別是 castle.obj 和 castle.mtl.
-----------------------
就如先前的教學一般, 讀者們, 你, 辛苦的把教學看完之後, 到底得到什麼呢?
就是... 一份功課...
smooth.zip 的 data 資料夾內, 有很多 .obj 檔, 試試不要繪畫 castle.obj, 改為繪畫其他呀. 還有, .obj 檔, 其實是頗多人應用的立體模型檔案格式, 這也意味著你可以在網上找到好些 .obj 檔.
( 當然, 最實在的, 還是自己會用 3D Max 或 Maya 去畫立體模型 )
---------------------
在 http://www.xmission.com/~nate/smooth.html 之內, 有一個 link
http://www.xmission.com/~nate/smooth/smooth.zip
這個 zip 之內, 有兩個檔案, glm.h 和 glm.c, 把它解壓出來到你的專案資料夾, 然後把 glm.c 更名成 glm.cpp, 然後把 glm.h 和 glm.cpp 都加到你的專案.
-------------------
所謂 display list, 實質上只是 OpenGL 順序的指令記錄而已, 這個沒什麼特別的, 但是對於簡化程式, 有很大的幫助的, 因為只要把 立體模型資料 錄制成 display list 後, 用一句 glCallList() 就可以把 立體模型 晝出來.
display list 只要錄制一次就可以了, 所以錄制 display list 一般會放在程式開頭完成.
------------------
一個小修正,
glm.h 內的 #include <GL/glut.h> 要改成為 #include "glut.h"
不然就會出現 "No such file or directory" 的問題.
---------------- |
|