2022年5月31日 星期二

雪⛄電腦圖學筆記15~

  2022/5/31 第十五周 

主題 : 播放聲音、動畫

1. 播放聲音PlaySound()

(1) 開一個 new-file :  week15-1_PlaySound.cpp 放在week15資料夾

(2) 程式碼...但跑不動(因為沒加咒語) ///下圖紅色一行

#include<windows.h>

#include<stdio.h>

int main()

{

    printf("PlaySound()之前\n");

    ///PlaySound 只能撥wav檔  ///等待、同步

    PlaySound("badbad.wav", NULL, SND_SYNC);///檔案不存在

    printf("PlaySound()之後\n");

}




(3) 加上咒語(settings/compiler/linker settings/add: winmm) + 找一個wav檔放在week15資料夾

#include<windows.h>

#include<stdio.h>

int main()

{

    printf("PlaySound()之前\n");

    ///PlaySound 只能撥wav檔  ///等待、同步

    PlaySound("07072006.wav", NULL, SND_SYNC);

    printf("PlaySound()之後\n");

}



2. 
播放聲音PlaySound() 更多參數: 

#include<windows.h>

#include<stdio.h>

int main()

{   ///SYNC等待同步(有聲音)、ASYNC不等待同步(沒聲音)

    PlaySound("do.wav", NULL, SND_ASYNC);

    PlaySound("re.wav", NULL, SND_ASYNC);

    PlaySound("mi.wav", NULL, SND_ASYNC);

} ///最後一行,就結束了


3. ASYNC和SYNC的差別

(1) ASYNC ---> 比較同步,第七行的PlaySound聲音還沒播完,就可以執行下面幾行

#include<windows.h>

#include<stdio.h>

int main()

{   ///ASYNC不等待同步(就會比較快執行到下一行,互動性佳)

    PlaySound("07072006.wav", NULL, SND_ASYNC);

    while(1){

    printf("請輸入數字: ");

    int N;

    scanf("%d",&N);

        if(N==1) PlaySound("do.wav", NULL, SND_ASYNC);

        if(N==2) PlaySound("re.wav", NULL, SND_ASYNC);

        if(N==3) PlaySound("mi.wav", NULL, SND_ASYNC);

    }

}




(2) SYNC ---> 比較不同步,第七行的PlaySound聲音還沒播完,就跑不到下面幾行

#include<windows.h>

#include<stdio.h>

int main()

{   ///ASYNC不等待同步(就會比較快執行到下一行,互動性佳)

    PlaySound("07072006.wav", NULL, SND_SYNC);

    while(1){

    printf("請輸入數字: ");

    int N;

    scanf("%d",&N);

        if(N==1) PlaySound("do.wav", NULL, SND_ASYNC);

        if(N==2) PlaySound("re.wav", NULL, SND_ASYNC);

        if(N==3) PlaySound("mi.wav", NULL, SND_ASYNC);

    }

}




4. PlaySound只能播wav檔....想播放mp3檔

(1) 去moodle下載CMP3_MCI.h放在week15目錄

(2) 下載mp3檔

(3) 程式碼:

#include<stdio.h>

#include "CMP3_MCI.h"///記得要下載並放在同目錄

CMP3_MCI mp3;///宣告變數


int main()

{

    mp3.Load("07072006.mp3");

    mp3.Play();


    printf("隨便等你輸入數字,程式就卡囉: ");

    int N;///為了卡住程式不要直接結束

    scanf("%d",&N);

}


5. 動畫: 修改上一周程式

(1) 想要擺好動作,才save存檔

///檔案修改自上周

///week14_angles_fprintf_fscanf

#include <GL/glut.h>

#include <stdio.h>

float angle[20], oldX=0;

int angleID=0; ///0號關節,1號關節...

FILE * fout = NULL, * fin = NULL;   ///f out、f in

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]);///檔案印出來

    }

    printf("\n");///每呼叫一次myWrite(),小黑跳行

    fprintf(fout,"\n");///每呼叫一次myWrite(),檔案也跳行

}


void myRead(){

    if( fout != NULL ){ fclose(fout); fout=NULL; }

    if( fin == NULL ) fin = fopen("file.txt","r");

    for(int i=0; i<20; i++){ ///因為下面關節20個,所以要開陣列大小20(第4行)

        fscanf(fin, "%f", &angle[i]);

    }

    glutPostRedisplay();///重畫畫面

}


void keyboard(unsigned char key, int x, int y)///鍵盤按數字

{

    if(key=='s') myWrite();///調好動作,才save存檔

    if(key=='r') myRead(); ///一直按著r才能播放

    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(); ///請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);      ///(3)把手臂掛回身體

        glRotatef(angle[0],0,0,1);   ///(2)對z軸做旋轉

        glTranslatef( -0.3, -0.4,0);   ///(1)把手的旋轉中心,放到中心

        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);      ///(3)把手臂掛回身體

        glRotatef(angle[2],0,0,1);   ///(2)對z軸做旋轉

        glTranslatef(+0.3, -0.4,0);   ///(1)把手的旋轉中心,放到中心

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

    ///glutInitWindowSize(600,600);

    glutCreateWindow("week13 rect TRT TRT");


    glutKeyboardFunc(keyboard);

    glutMouseFunc(mouse);

    glutMotionFunc(motion);

    glutDisplayFunc(display);


    glutMainLoop();


}

--->擺好動作時,按s存動作。存好所有的動作後,在按r播放

--->可以去freeglut/bin/file.txt偷改內容後,再回檔案直接按r播放



6. 機器人擺動作

(1) 需要3D模型 model (glm.h glm.cpp)

(2) 把模型切成很多塊

(3) TRT程式

(4) keyboard() 切換關節,mouse motion() 轉動那個關節


(5-1) 開新專案week15_hw_gumdam_parts

(5-2) working_dir不太好: 去notepad++把week15_hw_gumdam_parts .cbp 檔,的第11、21行改 <Option working_dir="." />




(5-3) 將放在freeglut/bin裡的freeglut.dll複製,放到week15_hw_gumdam_parts目錄裡


(5-4) 要把 glm.h 、glm.cpp 、 gundam的data目錄and模型obj、mtl檔,放在同目錄裡



(5-5) 加上程式碼: 宣告

GLMmodel * body = NULL; ///分塊的模型

(5-6) 加上程式碼: 一起讀模型

GLMmodel * myReadOne(char * filename){

    GLMmodel * one = NULL;

    if(one==NULL){

        body = glmReadOBJ("data/body.obj");

        glmUnitize(body);

        glmFacetNormals(body);

        glmVertexNormals(one,90);

    }

    return one;

}

(5-7) 加上程式碼: 畫出模型

if(arm1==NULL) arm1 = myReadOne("data/arm1.obj");

glmDraw(body, GLM_TEXTURE|GLM_SMOOTH);

.....可以下載team/week15的 gundam資料夾 參考


沒有留言:

張貼留言

VERY BEAUTIFUL, VERY POWERFUL

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