1 / 21

GLUT 事件處理函式

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

arvid
Download Presentation

GLUT 事件處理函式

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


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

  2. 大綱 • 註冊處理事件的 callback 函式 • 註冊鍵盤輸入的 callback • glutKeyboardFunc • glutSpecialFunc • 註冊滑鼠操作的 callback • glutMouseFunc • glutMotionFunc & glutPassiveMotionFunc • glutGetModifiers

  3. glutKeyboardFunc void glutKeyboardFunc(void (*func)(unsigned char key, int x, int y)); • 此函式註冊處理鍵盤輸入字元鍵的 callback 函式。當使用者在目前視窗中敲入能產生 ASCII 碼的按鍵時,GLUT 就會自動執行你所指定的 callback 函式,並傳入下列三項資料: • key: 輸入鍵的 ASCII 碼。 • x: 按鍵時滑鼠在視窗位置的 x 座標。 • y: 按鍵時滑鼠在視窗位置的 y 座標。

  4. 範例 • // 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);

  5. glutSpecialFunc void glutSpecialFunc(void (*func)(int key, int x, int y)); • 此函式註冊處理鍵盤輸入功能鍵或方向鍵的 callback 函式。當使用者在目前視窗中敲入功能鍵或方向鍵時,GLUT 就會自動執行你所指定的 callback 函式,並傳入下列三項資料: • key: 功能鍵或方向鍵的 GLUT 鍵名(見下一頁)。 • x: 按鍵時滑鼠在視窗位置的 x 座標。 • y: 按鍵時滑鼠在視窗位置的 y 座標。

  6. 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 鍵

  7. 範例 #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 (); }

  8. 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 }

  9. 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 }

  10. 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. */ }

  11. glutMouseFunc void 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: 按鈕操作發生時滑鼠的視窗座標。

  12. 範例 • 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() function • glutMouseFunc(handle_mouse_buttons);

  13. glutMotionFunc & glutPassiveMotionFunc void glutMotionFunc(void (*func)(int x, int y)); 此函式註冊處理滑鼠移動的 callback。按住任何一個滑鼠鈕在目前視窗中移動滑鼠時, GLUT 就會自動執行你所指定的 callback 函式。 void glutPassiveMotionFunc(void (*func)(int x, int y)); 此函式註冊處理滑鼠移動的 callback。當不按任何鈕地在目前視窗中移動滑鼠時, GLUT 就會自動執行你所指定的 callback 函式。 x, y: 移動時滑鼠在視窗位置的座標。

  14. glutGetModifiers int 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 鍵 • }

  15. 範例 /* * 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); }

  16. 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(); } }

  17. 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. */ }

  18. 範例 /* * 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); }

  19. 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(); }

  20. 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 (); }

  21. 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(); } }

More Related