在OpenGL程序中,交互设备输入有GLUT中的子程序处理,GLUT有从标准输入设备(包括鼠标、键盘、数据板、空间球、按钮盒和拨号盘)接受输入的函数。我们来看一个示例。
#include <Gl/glut.h>
GLsizei winWidth = 400, winHeight = 300;
void init()
{
glClearColor(0.0,0.0,1.0, 1.0);
glMatrixMode(GL_PROJECTION);
gluOrtho2D(0.0, 200.0, 0.0, 150.0);
}
void displayFcn()
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 0.0, 0.0);
glPointSize(3.0);
}
void winReshapeFcn(GLint newWidth, GLint newHeight)
{
glViewport(0, 0, newWidth, newHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, GLdouble(newWidth), 0.0, GLdouble(newHeight));
winWidth = newWidth;
winHeight = newHeight;
}
void plotPoint(GLint x, GLint y)//点绘制函数
{
glBegin(GL_POINTS);
glVertex2i(x, y);
glEnd();
}
void mousePtPlot(GLint button, GLint action, GLint xMouse, GLint yMouse)//鼠标信息响应回调函数
{
if (button==GLUT_LEFT_BUTTON&&action==GLUT_DOWN)//如果鼠标左键按下
{
plotPoint(xMouse, winHeight - yMouse);
}
glFlush();
}
void main(int argc, char**argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowPosition(100, 100);
glutInitWindowSize(winWidth, winHeight);
glutCreateWindow("An Example OpenGL Program");
init();
glutDisplayFunc(displayFcn);
glutReshapeFunc(winReshapeFcn);
glutMouseFunc(mousePtPlot);//鼠标消息响应函数
glutMainLoop();//启动主循环,等待消息
}
在这个示例中,程序对我们的鼠标消息做出响应,在鼠标点击的位置绘制红色的点。这里关键的函数有两个,一个是鼠标消息响应函数:
glutMouseFunc(mousePtPlot);
另一个是回调函数;
void mousePtPlot(GLint button, GLint action, GLint xMouse, GLint yMouse)
该函数有四个参数,分别对应鼠标按钮(GLUT_LEFT_BUTTON、GLUT_MIDDLE_BUTTON、GLUT_RIGHT_BUTTON)、按钮行为(GLUT_DOWN或GLUT_UP)、鼠标响应位置。
下面的示例展示了直线段绘制程序:
#include <Gl/glut.h>
GLsizei winWidth = 400, winHeight = 300;
GLint endPtCtr = 0;
class scrPt{
public:
GLint x, y;
};
void init()
{
glClearColor(0.0,0.0,1.0, 1.0);
glMatrixMode(GL_PROJECTION);
gluOrtho2D(0.0, 200.0, 0.0, 150.0);
}
void displayFcn()
{
glClear(GL_COLOR_BUFFER_BIT);
}
void winReshapeFcn(GLint newWidth, GLint newHeight)
{
glViewport(0, 0, newWidth, newHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, GLdouble(newWidth), 0.0, GLdouble(newHeight));
winWidth = newWidth;
winHeight = newHeight;
}
void drawLineSegment(scrPt endPt1, scrPt endPt2)
{
glBegin(GL_LINES);
glVertex2i(endPt1.x, endPt1. y);
glVertex2i(endPt2.x, endPt2. y);
glEnd();
}
void polyline(GLint button, GLint action, GLint xMouse, GLint yMouse)
{
static scrPt endPt1, endPt2;
if (endPtCtr==0)
{
if (button==GLUT_LEFT_BUTTON&&action==GLUT_DOWN)
{
endPt1.x = xMouse;
endPt1.y = winHeight - yMouse;
endPtCtr = 1;
}
else
if (button==GLUT_RIGHT_BUTTON)
{
exit(0);
}
}
else
if (button == GLUT_LEFT_BUTTON&&action == GLUT_DOWN)
{
endPt2.x = xMouse;
endPt2.y = winHeight - yMouse;
drawLineSegment(endPt1, endPt2);
endPt1 = endPt2;
}
else
if (button == GLUT_RIGHT_BUTTON)
{
exit(0);
}
glFlush();
}
void main(int argc, char**argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowPosition(100, 100);
glutInitWindowSize(winWidth, winHeight);
glutCreateWindow("An Example OpenGL Program");
init();
glutDisplayFunc(displayFcn);
glutReshapeFunc(winReshapeFcn);
glutMouseFunc(polyline);
glutMainLoop();
}
可以使用的另一个GLUT鼠标子程序是:
glutMotionFunc(fcnDoSomething);
当鼠标在窗口内移动并且一个或多个鼠标按钮被激活时,这个例程调用下面的函数:
void fcnDoSomthing(GLint xMouse,GLint yMouse)
其中参数是当鼠标被移动并且按钮被按下时,鼠标光标相对于窗口左上角的位置。
类似地,可以使用的另一个GLUT鼠标子程序是:
glutPassiveMotionFunc(fcnDoSomethingElse);
当鼠标在窗口内移动并且没有一个或多个鼠标按钮被激活时,这个例程调用下面的函数:
void fcnDoSomthingElse(GLint xMouse,GLint yMouse)
其中参数是当鼠标被移动时,鼠标光标相对于窗口左上角的位置。
GLUT键盘响应函数是:
glutKeyboardFunc(keyFcn);
当键盘某个键被按下时,这个例程调用下面的函数:
void keyFcn(GLubyte key,GLint xMouse,GLint yMouse)
其中参数是当某个键被按下时,鼠标光标相对于窗口左上角的位置。
我们看一个简单的示例:
#include <Gl/glut.h>
GLsizei winWidth = 400, winHeight = 300;
void init()
{
glClearColor(0.0, 0.0, 1.0, 1.0);
glMatrixMode(GL_PROJECTION);
gluOrtho2D(0.0, 200.0, 0.0, 150.0);
}
void displayFcn()
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 0.0, 0.0);
glPointSize(3.0);
}
void winReshapeFcn(GLint newWidth, GLint newHeight)
{
glViewport(0, 0, newWidth, newHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, GLdouble(newWidth), 0.0, GLdouble(newHeight));
winWidth = newWidth;
winHeight = newHeight;
}
void plotPoint(GLint x, GLint y)//点绘制函数
{
glBegin(GL_POINTS);
glVertex2i(x, y);
glEnd();
}
void curveDrawing(GLubyte curvePlotKey, GLint xMouse, GLint yMouse)
{
GLint x = xMouse;
GLint y = winHeight-yMouse;
switch (curvePlotKey)
{
case 'c':
plotPoint(x, y);
break;
default:
break;
}
glFlush();
}
void main(int argc, char**argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowPosition(100, 100);
glutInitWindowSize(winWidth, winHeight);
glutCreateWindow("An Example OpenGL Program");
init();
glutDisplayFunc(displayFcn);
glutReshapeFunc(winReshapeFcn);
glutKeyboardFunc(curveDrawing);//键盘消息响应函数
glutMainLoop();//启动主循环,等待消息
}
该程序捕获键盘消息,当键盘c键按下时,开启绘点功能。
我们可以使用以下命令指定对于功能键、方向键及其他特殊键的处理函数:
glutSpecialFunc(specialKeyFcn);
回调函数:
void specialKeyFcn(GLint specialKey,GLint xMouse,yMouse);
功能键的符号常量从GLUT_KEY_F1到GLUT_KEY_F12,方向键类似GLUT_KEY_UP,其他特殊件类似GLUT_KEY_PAGE_DOWN。我们来看一段示例代码:
#include <Gl/glut.h>
#include <stdlib.h>
GLsizei winWidth = 400, winHeight = 300;
GLint edgeLength = 10;
void init()
{
glClearColor(0.0, 0.0, 1.0, 1.0);
glMatrixMode(GL_PROJECTION);
gluOrtho2D(0.0, 200.0, 0.0, 150.0);
}
void displayFcn()
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 0.0, 0.0);
}
void winReshapeFcn(GLint newWidth, GLint newHeight)
{
glViewport(0, 0, newWidth, newHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, GLdouble(newWidth), 0.0, GLdouble(newHeight));
winWidth = newWidth;
winHeight = newHeight;
}
void fillSquare(GLint button, GLint action,GLint xMouse,GLint yMouse)
{
GLint x1, y1, x2, y2;
if (button == GLUT_LEFT_BUTTON&&action==GLUT_DOWN)
{
x1 = xMouse;
y1 = winHeight - yMouse;
x2 = x1 + edgeLength;
y2 = y1 + edgeLength;
glRecti(x1, y1, x2, y2);
}
else
{
if (button == GLUT_RIGHT_BUTTON)
exit(0);
}
glFlush();
}
void enlrgeSquare(GLubyte sizeFactor, GLint xMouse, GLint yMouse)
{
switch (sizeFactor)
{
case '2':
edgeLength *= 2;
break;
case '3':
edgeLength *= 3;
break;
case '4':
edgeLength *= 4;
break;
default:
break;
}
}
void reduceSquare(GLint reductionKey, GLint xMouse, GLint yMouse)
{
switch (reductionKey)
{
case GLUT_KEY_F2:
edgeLength /= 2;
break;
case GLUT_KEY_F3:
edgeLength /= 4;
break;
default:
break;
}
}
void main(int argc, char**argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowPosition(100, 100);
glutInitWindowSize(winWidth, winHeight);
glutCreateWindow("An Example OpenGL Program");
init();
glutDisplayFunc(displayFcn);
glutReshapeFunc(winReshapeFcn);
glutMouseFunc(fillSquare);//鼠标消息响应函数
glutKeyboardFunc(enlrgeSquare);//键盘消息响应函数
glutSpecialFunc(reduceSquare);//特殊键消息响应函数
glutMainLoop();//启动主循环,等待消息
}
在这个程序中,鼠标消息用于确定方块位置,键盘输入用于缩放方块的大小。每次单击鼠标左键生成一个当前大小的正方形。