顯示具有 09160455_黃榆萱 標籤的文章。 顯示所有文章
顯示具有 09160455_黃榆萱 標籤的文章。 顯示所有文章

2022年6月14日 星期二

Ucc的week17上課筆記~

#Week17
## 電腦圖學 Week17 2022-06-14
```
1. 期末作品繳交方式
2. 期末作品評分方式
3. 網友問 push matrix 和 pop matrix 事件
4. 整學期大複習-示範期末作品怎麼做
```
## 怎把期末作業做出來
<<<環境的部分
```
1.開啟codeblocks
2.File->New->project->GLUT專案->打上專案名稱
3.Q:如何改變工作目錄?
   A1:點擊專案的main按右鍵->Notepad++
   A2:找到working_dir將路徑改成小數點
   A3:複製freeglut裡的dll檔案貼上到專案檔案裡
4.opencv的設定()


5.貼上10行程式碼
```
## 程式碼的部分
>>>基本十行
```C
#include <GL/glut.h>
 void display()
 {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glColor3f(1,1,0);
    glutSolidTeapot(0.3);

    glutSwapBuffers();
 }
 int main(int argc, char *argv[])//main()主函式 進階版
 {
    glutInit(&argc,argv);//把參數送給glutInit初始化
    glutInitDisplayMode(GLUT_DOUBLE|GLUT_DEPTH);//雙緩衝區+3D深度功能
    glutCreateWindow("第02週的程式喔!!");//開GLUT視窗

    glutDisplayFunc(display);//顯示用的函式

    glutMainLoop();
 }
```
## 打光
<<<函示呼叫
```C
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 };

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 };
```
<<<函示宣告
```C
 glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LESS);

    glEnable(GL_LIGHT0);
    glEnable(GL_NORMALIZE);
    glEnable(GL_COLOR_MATERIAL);
    glEnable(GL_LIGHTING);

    glLightfv(GL_LIGHT0, GL_AMBIENT,  light_ambient);
    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);
    glMaterialfv(GL_FRONT, GL_DIFFUSE,   mat_diffuse);
    glMaterialfv(GL_FRONT, GL_SPECULAR,  mat_specular);
    glMaterialfv(GL_FRONT, GL_SHININESS, high_shininess);
```
## 貼圖
>>>#include <GL/glut.h>,main裡加上myTexture();
```C
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;
}
```
## 帶入3D模型
>>>#include "glm.h"
```C
GLMmodel *(obj檔案的名稱)=NULL;
```
<<<在void display裡加入(一個關節一段)
## 如果模型太大
```
glmScale(模型名稱,大小.0)
```
```C
     if(關節名稱==NULL)
        {
            pmodel=glmReadOBJ("data/關節名稱.obj");
            glmUnitize(關節名稱);
glmFacetNormals(關節名稱);
glmVertexNormals(關節名稱,90);
} glmDraw(關節名稱,GLM_TEXTURE);///劃出模型
glPopMatrix();
```
<<<main裡加上
```C
    glutDisplayFunc(display);///顯示用的函式
    glutIdleFunc(display);
```
## 怎麼辦怎麼立體感沒出來!!!
<<< 在main裡加上
```
 glutInitDisplayMode(GLUT_DOUBLE|GLUT_DEPTH);
```

## 攝影機
```C
void reshape(int w,int h){///不能 整數除
    float ar = (float) w/(float) h;
    glViewport(0,0,w,h);
    glMatrixMode(GL_PROJECTION);///3D變2D
    glLoadIdentity();
    gluPerspective(60,ar,0.1,100);

    glMatrixMode(GL_MODELVIEW);///3D Model+view
    glLoadIdentity();
    gluLookAt(0,0,3, ///eye
              0,0,0, ///center看哪裡
              0,1,0);///up向量
}
```
## main裡加上
```C
 glutReshapeFunc(reshape)
```

## TRT 調整步驟(目前結果)
```
1. 先調整最下面的Translate改變中心點
2.改變Rotate數值改變旋轉角度
3.最後調整最上面的Translate將手臂位置移回原處
```

## 想要移動各個關節(Mouse keyboard)
```C
void myWrite()
{
    if(fout == NULL)fout=fopen("file.txt","w+");

    for(int i = 0;i<20;i++)
    {
        printf("%.1f",angle[i]);///小黑印出來
        fprintf(fout,"%.1f",angle[i]);///檔案印出來
    }///這裡老師沒有fclose
}
void keyboard(unsigned char key,int x,int y)
{
    if(key=='0') angleID=0;
    if(key=='1') angleID=1;
    if(key=='2') angleID=2;
    if(key=='3') angleID=3;
}
void mouse(int button,int state,int x,int y)
{
    oldX=x;
}
void motion(int x,int y)
{
    angle[angleID]+=(x-oldX);
    myWrite();
    oldX=x;
    glutPostRedisplay();
}
```
## main裡要記得宣告!!!
```C

glutMouseFunc(mouse);
glutMotionFunc(motion);
glutKeyboardFunc(keyboard);

```

