2023年5月17日 星期三

rita - week14 - 主題: 切換關節 2. 切換移動、旋轉 3.計時器、內插動作

         

        先將git指令下載  把專案clone下來


    下載葉老師上課用軟體freeglut壓縮  / 將裡面的freeglut檔案複製到桌面  
    再將裡頭lib的libfreeglut.a複製並貼上  / 將複製的改檔名為libglut32.a

    開啟codeblocks / 新增 glut專案 / 取名為 week14-1_timer


    第一個程式

    #include <GL/glut.h>
    float angle=0;
    void display()
    {
        glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
        glPushMatrix();
            glRotatef(angle,0,0,1);
            glutSolidTeapot(0.3);
        glPopMatrix();
        glutSwapBuffers();
    }
    void timer(int t)
    {
        glutTimerFunc(500,timer,t+1);///設定下個鬧鐘
        angle+=90;///+90度
        glutPostRedisplay();///重新畫畫面
    }
    int main(int argc,char** argv)
    {
        glutInit(&argc,argv);
        glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH);
        glutCreateWindow("week14");

        glutDisplayFunc(display);
        glutTimerFunc(2000,timer,0);///設定timer格式
    
        glutMainLoop();
    }



    新增 glut專案 / 取名為 week14-2_timer_play

    第二個程式(可90度90度旋轉茶壺)

    ///week14-2_timer_play
    #include <GL/glut.h>
    float angle=0;
    void display()
    {
        glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
        glPushMatrix();
            glRotatef(angle,0,0,1);
            glutSolidTeapot(0.3);
        glPopMatrix();
        glutSwapBuffers();
    }
    void timer(int t)
    {
        glutTimerFunc(500,timer,t+1);///設定下個鬧鐘
        angle+=90;///+90度
        glutPostRedisplay();///重新畫畫面
    }
    void keyboard(unsigned char key, int x, int y)
    {
        glutTimerFunc(0,timer,0);
    }
    int main(int argc,char** argv)
    {
        glutInit(&argc,argv);
        glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH);
        glutCreateWindow("week14");

        glutDisplayFunc(display);
        glutKeyboardFunc(keyboard);///用keyboard()
        ///glutTimerFunc(2000,timer,0);///設定timer格式

        glutMainLoop();
    }

按下空白鍵的話 會開始旋轉90度
再多按一下空白鍵的話 茶壺會旋轉更快

    開啟excel檔 / 撰寫以下數值 


    新增 glut專案 / 取名為 week14-3_timer_alpha_interpolation

    第三個程式(用空白鍵來播放動畫)

 ///week14-2_timer_play
#include <GL/glut.h>
float angle=0,oldAngle=0,newAngle=0;
void display()
{
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    glPushMatrix();
        glRotatef(angle,0,0,1);
        glutSolidTeapot(0.3);
    glPopMatrix();
    glutSwapBuffers();
}
void timer(int t)
{
    if(t<100) glutTimerFunc(50,timer,t+1);///在100之內 設定
    float alpha =t/100.0;
    angle=newAngle*alpha+(1-alpha)*oldAngle;///alpha介於0.00~1.00之間
    glutPostRedisplay();///重新畫畫面
}
void motion(int x,int y)
{
    angle=x;///即時更新角度
    glutPostRedisplay();
}
void mouse(int button,int state,int x,int y)
{
    if(state==GLUT_DOWN) oldAngle=x;///按下去
    if(state==GLUT_UP) newAngle=x;///放開來
    glutPostRedisplay();
}
void keyboard(unsigned char key, int x, int y)///按任意建,就會播放動畫
{
    glutTimerFunc(0,timer,0);
}
int main(int argc,char** argv)
{
    glutInit(&argc,argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH);
    glutCreateWindow("week14");

    glutDisplayFunc(display);
    glutMotionFunc(motion);
    glutMouseFunc(mouse);
    glutKeyboardFunc(keyboard);///用keyboard()
    ///glutTimerFunc(2000,timer,0);///設定timer格式

    glutMainLoop();
}

    將所有檔案save everything / 開啟git bash / git status / 將桌面三個檔案複製到                  2023graphicsa裡頭 / git add . / git status / git config --global user.email "" / 
    git config --global user.name ""  /  git commit -m "更新 week14 "
        

    開啟final project



    開啟 glut專案 / 名為 final porject

    第四個程式(可以用顏色來挑選不同關節)

