2022年3月28日 星期一

RH的學習筆記٩(ˊᗜˋ*)و week06

 1.介紹電腦圖學之父 伊凡·蘇澤蘭(Ivan Edward Sutherland)

    生於美國內布拉斯加州黑斯挺斯,計算機科學家,被認為是「計算機圖形學之父。因1962年在麻省理工學院發明Sketchpad,拓展了計算機圖形學的領域,為1988年圖靈獎得主。

2.看課本範例

先到jsyeh.org/3dcg10 下載windows.zip/data.zip,將兩者解壓縮後把data放入windows裡面,並執行Transformation.exe

程式下方可以按右鍵Swap Translate/Rotate,能讓物件進行自轉或公轉的切換



3.鍵盤函式glutKeyboardfunc(),以鍵盤按鍵作為按鈕啟動函式,顯示當前滑鼠位置的座標



程式碼如下
#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函式

新增floatx,y,z三個茶壺座標;新增oldx、oldy用來記錄就座標,並將當前座標改成mousex、mousey;在設定加入motion、mouse。
mouse函式使當前座標化為舊座標
motion函式使茶壺座標等於舊座標減當前座標,以算出移動距離,並呼叫display函式


程式碼如下
#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);
        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");

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

    glutMainLoop();
}

5.修改第4篇的程式,改成能縮放

1.增加scale一個變數設成1.0
2.把gltranslation注解掉,新增glScalef
3.motion函式內改成
if(mousex>oldx) scale=scale *1.01;
if(mousex<oldx) scale=scale *0.99;
oldx=mousex;
oldy=mousey;
display();

6.修改第五篇的程式,將縮放、移動功能結合

1.增加新變數now=1,angle=0.0
2.display函式內增加glTranslation、Rotate
3.把keyboard增加三種案件功能w、e、r
4.motion函式增加if迴圈,假如now=1就移動、now=3就縮放

'w'、'W'鍵

'r'、'R'鍵


7.增加旋轉功能

1.先調整式窗大小    glutInitWindowSize(500,500);
2.把x,y,z中心點改成250
3.調整背景顏色    glClearColor(0.5,0.5,0.5,1); 灰色
4.motion函式增加
else if(now==2) ///旋轉
    {
        angle+=(mousex-oldx);
    }


三種功能使用後

最終程式碼如下

#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.4,0.4,1);   ///條背景色
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    glPushMatrix();
        glTranslatef((x-250)/250.0,-(y-250)/250.0,z);
        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);
    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");

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

    glutMainLoop();
}




沒有留言:

張貼留言