2018年4月13日 星期五

Week07_黃偉愷

了解如和使用 Light Material

(1) 從 http://www.cmlab.csie.ntu.edu.tw/~jsyeh/3dcg10/
     下載 data.zip, windows.zip, glut32.dll 三個

(2) 打開 Light Material 後,在左上方 Screen-space view 上按右鍵可以更改模型

(3) 在下方的 World-space view 上按右鍵可以更改模型的材質

(4) 上方的部份主要是一些針對光源的設定,pos為光源位置的設置,第四個參數代表光源種類,1是點光源,0是平行光,ka 的 a 代表 Ambient 無所不在的光,kd 的 d 代表 Diffuse(擴散)  , s  代表 Specular(鏡面)

在程式碼內讀入模型


(1) 先新增一個 glut 專案
(2) 將 source 裡的 glm.c 改名為 glm.cpp 讓他變成 c++ 檔案

(3) 將 glm.cpp 和 glm.h 複製到我們剛剛新增的 glut 專案的資料夾內

(4) 將 glm.cpp 匯入專案內



(5)記得要在外部 #include"glm.h" 還有宣告一個空指標 GLMmodel *pmodel=NULL;

(6) 打開 source 資料夾內的 transformation.c 檔案,我們要從裡面拿到讀取模型和畫模型的程式碼,並將其複製下來


Code

if (!pmodel) {
pmodel = glmReadOBJ("data/porsche.obj");//模型所在的位置路徑
if (!pmodel) exit(0);
glmUnitize(pmodel);
glmFacetNormals(pmodel);
glmVertexNormals(pmodel, 90.0);
    }

    glmDraw(pmodel, GLM_SMOOTH | GLM_MATERIAL);
//將模型畫出來

(7) 將我們剛剛複製的程式碼貼回我們的 glut 專案 main.cpp 內然後將之前下載過的 data 資料夾複製到 freeglut -> bin 資料夾內後回到我們的專案內 Build and run




(8) 我們會發現我們已經成功的將 data 資料夾內的保時捷模型匯入我們的專案裡囉!


匯入多個模型來模擬機器人關節的轉動

(1) 將多餘的程式碼刪除只留下我們剛剛匯入模型的部份

Code

#include"glm.h"
GLMmodel *pmodel=NULL;

static void display(void)
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glColor3d(1,0,0);

    glPushMatrix();
            if (!pmodel) {
            pmodel = glmReadOBJ("data/porsche.obj");
            if (!pmodel) exit(0);
            glmUnitize(pmodel);
            glmFacetNormals(pmodel);
            glmVertexNormals(pmodel, 90.0);
            }
            glmDraw(pmodel, GLM_SMOOTH | GLM_MATERIAL);
    glPopMatrix();
    glutSwapBuffers();
}

//光源的設定
const GLfloat light_ambient[]  = { 0.0f, 0.0f, 0.0f, 1.0f };
const GLfloat light_diffuse[]  = { 1.0f, 1.0f, 1.0f, 1.0f };
const GLfloat light_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f };
const GLfloat light_position[] = { 2.0f, 5.0f, 5.0f, 0.0f };
//Material 的設定
const GLfloat mat_ambient[]    = { 0.7f, 0.7f, 0.7f, 1.0f };
const GLfloat mat_diffuse[]    = { 0.8f, 0.8f, 0.8f, 1.0f };
const GLfloat mat_specular[]   = { 1.0f, 1.0f, 1.0f, 1.0f };
const GLfloat high_shininess[] = { 100.0f };

/* Program entry point */

int main(int argc, char *argv[])
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);

    glutCreateWindow("Week 07 model with Lighting");


    glutDisplayFunc(display);

    glEnable(GL_CULL_FACE);//背面不要畫
    glCullFace(GL_BACK);

    glEnable(GL_DEPTH_TEST);//3D測試打開,才會有3D效果
    glDepthFunc(GL_LESS);//前後的3D深度的比較方法

    glEnable(GL_LIGHT0); //開 Light 0
    glEnable(GL_NORMALIZE);//自動做法向量normalize
    glEnable(GL_COLOR_MATERIAL);//要使用material
    glEnable(GL_LIGHTING);//開 Lighting 打光系統啟動

    glLightfv(GL_LIGHT0, GL_AMBIENT,  light_ambient);// Light 0 的設定
    glLightfv(GL_LIGHT0, GL_DIFFUSE,  light_diffuse);
    glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
    glLightfv(GL_LIGHT0, GL_POSITION, light_position);

    glMaterialfv(GL_FRONT, GL_AMBIENT,   mat_ambient);//Material 的設定
    glMaterialfv(GL_FRONT, GL_DIFFUSE,   mat_diffuse);
    glMaterialfv(GL_FRONT, GL_SPECULAR,  mat_specular);
    glMaterialfv(GL_FRONT, GL_SHININESS, high_shininess);

    glutMainLoop();

    return EXIT_SUCCESS;

}

(2) Build and run 看效果

(3) 如果沒有做深度測試 ( glEnable(GL_DEPTH_TEST) ) 可能會造成破圖的情況發生

(4) 將原本 display 函式的內容做些修改,用另一個保時捷模型來當手
Code
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glColor3d(1,0,0);

    glPushMatrix();
           // glRotatef(angle,0,1,0);
            if (!pmodel) {
            pmodel = glmReadOBJ("data/porsche.obj");
            if (!pmodel) exit(0);
            glmUnitize(pmodel);
            glmFacetNormals(pmodel);
            glmVertexNormals(pmodel, 90.0);
            }
            glPushMatrix();
                glmDraw(pmodel, GLM_SMOOTH | GLM_MATERIAL);//畫身體
                glPushMatrix();
                    glTranslatef(0.5,0,0);
                    glRotatef(angle,0,0,1);//(2) 轉動
                    glTranslatef(0.4,0,0);//(1)移動旋轉軸到中心
                    glmDraw(pmodel, GLM_SMOOTH | GLM_MATERIAL);//畫身體
                glPopMatrix();
            glPopMatrix();
    glPopMatrix();
    glutSwapBuffers();

(4) 執行看效果

(5) 新增一個 motion 函式讓我們可以透過滑鼠來改變手臂的旋轉角度

Code
void motion(int x,int y)
{
    angle=x;//改變角度
    glutPostRedisplay();//重新畫畫面
}
(6) 滑鼠按住左鍵左右移動就可以看到效果囉!




沒有留言:

張貼留言