///要用keyboard mouse來控制茶壺,可存檔,可自己動
#include <stdio.h>
#include <GL/glut.h>
#include "glm.h"
GLMmodel * head =NULL;///week13 step02-1
GLMmodel * body =NULL;
GLMmodel * uparmR =NULL;
GLMmodel * lowarmR =NULL;
int show[4]={1,1,1,1};///week14_step02-2
int ID=0;///0:頭 1:身體 2:上手臂 3:下手臂///week14_step02-2
void keyboard(unsigned char key,int x ,int y)
{
    if(key=='0') ID = 0;///week14_step02-2
    if(key=='1') ID = 1;///week14_step02-2
    if(key=='2') ID = 2;///week14_step02-2
    if(key=='3') ID = 3;///week14_step02-2
    ///if(key=='0') show[0] = !show[0];///!是將1變0,0變1
    ///if(key=='1') show[1] = !show[1];
    ///if(key=='2') show[2] = !show[2];
    ///if(key=='3') show[3] = !show[3];
    glutPostRedisplay();
}///將原本的keyboard函式先註解掉
FILE * fout = NULL;///一開始,檔案沒有開 NULL
FILE * fin = NULL;///要讀檔用的指標,一開始也是NULL
float teapotX=0,teapotY=0;
float angle=0, angle2=0, angle3=0;
void display()
{
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    glPushMatrix();
        glScalef(0.2, 0.2, 0.2);
        if(body==NULL)
        {
            head=glmReadOBJ("model/head.obj");
            body=glmReadOBJ("model/body.obj");
            uparmR=glmReadOBJ("model/uparmR.obj");
            lowarmR=glmReadOBJ("model/lowarmR.obj");
            ///glmUnitize(body);///這之後還會更改
        }
        if(ID==0) glColor3f(1,0,0);///選定的,紅色
        else glColor3f(1,1,1);///沒選定,白色
        if(show[0]) glmDraw(head,GLM_MATERIAL);

        if(ID==1) glColor3f(1,0,0);///選定的,紅色
        else glColor3f(1,1,1);///沒選定,白色
        if(show[1]) glmDraw(body,GLM_MATERIAL);
        glPushMatrix();
            glTranslatef(teapotX, teapotY, 0);

            if(ID==2) glColor3f(1,0,0);///選定的,紅色
            else glColor3f(1,1,1);///沒選定,白色
            if(show[2]) glmDraw(uparmR,GLM_MATERIAL);
        glPopMatrix();

        if(ID==3) glColor3f(1,0,0);///選定的,紅色
        else glColor3f(1,1,1);///沒選定,白色
        if(show[3]) glmDraw(lowarmR,GLM_MATERIAL);
    glPopMatrix();
    glutSwapBuffers();
}
int oldX=0, oldY=0;
void motion(int x, int y)
{
    teapotX += (x - oldX)/150.0;
    teapotY -= (y - oldY)/150.0;
    oldX = x;
    oldY = y;
    printf("glTranslatef(%f, %f, 0);\n",teapotX, teapotY);
    glutPostRedisplay();
}
void mouse(int button, int state, int x, int y)
{
    if(state==GLUT_DOWN)
    {
        oldX = x;///teapotX = (x-150)/150.0;
        oldY = y;///teapotY = (150-y)/150.0;
        angle = x;
        ///if(fout==NULL) fout=fopen("file4.txt","w");///沒開檔就開檔
        ///fprintf(fout,"%f %f\n",teapotX, teapotY);///要再存座標
    }
    display();
}
//void keyboard(unsigned char key, int x, int y)
//{
//    if(fin==NULL)///如果檔案還沒fopen(),就開它
//    {
//        fclose(fout);///要關掉前面mouse開的fout指標
//        fin = fopen("file4.txt","r");///沒開檔就開檔
//    }
//    fscanf(fin, "%f %f",&teapotX, &teapotY);///讀檔
//    display();
//}
 int main(int argc, char *argv[])
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH);
    glutCreateWindow("week13");

    glutDisplayFunc(display);
    glutMouseFunc(mouse);
    glutMotionFunc(motion);
    glutKeyboardFunc(keyboard);///keyboard要開檔,讀檔

    glutMainLoop();
}


    按下0,1,2,3後出現的結果
0

1
2

3

    將所有檔案save everything / 開啟git bash / git status  / git add . / git status
     /  git commit -m "更新 week14_挑選關節 "


    第四個程式版本2(加入超小綠色茶壺 將手臂移動到茶壺點上)

