2022年5月3日 星期二

雪⛄電腦圖學筆記11~

  2022/5/3 第十一周 

主題 : glm 模型

1. 安裝freeglut 和 OpenCV2.1(+咒語)

2. 開GLUT專案+把鋼彈模型的模式檔放入

     (1)把下載的gundam.zip的模式檔 data裡的檔案 放到 桌面/freeglut/bin/data/裡面

     (2) 把week09_opencv的範例複製到week10_gundam使用

          #include <opencv/highgui.h>

          int main()

         {

               IplImage * img = cvLoadImage("data/Diffuse.jpg");

               cvShowImage("week11", img);

               cvWaitKey(0);

          }



3. 實作glm模型: 把茶壺貼上Gundam的貼圖
    (1)複製上禮拜的myTexture 、 display 跟 main
    #include <GL/glut.h>
    #include <opencv/highgui.h>
    #include <opencv/cv.h>
    int myTexture(char * filename)
    {
        IplImage * img = cvLoadImage(filename);
        cvCvtColor(img,img, CV_BGR2RGB);
        glEnable(GL_TEXTURE_2D);
        GLuint id;
        glGenTextures(1, &id);
        glBindTexture(GL_TEXTURE_2D, id);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, img->width, img->height, 0, GL_RGB,  GL_UNSIGNED_BYTE, img->imageData);
        return id;
    }
    void display()
    {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glutSolidTeapot(0.3);
        glutSwapBuffers();
    }
    int main(int argc, char** argv)
    {
        glutInit(&argc, argv);
        glutInitDisplayMode( GLUT_DOUBLE | GLUT_DEPTH);
        glutCreateWindow("week11 gundam");

        glutDisplayFunc(display);
        myTexture("data/Diffuse.jpg");    ///這邊要修改!!

        glutMainLoop();
    }

