2023年3月29日 星期三

突然沒有聲音的小葉老師教電腦圖學 Week07 貼圖 Texture

 Week07


說明: 大家早安,我是葉正聖老師。昨天早上上課上到11點時, 突然沒有聲音, 沒辦法上課。

症狀與就診: 先喉嚨不舒服,週一去看醫生。但週二上課用盡生命點數, 11點就沒聲音了。週二再看醫生, 有換藥, 希望讓聲帶儘量恢復。)

解釋細節: 停止講話20小時後,有恢復一點聲音。但是只要再講2個小時,就會突然沒聲音。所以今天講話會很輕、很小聲、很溫柔。

今天的上課的主題, 與貼圖相關

0. 公布 T-R-T 小考成績

1. 主題: 貼圖 Texture

2. 主題: OpenCV

3. 貼圖 15行程式碼

4. 實作 glTexCoord2f(tx, ty) 貼圖座標

一開始上課前, 先介紹畢業3年的學姐傳訊息說, 在銘傳學電腦圖學對她現在的幫助。


step01-1

step01-1_利用上課的教材 jsyeh.org/3dcg10 下載今天的程式 Texture.exe 裡面會去讀圖檔, 並讓大家示範貼圖的一些細節。第一個細節是 glColor3f(r,g,b)的結果, 會與貼圖的結果混在一起。我們已經熟悉glVertex3f(x,y,z)是畫3D點的座標, 在畫之前, 可設定對應的貼圖座標 glTexCoord2f(tx, ty) 而這些程式碼,會放在 glBegin()程 glEnd()中間






















step01-2

step01-2_想要繼續了解貼圖的運作方式, 所以試著改一個頂點的貼圖座標。如果超過0...1範圍的話, 也會有圖, 目前是用重覆的方式呈現。同時請觀察,四邊形其實會被拆解成2個3角形畫出來。在3D的世界, 圖學都是用3角形來畫, 又快又好, 像 Unity, 3dsMax, 底層的OpenGL等。但人類理解的世界, 4邊形比較好用, 人類好理解, 所以Maya用4邊形。只是匯入遊戲後, 還是3角形在畫














step01-3

step01-3_在範例裡, 也可切換貼圖的矩陣Matrix, 這時候 glTranslatef() glRotatef() glScalef()就都會套用到貼圖的座標計算裡。接下來老師複習期中考的10行 OpenGL程式碼, 方便大家下次第10週上課時考期中考

```cpp

1.  glPushMatrix(); //備份矩陣 現在有90分

2.    glTranslatef( x, y, z);//移動

3.    glRotatef(角度, x, y, z);//轉動

4.    glScalef(x, y, z);//縮放

5.    glBegin(GL_POLYGON); //開始畫(多邊形)

6.      glColor3f(r,g,b); //色彩

7.      glNormal3f(nx, ny, nz);//打光的法向量

8.      glTexCoord2f(tx, ty);//貼圖座標

9.      glVertex3f(x,y,z);//頂點

10.   glEnd();//結束畫

11. glPopMatrix(); //還原矩陣

```









step02-1

step02-1_為了要做貼圖, 我們需要將圖片讀入。有很多讀圖的方法, 最好的讀圖的方法 OpenCV 用舊版 OpenCV 2.1 在桌面,請點葉正聖老師上課軟體, 安裝 OpenCV-2.1.0-win32-vs2008.exe 這個程式, 第2步 Add PATH 一定要設, 用原來的目錄 C的OpenCV2.1目錄。請把 CodeBlocks重開!!!要寫人生中第一個 OpenCV程式, 最常遇到「設定出錯」的問題。設定法: Setting-Compiler, 有3個咒語要下, Search directory搜尋的目錄(Compiler include, linker lib), 及 Linker setting cv210 cxcore210 highgui210


1. Compiler: C:\OpenCV2.1\include

2. Linker: C:\OpenCV2.1\lib

3. 在 Linker setting裡, 要加 3個名字: cv210 cxcore210 highgui210 要很小心,不要拼錯了

































step02-2

