21
GLUT 事事事事事事 事事事事事事事 事事事 事事事 2003-2006

GLUT 事件處理函式

  • Upload
    arvid

  • View
    123

  • Download
    0

Embed Size (px)

DESCRIPTION

GLUT 事件處理函式. 靜宜大學資管系 蔡奇偉 副教授 2003-2006. 大綱. 註冊處理事件的 callback 函式 註冊鍵盤輸入的 callback glutKeyboardFunc glutSpecialFunc 註冊滑鼠操作的 callback glutMouseFunc glutMotionFunc & glutPassiveMotionFunc glutGetModifiers. glutKeyboardFunc. void glutKeyboardFunc(void (*func)(unsigned char key, - PowerPoint PPT Presentation

Citation preview

Page 1: GLUT  事件處理函式

GLUT 事件處理函式靜宜大學資管系蔡奇偉 副教授2003-2006

Page 2: GLUT  事件處理函式

大綱 註冊處理事件的 callback 函式 註冊鍵盤輸入的 callback

glutKeyboardFunc glutSpecialFunc

註冊滑鼠操作的 callback glutMouseFunc glutMotionFunc & glutPassiveMotionFunc

glutGetModifiers

Page 3: GLUT  事件處理函式

glutKeyboardFuncvoid glutKeyboardFunc(void (*func)(unsigned char key, int x, int y));

此函式註冊處理鍵盤輸入字元鍵的 callback 函式。當使用者在目前視窗中敲入能產生 ASCII 碼的按鍵時, GLUT 就會自動執行你所指定的 callback 函式,並傳入下列三項資料:

• key: 輸入鍵的 ASCII 碼。• x: 按鍵時滑鼠在視窗位置的 x 座標。• y: 按鍵時滑鼠在視窗位置的 y 座標。

Page 4: GLUT  事件處理函式

範例// draw_triangle(), draw_square(), and draw_circle() are// functions to darw a triangle, a square, and a circle,// respectively.void draw_figure (unsigned char key, int x, int y){

switch (key) {case ‘1’: draw_triangle(); break;case ‘2’: draw_square(); break;case ‘3’: draw_circle(); break;

}glutPostRedisplay(); // update the window

}

// in main() function// glutKeyboardFunc(draw_figure);

Page 5: GLUT  事件處理函式

glutSpecialFuncvoid glutSpecialFunc(void (*func)(int key, int x, int y));

此函式註冊處理鍵盤輸入功能鍵或方向鍵的 callback 函式。當使用者在目前視窗中敲入功能鍵或方向鍵時, GLUT 就會自動執行你所指定的 callback 函式,並傳入下列三項資料:

• key: 功能鍵或方向鍵的 GLUT 鍵名(見下一頁)。• x: 按鍵時滑鼠在視窗位置的 x 座標。• y: 按鍵時滑鼠在視窗位置的 y 座標。

Page 6: GLUT  事件處理函式

GLUT 鍵名 按鍵GLUT_KEY_F1 F1 功能鍵GLUT_KEY_F2 F2 功能鍵GLUT_KEY_F3 F3 功能鍵GLUT_KEY_F4 F4 功能鍵GLUT_KEY_F5 F5 功能鍵GLUT_KEY_F6 F6 功能鍵GLUT_KEY_F7 F7 功能鍵GLUT_KEY_F8 F8 功能鍵GLUT_KEY_F9 F9 功能鍵GLUT_KEY_F10 F10 功能鍵GLUT_KEY_F11 F11 功能鍵GLUT_KEY_F12 F12 功能鍵GLUT_KEY_LEFT 方向鍵GLUT_KEY_UP 方向鍵GLUT_KEY_RIGHT 方向鍵GLUT_KEY_DOWN 方向鍵GLUT_KEY_PAGE_UP Page up 方向鍵GLUT_KEY_PAGE_DOWN Page down 方向鍵GLUT_KEY_HOME Home 方向鍵GLUT_KEY_END End 方向鍵GLUT_KEY_INSERT Insert 鍵

Page 7: GLUT  事件處理函式

#include <GL/glut.h>int window_width = 250, window_height = 250;float center_x = 0.5, center_y = 0.5, half_width = 0.25;const float inc_amount = 0.01;

void display(void){ glClear (GL_COLOR_BUFFER_BIT); /* clear all pixels */ glColor3f (1.0, 1.0, 1.0); glBegin(GL_POLYGON); glVertex3f (center_x - half_width, center_y - half_width, 0.0); glVertex3f (center_x + half_width, center_y - half_width, 0.0); glVertex3f (center_x + half_width, center_y + half_width, 0.0); glVertex3f (center_x - half_width, center_y + half_width, 0.0); glEnd(); glFlush ();}

範例

Page 8: GLUT  事件處理函式

void handle_special_key (int key, int x, int y){

switch (key) {case GLUT_KEY_LEFT:

if (center_x >= half_width)center_x -= inc_amount;

break;case GLUT_KEY_RIGHT:

if (1.0 - center_x >= half_width)center_x += inc_amount;

break;case GLUT_KEY_UP:

if (1.0 - center_y >= half_width)center_y += inc_amount;

break;case GLUT_KEY_DOWN:

if (center_y >= half_width)center_y -= inc_amount;

break;}glutPostRedisplay(); // update the window

}

Page 9: GLUT  事件處理函式

void handle_key (unsigned char key, int x, int y){

switch (key) {case 's':

if (half_width >= 0.1)half_width -= inc_amount;

break;case 'l':

if (half_width < 0.5)half_width += inc_amount;

break;}glutPostRedisplay(); // update the window

}

Page 10: GLUT  事件處理函式

int main(int argc, char** argv){ glutInit(&argc, argv); glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB); glutInitWindowSize (window_width, window_height); glutInitWindowPosition (100, 100); glutCreateWindow ("hello");

init (); glutDisplayFunc(display);

glutKeyboardFunc(handle_key); glutSpecialFunc(handle_special_key);

glutMainLoop(); return 0; /* ANSI C requires main to return int. */}