4. 把鋼彈模型讀進來 並 畫出來
    (1) 在jsyeh.org/3dcg10 下載 source.zip ,將source.zip裡面的glm.h、glm.c(改成glm.cpp) 和 transformation.c  放到week11_gundam裡(當main.cpp的鄰居)
    (2) 在week11_gundam專案的左邊workspace的week11_gundam那裡按右鍵Add file...,選glm.cpp


    (3)加上讀入gundam模型的程式碼
    #include <GL/glut.h>
    #include <opencv/highgui.h>
    #include <opencv/cv.h>
    #include "glm.h"
    GLMmodel * pmodel = NULL;   ///空指標
    int myTexture(char * filename)
    {
        IplImage * img = cvLoadImage(filename);
        cvCvtColor(img,img, CV_BGR2RGB);
        glEnable(GL_TEXTURE_2D);
        GLuint id;
        glGenTextures(1, &id);
        glBindTexture(GL_TEXTURE_2D, id);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, img->width, img->height, 0, GL_RGB,  GL_UNSIGNED_BYTE, img->imageData);
        return id;
    }
    void display()
    {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        ///glutSolidTeapot(0.3);
        if( pmodel == NULL){   ///如果是空指標(第5行),表示模型沒裝好,所以要讀模型(只會跑一次,裝好了就不會再裝一次)
           pmodel = glmReadOBJ("data/Gundam.obj"); ///讀模型
            glmUnitize( pmodel );   ///換算成Unit單位大小(-1...+1)
            glmFacetNormals( pmodel );   ///重新計算模型的"面"的法向量
            glmVertexNormals( pmodel , 90 );   ///重新計算模型的"頂點"的法向量
        }
        glmDraw( pmodel, GLM_TEXTURE );  ///有模型後,把pmodel畫出來(面、貼圖)   ///25~31行其實是從transformation.c裡抄來的!
        glutSwapBuffers();
    }
    int main(int argc, char** argv)
    {
        glutInit(&argc, argv);
        glutInitDisplayMode( GLUT_DOUBLE | GLUT_DEPTH);
        glutCreateWindow("week11 gundam");

        glutDisplayFunc(display);
        myTexture("data/Diffuse.jpg");    ///這邊要修改!!

        glutMainLoop();
    }


    (4) 模型貼圖怪怪的......將圖上下顛倒
     --->  去小畫家把data/Diffuse.jpg 垂直翻轉,再將week11_gundam跑一次

    (5) 模型好像被壓扁了......因為還沒將3D的前後深度測試
     --->   在main函式裡加上glEnable(GL_DEPTH_TEST);

    (6) 讓模型轉起來!!
        #include <GL/glut.h>
        #include <opencv/highgui.h>
        #include <opencv/cv.h>
        #include "glm.h"
        GLMmodel * pmodel = NULL;///空指標
        int myTexture(char * filename)
        {
            IplImage * img = cvLoadImage(filename);
            cvCvtColor(img,img, CV_BGR2RGB);
            glEnable(GL_TEXTURE_2D);
            GLuint id;
            glGenTextures(1, &id);
            glBindTexture(GL_TEXTURE_2D, id);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, img->width, img->height, 0, GL_RGB,  GL_UNSIGNED_BYTE, img->imageData);
        return id;
    }
    float angle=0;
    void display()
    {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        ///glutSolidTeapot(0.3);
        if( pmodel == NULL){///如果是空指標(第5行),表示模型沒裝好,所以要讀模型(只會跑一次)
            pmodel = glmReadOBJ("data/Gundam.obj"); ///讀模型
            glmUnitize( pmodel ); ///換算成Unit單位大小(-1...+1)
            glmFacetNormals( pmodel ); ///重新計算模型的"面"的法向量
            glmVertexNormals( pmodel , 90 ); ///重新計算模型的"頂點"的法向量
        }

        glPushMatrix();
            glRotatef(angle, 0,1,0);
            glmDraw( pmodel, GLM_TEXTURE );///有模型後,把pmodel畫出來(面、貼圖)
        glPopMatrix();

        glutSwapBuffers();
        angle +=1;
    }
    int main(int argc, char** argv)
    {
        glutInit(&argc, argv);
        glutInitDisplayMode( GLUT_DOUBLE | GLUT_DEPTH);
        glutCreateWindow("week11 gundam");

        glutIdleFunc(display);
        glutDisplayFunc(display);
        myTexture("data/Diffuse.jpg");    ///這邊要修改!!
        glEnable(GL_DEPTH_TEST);

        glutMainLoop();
    }



5. 如何使用Maya匯出3D模型檔(OBJ) + 切模型(分成頭、身體、腳...)
----> google搜尋: maya obj 檔案
ex頭: 將body.mtl body.obj放入freeglut/bin/data裡 ,在改讀模型那行-->data/body.obj 就可以讀出模型了!

###如何讀出一個人體模型: 先用maya將頭、身體、腳(可以拆成更細部的關節)各做成一個obj檔,在將所有的obj檔案放入freeglut/bin/data裡,就可以讀入各個關節了

6. 對特定軸做旋轉(轉手的部分)
   #include <GL/glut.h>
    void hand(){   ///畫手
        glColor3f(0,1,0);
        glutSolidTeapot(0.2);
    }
    void body(){   ///畫身體
        glColor3f(1,1,0);
        glutSolidTeapot(0.3);
    }
    float angle=0;
    void display()
    {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        body();
        glPushMatrix();
            glTranslatef(0.5,0.2,0);
            glRotatef(angle, 0,0,1);
            glTranslatef(0.3,0,0);
            hand();
        glPopMatrix();

        glutSwapBuffers();
        angle +=1;
     }
    int main(int argc, char** argv)
    {
        glutInit(&argc, argv);
        glutInitDisplayMode( GLUT_DOUBLE | GLUT_DEPTH);
        glutCreateWindow("week11_TRT");

        glutIdleFunc(display);

        glutDisplayFunc(display);
        glutMainLoop();
    }


沒有留言:

張貼留言

VERY BEAUTIFUL, VERY POWERFUL

一.     一樣先安裝且設定好freeglut,OpecCV, 開啟CodeBlocks建立新專案 week11_gundam,                 把 MyGundam.zip下載解壓縮後的data資料夾放到freeglut/bin裡面 把week09_openc...