2022年6月7日 星期二

Ucc的week16上課筆記~

# Week16
 ## 電腦圖學 Week16 2022-06-07
```
1. 主題: 內插、動作內插
2. 主題: 攝影機、運鏡 
3. 實作: gluLookAt()
```
## step01-1 Alpha內插公式    =>   alpha: 0.0~1.0
>>> angle=alpha*新+(1-alpha)*舊
```
ex.
-  alpha:0  =>  舊
-  alpha:0.5  =>半新半就
-  alpha:1  =>新
可以使用Excel or Google Spreadsheet 來做
```

## step01-2 用程式試試看(●´ω`●)ゞ
>>> 使用上週 week15_angles_TRT_again 改動
```C
1.File-New-Project-GLUT專案-week16_interpolation 內插
2.複製程式=>執行=>mouse motion改動作,按s存檔一行關節動作*4次
3.按r之後發現動作不連續
```
## 改造程式碼
```C
1.void myInterpolate(float alpha)
2.一樣按s儲存每個動作
3.按下p可以逐步計算內插,做新舊角度交換
    if(key=='p'){///play
            if(t%30==0) myRead();///介於0.0~1.0
            myInterpolate((t%30)/30.0);
            glutPostRedisplay();
            t++;
        }
=>>動畫變得更順👍👍
```

## step02-1 讓動畫跑得更順(將myInterpolate在timer裡呼叫)
```
1.透過上一節課的程式碼進行修改
2.將原本的一直按著p改成按一次p可以自動重複撥放
3.timer計時器可以設定幾秒撥一次動畫
4.%50的原因是因為這樣計算下來每1秒會跑一格動畫
```
## 目前程式碼
```C
///week15修改自week14_angles_fprintf
///week16_interpolation
#include <GL/glut.h>
#include <stdio.h>
float angle[20],oldX=0;
int angleID=0;
FILE * fout=NULL, * fin = NULL;
void myWrite()
{///每呼叫一次myWrite
    if(fout == NULL)fout=fopen("file.txt","w+");

    for(int i = 0;i<20;i++)
    {
        printf("%.1f ",angle[i]);///小黑印出來
        fprintf(fout,"%.1f ",angle[i]);///檔案印出來
    }///這裡老師沒有fclose
    printf("\n");///小黑印出跳行
    fprintf(fout,"\n");///檔案跳行
}
float NewAngle[20],OldAngle[20];
void myRead()
{
    if(fout!=NULL){fclose(fout); fout=NULL;}
    if(fin==NULL) fin=fopen("file.txt","r");
    for(int i=0;i<20;i++)
    {
        OldAngle[i]=NewAngle[i];///原來新的變舊
        fscanf(fin,"%f",&NewAngle[i]);///得到新角度
        ///fscanf(fin,"%f",&angle[i]);
    }
    glutPostRedisplay();///重劃畫面
}
void myInterpolate(float alpha)
{
    for(int i=0;i<20;i++)
    {
        angle[i]=alpha*NewAngle[i]+(1-alpha)*OldAngle[i];
    }
}
void timer (int t)
{  if(t%50==0) myRead();
    myInterpolate((t%50)/50.0);
    glutPostRedisplay();
    glutTimerFunc(20,timer,t+1);
}
///int t=0;
void keyboard(unsigned char key,int x,int y)
{
    if(key=='p'){///play
            myRead();
            glutTimerFunc(0,timer,0);
        ///if(t%30==0) myRead();///介於0.0~1.0
        ///myInterpolate((t%30)/30.0);
        ///glutPostRedisplay();
        ///t++;
    }
    if(key=='s') myWrite();///調好動作才save存檔
    if(key=='r') myRead();
    if(key=='0') angleID=0;
    if(key=='1') angleID=1;
    if(key=='2') angleID=2;
    if(key=='3') angleID=3;
}
void mouse(int button,int state,int x,int y)
{
    oldX=x;
}
void motion(int x,int y)
{
    angle[angleID]+=(x-oldX);
    ///myWrite();
    oldX=x;
    glutPostRedisplay();
}
 void display()
 {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glColor3f(1,1,1);
    glRectf(0.3,0.5,-0.3,-0.5);

    glPushMatrix();
        glTranslatef(0.3,0.4,0);
        glRotatef(angle[0],0,0,1);
        glTranslatef(-0.3,-0.4,0);
        glColor3f(1,0,0);
        glRectf(0.3,0.5,0.7,0.3);
        glPushMatrix();
            glTranslatef(0.7,0.4,0);
            glRotatef(angle[1],0,0,1);
            glTranslatef(-0.7,-0.4,0);
            glColor3f(0,1,0);
            glRectf(0.7,0.5,1.0,0.3);
        glPopMatrix();
    glPopMatrix();

        glPushMatrix();
            glTranslatef(-0.3,0.4,0);
            glRotatef(angle[2],0,0,1);
            glTranslatef(0.3,-0.4,0);
            glColor3f(1,0,0);
            glRectf(-0.3,0.5,-0.7,0.3);

            glPushMatrix();
                glTranslatef(-0.7,0.4,0);
                glRotatef(angle[3],0,0,1);
                glTranslatef(0.7,-0.4,0);
                glColor3f(0,1,0);
                glRectf(-0.7,0.5,-1.0,0.3);
            glPopMatrix();
    glPopMatrix();
    glutSwapBuffers();
 }
 int main(int argc, char *argv[])
 {
    glutInit(&argc,argv);
    glutInitDisplayMode(GLUT_DOUBLE|GLUT_DEPTH);
    glutCreateWindow("week16_interpolation");
    glutMouseFunc(mouse);
    glutMotionFunc(motion);
    glutKeyboardFunc(keyboard);
    glutDisplayFunc(display);

    glutMainLoop();
 }

```