Page 11: GLUT  事件處理函式

glutMouseFuncvoid glutMouseFunc(void (*func)(int button, int state, int x, int y));此函式註冊處理滑鼠按鈕的 callback 。當滑鼠按鈕在目前視窗中按下或放開時, GLUT 就會自動執行你所指定的 callback 函式。button: 下列三種按鈕值之一

• GLUT_LEFT_BUTTON (左按鈕)• GLUT_MIDDLE_BUTTON (中按鈕)• GLUT_RIGHT_BUTTON (右按鈕)

state: 按鈕的狀態• GLUT_UP (放開按鈕)• GLUT_DOWN (壓下按鈕)

x, y: 按鈕操作發生時滑鼠的視窗座標。

Page 12: GLUT  事件處理函式

範例void handle_mouse_buttons (int button, int state, int x, int y){

if (state == GLUT_DOWN) { // 只處理壓下滑鼠按鈕switch (button) {

case GLUT_LEFT_BUTTON:// 處理滑鼠的左按鈕break;

case GLUT_MIDDLE_BUTTON:// 處理滑鼠的中按鈕break;

case GLUT_RIGHT_BUTTON:// 處理滑鼠的右按鈕break;

}}

}

// in main() functionglutMouseFunc(handle_mouse_buttons);

Page 13: GLUT  事件處理函式

glutMotionFunc & glutPassiveMotionFunc void glutMotionFunc(void (*func)(int x, int y));

此函式註冊處理滑鼠移動的 callback 。按住任何一個滑鼠鈕在目前視窗中移動滑鼠時, GLUT 就會自動執行你所指定的 callback 函式。

x, y: 移動時滑鼠在視窗位置的座標。

void glutPassiveMotionFunc(void (*func)(int x, int y));

此函式註冊處理滑鼠移動的 callback 。當不按任何鈕地在目前視窗中移動滑鼠時, GLUT 就會自動執行你所指定的 callback 函式。

Page 14: GLUT  事件處理函式

glutGetModifiersint glutGetModifiers(void);

GLUT_ACTIVE_SHIFT 若按下 Shift 鍵或 Caps Lock 鍵GLUT_ACTIVE_CTRL 若按下 Ctrl 鍵GLUT_ACTIVE_ALT 若按下 Alt 鍵此函式傳回鍵盤輸入或滑鼠操作時的修飾鍵狀態。在鍵盤 callback 或滑鼠 callback 中,你可以把函式的傳回值和上面的三個常數做 bit AND 運算來測試那一個修飾鍵被按下。譬如:

int modifier_key = glutGetModifiers();if (modifier_key & GLUT_ACTIVE_CTRL) {

// 按下 Ctrl 鍵}

Page 15: GLUT  事件處理函式

/* * mouseclick.c * This is a simple, introductory OpenGL program. */#include <GL/glut.h>#include <stdio.h>

int window_width = 250, window_height = 250;const int max_point = 100;

GLint x_coord[max_point], y_coord[max_point];int nPoints = 0;

inline GLfloat x_convert (int x){

return x/(window_width-1.0);}

inline GLfloat y_convert (int y){

return 1.0 - y /(window_height-1.0);}

範例

Page 16: GLUT  事件處理函式

void display(void){ glClear (GL_COLOR_BUFFER_BIT); /* clear all pixels */

glColor3f (1.0, 1.0, 1.0); glBegin(GL_POINTS); for (int i = 0; i < nPoints; i++) {

glVertex3f (x_convert(x_coord[i]), y_convert(y_coord[i]), 0.0); } glEnd();

glFlush ();}

void handle_mouseclick (int button, int state, int x, int y){

if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {if (nPoints == max_point) nPoints = 0;x_coord[nPoints] = x;y_coord[nPoints] = y;nPoints++;glutPostRedisplay();

}}

Page 17: GLUT  事件處理函式

int main(int argc, char** argv){ glutInit(&argc, argv); glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB); glutInitWindowSize (window_width, window_height); glutInitWindowPosition (100, 100); glutCreateWindow ("mouseclick"); init ();

glutDisplayFunc(display);

glutMouseFunc(handle_mouseclick);

glutMainLoop(); return 0; /* ANSI C requires main to return int. */}

Page 18: GLUT  事件處理函式

/* * hermite.c * This is a simple, introductory OpenGL program. */#include <GL/glut.h>#include <stdio.h>

int window_width = 250, window_height = 250;GLfloat x_coord[3], y_coord[3];int nPoints = 0;

inline GLfloat x_convert (int x){

return x/(float)(window_width-1);}

inline GLfloat y_convert (int y){

return 1.0 - y /(float)(window_height-1);}

範例

Page 19: GLUT  事件處理函式

void HermiteCurve(int n){ float t, dt, t2, t3, f1, f2, f3, f4;

dt = 1.0/n; // t runs from 0 to 1. GLfloat PT0_x = x_coord[1] - x_coord[0]; GLfloat PT0_y = y_coord[1] - y_coord[0]; GLfloat PT1_x = x_coord[2] - x_coord[1]; GLfloat PT1_y = y_coord[2] - y_coord[1]; glBegin(GL_LINE_STRIP);

for (t = 0.0; t <= 1.0; t += dt) { t2 = t * t; t3 = t2 * t; // t3 = t * t * t f1 = 2.0*t3 - 3.0*t2 + 1.0; f2 = -2.0*t3 + 3.0*t2; f3 = t3 - 2.0*t2 + t; f4 = t3 - t2; glVertex2f( f1*x_coord[0] + f2*x_coord[2] + f3*PT0_x + f4*PT1_x, f1*y_coord[0] + f2*y_coord[2] + f3*PT0_y + f4*PT1_y ); } glEnd();}

Page 20: GLUT  事件處理函式

void display(void){ glClear (GL_COLOR_BUFFER_BIT); /* clear all pixels */

glColor3f (0.0, 1.0, 0.0); glBegin(GL_LINE_STRIP); for (int i = 0; i < nPoints; i++) {

glVertex3f (x_coord[i], y_coord[i], 0.0); } glEnd();

if (nPoints == 3) {glColor3f (1.0, 1.0, 1.0);HermiteCurve(20);

}

glFlush ();}

Page 21: GLUT  事件處理函式

void handle_mouseclick (int button, int state, int x, int y){

if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {if (nPoints == 3) nPoints = 0;x_coord[nPoints] = x_convert(x);y_coord[nPoints] = y_convert(y);nPoints++;glutPostRedisplay();

}}