2018年3月16日 星期五

Week03_黃偉愷

了解如何使用Shapes

(1) 從 http://www.cmlab.csie.ntu.edu.tw/~jsyeh/3dcg10/
     下載 data.zip, windows.zip, glut32.dll 三個檔案

(2) 將 glut32.dll 複製到 windows 資料夾內

(3) 打開 Shapes 

(4) 在 Command manipulation window (右邊的黑視窗) 上按右鍵可以更改顯示的圖形

(5) 在每個數值上按住上下拖曳可以調整數值的大小

(6) 在 Screen-space view (左邊的視窗) 上按右鍵選 Toggle big vertices 可以將圖形的頂點放大

(7) 在 Screen-space view (左邊的視窗) 上按右鍵選 Toggle drawing outlines 可以幫圖形加上邊框

繪製茶壺
(1) 先新增一個 GLUT project (依照上週的步驟新增)

code:

#include <stdio.h>
#include <GL/glut.h> //整GLUT外掛
void display()
{
    glClear(GL_COLOR_BUFFER_BIT  | GL_DEPTH_BUFFER_BIT);
    glutSolidTeapot(0.3);
    glutSwapBuffers(); //搭配GLUT_DOUBLE兩倍顯示
}

int main(int argc, char** argv)
{
    glutInit(&argc,argv);//初始的參數,照著丟進去
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH);//2個顯示的參數
    glutCreateWindow("Week03 Mouse");//設定視窗的名稱
    glutDisplayFunc(display);
    //glutMouseFunc(mouse);
    //glutMotionFunc(motion);
    glutMainLoop();//主要GLUT迴圈
}


將 Code::Blocks 的編輯區放大

(1) View -> Perspectives -> Code::Blocks minimal

印出滑鼠點擊的座標以及狀態

(1) button: 0代表左鍵,1代表中鍵(滾輪)下壓,2代表右鍵,3代表中鍵(滾輪)下滾,4代表中鍵(滾輪)上滾

code:

#include <stdio.h>
#include <GL/glut.h> //整GLUT外掛
void display()
{
    glClear(GL_COLOR_BUFFER_BIT  | GL_DEPTH_BUFFER_BIT);
    glutSolidTeapot(0.3);
    glutSwapBuffers(); //搭配GLUT_DOUBLE兩倍顯示
}
void mouse(int button, int state, int x, int y)
{
    printf("%d %d %d %d\n",button, state,x,y);
    //button: 左, 中, 右鍵
    //state: 按下去/彈起來
    //x,y: mouse 位置
}
int main(int argc, char** argv)
{
    glutInit(&argc,argv);//初始的參數,照著丟進去
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH);//2個顯示的參數
    glutCreateWindow("Week03 Mouse");//設定視窗的名稱
    glutDisplayFunc(display);
    glutMouseFunc(mouse);
    //glutMotionFunc(motion);
    glutMainLoop();//主要GLUT迴圈
}

取得圖形每個頂點的座標

(1) 在圖形上任意點點擊即可將對應的座標印出,mouse下壓才會紀錄

code:

#include <stdio.h>
#include <GL/glut.h> //整GLUT外掛
void display()
{
    glClear(GL_COLOR_BUFFER_BIT  | GL_DEPTH_BUFFER_BIT);
    glutSolidTeapot(0.3);
    glutSwapBuffers(); //搭配GLUT_DOUBLE兩倍顯示
}
void mouse(int button, int state, int x, int y)
{
    if(state == GLUT_DOWN)
    {
        printf("   glVertex2f(%f, %f);\n", (x-150)/150.0, (150-y)/150.0);
    }
}
int main(int argc, char** argv)
{
    glutInit(&argc,argv);//初始的參數,照著丟進去
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH);//2個顯示的參數
    glutCreateWindow("Week03 Mouse");//設定視窗的名稱
    glutDisplayFunc(display);
    glutMouseFunc(mouse);
    //glutMotionFunc(motion);
    glutMainLoop();//主要GLUT迴圈
}

(2) 將所有點複製貼回程式碼


讓圖形可以跟著滑鼠一起移動(1)

(1) 此款滑鼠的游標(紅圈處)在移動過程中會位於圖形的中心點
並且圖形的中心點會一直黏著游標


code:

#include <stdio.h>
#include <GL/glut.h> //整GLUT外掛
float teapotX=0, teapotY=0;
void display()
{
    glClear(GL_COLOR_BUFFER_BIT  | GL_DEPTH_BUFFER_BIT);
    glPushMatrix();//備份矩陣
        glTranslatef(teapotX, teapotY, 0); //依照茶壺的座標移動
        glutSolidTeapot(0.3);
    glPopMatrix();//還原矩陣
    glutSwapBuffers(); //搭配GLUT_DOUBLE兩倍顯示
}
/*void mouse(int button, int state, int x, int y)
{
    if(state == GLUT_DOWN)
    {
        printf("   glVertex2f(%f, %f);\n", (x-150)/150.0, (150-y)/150.0);
    }
}*/
void motion(int x, int y) //mouse motion 事件
{
    teapotX = (x-150)/150.0; // 依照motion時的x來改teapot的座標
    teapotY = (150-y)/150.0;// 依照motion時的y來改teapot的座標
    glutPostRedisplay(); //重畫畫面
}
int main(int argc, char** argv)
{
    glutInit(&argc,argv);//初始的參數,照著丟進去
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH);//2個顯示的參數
    glutCreateWindow("Week03 Mouse");//設定視窗的名稱
    glutDisplayFunc(display);
    //glutMouseFunc(mouse);
    glutMotionFunc(motion);
    glutMainLoop();//主要GLUT迴圈
}

讓圖形可以跟著滑鼠一起移動(2)

(1) 此款在移動的過成中圖形的中心點不會黏著游標(紅圈處),類似Googol Map在移動地圖的感覺


code:


#include <stdio.h>
#include <GL/glut.h> //整GLUT外掛
float teapotX=0, teapotY=0; //茶壺的座標
int oldX=0, oldY=0; //紀錄mouse在哪裡按下去
void display()
{
    glClear(GL_COLOR_BUFFER_BIT  | GL_DEPTH_BUFFER_BIT);
    glPushMatrix();//備份矩陣
        glTranslatef(teapotX, teapotY, 0); //依照茶壺的座標移動
        glutSolidTeapot(0.3);
    glPopMatrix();//還原矩陣
    glutSwapBuffers(); //搭配GLUT_DOUBLE兩倍顯示
}
void mouse(int button, int state, int x, int y)
{
    oldX = x;
    oldY = y;
    //紀錄按下去的點在哪裡
}
void motion(int x, int y) //mouse motion 事件
{
    teapotX += (x-oldX)/150.0;
    teapotY += (oldY-y)/150.0;
    oldX = x;       oldY = y;  //紀錄移動後新的位置
    glutPostRedisplay(); //重畫畫面
}
int main(int argc, char** argv)
{
    glutInit(&argc,argv);//初始的參數,照著丟進去
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH);//2個顯示的參數
    glutCreateWindow("Week03 Mouse");//設定視窗的名稱
    glutDisplayFunc(display);
    glutMouseFunc(mouse);
    glutMotionFunc(motion);
    glutMainLoop();//主要GLUT迴圈
}

沒有留言:

張貼留言