## step02-2_最簡單的三行程式碼,使用 CodeBlocks File-New-Empty空白檔案, 存檔成 week07-1_opencv_cvLoadImage_cvShowImage.cpp 注意副檔名要 .cpp 不能是 .c 。寫下下面3行程式。記得把你的圖檔放在程式執行的同一個目錄裡, 圖的副檔名 要和程式裡一樣。這樣就會秀圖了。


```cpp

#include <opencv/highgui.h>

int main()

{

    IplImage * img = cvLoadImage("檔名.png");

    cvShowImage("week07", img);

    cvWaitKey(0);

}

```

OpenCV非常好用, 之前老師有寫一個 ResizeCam 的程式, 可以開視訊、利用 mouse wheel 來縮放視窗, 就是用 OpenCV 寫的 https://github.com/jsyeh/ResizeCam












step03-1

step03-1_接下來要在我們的 GLUT專案裡, 使用圖片來貼圖, 安裝好 freeglut 後, 新增GLUT專案 week07-2_myTexture, 程式從 gist.github.com/jsyeh 裡找下 myTexture 的範例, 拿 sample 來用。圖檔比較麻煩, 因為歷史原因, GLUT專案的工作執行目錄藏在 桌面的 freeglut 的 bin裡面, 所以把 earth.jpg 世界地圖的圖檔放在那裡。


```cpp

///Week07-2_myTexture 來自 gist.github.com/jsyeh 裡面 myTexture

///有 sample 可以剪貼,但要小心 earth.jpg 要自己去下載

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

#include <opencv/cv.h>

#include <GL/glut.h>

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

    glutSolidTeapot( 0.3 );

    glutSwapBuffers();

}


int main(int argc, char**argv)

{

    glutInit( &argc, argv );

    glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH);

    glutCreateWindow("week07 texture");


    glutDisplayFunc(display);

    myTexture("earth.jpg");///這個圖檔, 現在不存在

    ///圖檔要放在特別的工作執行目錄


    glutMainLoop();

}

```
























step03-2

step03-2_今天第1節課有教 glTexCoord2f(tx,ty) 的貼圖座標設定, 我們就把那個茶壼的貼圖, 把它改成有貼圖的部分。




```cpp

void display()

{

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    ///glutSolidTeapot( 0.3 );

    glBegin(GL_POLYGON);

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

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

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

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

    glEnd();

    glutSwapBuffers();

}

```




step03-3

step03-3_要做出會旋轉的世界地球,在 gist.github.com的jsyeh找到myEarth的範例,把它拿來用, 要記得把圖檔放在工作執行目錄(以原本的GLUT專案為例,會在 freeglut的bin目錄裡。檔名改成 earth.jpg 就可以看到地球在旋轉了。


```cpp

///Week07-3_myEarth, 來自 gist.github.com/jsyeh 的 myEarth

///把程式最下面的 myEarth.jpg 改成你的 earth.jpg

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

#include <opencv/cv.h>

#include <GL/glut.h>

GLUquadric * sphere = NULL;///一個指到二次曲面的指標

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

    glPushMatrix();

        glRotatef(angle, 0,-1,0);

        glRotatef(90, 1,0,0);

        gluQuadricTexture(sphere, 1);

        gluSphere(sphere, 1, 30, 30);///glutSolidTeapot(0.3);

    glPopMatrix();

    glutSwapBuffers();

    angle++;

}

int main(int argc,char**argv)

{

    glutInit(&argc,argv);

    glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH);

    glutCreateWindow("week10 texture background");


    glutIdleFunc(display);

    glutDisplayFunc(display);

    myTexture("earth.jpg");

    sphere = gluNewQuadric();

    glEnable(GL_DEPTH_TEST);


    glutMainLoop();

}

```







step03-4

step03-4_使用Git指令上傳GitHub


- 0. 安裝 Git 再開啟 Git Bash

- 1. cd desktop 進入桌面 git clone https://網址 , 再 cd 2023graphicsa

- 2. start .   (注意那個點)開啟檔案總管, 整理你的程式(有兩個目錄、1個獨立的.cpp檔)

- 3. git add .    (注意那個點)加到帳冊

- 4.0. git config --global user.email jsyeh@mail.mcu.edu.tw

- 4.0. git config --global user.name jsyeh

- 4.1 git commit -m week07

- 5. git push


沒有留言:

張貼留言