2022年3月28日 星期一

*嗚嗚* Week06

# week06

上課內容:

  1. 今日主題:電腦圖學之父:Ivan Sutherland (Sketchpad)
  2. 課本範例:網址:jsyeh.org/3dcg10
    1. data.zip/解壓縮後/放進已解壓縮的window資料夾
    2. windows.zip/解壓縮後/打開Transformation.exe

    3. 公轉&自轉 的切換:在程式碼旁邊按右鍵/Swap Translate/Rotate

  3.  實作程式一:今天要教的概念是keyboard,我們一樣要先下載freeglut資料夾,並修改lib(最短的再變更短)。然後打開new GLUT project,並先複製之前的茶壺程式(最基本的程式)。今天的程式一,要能做到keyboard的互動,利用glutKeyboardFunc(keyboard)和定義keyboard的函式void keyboard(unsigned char key,int x,int y),再把鍵盤的值印出在小黑窗。記得使用printf(),必須要先引入#include<stdio.h>。程式碼(螢光筆是改變的地方):  #include <GL/glut.h>

    #include <stdio.h>
    void display()
    {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glColor3f(1,1,0);//顏色
    glutSolidTeapot(0.3);//實心茶壺的造型
    glutSwapBuffers();
    }
    void keyboard(unsigned char key,int x,int y)
    {
    printf("現在按下:%c 座標在:%d %d\n",key,x,y);
    }
    int main(int argc,char**argv)
    {
    glutInit(&argc,argv);
    glutInitDisplayMode( GLUT_DOUBLE | GLUT_DEPTH );
    glutCreateWindow("week06 keyboard");
    glutDisplayFunc( display );
    glutKeyboardFunc(keyboard);
    glutMainLoop();
    }
  4. 實作程式二之一:再加上mouse()和motion()函式,做到完整的互動。怕一次做太多,只有增加mouse()和motion()函式,並沒有完成程式。

  5. 實作程式二之二:使用glTranslatef()移動,並把函式都完成。現在茶壺會跟著滑鼠移動位置,按下鍵盤,會在小黑窗裡顯示位置座標。#include <GL/glut.h>
    #include <stdio.h>
    float x=0, y=0, z=0, oldX, oldY;
    void display()
    {
        glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
        glPushMatrix();
            glTranslatef(  (x-150)/150.0  , -(y-150)/150.0  ,  z  ); ///Maya: w
            ///glRotatef( angle,  0, 0, 1);
            ///glScalef( scale, scale, scale );
            glColor3f( 1, 1, 0 );
            glutSolidTeapot(0.3);
        glPopMatrix();
        glutSwapBuffers();
    }
    void keyboard( unsigned char key, int mouseX, int mouseY )
    {
        printf("現在按下:%c 座標在:%d %d\n", key, mouseX, mouseY);
    }
    void mouse( int button, int state, int mouseX, int mouseY )
    {
        oldX = mouseX; oldY = mouseY;
    }
    void motion( int mouseX, int mouseY )
    {
        x += (mouseX-oldX);
        y += (mouseY-oldY);
        oldX = mouseX; oldY = mouseY;
        display();
    }
    int main(int argc, char**argv)
    {
        glutInit(&argc, argv);
        glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH);
        glutCreateWindow("week06 keyboard mouse motion");
    
        glutDisplayFunc(display);
        glutKeyboardFunc(keyboard);
        glutMouseFunc(mouse);
        glutMotionFunc(motion);
    
        glutMainLoop();
    }

  6. 實作程式二之三:接下來,要完成"縮放"程式,利用變數float scale,再用if判斷式去判斷動作if (mouseX>oldX),就讓茶壺大小放大1%。小於的話,就會變小1%。改變motion函式,先把移動位置的函式註解掉,加上調整大小的函式。#include <GL/glut.h>
    #include <stdio.h>
    float x=0, y=0, z=0, scale=1.0, oldX, oldY;
    void display()
    {
        glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
        glPushMatrix();
            //glTranslatef(  (x-150)/150.0  , -(y-150)/150.0  ,  z  ); ///Maya: w
            ///glRotatef( angle,  0, 0, 1);
            glScalef( scale, scale, scale ); ///Maya: r
            glColor3f( 1, 1, 0 );
            glutSolidTeapot(0.3);
        glPopMatrix();
        glutSwapBuffers();
    }
    void keyboard( unsigned char key, int mouseX, int mouseY )
    {
        printf("現在按下:%c 座標在:%d %d\n", key, mouseX, mouseY);
    }
    void mouse( int button, int state, int mouseX, int mouseY )
    {
        oldX = mouseX; oldY = mouseY;
    }
    void motion( int mouseX, int mouseY )
    {
        if( mouseX>oldX ) scale = scale * 1.01;
        if( mouseX<oldX ) scale = scale * 0.99;
        //x += (mouseX-oldX);
        //y += (mouseY-oldY);
        oldX = mouseX; oldY = mouseY;
        display();
    }
    int main(int argc, char**argv)
    {
        glutInit(&argc, argv);
        glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH);
        glutCreateWindow("week06 keyboard mouse motion");
    
        glutDisplayFunc(display);
        glutKeyboardFunc(keyboard);
        glutMouseFunc(mouse);
        glutMotionFunc(motion);
    
        glutMainLoop();
    }

  7. 實作程式三之一:今天最厲害!我們要做一個模仿maya的快速按鍵WER,那我們先做W移動和R縮放的部分。if(key=='w' 或 key=='W') now=1移動。if(key=='r' 或 key=='R')now=3縮放。motion 裡去判斷我們按了W還是R。
