zoukankan      html  css  js  c++  java
  • OpenGL编程 基础篇(四)与鼠标的交互

    当用户按下或释放鼠标按钮、按下按钮时移动鼠标或按下和松开键盘按键时,就会产生一个相关事件。程序员可以用每类事件注册一个回调函数,例如使用如下函数:

    • glutMouseFunc(myMouse):利用按下或释放鼠标按钮时发生的事件来注册myMouse
    • glutMotionFunc(myMovedMouse):利用按下按钮同时移动鼠标的事件来注册myMovedMouse
    • glutKeyboardFunc(myKeyboard):利用按下和松开键盘按键的事件来注册myKeyboard

    1.用鼠标交互

    回调函数的名字可以随便起,但是一定要带4个参数,其原型如下:

    void myMouse(int button,int state,int x,int y); 当鼠标事件发生时,系统会调用注册的函数,并向其提供这些参数值。

     button的值可能是下面明显含义中的一个:GLUT_LEFT_BUTTON、GLUT_MIDDLE_BUTTON、GLUT_RIGHT_BUTTON

     state 的值可能是:GLUT_UP、GLUT_DOWN

    x和y的值指明事件发生时鼠标的位置(注意:x是距离窗口左边的像素数、y是距离窗口顶端的像素数)

    时间处理器本身并不引起屏幕的重新绘制事件。因此,为了看到鼠标的效果,鼠标处理器应该调用glutPostRedisplay()

    #include "stdafx.h"
    #include <cstdlib>
    #include <glglut.h>
    const int screenWidth = 600;
    const int screenHeight = 480;
    class GLintPoint
    {
    public:
        GLint x;
        GLint y;
        GLintPoint(){
            x = 0; y = 0;
        }
        GLintPoint(GLint a, GLint b){
            x = a;
            y = b;
        }
    };
    void myInit(){
        glClearColor(1.0, 1.0, 1.0, 0.0);
        glColor3f(0.0f, 0.0f, 0.0f);
        glPointSize(2.0);
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        gluOrtho2D(0.0, (GLdouble)screenWidth, 0.0, (GLdouble)screenHeight);
    }
    
    void drawDot(GLint x, GLint y){
        glBegin(GL_POINTS);
        glVertex2i(x, y);
        glEnd();
    }
    void myDisplay(GLintPoint corner[3]){  //绘制Sierrapinski垫片的函数,参数为三个坐标点
        glClear(GL_COLOR_BUFFER_BIT);
        int index = rand() % 3;
        GLintPoint point = corner[index];
        drawDot(point.x, point.y);
        for (int i = 0; i < 55000; i++){
            index = rand() % 3;
            point.x = (point.x + corner[index].x) / 2;
            point.y = (point.y + corner[index].y) / 2;
            //printf("%d %d
    ", point.x, point.y);
            drawDot(point.x, point.y);
        }
        glFlush();
    }
    //Simple One 用鼠标放置点,用户每次按下左键时,就会在屏幕窗口鼠标所在位置绘制出一个点;如果用户按下右键,就改变窗口背景颜色
    void myMouse(int button, int state, int x, int y){
        if (state == GLUT_DOWN){
            if (button == GLUT_LEFT_BUTTON){
                drawDot(x, screenHeight - y);
                glFlush();
            }
            else if (button == GLUT_RIGHT_BUTTON){
                glClearColor(1.0f,0.0f,0.0f,0.0f);
                glClear(GL_COLOR_BUFFER_BIT);
                glFlush();
            }
        }
        return;
    }
    //Sierpinski 用鼠标控制Sierpinski垫片
    void myMouseForSierpinski(int button, int state, int x, int y)
    {
    
        static GLintPoint corner[3];
        static int numCorners = 0;
        if (state == GLUT_DOWN){
            if (button == GLUT_LEFT_BUTTON){
                corner[numCorners].x = x;
                corner[numCorners].y = screenHeight - y;
                if (++numCorners == 3){
                    myDisplay(corner);
                    numCorners = 0;
                }
            }
        }
        else if (button == GLUT_RIGHT_BUTTON){
            glClear(GL_COLOR_BUFFER_BIT);
            glFlush();
        }
    }
    void myDis(){}
    int main(int argc, char **argv){
    
        glutInit(&argc, argv);
        glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
        glutInitWindowPosition(100, 100);
        glutInitWindowSize(screenWidth, screenHeight);
        glutCreateWindow("Mouse Sierpinski");
    
        glutMouseFunc(myMouseForSierpinski);
        //glutMouseFunc(myMouse);
        glutDisplayFunc(myDis);
        myInit();
        glutMainLoop();
        return 0;
    }

     2.用键盘交互

    回调函数的名字可以随便起,其原型如下:

    void myKeyBoard(unsigned int key,int x,int y); 当键盘事件发生时,系统会调用注册的函数,并向其提供这些参数值。

    按键的值是所按键的ASCII值,数值x和y指示事件发生时鼠标所在的位置(y是距离窗口顶端的像素个数)

    大多数myKeyBoard()函数都由很长的switch case语句组成

    样例:按下p键会在鼠标位置上绘制一个点;按下左箭头会在某个全局列表中添加一个点,但是不绘图;按下E会退出程序。

    如果用户一直按着p键并移动鼠标,就会产生一个快速点序列,这就是“徒手”绘图。

    void myKeyboard(unsigned char key,int mouseX,int mouseY){
    GLint x = mouseX;
    GLint y = mouseY;
        switch(key)
        {
            case 'p':
                drawDot(x,y);
                break;
            case 'E':
                exit(-1);
            case GLUT_KEY_LEFT:List[++last].x = x;
                               List[last].y = y;
                               break;
            default:
                break;
        }
    }
  • 相关阅读:
    JavaScript高级-----8.函数进阶(2)
    JavaScript高级-----7.函数进阶(1)
    2014-10-18 来美半个月
    修手机记
    圆梦美利坚之三:租房记
    圆梦美利坚之二:买机票记
    Hadoop 停止Job
    IIS应用程序池数目
    HTML5 microdata
    Java sql helper[转]
  • 原文地址:https://www.cnblogs.com/starryxsky/p/7184032.html
Copyright © 2011-2022 走看看