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();
}
--->可以去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資料夾 參考












沒有留言:
張貼留言