## Step02-2 運鏡
```
eye=>眼睛座標位置
center=>看哪裡位置
up=>向量(攝影機指向的地方)
謝謝老師熱情的代入教學
```

##  Step03-1 保持長寬比
>>> 不會變形
```
1.File-New-Project-GLUT專案-week16_camera_projection_GlutLookat
2.備份177行範例,透過那段程式進行修改
3.aspect ratio 長寬比(左寬右高) ex.1920x1080 1280x720 640x480,16:9,4:3....
```

## 在做一些改動
```
1.新增void motion函式
2.原本視角固定在0,0,3的位置=>(x-150)/150.0,(y-150)/150.0,3, ///eye
   (透過滑鼠的滑動做出視窗的轉變)
```
## 現在程式碼
```C
#include <GL/glut.h>
void reshape(int w,int h){///不能 整數除
    float ar = (float) w/(float) h;
    glViewport(0,0,w,h);
    glMatrixMode(GL_PROJECTION);///3D變2D
    glLoadIdentity();
    gluPerspective(60,ar,0.1,100);

    glMatrixMode(GL_MODELVIEW);///3D Model+view
    glLoadIdentity();
    gluLookAt(0,0,3, ///eye
              0,0,0, ///center看哪裡
              0,1,0);///up向量
}
void display()
{
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    glutSolidTeapot(1);
    glutSwapBuffers();
}
void motion(int x,int y)
{
    glMatrixMode(GL_MODELVIEW);///3D Model+view
    glLoadIdentity();
    gluLookAt((x-150)/150.0,(y-150)/150.0,3, ///eye
              0,0,0, ///center看哪裡
              0,1,0);///up向量
    glutPostRedisplay();///重劃畫面
}
int main(int argc, char *argv[])
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH);
    glutCreateWindow("week16 camera");
    glutDisplayFunc(display);
    glutMotionFunc(motion);
    glutReshapeFunc(reshape);///範例是resize
    glutMainLoop();

}

```




2022年5月31日 星期二

Ucc的上課筆記week15~

