2023年5月17日 星期三

SangMo電腦圖學 Week14 切換關節、換移動、旋轉、計時器、內插動作

 



Step01-1 認識Timer程式

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) 你的timer函式 做對應動作
{
    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();
}


Step01-2 鍵盤控制 keyboard觸發timer

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

    glutMainLoop();
}


隨機鍵盤按鍵就能觸發

Step02-1 滑鼠控制

#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);
    float alpha = t/100.0; ///alpha介於0.00~1.00之間
    angle = newAngle*alpha + (1-alpha) * oldAngle; ///alpha內插公式
    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);
    glutMouseFunc(mouse);///按下去=起點 放開=終點
    glutMotionFunc(motion);
    glutKeyboardFunc(keyboard);///用keyboard


    glutMainLoop();
}
main()裡面要加
glutMotionFunc(motion);
glutMouseFunc(mouse);

Step02-2 final_project


設定函數ID
int ID=0;
void keyboard(unsigned char key, int x, int y)
{
    if(key== '0') ID=0;
    if(key== '1') ID=1;
    if(key== '2') ID=2;
    if(key== '3') ID=3;
    glutPostRedisplay();
}


選定特定部位並標上顏色
void display()
{
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    glPushMatrix();
        glScalef(0.2,0.2,0.2);
        ///glTranslatef(teapotX,teapotY, 0);
        ///glutSolidTeapot(0.3);
    if(body == NULL){
        head = glmReadOBJ("model/head.obj");
        body = glmReadOBJ("model/body.obj");///week13 Step02-1
        uparmL = glmReadOBJ("model/uparmL.obj");///week13 Step03-1
        lowarmL = glmReadOBJ("model/lowarmL.obj");///week13 Step03-1
        ///glmUnitize(body);
    }
    if(ID==0) glColor3f(1,0,0);///選定的設紅色
    else glColor3f(1,1,1);///沒選設白色
    if(show[0])glmDraw(head, GLM_MATERIAL);///week13 Step03-1

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

    if(ID==3) glColor3f(1,0,0);///選定的設紅色
    else glColor3f(1,1,1);///沒選設白色
    if(show[3])glmDraw(lowarmL , GLM_MATERIAL);///week13 Step03-1
    glPopMatrix();
    glutSwapBuffers();
}



Step03-1 移動中心點

修改部分程式只讓手臂出現


新增2段程式
成品

利用找到的中心點座標來選轉手臂
if(ID==1) glColor3f(1,0,0);///選定的設紅色
    else glColor3f(1,1,1);///沒選設白色
    if(show[1])glmDraw(body, GLM_MATERIAL);///week13 Step03-1
    glPushMatrix();
        glTranslatef(1.159999, 0.580000, 0);
        glRotatef(angle ,0,0,1);
        glTranslatef(-1.159999, -0.580000, 0);

在第71行幫angle設定函數

同樣方法弄到手上

同時轉動為完成

沒有留言:

張貼留言