OpenGL从1.0开始--交互式输入设备函数

在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();//启动主循环,等待消息
}

这里写图片描述
在这个程序中,鼠标消息用于确定方块位置,键盘输入用于缩放方块的大小。每次单击鼠标左键生成一个当前大小的正方形。

猜你喜欢

转载自blog.csdn.net/wudiliyao/article/details/78654965