2021年5月20日 星期四

JOJO的電腦圖學_week13

  210517 week13

                                                                        🔔❤️

首先先來複習個放背景圖片!

還有超時尚鋼彈茶壺!


首先先設定好openCV

可以參考我的💁第八週




然後開啟一個GLUT project












freeglut>bin>freeglut.dll
老師給的gundam還沒切開>Diffuse圖檔
自己找的背景圖:命名為bg
的三個檔案放進week13 gundam資料夾中












working_dir後的網址改成"."
(我沒有Notepad++所以先用記事本開啟😂)

可以參考我的💁第十二週
https://2021graphics.blogspot.com/2021/05/jojoweek12.html

放上程式碼以及正確的圖片名稱
就能得到一個時尚的鋼彈茶壺以及你也可以君

 (你也可以君介紹:2020程式設計二,孤獨月宮的花園week04)
#include <opencv/highgui.h> ///使用 OpenCV 2.1 比較簡單, 只要用 High GUI 即可
#include <opencv/cv.h>
#include <GL/glut.h>

GLuint id1, id2; ///TODO:增加2個 貼圖ID
int myTexture(char * filename)
{
    IplImage * img = cvLoadImage(filename); ///OpenCV讀圖
    cvCvtColor(img,img, CV_BGR2RGB); ///OpenCV轉色彩 (需要cv.h)
    glEnable(GL_TEXTURE_2D); ///1. 開啟貼圖功能
    GLuint id; ///準備一個 unsigned int 整數, 叫 貼圖ID
    glGenTextures(1, &id); /// 產生Generate 貼圖ID
    glBindTexture(GL_TEXTURE_2D, id); ///綁定bind 貼圖ID
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); /// 貼圖參數, 超過包裝的範圖T, 就重覆貼圖
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); /// 貼圖參數, 超過包裝的範圖S, 就重覆貼圖
    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);

    glBindTexture(GL_TEXTURE_2D, id1);
    glutSolidTeapot(0.3);

    glBindTexture(GL_TEXTURE_2D, id2);
    glBegin(GL_POLYGON);
        glTexCoord2f( 0, 0 ); glVertex2f( -1, -1 );
        glTexCoord2f( 0, 1 ); glVertex2f( -1, +1 );
        glTexCoord2f( 1, 1 ); glVertex2f( +1, +1 );
        glTexCoord2f( 1, 0 ); glVertex2f( +1, -1 );
    glEnd();
    glutSwapBuffers();
}
int main(int argc, char** argv)
{
    glutInit( &argc, argv );
    glutInitDisplayMode( GLUT_DOUBLE | GLUT_DEPTH );
    glutCreateWindow(" 我是JOJO ");
    glutDisplayFunc(display);

    id1 = myTexture("Diffuse.jpg");///放鋼彈的貼圖
    id2 = myTexture("bg.jpg");///背景
    glEnable(GL_DEPTH_TEST);
    glutMainLoop();
}

變出真正鋼彈的部分
將source資料夾中的

glm.c
glm.h
transformation.c

放進week13 gundam資料夾中












把glm.c改成glm.cpp


將gl
m.cpp匯入

可以參考我的💁第十一週
https://2021graphics.blogspot.com/2021/05/jojoweek11.html

把transformation.c打開,把反黑那行程式碼複製下來
(好我下次會去下載Notepad++😂)
void
drawmodel(void)
{
    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);
}

貼上&加一行
👉 GLMmodel * pmodel= NULL;


更改反黑那一行
👉drawmodel();
更改反黑那一行(圖片名稱)
👉gundam.obj
將 gundam還沒切開 資料夾中的

Gundam.mtl
Gundam.obj

放進week13 gundam資料夾中












更改反黑那一行
👉glmDraw(pmodel, GLM_SMOOTH | GLM_TEXTURE);












還有更改很上面的這行(對差點忘記😅)
👉#include"glm.h"///使用外掛












就出現鋼彈啦!(等等這貼圖是反的吧😂)

所以我們要把圖反過來~

用小畫家開啟Diffuse.jpg
將圖片垂直翻轉












好多了!












現在要讓鋼彈轉過來

加上好多行😀
👉float angle=0;

👉glPushMatrix();   ///開始畫鋼彈
      glRotatef(angle,0,1,0);   ///軸心旋轉
      drawmodel();
   glPopMatrix();

👉angle++;

👉glutIdleFunc(display);

鋼彈會轉動了呢!