#include <GL/glut.h>
#include <stdio.h>
float x=150, y=150, z=0, scale=1.0, angle=0.0, oldX, oldY;
int now=1;///1:移動, 2:旋轉, 3:縮放
void display()
{
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    glPushMatrix();
        glTranslatef( (x-150)/150.0 , -(y-150)/150.0 , z ); ///Maya: w
        //glRotatef( angle,  0, 0, 1); ///Maya: e
        glScalef( scale, scale, scale ); ///Maya: r
        glColor3f( 1, 1, 0 );
        glutSolidTeapot(0.3);
    glPopMatrix();
    glutSwapBuffers();
}
void keyboard( unsigned char key, int mouseX, int mouseY )
{   //printf("現在按下:%c 座標在:%d %d\n", key, mouseX, mouseY);
    if(key=='w' || key=='W') now=1;///移動 (小心不要中文)
    //if(key=='e' || key=='E') now=2;///旋轉
    if(key=='r' || key=='R') now=3;///縮放
}
void mouse( int button, int state, int mouseX, int mouseY )
{
    oldX = mouseX; oldY = mouseY;
}
void motion( int mouseX, int mouseY )
{
    if(now==1){///移動
        x += (mouseX-oldX);
        y += (mouseY-oldY);
    }else if(now==3){///縮放
        if( mouseX>oldX ) scale = scale * 1.01;
        if( mouseX<oldX ) scale = scale * 0.99;
    }
    oldX = mouseX; oldY = mouseY;
    display();
}
int main(int argc, char**argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH);
    glutCreateWindow("week06 keyboard mouse motion");

    glutDisplayFunc(display);
    glutKeyboardFunc(keyboard);
    glutMouseFunc(mouse);
    glutMotionFunc(motion);

    glutMainLoop();
}
   8.實作程式三之二:今天最後!再把E按鍵補上。E為旋轉。最後補充:glutInitWindowSize(500,500)可以放大視窗,但記得glTranslatef()裡面減一半除一半的值要做修改,茶壺才會在對的位置。#include <GL/glut.h>
#include <stdio.h>
float x=250, y=250, z=0, scale=1.0, angle=0.0, oldX, oldY;
int now=1;///1:移動, 2:旋轉, 3:縮放
void display()
{
    glClearColor(0.5, 0.5, 0.5, 1);///用來 Clear的色彩 R,G,B,A Alpha沒用到
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    glPushMatrix();
        glTranslatef( (x-250)/250.0 , -(y-250)/250.0 , z ); ///Maya: w
        glRotatef( angle,  0, 0, 1); ///Maya: e
        glScalef( scale, scale, scale ); ///Maya: r
        glColor3f( 1, 1, 0 );
        glutSolidTeapot(0.3);
    glPopMatrix();
    glutSwapBuffers();
}
void keyboard( unsigned char key, int mouseX, int mouseY )
{   //printf("現在按下:%c 座標在:%d %d\n", key, mouseX, mouseY);
    if(key=='w' || key=='W') now=1;///移動 (小心不要中文)
    if(key=='e' || key=='E') now=2;///旋轉
    if(key=='r' || key=='R') now=3;///縮放
}
void mouse( int button, int state, int mouseX, int mouseY )
{
    oldX = mouseX; oldY = mouseY;
}
void motion( int mouseX, int mouseY )
{
    if(now==1){///移動
        x += (mouseX-oldX);
        y += (mouseY-oldY);
    }else if(now==2){///旋轉
        angle += (mouseX-oldX);
    }else if(now==3){///縮放
        if( mouseX>oldX ) scale = scale * 1.01;
        if( mouseX<oldX ) scale = scale * 0.99;
    }
    oldX = mouseX; oldY = mouseY;
    display();
}
int main(int argc, char**argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH);
    glutInitWindowSize(500, 500);
    glutCreateWindow("week06 keyboard mouse motion");

    glutDisplayFunc(display);
    glutKeyboardFunc(keyboard);
    glutMouseFunc(mouse);
    glutMotionFunc(motion);

    glutMainLoop();
}




沒有留言:

張貼留言