GLUT Tutorials 11: 切换菜单

博客转自:http://www.lighthouse3d.com/tutorials/glut-tutorial/swapping-menus/

上一个教程主要是一个菜单内的Item的切换,这个教程是在应用程序运行中直接切换整个菜单。两个功能函数是 glutSetMenu 和 glutGetMenu

void glutSetMenu(int menu);

Parameters:

menu – the index of a previously created menu

此函数的功能是根据菜单索引切换菜单。

int glutGetMenu(void);

此函数返回当前菜单的索引。接下来,我们呈现一个程序运行中,当用户按F1时候,两个菜单交换的例子。

完整代码如下

#include <stdio.h>
#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;

int menu1,menu2;

int flag = 1;

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() 
{
    // 创建菜单并告诉GLUT,processMenuEvents处理菜单事件。
    menu1 = glutCreateMenu(processMenuEvents);

    //给菜单增加条目
    glutAddMenuEntry("Red", RED);
    glutAddMenuEntry("Blue", BLUE);
    glutAddMenuEntry("Green", GREEN);
    glutAddMenuEntry("White", WHITE);
    // 把菜单和鼠标右键关联起来。
    glutAttachMenu(GLUT_RIGHT_BUTTON);

    menu2 = glutCreateMenu(processMenuEvents);
    glutAddMenuEntry("Blue", BLUE);
    glutAddMenuEntry("Green", GREEN);
    glutAddMenuEntry("Red", RED);
}

void processKeys(unsigned char c, int x, int y) 
{
    if (flag)
    {
        return;
    }

    int num = glutGet(GLUT_MENU_NUM_ITEMS);

    switch (c)
    {
    case 'a':
        glutChangeToMenuEntry(1, "Blue", BLUE);
        glutChangeToMenuEntry(3, "Red", RED);
        break;
    case 'b':
        glutChangeToMenuEntry(3, "Blue", BLUE);
        glutChangeToMenuEntry(1, "Red", RED);
        break;
    case 'c':
        if (num > 3)
            glutRemoveMenuItem(num);
        break;
    case 'd': 
        if (num == 3)
        glutAddMenuEntry("White", WHITE);
        break;
    }

    glutSetMenu(menu1);
}

void processSpecialKeys(int c, int x, int y) 
{
    if (!flag)
    {
        if (c == GLUT_KEY_F1) 
        {
            int x = glutGetMenu();
            if (x == menu1)
                glutSetMenu(menu2);
            else
                glutSetMenu(menu1);
            // don't forget to attach the menu!!!
            glutAttachMenu(GLUT_RIGHT_BUTTON);
        }
    }
}

void processMenuStatus(int status, int x, int y) 
{
    if (status == GLUT_MENU_IN_USE)
    {
        printf("Menu is using
");
        flag = 1;
    }
    else
    {
        printf("Menu is not using
");
        flag = 0;
    }
}

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);

    glutKeyboardFunc(processKeys);
    glutSpecialFunc(processSpecialKeys);
    glutMenuStatusFunc(processMenuStatus);

    //调用我们的函数来创建菜单
    createGLUTMenus();

    glutMainLoop();
}

显示效果如下

原文地址:https://www.cnblogs.com/flyinggod/p/12940406.html