# Week15
## 電腦圖學 Week15 2022-05-31
```
1. 播聲音、播MP3
2. 播放動畫、內插
3. 機器人擺動作、跳舞
```
## Step01-1 PlaySound()解釋
```C
0.File-New-Empty File-week15_playsound.cpp
1.上週#include<mmsystem.h>
2.這週使用#include<windows.h>
3.上週playsound("檔名.wav",NULL,SND_ASYNC);//不等待,不同步
4.這週PlaySound("檔名.wav",NULL,SND_SYNC);//等待,同步
5.setting-compiler setting-linker加入winmm(可以撥聲音)
6.注意工作目錄的位置!
7.將下載下來的聲音檔放在你檔案存放的位置(記得音樂檔是wav檔)
```
##Step01-2 PlaySound()更多參數
```C
0.File-New-Empty File-week15-2_SND_SYNC_SND_ASYNC
1.PlaySound("檔名.wav",NULL,SND_SYNC);=>加上變ASYNC就會不播音樂直接結束
```
## 做一些變更
```C
#include <windows.h>
#include <stdio.h>
int main()
{///不等待會快速執行下一行,互動性佳
    PlaySound("07013033.wav",NULL,SND_ASYNC);///背景會先撥放此段音樂
    while(1){
        printf("請輸入數字: ");///邊秀出文字
        int n;
        scanf("%d",&n);
        if(n==1)PlaySound("do.wav",NULL,SND_ASYNC);///ASYNC不等待
        if(n==2)PlaySound("re.wav",NULL,SND_ASYNC);
        if(n==3)PlaySound("mi.wav",NULL,SND_ASYNC);
    }
}

```
## Step02-1 MP3(小/有壓縮) vs WAV(大/原始檔)
>>PlaySound()只能撥最原始的檔案,只要一行
>>MP3比較麻煩,需要打比較多行
```
1.在Moodle下載CMP3_MCI.h
2.程式碼#include<CMP3_MCI.h>
3.宣告 CMP3_MCI mp3
4.mp3.Load("檔名.mp3");
5.mp3.play();
```
## Step02-2 接續上周的week14_angles_TRT_write_and_read
```
0.File-New-Project-GLUT專案,week15_angles_TRT_again
1.複製上週程式碼,並試跑看看能否正確執行
2.發現問題: 不像動畫,只會動一個關節,而且很慢
3.myWrite()會寫一行,myRead()會讀一行
4.不能把myWrite()放在motion()
5.把動作對應的關節全部做好再存起來成一個動作
6.擺好動作按下's'存檔
7.執行時可以存入幾個動作'r'可讀入
8.事後在工作目錄裡(C:\Users\YUXUAN\Desktop\freeglut\bin)有file.txt可以大量copy動作,重新跑完程式動作就變多了
```
## Step03-1 讓他搖擺(*´ω`)人(´ω`*)
```C
1.需要 3D Model (glm.h/.cpp) (.obj .mtl .jpg.....)
2.需要把模型切很多塊(因為整塊的話關節不會動)
3.TRT的程式才會轉動
4.keyboard()切換關節,mouse motion()旋轉關節
```
##慢慢做
```C
1.File-new-project,GLUT專案,week15_hw4
2.改善電腦餘毒=>開啟notepad++將工作目錄改成<Option working_dir="." />
3.將freeglut.dll複製貼上到程式所在的檔案夾
4.把glm.h glm.cpp和gundam的data目錄,全放在現在要用的檔案目錄
```
## 實作小tips
```
1.為了不要打太多行程式碼進行縮減
2.建立一個類似於檔案夾的東西
GLMmodel * myReadone(char * filename)
{
    if(one==NULL)
    {
        one=glmReadOBJ("data/body.obj");
        glmUnitize(one);
        glmFacetNormals(one);
        glmVertexNormals(one,90);
    }
    return one;
}
3.這樣每次要從裡面抓檔案時只要打一行程式碼就好
ex.if (body==NULL) body=myReadOne("data/body.obj");
    glmDraw(body,GLM_TEXTURE|GLM_SMOOTH);
4.再去調整關節的TRT
```

2022年5月24日 星期二

Ucc的上課筆記week14~

## 電腦圖學 Week14 2022-05-24
```
1. 寫檔、讀檔
2. 關節、做動畫
3. 計時器 glutTimerFunc(時間, timer, 參數t)
4. 播放聲音
```
## step01-1寫檔 File Output (紀錄)
```C
0.File-New-Empty File-存檔到week14-1_fprintf目錄裡的week14-1.cpp
1.fopen() 開啟檔案
2.printf()   =>  fprintf()
3.fclose(fout) 關閉檔案
```
## step01-2 讀檔 File Input
## 貼心小提醒d(`・∀・)b
```
在做scanf()時,讀檔的位置要記得加個&才能讀到檔呦
```
```C
0.File-New-Empty File-存檔到week14-2_fprintf_fscanf 目錄裡的 week14-2.cpp
1.把剛剛的week14-1拿來用
2.另外一組 FILE * fin = fopen("檔名","r");
3.scanf ()   =>    fscanf()
4.fclose(fin)
```

## step01-3 把上週的week13_rect_many_TRT 拿來改
```C
0. File-New-Project-GLUT專案->week14_angles_fprintf
1.貼上上週的最後程式
2.新增些許程式碼 printf("%.1f",angle[i]);///小黑印出來
3.                             fprintf(fout,"%.1f",angle[i]);///檔案印出來
4.以上是存檔和讀檔                                
```
## 目前加上的程式碼
```
///week14_angles_fprintf
#include <GL/glut.h>
#include <stdio.h>
float angle[20],oldX=0;
int angleID=0;
FILE * fout=NULL;
void myWrite()
{
    if(fout == NULL)fout=fopen("file.txt","w+");

    for(int i = 0;i<20;i++)
    {
        printf("%.1f",angle[i]);///小黑印出來
        fprintf(fout,"%.1f",angle[i]);///檔案印出來
    }///這裡老師沒有fclose
}
void keyboard(unsigned char key,int x,int y)
{
    if(key=='0') angleID=0;
    if(key=='1') angleID=1;
    if(key=='2') angleID=2;
    if(key=='3') angleID=3;
}
void mouse(int button,int state,int x,int y)
{
    oldX=x;
}
void motion(int x,int y)
{
    angle[angleID]+=(x-oldX);
    myWrite();
    oldX=x;
    glutPostRedisplay();
}
```

