2018年6月13日 星期三

Week07 打光

(1)用Light Material.exe 來了解打光
1.從http://jsyeh.org/3dcg10下載 data.zip,windows.zip和glut.dll三個(照之前的作法Week04)
快速簡單步驟回想:
             1.先到http://jsyeh.org/3dcg10下載data.zipwindows.zipglut32.dll 這三個檔案
             2.data.zipwindows.zip 解壓縮
             3.壓縮好後,將glut32.dll data 複製到windows裡
2.打開windows裡頭的Light Material.exe,就可以使用


功能:



(2)在專案檔的程式碼內讀入模型

   1.開啟CodeBlocks新增GLUT專案



   2.將從http://jsyeh.org/3dcg10下載 Source.zip解壓縮後,將裡面的glm.c改成glm.cpp,並將glm.cpp 和glm.h複製剛剛新稱的專案檔裡



   3.將glm.cpp匯入專案檔裡



   4.到程式碼裡要在外部加上#include"glm.h"與宣告一個空指標 GLMmodel*pmodel=NULL;



   5.打開Source資料夾內 的 transformation.c,要複製起來並貼回GLUT專案main.cpp內(為了裏頭的讀取模型和畫模型的程式碼)




程式碼:
 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);

   6.將data資料夾複製到freeglut的bin資料夾內



   7.執行後就成功



(3)匯入多個模型來模擬關節的轉動
   1.將多餘的程式碼刪除!        只剩下剛剛匯入模型的部分!!

程式碼:

#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("QWQ");

    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.將原本display函式做些修改(先用用保時捷模型來當手臂)

程式碼:

#include"glm.h"
GLMmodel *pmodel=NULL;
int angle;
static void display(void)
{
    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();
}
//光源的設定
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("QWQ");

    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;
}




3.新增一個motion函式(目的用滑鼠來改變手臂的旋轉角度)


程式碼:
#include"glm.h"
GLMmodel *pmodel=NULL;
int angle;
static void display(void)
{
    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();
}
void motion(int x,int y)
{
    angle=x;//改變角度
    glutPostRedisplay();
//重新畫畫面
}
//光源的設定
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("QWQ");

    glutDisplayFunc(display);
    glutMotionFunc(motion);
    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;
}


4.滑鼠按住左鍵,模型就會左右旋轉!!







沒有留言:

張貼留言