///要用keyboard mouse來控制茶壺,可存檔,可自己動
#include <stdio.h>
#include <GL/glut.h>
#include "glm.h"
GLMmodel * head =NULL;///week13 step02-1
GLMmodel * body =NULL;
GLMmodel * uparmR =NULL;
GLMmodel * lowarmR =NULL;
int show[4]={0,0,1,0};///week14_step03-1
int ID=2;///0:頭 1:身體 2:上手臂 3:下手臂///week14_step03-1
void keyboard(unsigned char key,int x ,int y)
{
    if(key=='0') ID = 0;///week14_step02-2
    if(key=='1') ID = 1;///week14_step02-2
    if(key=='2') ID = 2;///week14_step02-2
    if(key=='3') ID = 3;///week14_step02-2
    ///if(key=='0') show[0] = !show[0];///!是將1變0,0變1
    ///if(key=='1') show[1] = !show[1];
    ///if(key=='2') show[2] = !show[2];
    ///if(key=='3') show[3] = !show[3];
    glutPostRedisplay();
}///將原本的keyboard函式先註解掉
FILE * fout = NULL;///一開始,檔案沒有開 NULL
FILE * fin = NULL;///要讀檔用的指標,一開始也是NULL
float teapotX=0,teapotY=0;
float angle=0, angle2=0, angle3=0;
void display()
{
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    glPushMatrix();
        glScalef(0.2, 0.2, 0.2);
        if(body==NULL)
        {
            head=glmReadOBJ("model/head.obj");
            body=glmReadOBJ("model/body.obj");
            uparmR=glmReadOBJ("model/uparmR.obj");
            lowarmR=glmReadOBJ("model/lowarmR.obj");
            ///glmUnitize(body);///這之後還會更改
        }
        if(ID==0) glColor3f(1,0,0);///選定的,紅色
        else glColor3f(1,1,1);///沒選定,白色
        if(show[0]) glmDraw(head,GLM_MATERIAL);

        if(ID==1) glColor3f(1,0,0);///選定的,紅色
        else glColor3f(1,1,1);///沒選定,白色
        if(show[1]) glmDraw(body,GLM_MATERIAL);
        glPushMatrix();
            ///glTranslatef(-teapotX, -teapotY, 0);///week14_step03-1
            ///glRotatef(angle, 0, 0, 1);///week14_step03-1
            glTranslatef(teapotX, teapotY, 0);///week14_step03-1

            if(ID==2) glColor3f(1,0,0);///選定的,紅色
            else glColor3f(1,1,1);///沒選定,白色
            if(show[2]) glmDraw(uparmR,GLM_MATERIAL);
        glPopMatrix();

        if(ID==3) glColor3f(1,0,0);///選定的,紅色
        else glColor3f(1,1,1);///沒選定,白色
        if(show[3]) glmDraw(lowarmR,GLM_MATERIAL);
    glPopMatrix();
    glColor3f(0,1,0);///week14_step03-1
    glutSolidTeapot(0.02);///week14_step03-1
    glutSwapBuffers();
}
int oldX=0, oldY=0;
void motion(int x, int y)
{
    teapotX += (x - oldX)/150.0;
    teapotY -= (y - oldY)/150.0;
    oldX = x;
    oldY = y;
    printf("glTranslatef(%f, %f, 0);\n",teapotX, teapotY);
    glutPostRedisplay();
}
void mouse(int button, int state, int x, int y)
{
    if(state==GLUT_DOWN)
    {
        oldX = x;///teapotX = (x-150)/150.0;
        oldY = y;///teapotY = (150-y)/150.0;
        angle = x;
        ///if(fout==NULL) fout=fopen("file4.txt","w");///沒開檔就開檔
        ///fprintf(fout,"%f %f\n",teapotX, teapotY);///要再存座標
    }
    display();
}
//void keyboard(unsigned char key, int x, int y)
//{
//    if(fin==NULL)///如果檔案還沒fopen(),就開它
//    {
//        fclose(fout);///要關掉前面mouse開的fout指標
//        fin = fopen("file4.txt","r");///沒開檔就開檔
//    }
//    fscanf(fin, "%f %f",&teapotX, &teapotY);///讀檔
//    display();
//}
 int main(int argc, char *argv[])
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH);
    glutCreateWindow("week13");

    glutDisplayFunc(display);
    glutMouseFunc(mouse);
    glutMotionFunc(motion);
    glutKeyboardFunc(keyboard);///keyboard要開檔,讀檔

    glutMainLoop();
}


    第四個程式版本2(手臂可以晃動了)