## step 02-1 做動畫囉~
```
0.File-New-Project-GLUT專案->week14_angles_fprintf_fscanf
1.copy前一個版本的程式進行修改
2.要寫void myRead()
3.在keyboard()裡 按下'r' 可以呼叫 myRead()
>>這裡R要一直按著!!!只是因為鍵盤的關西,重播會跑很慢
>>fout 那的printf和fprintf裡的跳行要記得空格,不然會發生錯誤!!
```
```C
///week14_angles_fprintf
#include <GL/glut.h>
#include <stdio.h>
float angle[20],oldX=0;
int angleID=0;
FILE * fout=NULL, * fin = NULL;
void myWrite()
{///每呼叫一次myWrite
    if(fout == NULL)fout=fopen("file.txt","w+");

    for(int i = 0;i<20;i++)
    {
        printf("%.1f ",angle[i]);///小黑印出來
        fprintf(fout,"%.1f ",angle[i]);///檔案印出來
    }///這裡老師沒有fclose
    printf("\n");///小黑印出跳行
    fprintf(fout,"\n");///檔案跳行
}
void myRead()
{
    if(fout!=NULL){fclose(fout); fout=NULL;}
    if(fin==NULL) fin=fopen("file.txt","r");
    for(int i=0;i<20;i++)
    {
        fscanf(fin,"%f",&angle[i]);
    }
    glutPostRedisplay();///重劃畫面
}
void keyboard(unsigned char key,int x,int y)
{
    if(key=='r') myRead();
    if(key=='0') angleID=0;
    if(key=='1') angleID=1;
    if(key=='2') angleID=2;
    if(key=='3') angleID=3;
}
```
## step02-2 為啥我們產生的檔案file.txt放在很神奇的地方ㄋ?
>> C:\Users\YUXUAN\Desktop\freeglut\bin 目標放在程式專案的目錄
```
0.為甚麼呢?
1.原來是電腦餘讀 GLUT專案需要freeglut.dll 所以工作目錄才會跑到freeglut/bin裡
2.在 .cbp codeblocks project檔裡,有工作目錄的設定 工作執行的目錄
3.使用notepad++ 開啟.cbp檔 將 裡面的working dir裡改成<Option working_dir="." />
4.notepad++檔案存檔後,codeblock檔案reload 後就完成
5.小心歷史餘毒!!=>將原freeglut/bin裡的freeglut.dll複製貼上到程式專案的資料夾中
```
## step03-1 glutTimerFunc() 計時器
```
0.為甚麼要這個? 因為每個人鍵盤輸入速度步一樣
0-1.File-New-Project-GLUT專案->week14_timer
1.void timer(int t)寫入timer函式
2.glutTimerFunc(等多久,timer,t參數);
3.其他就是GLUT的10行程式碼
```
```C
///week14_timer
#include <GL/glut.h>
#include <stdio.h>
void timer(int t){
    printf("起床,現在時間: %d\n",t);
}
void display()
{
}
 int main(int argc, char *argv[])
 {
    glutInit(&argc,argv);
    glutInitDisplayMode(GLUT_DOUBLE|GLUT_DEPTH);
    glutCreateWindow("week14_timer");

    glutTimerFunc(1000,timer,1);
    glutTimerFunc(2000,timer,2);
    glutTimerFunc(3000,timer,3);
    glutTimerFunc(4000,timer,4);
    glutTimerFunc(5000,timer,5);
    glutDisplayFunc(display);
    glutMainLoop();
 }

```

## step03-2 期末作業30秒要30格,900個timer有點麻煩,程式應該自動一點
```
1.透過函式呼叫函式
2.glutTimerFunc(1000,timer,t+1); 隨著時間每秒+1
3. glutTimerFunc(5000,timer,0);///設定:5秒後,才叫第0個timer
```
```C
///week14_timer
#include <GL/glut.h>
#include <stdio.h>
void timer(int t){
    printf("起床,現在時間: %d\n",t);
    glutTimerFunc(1000,timer,t+1);
}
void display()
{
}
 int main(int argc, char *argv[])
 {
    glutInit(&argc,argv);
    glutInitDisplayMode(GLUT_DOUBLE|GLUT_DEPTH);
    glutCreateWindow("week14_timer");

    glutTimerFunc(5000,timer,0);///設定:5秒後,才叫第0個timer

    glutDisplayFunc(display);
    glutMainLoop();
 }
```


## step03-3 播放聲音PlaySound() 下載do.wav
```
1.繼續改 剛剛那隻程式(week14_timer_auto)
2.#include <mmsytem.h>
3.PlaySound("do.wav",NULL,SND_ASYNC);
```
## 有聲音的程式碼(*´∀`)~♥
```C
///week14_timer
#include <GL/glut.h>
#include <stdio.h>
#include <mmsystem.h>
void timer(int t){
    printf("我起床囉!  %d\n",t);
    PlaySound("do.wav",NULL,SND_ASYNC);
    glutTimerFunc(2000,timer,t+1);
}
void display()
{
}
 int main(int argc, char *argv[])
 {
    glutInit(&argc,argv);
    glutInitDisplayMode(GLUT_DOUBLE|GLUT_DEPTH);
    glutCreateWindow("week14_timer");

    glutTimerFunc(5000,timer,0);///設定:5秒後,才叫第0個timer

    glutDisplayFunc(display);
    glutMainLoop();
 }

```




