8-Chuột:Trong các trò chơi ta đều thấy sự quan trọng của việc sử dụng chuột, trong phần này chúng ta sẽ xem xét làm thế nào để chương trình chúng ta nhận ra chúng ta đang bấm trái chuột, chúng ta đang di chuyển chuột. Để làm được điều này chúng ta sử dụng hàm auxMouseFunc().Dưới đây là mã nguồn của chương trình mouse1.cpp/°filename mouse1.cpp°/ #else#include<windows.h>#include<GL/gl.h>#include<GL/glaux.h>#include"stdio.h" /°nếu bạn không có dòng này thì hàm printf() không thực hiện°/#endifGLvoid CALLBACK draw(void){ glClearColor(0.0,0.0,0.0,0.0); glClear(GL_COLOR_BUFFER_BIT); glClearColor(0.0,0.0,0.0,0.0); glClear(GL_COLOR_BUFFER_BIT); glBegin(GL_QUADS); glColor3d(1.0,0.0,0.0); glVertex2d(0.1,0.1); glColor3d(0.0,1.0,0.0); glVertex2d(0.9,0.1); glColor3d(0.0,0.0,1.0); glVertex2d(0.9,0.9); glColor3d(1.0,0.0,1.0); glVertex2d(0.1,0.9); glEnd(); glFlush();}GLvoid CALLBACK left(AUX_EVENTREC °event){ printf("%d,%d\n",event->data[AUX_MOUSEX],event->data[AUX_MOUSEY]);}GLvoid CALLBACK resize(GLsizei w,GLsizei h){ glLoadIdentity(); glViewport(0,0,w/2,h/2); glOrtho(-1.0,1.0,-1.0,1.0,0.0,1.0);}int main(int argc, char °argv[]){ auxInitPosition(200,100,640,480); auxInitDisplayMode(AUX_RGBA); auxInitWindow(argv[0]); auxReshapeFunc(resize);/°hàm mới°/ auxMouseFunc(AUX_LEFTBUTTON,AUX_MOUSEDOWN,left);/°hàm mới°/ auxMainLoop(draw); return 0;}Trong chương trình trên, chúng ta thấy xuất hiện hàm left() và hàm auxMouseFunc().Hàm auxMouseFunc() có gọi đến hàm left(), nó có ý nghĩa rằng, khi chuột được bấm thì sẽ thực hiện hàm left().Trong tham số của hàm auxMouseFunc() có các tham sô sau: tham số đầu tiên nói đến phần nào của chuột được tác động, tham số thứ 2 nói đến nó được tác động như thế nào, và tham số cuối cùng muốn nói tác động rồi thì làm gì.Trong hàm left() tham số có dạng con trỏ và có kiểu là AUX_EVENTREC, nó lấy dữ liệu về toạ độ x và y của chuột.Trong một chương trình không phải là chỉ có một hàm auxMouseFunc() mà bạn có thể dùng bao nhiêu tuỳ thích, miễn là đừng va chạm nhau là được, trong phần mã nguồn tôi có cho thêm một chương trình ví dụ về cách dùng 2 lần hàm auxMouseFunc()(trong file mouse2.cpp)Dưới đây tôi sẽ trình bày một chương trình khá thú vị, mã nguồn của nó như sau:/°filename connectlines.cpp°/ #else#include<windows.h>#include<GL/gl.h>#include<GL/glaux.h>#include"stdio.h"#endifGLvoid CALLBACK draw(void){}GLvoid CALLBACK left(AUX_EVENTREC °event){ static int flag=0; static GLint x,y; if(flag){glColor3d(0.0,0.0,0.0);glBegin(GL_LINE_STRIP);glVertex2i(x,y);glVertex2i(event->data[AUX_MOUSEX],event->data[AUX_MOUSEY]);glEnd();glFlush(); } x=event->data[AUX_MOUSEX]; y=event->data[AUX_MOUSEY]; flag=1;}GLvoid CALLBACK resize(GLsizei w,GLsizei h){ glLoadIdentity(); glViewport(0,0,w,h); glOrtho(0.0,(GLdouble)w,(GLdouble)h,0.0,0.0,1.0);/° đổi thông số°//°chuyển vị trí 2 hàm này°/ glClear(GL_COLOR_BUFFER_BIT);}int main(int argc, char °argv[]){ auxInitPosition(200,100,640,480); auxInitDisplayMode(AUX_RGBA); auxInitWindow(argv[0]); auxReshapeFunc(resize); auxMouseFunc(AUX_LEFTBUTTON,AUX_MOUSEDOWN,left); auxMainLoop(draw); return 0;}Thực ra chương trình này rất dễ hiểu, có lẽ không phải trình bày gì nhiều.Nó lưu cá điểm lại và nối thành một đường gấp khúc.Nhược điểm của chương trình trên hẳn các bạn đã rõ khi biên dịch nó.Nó không vẽ lại cửa sổ của bạn khi cửa sổ của bạn bị che bởi một cửa sổ khác, hay bị minimize, tức là hình mà bạn muốn vẽ không được gửi tới hàm draw().Vì vậy bạn phải lưu những điểm đã chọn và vẽ lại chúng trong hàm draw().Dưới đây là mã nguồn:/°filename connectlines1.cpp°/ #else#include<windows.h>#include<GL/gl.h>#include<GL/glaux.h>#endif/°số điểm tối đa có thể được chọn°//°mảng lưu trữ các điểm đó°//°số điểm đã chọn đến thời điểm hiện tại°/GLvoid CALLBACK draw(void){ int i; if(num>=2){glClearColor(1.0,1.0,1.0,0.0);glClear(GL_COLOR_BUFFER_BIT);glColor3d(0.0,0.0,0.0);/°bạn hãy nhớ cấu trúc này°/{glVertex2iv(point[i]); }glEnd();glFlush(); }}GLvoid CALLBACK left(AUX_EVENTREC °event){ /°giới hạn số điểm bạn vẽ °/ point[num][0]=event->data[AUX_MOUSEX]; /°lưu trữ toạ độ x của chuột°/ point[num][1]=event->data[AUX_MOUSEY]; /°lưu trữ toạ độ y của chuột°//°tăng số điểm sau mỗi lần bấm°/}GLvoid CALLBACK resize(GLsizei w,GLsizei h){ glLoadIdentity(); glViewport(0,0,w,h); glOrtho(0.0,(GLdouble)w,(GLdouble)h,0.0,0.0,1.0);}int main(int argc, char °argv[]){ auxInitPosition(200,100,640,480); auxInitDisplayMode(AUX_RGBA); auxInitWindow(argv[0]); auxReshapeFunc(resize); auxMouseFunc(AUX_LEFTBUTTON,AUX_MOUSEDOWN,left); auxMainLoop(draw); return 0;}Bây giờ bạn không phải lo đến việc cửa sổ không chịu vẽ lại khi nó bị che mất.Một điều cũng đáng chú ý trong chương trình trên là chúng ta đã sử dụng hàm glVertex2iv() hàm này có tham số là thành viên của mảng và thành viên của mảng có các giá trị x,y là số nguyên, chữ i trong phần hậu tố của hàm trên biểu hiện cho giá trị nguyên còn chữ v biểu hiện cho kiểu pointer.Dưới đây cung cấp cho bạn một chương trình có thể vẽ được cả những đường gấp khúc và các đa giác.Mã nguồn không có gì phức tạp và đáng bàn ở đây cả, nó chỉ là cách sắp xếp dữ liệu và có thêm một hàm right() mà thực ra tôi đã đề cập ở các phần trên./°filename connectlines2.cpp°/ #else#include<windows.h>#include<GL/gl.h>#include<GL/glaux.h>#endif#define MAXPOINTS 100GLint point[MAXPOINTS][2];int num=0;int flag=0;GLvoid CALLBACK draw(void){ int i; if(num>=2){if(flag){flag=0;i=num-2;glColor3d(0.0,0.0,0.0);glBegin(GL_LINE_STRIP);}else{i=0;glClearColor(1.0,1.0,1.0,0.0);glClear(GL_COLOR_BUFFER_BIT);glColor3d(0.0,0.0,0.0);glBegin(GL_POLYGON);}for(;i<num;i++){glVertex2iv(point[i]);}glEnd();glFlush(); }}GLvoid CALLBACK left(AUX_EVENTREC °event){ if(num>=MAXPOINTS) return; point[num][0]=event->data[AUX_MOUSEX]; point[num][1]=event->data[AUX_MOUSEY]; num++; flag=1;}GLvoid CALLBACK right(AUX_EVENTREC °event){ draw();}GLvoid CALLBACK resize(GLsizei w,GLsizei h){ glLoadIdentity(); glViewport(0,0,w,h); glOrtho(0.0,(GLdouble)w,(GLdouble)h,0.0,0.0,1.0); glClearColor(1.0,1.0,1.0,0.0); glClear(GL_COLOR_BUFFER_BIT);}int main(int argc, char °argv[]){ auxInitPosition(200,100,640,480); auxInitDisplayMode(AUX_RGBA); auxInitWindow(argv[0]); auxReshapeFunc(resize); auxMouseFunc(AUX_LEFTBUTTON,AUX_MOUSEDOWN,left); auxMouseFunc(AUX_RIGHTBUTTON,AUX_MOUSEDOWN,right); auxMainLoop(draw); return 0;}