///要用keyboard mouse來控制茶壺,可存檔,可自己動
#include <stdio.h>
#include <GL/glut.h>
#include "glm.h"
GLMmodel * head =NULL;///week13 step02-1
GLMmodel * body =NULL;
GLMmodel * uparmR =NULL;
GLMmodel * lowarmR =NULL;
int show[4]={0,1,1,0};///week14_step03-1
int ID=2;///0:頭 1:身體 2:上手臂 3:下手臂///week14_step03-1
void keyboard(unsigned char key,int x ,int y)
{
    if(key=='0') ID = 0;///week14_step02-2
    if(key=='1') ID = 1;///week14_step02-2
    if(key=='2') ID = 2;///week14_step02-2
    if(key=='3') ID = 3;///week14_step02-2
    ///if(key=='0') show[0] = !show[0];///!是將1變0,0變1
    ///if(key=='1') show[1] = !show[1];
    ///if(key=='2') show[2] = !show[2];
    ///if(key=='3') show[3] = !show[3];
    glutPostRedisplay();
}///將原本的keyboard函式先註解掉
FILE * fout = NULL;///一開始,檔案沒有開 NULL
FILE * fin = NULL;///要讀檔用的指標,一開始也是NULL
float teapotX=0,teapotY=0;
float angle=0, angle2=0, angle3=0;
void display()
{
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    glPushMatrix();
        glScalef(0.2, 0.2, 0.2);
        if(body==NULL)
        {
            head=glmReadOBJ("model/head.obj");
            body=glmReadOBJ("model/body.obj");
            uparmR=glmReadOBJ("model/uparmR.obj");
            lowarmR=glmReadOBJ("model/lowarmR.obj");
            ///glmUnitize(body);///這之後還會更改
        }
        if(ID==0) glColor3f(1,0,0);///選定的,紅色
        else glColor3f(1,1,1);///沒選定,白色
        if(show[0]) glmDraw(head,GLM_MATERIAL);

        if(ID==1) glColor3f(1,0,0);///選定的,紅色
        else glColor3f(1,1,1);///沒選定,白色
        if(show[1]) glmDraw(body,GLM_MATERIAL);
        glPushMatrix();
            glTranslatef(-1.426666, +0.320000, 0);///week14_step03-1
            glRotatef(angle, 0, 0, 1);///week14_step03-1
            ///glTranslatef(teapotX, teapotY, 0);///week14_step03-1
            glTranslatef(1.426666, -0.320000, 0);///week14_step03-1

            if(ID==2) glColor3f(1,0,0);///選定的,紅色
            else glColor3f(1,1,1);///沒選定,白色
            if(show[2]) glmDraw(uparmR,GLM_MATERIAL);
        glPopMatrix();

        if(ID==3) glColor3f(1,0,0);///選定的,紅色
        else glColor3f(1,1,1);///沒選定,白色
        if(show[3]) glmDraw(lowarmR,GLM_MATERIAL);
    glPopMatrix();
    glColor3f(0,1,0);///week14_step03-1
    glutSolidTeapot(0.02);///week14_step03-1
    glutSwapBuffers();
}
int oldX=0, oldY=0;
void motion(int x, int y)
{
    teapotX += (x - oldX)/150.0;
    teapotY -= (y - oldY)/150.0;
    oldX = x;
    oldY = y;
    angle= x;
    printf("glTranslatef(%f, %f, 0);\n",teapotX, teapotY);
    glutPostRedisplay();
}
void mouse(int button, int state, int x, int y)
{
    if(state==GLUT_DOWN)
    {
        oldX = x;///teapotX = (x-150)/150.0;
        oldY = y;///teapotY = (150-y)/150.0;
        angle = x;
        ///if(fout==NULL) fout=fopen("file4.txt","w");///沒開檔就開檔
        ///fprintf(fout,"%f %f\n",teapotX, teapotY);///要再存座標
    }
    display();
}
//void keyboard(unsigned char key, int x, int y)
//{
//    if(fin==NULL)///如果檔案還沒fopen(),就開它
//    {
//        fclose(fout);///要關掉前面mouse開的fout指標
//        fin = fopen("file4.txt","r");///沒開檔就開檔
//    }
//    fscanf(fin, "%f %f",&teapotX, &teapotY);///讀檔
//    display();
//}
 int main(int argc, char *argv[])
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH);
    glutCreateWindow("week13");

    glutDisplayFunc(display);
    glutMouseFunc(mouse);
    glutMotionFunc(motion);
    glutKeyboardFunc(keyboard);///keyboard要開檔,讀檔

    glutMainLoop();
}

    

    第四個程式版本3(全身手臂,手都可以晃動了)

