2024年3月14日 星期四

C~電腦圖學日誌 Week04

主題: keyboard、mouse、motion、移動、旋轉、縮放

week04_mouse_glScalef

功能是能縮放大小的茶壺

1. 貼上10行程式碼~

    並加上glClearColor()跟glClear()把背景改顏色

 #include <GL/glut.h>

void display(){

    glClearColor(1.0, 1.0, 0.9, 1.0);///清背景的淡黃色

    glClear(GL_COLOR_BUFFER_BIT |GL_DEPTH_BUFFER_BIT);///清背景

    glutSolidTeapot( 0.3 );

    glutSwapBuffers();

}

int main(int argc, char*argv[])

{

    glutInit(&argc, argv);

    glutInitDisplayMode(GLUT_DOUBLE|GLUT_DEPTH);

    glutCreateWindow("week04 mouse glScalef");

    glutDisplayFunc(display);


    glutMainLoop();

}


2. 改寫成上周week03_mouse_glRotatef的程式碼(順便複習)

    功能是滑鼠點擊並拖動,茶壺會旋轉

#include <GL/glut.h>
float angle = 0;///旋轉角度
void display(){
    glClearColor(1.0, 0.0, 0.9, 1.0);
    glClear(GL_COLOR_BUFFER_BIT |GL_DEPTH_BUFFER_BIT);
    glPushMatrix();
        glRotatef(angle, 0, 0, 1);
        glutSolidTeapot( 0.3 );
    glPopMatrix();

    glutSwapBuffers();
}
void motion(int x, int y){
    angle =x;
    display();
}
int main(int argc, char*argv[])
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE|GLUT_DEPTH);
    glutCreateWindow("week04 mouse glScalef");
    glutDisplayFunc(display);
    glutMotionFunc(motion);

    glutMainLoop();
}

縮放

3. 改成只具有縮放功能的茶壺 

    點擊滑鼠後向左移動茶壺縮小/向右放大


#include <GL/glut.h>
///float angle = 0;///旋轉角度
float s = 1;///縮放的比例
void display(){
    glClearColor(1.0, 0.0, 0.9, 1.0);
    glClear(GL_COLOR_BUFFER_BIT |GL_DEPTH_BUFFER_BIT);
    glPushMatrix();
        ///glRotatef(angle, 0, 0, 1);
        glScalef(s, s, s);///縮放
        glutSolidTeapot( 0.3 );
    glPopMatrix();

    glutSwapBuffers();
}
void motion(int x, int y){
    ///angle =x;
    s = 1 + (x-150)/150.0;///縮放比例參數
    display();
}
int main(int argc, char*argv[])
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE|GLUT_DEPTH);
    glutCreateWindow("week04 mouse glScalef");
    glutDisplayFunc(display);
    glutMotionFunc(motion);

    glutMainLoop();
}


week04_keyboard_mouse_motion

功能是能輸出按下的鍵盤按鍵、當下滑鼠在茶壺視窗中的座標、滑鼠能控制茶壺的旋轉

1. 貼10行+1程式碼並加上自訂義keyboard()函式

    功能是能輸出按下的鍵盤按鍵和當下滑鼠在茶壺視窗中的座標

#include <GL/glut.h>
#include <stdio.h>
void display(){
    glClear(GL_COLOR_BUFFER_BIT |GL_DEPTH_BUFFER_BIT);
    glutSolidTeapot( 0.3 );
    glutSwapBuffers();
}
void keyboard(unsigned char key, int x, int y){
    printf("key: %c x: %d y: %d\n", key, x, y);
}
int main(int argc, char*argv[])
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE|GLUT_DEPTH);
    glutCreateWindow("week04 keyboard mouse motion");
    glutDisplayFunc(display);
    glutKeyboardFunc(keyboard);

    glutMainLoop();
}


2. 新增自訂義mouse()函式來記錄滑鼠點擊時的X座標

    新增自訂義motion()函式來控制茶壺旋轉方向

