zoukankan      html  css  js  c++  java
  • GLUT Tutorials 8: GLUT菜单

    博客转自:https://www.cnblogs.com/yangxi/archive/2011/09/16/2178505.html

    弹出式菜单(像点鼠标右键出来的菜单那样的)也是GLUT的一部分,虽然它不能实现我们经常看到的windows系统弹出式菜单的所有的功能,但是它也有很大的作用。给一个程序增加菜单提供了一个比键盘更简单的方法来和程序交互,选择不同选项,而不用去记那些按键。

    我们首先要做的是创建菜单,创建菜单函数glutCreateMenu的原型如下:

    int glutCreateMenu(void (*func)(int value));
    参数:
    func:为新建的菜单处理菜单事件的函数名。
    这个函数的返回值是菜单的标识符(menu identifier)
    我们的程序中,我们可以想设置多少菜单就设置多少菜单。对每个菜单我们要指定一个回调函数,而且我们可以指定相同的函数。下面为菜单增加一些条目(出来个空菜单也没什么用)。
    使用的函数是glutAddMenuEntry
    void glutAddMenuEntry(char *name,int value);
    参数:
     name:菜单名称的字符串。
     value:当你选择菜单里的一项后,这个值就返回给上面的glutCreateMenu里调用的函数。
    这个函数根据函数名来看,就是给菜单里添加条目的,可以一直添加(这里有个顺序,自己实验下就明白了的)
    好了现在有了一个弹出式菜单。但还有最后一件事要做,就是把菜单和一个鼠标键连接起来(attach)。因为我们必须指定菜单怎么出现,使用GLUT你可以在按下一个鼠标按键后让菜单显示,函数是glutAttachMenu:
    void glutAttachMenu(int button);
    参数:、
    button: 一个整数,指定菜单和哪个鼠标键关联起来,botton 可以去下面的值;
     GLUT_LEFT_BUTTON
     GLUT_MIDDLE_BUTTON
     GLUT_RIGHT_BUTTON

    下面就是一个应用了上面所有函数的例子。

    #define RED 1
    #define GREEN 2
    #define BLUE 3
    #define WHITE 4
    
    void createGLUTMenus() {
     
             int menu;
     
             // 创建菜单并告诉GLUT,processMenuEvents处理菜单事件。
             menu = glutCreateMenu(processMenuEvents);
             
             //给菜单增加条目
             glutAddMenuEntry("Red",RED);
             glutAddMenuEntry("Blue",BLUE);
             glutAddMenuEntry("Green",GREEN);
             glutAddMenuEntry("White",WHITE);
             
             // 把菜单和鼠标右键关联起来。
             glutAttachMenu(GLUT_RIGHT_BUTTON);
    }

    注意RED,BLUE,GREEN,和WHITE必须定义为整数,再就是你必须为每个选单(菜单里的条目)定义不同的value,下面我们写处理菜单事件的函数。我们将使用我们的菜单来设置三角形的颜色。函数如下:

    void processMenuEvents(int option) {
            //option,就是传递过来的value的值。
             switch (option) {
                     case RED : 
                              red = 1.0; 
                              green = 0.0; 
                              blue = 0.0; break;
                     case GREEN : 
                              red = 0.0; 
                              green = 1.0; 
                              blue = 0.0; break;
                     case BLUE : 
                              red = 0.0; 
                              green = 0.0; 
                              blue = 1.0; break;
                     case WHITE : 
                              red = 1.0; 
                              green = 1.0; 
                              blue = 1.0; break;
             }
    }

    剩下来的就是把我们的createGLUTMenus函数放到main函数里。下面的代码就是当前的main函数。

    void main(int argc, char **argv) {
             glutInit(&argc, argv);
             glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
             glutInitWindowPosition(100,100);
             glutInitWindowSize(320,320);
             glutCreateWindow("SnowMen");
             glutDisplayFunc(renderScene);
             glutIdleFunc(renderScene);
             glutReshapeFunc(changeSize);
     
             //调用我们的函数来创建菜单
             createGLUTMenus();
     
             glutMainLoop();
    }

    显示效果如下

    完整代码如下

    #include <gl/glut.h>
    
    #define RED 1
    #define GREEN 2
    #define BLUE 3
    #define WHITE 4
    
    //所有的变量被初始化为1,表明三角形最开始是白色的。
    float red = 1.0, blue = 1.0, green = 1.0;
    static float angle = 0.0, angleX = 0.0, ratio;
    // initially define the increase of the angle by 0.05;
    float deltaAngle = 0.05;
    
    void renderScene(void)
    {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glPushMatrix();
        glRotatef(angle, 0.0, 1.0, 0.0);
        glRotatef(angleX, 1.0, 0.0, 0.0);
        glColor3f(red, green, blue);
    
        glBegin(GL_TRIANGLES);
        glVertex3f(-0.5, -0.5, 0.0);
        glVertex3f(0.5, 0.0, 0.0);
        glVertex3f(0.0, 0.5, 0.0);
        glEnd();
        glPopMatrix();
        // this is the new line
        // previously it was: angle++;
        angle += deltaAngle;
        glutSwapBuffers();
    }
    
    void reShape(int w, int h)
    {
        // 防止被0除.
        if (h == 0)
            h = 1;
    
        ratio = 1.0f * w / h;
        //Reset the coordinate system before modifying
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
    
        //设置视口为整个窗口大小
        glViewport(0, 0, w, h);
    
        //设置可视空间
        gluPerspective(45, ratio, 1, 1000);
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        gluLookAt(0.0, 0.0, 5.0, 0.0, 0.0, -1.0, 0.0f, 1.0f, 0.0f);
    }
    
    void processMenuEvents(int option) 
    {
        //option,就是传递过来的value的值。
        switch (option) {
        case RED:
            red = 1.0;
            green = 0.0;
            blue = 0.0; break;
        case GREEN:
            red = 0.0;
            green = 1.0;
            blue = 0.0; break;
        case BLUE:
            red = 0.0;
            green = 0.0;
            blue = 1.0; break;
        case WHITE:
            red = 1.0;
            green = 1.0;
            blue = 1.0; break;
        }
    }
    
    void createGLUTMenus() 
    {
        int menu;
    
        // 创建菜单并告诉GLUT,processMenuEvents处理菜单事件。
        menu = glutCreateMenu(processMenuEvents);
    
        //给菜单增加条目
        glutAddMenuEntry("Red", RED);
        glutAddMenuEntry("Blue", BLUE);
        glutAddMenuEntry("Green", GREEN);
        glutAddMenuEntry("White", WHITE);
    
        // 把菜单和鼠标右键关联起来。
        glutAttachMenu(GLUT_RIGHT_BUTTON);
    }
    
    void main(int argc, char **argv)
    {
        glutInit(&argc, argv);
        glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
        glutInitWindowPosition(100, 100);
        glutInitWindowSize(320, 320);
        glutCreateWindow("GLUT Tutorial Menu");
        glutDisplayFunc(renderScene);
        glutIdleFunc(renderScene);
        glutReshapeFunc(reShape);
    
        //调用我们的函数来创建菜单
        createGLUTMenus();
    
        glutMainLoop();
    }

    下面我们还来看两个函数,第一个允许我们断开鼠标按键和一个菜单的关联。前面我们用glutAttachMenu来在鼠标和菜单间建立关联,但我们有时候需要断开这种关联。完成这个工作的函数是glutDetachMenu。函数原型如下:

    void glutDetachMenu(int button);
    参数:
    button:要断开的鼠标按键。

    Button的取值和glutAttachMenu一样。因此,要是我们想断开关联我们可以这样:

     glutDetachMenu(GLUT_RIGHT_BUTTON);

    最后,如果你想恢复被菜单使用了的资源,我们可以销毁(destroy)它,相应的函数是glutDestroyMenu,它的原型如下:

    void glutDestroyMenu(int menuIdentifier);
    参数:
    menuIdentifier:要销毁的菜单的标识符,它必须和函数glutCreateMenu返回的值相同。

    好了,到这里你已经知道了基本的在GLUT中建立菜单,下章我们将探索更多的弹出式菜单功能。

  • 相关阅读:
    P4556 [Vani有约会]雨天的尾巴(线段树合并)
    bzoj3590: [Snoi2013]Quare
    P3187 [HNOI2007]最小矩形覆盖
    对文件中的名字进行随机抽选(小脚本)
    用shell编写一个三角形图案
    HUE安装与使用
    史上最全CentOS6离线安装部署Cloudera Manager5.9.3
    ReLU 函数
    关于反向传播
    关于微分
  • 原文地址:https://www.cnblogs.com/flyinggod/p/12927108.html
Copyright © 2011-2022 走看看