#include <opencv/highgui.h> ///使用 OpenCV 2.1 比較簡單, 只要用 High GUI 即可

#include <opencv/cv.h>

#include <GL/glut.h>

#include"glm.h"///使用外掛

GLMmodel * pmodel= NULL;///glut模型的指標

void

drawmodel(void)

{

    if (!pmodel) {

pmodel = glmReadOBJ("gundam.obj");

if (!pmodel) exit(0);

glmUnitize(pmodel);

glmFacetNormals(pmodel);

glmVertexNormals(pmodel, 90.0);

    }

    glmDraw(pmodel, GLM_SMOOTH | GLM_TEXTURE);

}

GLuint id1, id2; ///TODO:增加2個 貼圖ID

int myTexture(char * filename)

{

    IplImage * img = cvLoadImage(filename); ///OpenCV讀圖

    cvCvtColor(img,img, CV_BGR2RGB); ///OpenCV轉色彩 (需要cv.h)

    glEnable(GL_TEXTURE_2D); ///1. 開啟貼圖功能

    GLuint id; ///準備一個 unsigned int 整數, 叫 貼圖ID

    glGenTextures(1, &id); /// 產生Generate 貼圖ID

    glBindTexture(GL_TEXTURE_2D, id); ///綁定bind 貼圖ID

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); /// 貼圖參數, 超過包裝的範圖T, 就重覆貼圖

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); /// 貼圖參數, 超過包裝的範圖S, 就重覆貼圖

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


    glBindTexture(GL_TEXTURE_2D, id1);

      glPushMatrix();   ///開始畫鋼彈

        glRotatef(angle,0,1,0);   ///軸心旋轉

        drawmodel();

    glPopMatrix();


    glBindTexture(GL_TEXTURE_2D, id2);

    glBegin(GL_POLYGON);

        glTexCoord2f( 0, 0 ); glVertex2f( -1, -1 );

        glTexCoord2f( 0, 1 ); glVertex2f( -1, +1 );

        glTexCoord2f( 1, 1 ); glVertex2f( +1, +1 );

        glTexCoord2f( 1, 0 ); glVertex2f( +1, -1 );

    glEnd();

    glutSwapBuffers();

    angle++;

}

int main(int argc, char** argv)

{

    glutInit( &argc, argv );

    glutInitDisplayMode( GLUT_DOUBLE | GLUT_DEPTH );

    glutCreateWindow("我是JOJO");

    glutDisplayFunc(display);

    glutIdleFunc(display);


    id1 = myTexture("Diffuse.jpg");///放鋼彈的貼圖

    id2 = myTexture("bg.jpg");///背景

    glEnable(GL_DEPTH_TEST);

    glutMainLoop();

}


改 GL_DEPTH_TEST的時機...

再加上兩行試試吧!😀(紅色部分)
👉glDisable(GL_DEPTH_TEST);///畫背景時,不要有3D深度測試
👉glEnable(GL_DEPTH_TEST);///再開3D深度,畫模型








對還可以更改Z軸

會變成醬😂







只叫出關節的部分

將 gundam 資料夾中的


arm1.mtl
arm1.obj
arm2.mtl
arm2.obj
body.mtl
body.obj
hand1.mtl
hand1.obj
hand2.mtl
hand2.obj

放進week13 gundam資料夾中







把 gundam 資料夾中的main.cpp中的這幾行複製

GLMmodel * body=NULL;

GLMmodel * arm1=NULL, * arm2=NULL;

GLMmodel * hand1=NULL, * hand2=NULL;



整理一下變醬(紅色部分記得要改)
GLMmodel * body=NULL;
GLMmodel * arm1=NULL;
GLMmodel * arm2=NULL;
還有這部分
body=glmReadOBJ("body.obj");
arm1=glmReadOBJ("arm1.obj");
arm2=glmReadOBJ("arm2.obj");











下面加這三行

pmodel = glmReadOBJ("gundam.obj");///完整的大模型

float dimensions[3];

glmDimensions(pmodel,dimensions);///取出長寬高


用gimDimensions()去查模型的長寬高
再以長寬高,縮小模型
把drawmodel();註解掉
加入glmDraw(body, GLM_SMOOTH | GLM_TEXTURE);

 加入這一行
👉glTranslatef(0,-1,0);
好我不玩😂
把 glRotatef(angle,0,1,0);   註解掉
就不會轉動啦!





加入這一行
👉glmDraw(arm1, GLM_SMOOTH | GLM_TEXTURE);
把手臂放進來


