2024年3月7日 星期四

從0到0.01的電腦圖學 Week03

本日主題: 

a. mouse 滑鼠

b. 移動glTranslatef(x,y,z);

c. 旋轉glRotatef(angle,x,y,z)

教材地點
https://jsyeh.org/3dcg10/

下載資料
    a. 05/04 Examples:[data]
    b. 05/04
 Examples:[win32]

1. GLUT程式1:使用滑鼠點擊視窗,小黑顯示文字

#include <GL/glut.h>
#include <stdio.h> //為了printf()
void mouse(int button, int state, int x, int y){
    printf("Hello Mouse!\n");
}

void display(){
    glutSolidTeapot(0.5);
    glutSwapBuffers();
}
int main(int argc, char *argv[]){
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
    glutCreateWindow("week03 mouse");
    glutDisplayFunc(display);
    glutMouseFunc(mouse); //宣告mouse函式
    glutMainLoop();
}

2. GLUT程式2:解析mouse 函式的參數

  • button :0為滑鼠左鍵,1為滑鼠中鍵,2為滑鼠右鍵
  • state:0為按下,1為鬆開
  • x:紀錄x座標點
  • y:紀錄y座標點

#include <GL/glut.h>
#include <stdio.h> //為了printf()
void mouse(int button, int state, int x, int y){
    //printf("Hello Mouse!\n");
    printf("%d %d %d %d\n",button, state,x,y); //打印參數訊息
}
void display(){
    glutSolidTeapot(0.5);
    glutSwapBuffers();
}
int main(int argc, char *argv[]){
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
    glutCreateWindow("week03 mouse");
    glutDisplayFunc(display);
    glutMouseFunc(mouse); //宣告mouse函式
    glutMainLoop();
}
3. GLUT程式3:使用mouse 函式紀錄圖形座標
#include <GL/glut.h>
#include <stdio.h> //為了printf()

void mouse(int button, int state, int x, int y){
    if(state==GLUT_DOWN) printf("glVertex2f((%d-image_x/2)/(image_x/2),-(%d-image_y/2)/image_y/2);\n",x,y);
}

void display(){
    glutSolidTeapot(0.5);
    glutSwapBuffers();
}

int main(int argc, char *argv[]){
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
    glutCreateWindow("week03 mouse");
    glutDisplayFunc(display);
    glutMouseFunc(mouse); //宣告mouse函式
    glutMainLoop();
}
4.範例程式碼:將data資料夾拉進windows(不要解壓縮)
    
windows→Transformation
5. GLUT程式4:使用glTranslatef(x,y,z)更新物件座標點
  • x:x座標點
  • y:y座標點
  • z:z座標點(設定0為平面)
#include <GL/glut.h>
#include <stdio.h>
float teapotX = 0,teapotY = 0; //設定茶壺的座標點

//當滑鼠事件發生,重設座標
void mouse(int button, int state, int x, int y){
    teapotX = (x-150)/150.0;
    teapotY = -(y-150)/150.0;
}
void display(){
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);//清除前一刻畫面
    glPushMatrix();
        glTranslatef(teapotX,teapotY,0);//更新茶壺的座標
        glutSolidTeapot(0.2);
    glPopMatrix();
    glutSwapBuffers();
}
int main(int argc, char *argv[]){
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
    glutCreateWindow("week03 mouse");
    glutDisplayFunc(display);
    glutMouseFunc(mouse);
    glutMainLoop();
}
6. 3D的轉動軸向
使用right-hand rule
右手拇指表示其空間中的向量,而四指的方向為正向轉動,負向轉動則是與四指轉動方向相反
下圖則是三個軸向的正向
7. GLUT程式5:使用glRotatef(angle,x,y,z)更新物件角度
#include <GL/glut.h>
#include <stdio.h>
float angle = 0; //設定角度
void display(){
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);//清除前一刻畫面
    glPushMatrix();
        glRotated(angle,0,0,1);//更新滑鼠角度
        glutSolidTeapot(0.2);
    glPopMatrix();
    glutSwapBuffers();
}
void motion(int x,int y){
    angle = x; //以x軸為基準,滑鼠點擊拖曳時,角度隨x軸的移動距離改變
    display();
}
int main(int argc, char *argv[]){
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
    glutCreateWindow("week03 mouse");
    glutDisplayFunc(display);
    glutMotionFunc(motion);//宣告motion的函數
    glutMainLoop();
}
8. GLUT程式6:使用keyboard(key,x,y)擷取按鍵按下的訊息
#include <GL/glut.h>
#include <stdio.h>
float teapotX = 0,teapotY = 0;
float angle = 0;
int method = 1; //1轉動 2 移動
int oldX = 0, oldY = 0; //舊的座標
void mouse(int button, int state, int x, int y){
    oldX = x;
    oldY = y;
}
void display(){
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);//清除前一刻畫面
    glPushMatrix();
        glTranslatef(teapotX,teapotY,0);
        glRotated(angle,0,0,1);
        glutSolidTeapot(0.2);
    glPopMatrix();
    glutSwapBuffers();
}
void motion(int x,int y){
    if(method == 1){
        angle += x - oldX;
    }
    else if(method == 2){
        teapotX += (x-oldX)/150.0;
        teapotY -= (y-oldY)/150.0;
    }
    oldX = x;
    oldY = y;
    display();
}
void keyboard(unsigned char key, int x, int y){
    if(key == 'e')method = 1; //轉動
    if(key == 'w')method = 2; //移動
}
int main(int argc, char *argv[]){
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
    glutCreateWindow("week03 mouse");
    glutDisplayFunc(display);
    glutMouseFunc(mouse);
    glutMotionFunc(motion);
    glutKeyboardFunc(keyboard); //使用按件切換模式
    glutMainLoop();
}

You say that I’m paranoid
But I’m pretty sure the world is out to get me
It’s not like I make the choice
To let my mind stay so fucking messy
I know I’m not the center of the universe
But you keep spinning ’round me just the same

I’m holding on
Why is everything so heavy?
Holding on
So much more than I can carry
I keep dragging around what’s bringing me down
If I just let go, I’d be set free
Holding on
Why is everything so heavy?

----Heavy , Linkin Park ft. Kiiara

沒有留言:

張貼留言