///要用keyboard mouse來控制茶壺,可存檔,可自己動
#include <stdio.h>
#include <GL/glut.h>
#include "glm.h"
GLMmodel * head =NULL;///week13 step02-1
GLMmodel * body =NULL;
GLMmodel * uparmR =NULL;
GLMmodel * lowarmR =NULL;
int show[4]={1,1,1,1};///week14_step03-1
int ID=3;///0:頭 1:身體 2:上手臂 3:下手臂///week14_step03-1
void keyboard(unsigned char key,int x ,int y)
{
    if(key=='0') ID = 0;///week14_step02-2
    if(key=='1') ID = 1;///week14_step02-2
    if(key=='2') ID = 2;///week14_step02-2
    if(key=='3') ID = 3;///week14_step02-2
    ///if(key=='0') show[0] = !show[0];///!是將1變0,0變1
    ///if(key=='1') show[1] = !show[1];
    ///if(key=='2') show[2] = !show[2];
    ///if(key=='3') show[3] = !show[3];
    glutPostRedisplay();
}///將原本的keyboard函式先註解掉
FILE * fout = NULL;///一開始,檔案沒有開 NULL
FILE * fin = NULL;///要讀檔用的指標,一開始也是NULL
float teapotX=0,teapotY=0;
float angle=0, angle2=0, angle3=0;
void display()
{
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    glPushMatrix();
        glScalef(0.2, 0.2, 0.2);
        if(body==NULL)
        {
            head=glmReadOBJ("model/head.obj");
            body=glmReadOBJ("model/body.obj");
            uparmR=glmReadOBJ("model/uparmR.obj");
            lowarmR=glmReadOBJ("model/lowarmR.obj");
            ///glmUnitize(body);///這之後還會更改
        }
        if(ID==0) glColor3f(1,0,0);///選定的,紅色
        else glColor3f(1,1,1);///沒選定,白色
        if(show[0]) glmDraw(head,GLM_MATERIAL);

        if(ID==1) glColor3f(1,0,0);///選定的,紅色
        else glColor3f(1,1,1);///沒選定,白色
        if(show[1]) glmDraw(body,GLM_MATERIAL);
        glPushMatrix();
            glTranslatef(-1.426666, +0.320000, 0);///week14_step03-1
            glRotatef(angle, 0, 0, 1);///week14_step03-1
            ///glTranslatef(teapotX, teapotY, 0);///week14_step03-1
            glTranslatef(1.426666, -0.320000, 0);///week14_step03-1

            if(ID==2) glColor3f(1,0,0);///選定的,紅色
            else glColor3f(1,1,1);///沒選定,白色
            if(show[2]) glmDraw(uparmR,GLM_MATERIAL);
            glPushMatrix();
                glTranslatef(-1.939999, +0.186667, 0);///week14_step03-1
                glRotatef(angle, 0, 0, 1);///week14_step03-1
                //glTranslatef(teapotX, teapotY, 0);///week14_step03-1
                glTranslatef(1.939999, -0.186667, 0);///week14_step03-1

            if(ID==3) glColor3f(1,0,0);///選定的,紅色
            else glColor3f(1,1,1);///沒選定,白色
            if(show[3]) glmDraw(lowarmR,GLM_MATERIAL);
            glPopMatrix();
        glPopMatrix();
    glPopMatrix();
    glColor3f(0,1,0);///week14_step03-1
    glutSolidTeapot(0.02);///week14_step03-1
    glutSwapBuffers();
}
int oldX=0, oldY=0;
void motion(int x, int y)
{
    teapotX += (x - oldX)/150.0;
    teapotY -= (y - oldY)/150.0;
    oldX = x;
    oldY = y;
    angle= x;
    printf("glTranslatef(%f, %f, 0);\n",teapotX, teapotY);
    glutPostRedisplay();
}
void mouse(int button, int state, int x, int y)
{
    if(state==GLUT_DOWN)
    {
        oldX = x;///teapotX = (x-150)/150.0;
        oldY = y;///teapotY = (150-y)/150.0;
        angle = x;
        ///if(fout==NULL) fout=fopen("file4.txt","w");///沒開檔就開檔
        ///fprintf(fout,"%f %f\n",teapotX, teapotY);///要再存座標
    }
    display();
}
//void keyboard(unsigned char key, int x, int y)
//{
//    if(fin==NULL)///如果檔案還沒fopen(),就開它
//    {
//        fclose(fout);///要關掉前面mouse開的fout指標
//        fin = fopen("file4.txt","r");///沒開檔就開檔
//    }
//    fscanf(fin, "%f %f",&teapotX, &teapotY);///讀檔
//    display();
//}
 int main(int argc, char *argv[])
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH);
    glutCreateWindow("week13");

    glutDisplayFunc(display);
    glutMouseFunc(mouse);
    glutMotionFunc(motion);
    glutKeyboardFunc(keyboard);///keyboard要開檔,讀檔

    glutMainLoop();
}








    









    












沒有留言:

張貼留言