最後讓它旋轉並調整旋轉軸!!!

#include <opencv/highgui.h> ///使用 OpenCV 2.1 比較簡單, 只要用 High GUI 即可
#include <opencv/cv.h>
#include <GL/glut.h>
#include"glm.h"///使用外掛
GLMmodel * pmodel= NULL;///glut模型的指標
GLMmodel * body=NULL;
GLMmodel * arm1=NULL;
GLMmodel * arm2=NULL;
///GLMmodel * hand1=NULL;
///GLMmodel * hand2=NULL;
void
drawmodel(void)
{
    if (!pmodel) {
pmodel = glmReadOBJ("body.obj");
if (!pmodel) exit(0);
glmUnitize(pmodel);
glmFacetNormals(pmodel);
glmVertexNormals(pmodel, 90.0);
    }
    glmDraw(pmodel, GLM_SMOOTH | GLM_TEXTURE);
}
GLuint id1, id2; ///TODO:增加2個 貼圖ID
int myTexture(char * filename)
{
    IplImage * img = cvLoadImage(filename); ///OpenCV讀圖
    cvCvtColor(img,img, CV_BGR2RGB); ///OpenCV轉色彩 (需要cv.h)
    glEnable(GL_TEXTURE_2D); ///1. 開啟貼圖功能
    GLuint id; ///準備一個 unsigned int 整數, 叫 貼圖ID
    glGenTextures(1, &id); /// 產生Generate 貼圖ID
    glBindTexture(GL_TEXTURE_2D, id); ///綁定bind 貼圖ID
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); /// 貼圖參數, 超過包裝的範圖T, 就重覆貼圖
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); /// 貼圖參數, 超過包裝的範圖S, 就重覆貼圖
    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);

    glBindTexture(GL_TEXTURE_2D, id1);
      glPushMatrix();   ///開始畫鋼彈
      glTranslatef(0,-1,0);
       /// glRotatef(angle,0,1,0);   ///軸心旋轉
        ///drawmodel();
        glmDraw(body, GLM_SMOOTH | GLM_TEXTURE);
        glPushMatrix();
        glTranslatef(-0.35,+0.68+1,0);
        glRotatef(angle,0,0,1);
        glTranslatef(+0.35,-0.68-1,0);
        glmDraw(arm1, GLM_SMOOTH | GLM_TEXTURE);
        glPopMatrix();

    glPopMatrix();

    glBindTexture(GL_TEXTURE_2D, id2);

    glBegin(GL_POLYGON);
        glTexCoord2f( 0, 0 ); glVertex2f( -1, -1 );
        glTexCoord2f( 0, 1 ); glVertex2f( -1, +1 );
        glTexCoord2f( 1, 1 ); glVertex2f( +1, +1 );
        glTexCoord2f( 1, 0 ); glVertex2f( +1, -1 );
    glEnd();
    glutSwapBuffers();
    angle++;
}
int main(int argc, char** argv)
{
    glutInit( &argc, argv );
    glutInitDisplayMode( GLUT_DOUBLE | GLUT_DEPTH );
    glutCreateWindow("我是JOJO");
    glutDisplayFunc(display);
    glutIdleFunc(display);

    id1 = myTexture("Diffuse.jpg");///放鋼彈的貼圖
    id2 = myTexture("bg.jpg");///背景
    body=glmReadOBJ("body.obj");
    arm1=glmReadOBJ("arm1.obj");
    arm2=glmReadOBJ("arm2.obj");

    pmodel = glmReadOBJ("gundam.obj");///完整的大模型
    float dimensions[3];
    glmDimensions(pmodel,dimensions);///取出長寬高
     glmScale(pmodel, 2.0/dimensions[1]);
     glmScale(body,   2.0/dimensions[1]);
     glmScale(arm1,   2.0/dimensions[1]);
     glmScale(arm2,   2.0/dimensions[1]);

    glEnable(GL_DEPTH_TEST);
    glutMainLoop();
}


如果喜歡我的部落格的話
請幫我按右上角的愛心(根本按不下去)
也可以按右上角的小鈴鐺(這也按不下去)
才不會錯過我的更新哦!😉

沒有留言:

張貼留言

Week18期末作業(橘貓的跳舞熊熊)

 期末作業(橘貓的跳舞熊熊) 影片: https://youtu.be/R89tptMaQZw 程式碼: #include <opencv/highgui.h> #include <opencv/cv.h> #include <GL/glut.h...