2022年5月17日 星期二

Ucc的week13上課筆記~

 ## 電腦圖學 Week13 2022-05-17
```
1. 示範複習作業/考試的 TRT(實際例子)
2. TRT 的R角度
3. 利用 keyboard/mouse 來改變
4. 如何轉正模型、如何調整模型大小
```
## step01-1 glRectf(x1,y1,x2,y2)方塊
```
1.File-new-Project專案-week13_rect_TRT
2.貼上GLUT的10行程式碼,不用茶壺
```
## 正方形的程式碼
```C
#include <GL/glut.h>
 void display()
 {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glRectf(0.3,0.5,-0.3,-0.5);

    glutSwapBuffers();
 }
 int main(int argc, char *argv[])//main()主函式 進階版
 {
    glutInit(&argc,argv);//把參數送給glutInit初始化
    glutInitDisplayMode(GLUT_DOUBLE|GLUT_DEPTH);//雙緩衝區+3D深度功能
    glutInitWindowSize(600,600);
    glutCreateWindow("week13_rect_TRT");//開GLUT視窗

    glutDisplayFunc(display);//顯示用的函式

    glutMainLoop();
 }

```
##step01-2 把手加上去而且可以旋轉!
```
1.另一個小方塊,且加上色彩
2.準備好TRT程式碼
```
## 加上小手臂
```C
#include <GL/glut.h>
 void display()
 {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glColor3f(1,1,1);///白色
    glRectf(0.3,0.5,-0.3,-0.5);///身體
    glPushMatrix();
        ///glTranslatef(x,y,z);///把手臂掛在身上
        ///glRotatef(angle,0,0,1);///對z軸旋轉
        ///glTranslatef(x2,y2,z2);///挑整手臂的旋轉中心
        glColor3f(1,0,0);
        glRectf(0.3,0.5,0.7,0.3);
    glPopMatrix();
    glutSwapBuffers();
 }
 int main(int argc, char *argv[])//main()主函式 進階版
 {
    glutInit(&argc,argv);//把參數送給glutInit初始化
    glutInitDisplayMode(GLUT_DOUBLE|GLUT_DEPTH);//雙緩衝區+3D深度功能
    glutInitWindowSize(600,600);
    glutCreateWindow("week13_rect_TRT");//開GLUT視窗

    glutDisplayFunc(display);//顯示用的函式

    glutMainLoop();
 }
```
## step01-3 把旋轉中心放在正中心
## 移動小手臂
```C
1.把(0.3,0.4)移到(0,0)=>glTranslatef(-0.3,-0.4,0);
```
## 轉動45度角
```C
加上
float angle=45;
glRotatef(angle,0,0,1);
可以旋轉45度~
```
## 把手移回原處
```C
glTranslatef(0.3,0.4,0);
```