#include <GL/glut.h>
#include <stdio.h>
float angle = 0, oldX = 0;
void display(){
    glClear(GL_COLOR_BUFFER_BIT |GL_DEPTH_BUFFER_BIT);
    glPushMatrix();
        glRotatef(angle, 0, 0, 1);
        glutSolidTeapot( 0.3 );
    glPopMatrix();
    glutSwapBuffers();
}
void mouse(int button, int state, int x, int y){
    oldX = x;///當按下滑鼠時,紀錄他的位置
}
void motion(int x, int y){
    angle += (x-oldX);
    oldX = x;
    display();
}
void keyboard(unsigned char key, int x, int y){
    printf("key: %c x: %d y: %d\n", key, x, y);
}
int main(int argc, char*argv[])
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE|GLUT_DEPTH);
    glutCreateWindow("week04 keyboard mouse motion");
    glutDisplayFunc(display);
    glutKeyboardFunc(keyboard);///1
    glutMouseFunc(mouse);///2
    glutMotionFunc(motion);///3

    glutMainLoop();
}


Transformation自轉公轉

下載課本範例

1. 去https://jsyeh.org/3dcg10/下載windows跟data檔案

程式碼從下往上讀

自轉

glTranslatef(0.6, 0.0, 0.0)移動到右邊
glRotatef(95.0, 0.0, 1.0, 0.0)轉動中的
glScalef(0.5, 1.5, 1.0)高高瘦瘦的
glBegin()藍色車子

解讀完畢:
移動到右邊轉動中的高高瘦瘦的藍色車子
轉動中的高高瘦瘦的藍色車子
高高瘦瘦的藍色車子
藍色車子

公轉

glRotatef(-58.0, 0.0, 1.0, 0.0)整盤全部轉動
glTranslatef(-0.6, 0.0, 0.0)移動到左邊
glScalef(1.0, 1.0, 1.0)大小沒變
glBegin(.......)藍色車子

整個(移動到左邊大小沒變的藍色車子)全部轉動
移動到左邊大小沒變的藍色車子
大小沒變的藍色車子
藍色車子

week04_translate_rotate_scale

功能是位移後的茶壺在原地自轉

1. 修改week03_mouse_glRotatef的程式碼

    茶壺自動旋轉

自動轉(自轉)
#include <GL/glut.h>
#include <stdio.h>
float angle = 0, oldX = 0;
void display(){
    glClear(GL_COLOR_BUFFER_BIT |GL_DEPTH_BUFFER_BIT);
    glPushMatrix();
        glRotatef(angle++, 0, 0, 1);
        glutSolidTeapot( 0.3 );
    glPopMatrix();
    glutSwapBuffers();
}

int main(int argc, char*argv[])
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE|GLUT_DEPTH);
    glutCreateWindow("week04 translate rotate scale");
    glutDisplayFunc(display);
    glutIdleFunc(display);///加這行,有空就重畫畫面

    glutMainLoop();
}


2. 新增位移glTranslatef()跟縮放glScalef()

    放到右邊轉動中小小的茶壺

#include <GL/glut.h>
#include <stdio.h>
float angle = 0, oldX = 0;
void display(){
    glClear(GL_COLOR_BUFFER_BIT |GL_DEPTH_BUFFER_BIT);
    glPushMatrix();
        glTranslatef(0.8, 0, 0);///放到右邊
        glRotatef(angle++, 0, 0, 1);///轉動ing
        glScalef(0.3, 0.3, 0.3);///小小的
        glutSolidTeapot( 0.3 );///茶壺
    glPopMatrix();
    glutSwapBuffers();
}

int main(int argc, char*argv[])
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE|GLUT_DEPTH);
    glutCreateWindow("week04 translate rotate scale");
    glutDisplayFunc(display);
    glutIdleFunc(display);///加這行,有空就重畫畫面

    glutMainLoop();
}


3. 改變背景、茶壺的顏色

void display(){
    glClearColor(1.0, 0.0, 0.9, 1.0);
    glClear(GL_COLOR_BUFFER_BIT |GL_DEPTH_BUFFER_BIT);
    glPushMatrix();
        glTranslatef(0.8, 0, 0);///放到右邊
        glRotatef(angle++, 0, 0, 1);///轉動ing
        glScalef(0.3, 0.3, 0.3);///茶壺小小的
        glColor3f(0, 1, 0);///綠色的
        glutSolidTeapot( 0.3 );///茶壺
    glPopMatrix();
    glutSwapBuffers();
}

week04_rotate_translate_scale

功能是位移後的茶壺繞中心公轉

新增公轉版本

1. 交換glTranslatef跟glRotatef這兩行程式碼


交換完的順序:
glRotatef(angle++, 0, 0, 1);///轉動ing
glTranslatef(0.8, 0, 0);///放到右邊
glScalef(0.3, 0.3, 0.3);///茶壺小小的

Github

沒有留言:

張貼留言