2022/5/24 第十四周
主題 : 寫、讀檔,動畫,計時器
1. 寫檔
(1) file-new-empty file,save : week14-1.cpp,存到week14-1_fprintf 目錄裡
(2) 程式碼:
///寫檔
#include <stdio.h>
int main()
{///檔案指標 fout 開啟檔案(檔名, write模式)
FILE * fout = fopen( "file.txt" , "w+" );
printf(" Hello World\n");
fprintf( fout, "Hello World\n");
fclose(fout);///關閉檔案
}
(3) 執行的時候資料夾會跑出file.txt、.exe檔、.o檔
2. 讀檔
(1) file-new-empty file,save : week14-2.cpp,存到week14-2_fprintf_fscanf 目錄裡
(2) 複製上面的程式碼(寫檔) + 讀檔的程式碼
///讀檔
#include <stdio.h>
int main()
{///檔案指標 fout 開啟檔案(檔名, write模式)
FILE * fout = fopen("file.txt","w+"); ///f out (f:file)
fprintf(fout,"3.1415926\n");
fclose(fout);///關閉檔案
float angle=0;
FILE * fin = fopen("file.txt","r"); ///f in
fscanf(fin,"%f",&angle); ///沒加&會當掉
printf("讀到了角度:%f",angle);
fclose(fin);
}
--------->黑色寫檔、紅色讀檔
(3) 執行的時候資料夾會跑出file.txt、.exe檔、.o檔
3. 加上周的程式碼
(1) 開專案week14_angles_fprintf,把上禮拜week13_rect_many的程式碼 複製貼上
(2) 加上寫檔的程式碼
///week14_angles_fprintf
#include <GL/glut.h>
#include <stdio.h>
float angle[20], oldX=0;
int angleID=0; ///0號關節,1號關節...
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(); ///請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();
}
(3)資料可讀性不高-->加上跳行
///week14_angles_fprintf
#include <GL/glut.h>
#include <stdio.h>
float angle[20], oldX=0;
int angleID=0; ///0號關節,1號關節...
FILE * fout = NULL; ///f out
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 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(); ///請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();
}
(1) 在開一個新的專案week14_angles_fprintf_fscanf,加上讀檔的程式碼
(2) Build : 先做完動作後,一直按著r就可以跑出剛剛做的動作(變成動畫)
///week14_angles_fprintf
#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=='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();
}
5. 想把file.txt檔案改放到專案裡(不是放在freeglut/bin裡面)
(1) 用notepad++開啟專案裡的cbp,將第11、21行的雙括號裡面改成 . : <Option working_dir="." />
(2) 再複製放在freeglut/bin裡的freeglut.dll 放到專案裡
(3) 在跑一次專案,就可以發現專案資料夾裡有file.txt
(1) 在開一個新的專案week14_timer
(2) 程式碼
///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); ///一秒=1000
glutTimerFunc(2000, timer, 2);
glutTimerFunc(3000, timer, 3);
glutTimerFunc(4000, timer, 4);
glutTimerFunc(5000, timer, 5);
glutDisplayFunc(display);
glutMainLoop();
}
7. 自動計時器: 不想設太多timer
(1) 在開一個新的專案week14_timer_one_by_one
(2) 複製上一個timer程式碼在修改:
///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秒後,開始呼叫timer
glutDisplayFunc(display);
glutMainLoop();
}
8. 想要加上聲音
(1) 下載do.wav檔案,放在桌面/freeglut/bin
(2) 改剛剛的檔案的程式碼:
///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秒後,開始呼叫timer
glutDisplayFunc(display);
glutMainLoop();
}










沒有留言:
張貼留言