## 調整步驟(目前結果)
```
1. 先調整最下面的Translate改變中心點
2.改變Rotate數值改變旋轉角度
3.最後調整最上面的Translate將手臂位置移回原處
```
```C
#include <GL/glut.h>
float angle=45;
 void display()
 {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glColor3f(1,1,1);///白色
    glRectf(0.3,0.5,-0.3,-0.5);///身體
    glPushMatrix();
        glTranslatef(0.3,0.4,0);///把手臂掛在身上
        glRotatef(angle,0,0,1);///對z軸旋轉
        glTranslatef(-0.3,-0.4,0);///挑整手臂的旋轉中心
        glColor3f(1,0,0);
        glRectf(0.3,0.5,0.7,0.3);
    glPopMatrix();
    glutSwapBuffers();
 }
 int main(int argc, char *argv[])//main()主函式 進階版
 {
    glutInit(&argc,argv);//把參數送給glutInit初始化
    glutInitDisplayMode(GLUT_DOUBLE|GLUT_DEPTH);//雙緩衝區+3D深度功能
    ///glutInitWindowSize(600,600);
    glutCreateWindow("week13_rect_TRT");//開GLUT視窗

    glutDisplayFunc(display);//顯示用的函式

    glutMainLoop();
 }

```
## step02-1 裡用Mouse motion來改變手臂的旋轉角度
```C
1.為了能使用滑鼠控制加上Mouse和Motion
2.用glutPostRedisplay();來重新畫出視窗
3.最後加上 glutMouseFunc(mouse);
                    glutMotionFunc(motion);來函式呼叫
```
## 目前程式碼
```C
#include <GL/glut.h>
float angle=45,oldX=0;
void mouse(int button,int state,int x,int y)
{
    oldX=x;
}
void motion(int x,int y)
{
    angle+=(x-oldX);
    oldX=x;
    glutPostRedisplay();///請GLUT重劃畫面
}
 void display()
 {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glColor3f(1,1,1);///白色
    glRectf(0.3,0.5,-0.3,-0.5);///身體
    glPushMatrix();
        glTranslatef(0.3,0.4,0);///把手臂掛在身上
        glRotatef(angle,0,0,1);///對z軸旋轉
        glTranslatef(-0.3,-0.4,0);///挑整手臂的旋轉中心
        glColor3f(1,0,0);
        glRectf(0.3,0.5,0.7,0.3);
    glPopMatrix();
    glutSwapBuffers();
 }
 int main(int argc, char *argv[])//main()主函式 進階版
 {
    glutInit(&argc,argv);//把參數送給glutInit初始化
    glutInitDisplayMode(GLUT_DOUBLE|GLUT_DEPTH);//雙緩衝區+3D深度功能
    ///glutInitWindowSize(600,600);
    glutCreateWindow("week13_rect_TRT");//開GLUT視窗
    glutMouseFunc(mouse);
    glutMotionFunc(motion);
    glutDisplayFunc(display);//顯示用的函式

    glutMainLoop();
 }
```
##  step02-2 要開新專案 week13_rect_TRT_TRT做出更多關節
```
1.File-New-Project-GLUT專案-week13_rect_TRT_TRT
2.把前面程式拿來用
3.要新增的地方是第二個手臂的關節
```
## 第二個手臂關節的部分~
```C
///week13_rect_TRT_TRT
#include <GL/glut.h>
float angle=0,oldX=0;
void mouse(int button,int state,int x,int y)
{
    oldX=x;
}
void motion(int x,int y)
{
    angle+=(x-oldX);
    oldX=x;
    glutPostRedisplay();///請GLUT重劃畫面
}
 void display()
 {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glColor3f(1,1,1);///白色
    glRectf(0.3,0.5,-0.3,-0.5);///身體
    glPushMatrix();
        glTranslatef(0.3,0.4,0);///把手臂掛在身上
        glRotatef(angle,0,0,1);///對z軸旋轉
        glTranslatef(-0.3,-0.4,0);///挑整手臂的旋轉中心
        glColor3f(1,0,0);
        glRectf(0.3,0.5,0.7,0.3);///上手臂

        glPushMatrix();
            ///glTranslatef(0.3,0.4,0);///把手臂掛在身上
            ///glRotatef(angle,0,0,1);///對z軸旋轉
            ////glTranslatef(-0.3,-0.4,0);///挑整手臂的旋轉中心
            glColor3f(0,1,0);
            glRectf(0.7,0.5,1.0,0.3);///下手肘
        glPopMatrix();

    glPopMatrix();
    glutSwapBuffers();
 }
 int main(int argc, char *argv[])//main()主函式 進階版
 {
    glutInit(&argc,argv);//把參數送給glutInit初始化
    glutInitDisplayMode(GLUT_DOUBLE|GLUT_DEPTH);//雙緩衝區+3D深度功能
    ///glutInitWindowSize(600,600);
    glutCreateWindow("week13_rect_TRT");//開GLUT視窗
    glutMouseFunc(mouse);
    glutMotionFunc(motion);
    glutDisplayFunc(display);//顯示用的函式

    glutMainLoop();
 }

```


## 把手肘掛在肚臍
```C
1.把第21行註解
2.執行程式可以發現只有綠色手臂在旋轉
glPushMatrix();
            ///glTranslatef(0.3,0.4,0);///把手臂掛在身上
            glRotatef(angle,0,0,1);///對z軸旋轉
            glTranslatef(-0.7,-0.4,0);///挑整手臂的旋轉中心
            glColor3f(0,1,0);
            glRectf(0.7,0.5,1.0,0.3);///下手肘
glPopMatrix();
```

## 掛回原處
```
1.將數值改成glTranslatef(0.7,0.4,0);///把手臂掛在身上
2.把剛剛註解的部分取消
3.可以看到手臂和手肘成功連接一起旋轉
```
```C
///week13_rect_TRT_TRT
#include <GL/glut.h>
float angle=0,oldX=0;
void mouse(int button,int state,int x,int y)
{
    oldX=x;
}
void motion(int x,int y)
{
    angle+=(x-oldX);
    oldX=x;
    glutPostRedisplay();///請GLUT重劃畫面
}
 void display()
 {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glColor3f(1,1,1);///白色
    glRectf(0.3,0.5,-0.3,-0.5);///身體
    glPushMatrix();
        glTranslatef(0.3,0.4,0);///把手臂掛在身上
        glRotatef(angle,0,0,1);///對z軸旋轉
        glTranslatef(-0.3,-0.4,0);///挑整手臂的旋轉中心
        glColor3f(1,0,0);
        glRectf(0.3,0.5,0.7,0.3);///上手臂

        glPushMatrix();
            glTranslatef(0.7,0.4,0);///把手臂掛在身上
            glRotatef(angle,0,0,1);///對z軸旋轉
            glTranslatef(-0.7,-0.4,0);///挑整手臂的旋轉中心
            glColor3f(0,1,0);
            glRectf(0.7,0.5,1.0,0.3);///下手肘
        glPopMatrix();

    glPopMatrix();
    glutSwapBuffers();
 }
 int main(int argc, char *argv[])//main()主函式 進階版
 {
    glutInit(&argc,argv);//把參數送給glutInit初始化
    glutInitDisplayMode(GLUT_DOUBLE|GLUT_DEPTH);//雙緩衝區+3D深度功能
    ///glutInitWindowSize(600,600);
    glutCreateWindow("week13_rect_TRT");//開GLUT視窗
    glutMouseFunc(mouse);
    glutMotionFunc(motion);
    glutDisplayFunc(display);//顯示用的函式

    glutMainLoop();
 }

```

