OpenGL滑鼠操作

滑鼠操作類似於圖像顯示,都是由OpenGL函數調取自己編寫的觸發事件來實現的。首先來看主函數:

void main(int argc, char** argv)n{nt//初始化GLntglutInit(&argc, argv);nt//設置顯示參數(雙緩存,RGB格式)ntglutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);nt//設置窗口尺寸:width*heightntglutInitWindowSize(width, height);nt//設置窗口位置:在屏幕左上角像素值(100,100)處ntglutInitWindowPosition(100, 100);nt//設置窗口名稱ntglutCreateWindow("OpenGL");nt//顯示函數,display事件需要自行編寫ntglutDisplayFunc(display);nt//滑鼠點擊函數,mouse_hit事件需要自行編寫ntglutMouseFunc(mouse_hit);nt//滑鼠拖動函數,mouse_move事件需要自行編寫ntglutMotionFunc(mouse_move);nnnt//重複循環GLUT事件ntglutMainLoop();n}n

其中,滑鼠操作函數為:

tglutMouseFunc(mouse_hit);ntglutMotionFunc(mouse_move);n

與顯示函數glutDisplayFunc(display)相同,滑鼠操作函數括弧內的GLUT相關事件mouse_hit與mouse_move也需自行編寫

滑鼠點擊事件

void mouse_hit(int button, int state, int x, int y)n

有四個參數:

參數int button:表示滑鼠按鍵,包括左鍵(GLUT_LEFT_BUTTON)、中鍵(GLUT_MIDDLE_BUTTON)、右鍵(GLUT_RIGHT_BUTTON),也可分別用整數0、1、2表示

參數int state:表示滑鼠按鍵狀態,包括按下(GLUT_DOWN)和抬起(GLUT_UP),也可分別用整數0和1表示

參數int x, int y:表示滑鼠所在坐標

滑鼠移動事件

void mouse_move(int x, int y)n

僅有兩個參數,int x, int y表示滑鼠所在坐標

為了操作方便,首先設置一些全局變數以便在滑鼠操作和顯示事件中共用

//窗口長寬nint width = 400, height = 400;n//滑鼠點擊位置nint hit_pos_x, hit_pos_y;n//滑鼠拖動位置nint move_pos_x, move_pos_y;n//滑鼠操作種類nint button_kind = -1;n

滑鼠點擊事件:(省略了中鍵操作,省略了按鍵抬起(GLUT_UP)的設置)

void mouse_hit(int button, int state, int x, int y)n{nt//滑鼠操作種類賦值ntbutton_kind = button;nnt//滑鼠操作基本結構ntswitch (button)nt{ntcase GLUT_LEFT_BUTTON:t//左鍵操作,也可為數字0nttif (state == GLUT_DOWN)t//左鍵按下時ntt{nttt//記錄按鍵位置nttthit_pos_x = x;tnttthit_pos_y = y;ntt}nttbreak;ntcase GLUT_RIGHT_BUTTON:t//右鍵操作,也可為數字1nttif (state == GLUT_DOWN)t//右鍵按下時ntt{nttt//記錄按鍵位置nttthit_pos_x = x;nttthit_pos_y = y;ntt}nttbreak;ntdefault:nttbreak;nt}n}n

滑鼠移動事件:

void mouse_move(int x, int y)n{nt//滑鼠移動時操作種類設為3(0 1 2分別為左鍵、中鍵、右鍵)ntbutton_kind = 3;nt//記錄拖動位置ntmove_pos_x = x;ntmove_pos_y = y;n}n

顯示事件:

void display()n{nt// 清除屏幕ntglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);nnt//重新設置OpenGL窗口:原點位置為左上角,x軸從左到右,y軸從上到下,坐標值與像素坐標值相同ntglViewport(0, 0, (GLsizei)width, (GLsizei)height);ntglMatrixMode(GL_PROJECTION);ntglLoadIdentity();ntgluOrtho2D(0, width, height, 0);nntif (button_kind == 0)t//左鍵點擊nt{ntt//畫一個藍色的點nttglPointSize(20);nttglBegin(GL_POINTS);nttglColor3f(0.0f, 0.0f, 1.0f);nttglVertex2f(hit_pos_x, hit_pos_y);nttglEnd();nt}ntelse if (button_kind == 2)t//右鍵點擊nt{ntt//畫一個綠色的點nttglPointSize(20);nttglBegin(GL_POINTS);nttglColor3f(0.0f, 1.0f, 0.0f);nttglVertex2f(hit_pos_x, hit_pos_y);nttglEnd();nt}ntelse if (button_kind == 3)t//滑鼠拖動nt{ntt//沿拖動軌跡畫一條紅色的線nttglLineWidth(5);nttglColor3f(1.0f, 0.0f, 0.0f);nttglBegin(GL_LINES);nttglVertex2f(hit_pos_x, hit_pos_y);nttglVertex2f(move_pos_x, move_pos_y);nttglEnd();nt}nnt//雙緩存交換緩存以顯示圖像ntglutSwapBuffers();nt//每次更新顯示ntglutPostRedisplay();n}n

結果:(分別為左鍵點擊、右鍵點擊、拖動滑鼠)

完整代碼:

#include "glut.h"n//窗口長寬nint width = 400, height = 400;n//滑鼠點擊位置nint hit_pos_x, hit_pos_y;n//滑鼠拖動位置nint move_pos_x, move_pos_y;n//滑鼠操作種類nint button_kind = -1;nnnvoid display()n{nt// 清除屏幕ntglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);nnt//重新設置OpenGL窗口:原點位置為左上角,x軸從左到右,y軸從上到下,坐標值與像素坐標值相同ntglViewport(0, 0, (GLsizei)width, (GLsizei)height);ntglMatrixMode(GL_PROJECTION);ntglLoadIdentity();ntgluOrtho2D(0, width, height, 0);nntif (button_kind == 0)t//左鍵點擊nt{ntt//畫一個藍色的點nttglPointSize(20);nttglBegin(GL_POINTS);nttglColor3f(0.0f, 0.0f, 1.0f);nttglVertex2f(hit_pos_x, hit_pos_y);nttglEnd();nt}ntelse if (button_kind == 2)t//右鍵點擊nt{ntt//畫一個綠色的點nttglPointSize(20);nttglBegin(GL_POINTS);nttglColor3f(0.0f, 1.0f, 0.0f);nttglVertex2f(hit_pos_x, hit_pos_y);nttglEnd();nt}ntelse if (button_kind == 3)t//滑鼠拖動nt{ntt//沿拖動軌跡畫一條紅色的線nttglLineWidth(5);nttglColor3f(1.0f, 0.0f, 0.0f);nttglBegin(GL_LINES);nttglVertex2f(hit_pos_x, hit_pos_y);nttglVertex2f(move_pos_x, move_pos_y);nttglEnd();nt}nnt//雙緩存交換緩存以顯示圖像ntglutSwapBuffers();nt//每次更新顯示ntglutPostRedisplay();n}nnvoid mouse_hit(int button, int state, int x, int y)n{nt//滑鼠操作種類賦值ntbutton_kind = button;nnt//滑鼠操作基本結構ntswitch (button)nt{ntcase GLUT_LEFT_BUTTON:t//左鍵操作,也可為數字0nttif (state == GLUT_DOWN)t//左鍵按下時ntt{nttt//記錄按鍵位置nttthit_pos_x = x;tnttthit_pos_y = y;ntt}nttbreak;ntcase GLUT_RIGHT_BUTTON:t//右鍵操作,也可為數字1nttif (state == GLUT_DOWN)t//右鍵按下時ntt{nttt//記錄按鍵位置nttthit_pos_x = x;nttthit_pos_y = y;ntt}nttbreak;ntdefault:nttbreak;nt}n}nnvoid mouse_move(int x, int y)n{nt//滑鼠移動時操作種類設為3(0 1 2分別為左鍵、中鍵、右鍵)ntbutton_kind = 3;nt//記錄拖動位置ntmove_pos_x = x;ntmove_pos_y = y;n}nnvoid main(int argc, char** argv)n{nt//初始化GLntglutInit(&argc, argv);nt//設置顯示參數(雙緩存,RGB格式)ntglutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);nt//設置窗口尺寸:width*heightntglutInitWindowSize(width, height);nt//設置窗口位置:在屏幕左上角像素值(100,100)處ntglutInitWindowPosition(100, 100);nt//設置窗口名稱ntglutCreateWindow("OpenGL");nt//顯示函數,display事件需要自行編寫ntglutDisplayFunc(display);nt//滑鼠點擊函數,mouse_hit事件需要自行編寫ntglutMouseFunc(mouse_hit);nt//滑鼠拖動函數,mouse_move事件需要自行編寫ntglutMotionFunc(mouse_move);nnnt//重複循環GLUT事件ntglutMainLoop();n}n

推薦閱讀:

怎樣通過靜態路由實現跨網段互通?
計算機專業需要什麼素養或者說品質?
如何評價2016年數學建模國賽?
計算機圖書方面,在 Kindle 或 Kindle for iPad 上閱讀 O』Reilly 和 Amazon 的書籍各有什麼優勢和劣勢?

TAG:计算机技术 | 图形图像 | OpenGL |