## step03-1 複製出左半部分手臂手肘
```
1.File-New-Project-GLUT專案-week13_rect_many_TRT
2.複製剛剛的程式碼
3.在把剛剛右半部手臂手肘複製貼上
4.透過鏡射原理改變x值(正負值顛倒)=>(變到左邊去)
```
## 雙手臂
```C
///week13_rect_many_TRT
#include <GL/glut.h>
float angle=0,oldX=0;
void mouse(int button,int state,int x,int y)
{
    oldX=x;
}
void motion(int x,int y)
{
    angle+=(x-oldX);
    oldX=x;
    glutPostRedisplay();///請GLUT重劃畫面
}
 void display()
 {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glColor3f(1,1,1);///白色
    glRectf(0.3,0.5,-0.3,-0.5);///身體

    glPushMatrix();///右半部
        glTranslatef(0.3,0.4,0);///把手臂掛在身上
        glRotatef(angle,0,0,1);///對z軸旋轉
        glTranslatef(-0.3,-0.4,0);///挑整手臂的旋轉中心
        glColor3f(1,0,0);
        glRectf(0.3,0.5,0.7,0.3);///上手臂

        glPushMatrix();
            glTranslatef(0.7,0.4,0);///把手臂掛在身上
            glRotatef(angle,0,0,1);///對z軸旋轉
            glTranslatef(-0.7,-0.4,0);///挑整手臂的旋轉中心
            glColor3f(0,1,0);
            glRectf(0.7,0.5,1.0,0.3);///下手肘
        glPopMatrix();
    glPopMatrix();

        glPushMatrix();///左半部
            glTranslatef(-0.3,0.4,0);///把手臂掛在身上
            glRotatef(angle,0,0,1);///對z軸旋轉
            glTranslatef(0.3,-0.4,0);///挑整手臂的旋轉中心
            glColor3f(1,0,0);
            glRectf(-0.3,0.5,-0.7,0.3);///左上手臂

            glPushMatrix();
                glTranslatef(-0.7,0.4,0);///把手臂掛在身上
                glRotatef(angle,0,0,1);///對z軸旋轉
                glTranslatef(0.7,-0.4,0);///挑整手臂的旋轉中心
                glColor3f(0,1,0);
                glRectf(-0.7,0.5,-1.0,0.3);///左下手肘
            glPopMatrix();
    glPopMatrix();
    glutSwapBuffers();
 }
 int main(int argc, char *argv[])//main()主函式 進階版
 {
    glutInit(&argc,argv);//把參數送給glutInit初始化
    glutInitDisplayMode(GLUT_DOUBLE|GLUT_DEPTH);//雙緩衝區+3D深度功能
    ///glutInitWindowSize(600,600);
    glutCreateWindow("week13_rect_TRT");//開GLUT視窗
    glutMouseFunc(mouse);
    glutMotionFunc(motion);
    glutDisplayFunc(display);//顯示用的函式

    glutMainLoop();
 }

```
## step03-2 如果只有一個角度,就不會有其他變化
```C
1.要有多少角度呢?? =>每個關節要分別有兩個軸向=>總共20個
   =>float angle=0改成float angle[20](全部的角度都要改)
2.多關節用keyboard 切換
```
## 加入哪些程式碼
### 透過鍵盤的輸入控制要用滑鼠改變的關節
```C
float angle[20],oldX=0;
int angleID=0;
void keyboard(unsigned char key,int x,int y)
{
    if(key=='0') angleID=0;
    if(key=='1') angleID=1;
    if(key=='2') angleID=2;
    if(key=='3') angleID=3;
}

```
## 調整角度的地方
```C
void mouse(int button,int state,int x,int y)
{
    oldX=x;
}
void motion(int x,int y)
{
    angle[angleID]+=(x-oldX);
    oldX=x;
    glutPostRedisplay();///請GLUT重劃畫面
}
```
## 宣告的地方(在main裡加上)
```C
glutKeyboardFunc(keyboard);
```


VERY BEAUTIFUL, VERY POWERFUL

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