zoukankan      html  css  js  c++  java
  • [译]GLUT教程

    Lighthouse3d.com >> GLUT Tutorial >> Subwindows >> Creating and Destroying Subwindows

    利用GLUT我们可以定义子窗体,例如切分主窗体到不同区域,每个子窗体有自己的OpenGL上下文和回调函数.一个可行的程序是可以同时提供几种相同场景的视觉.

    为了创建子窗体,我们可以使用glutCreateSubWindow函数,原型如下:

    int glutCreateSubWindow(int parentWindow, int x, int y, int width, int height);

    parentwindow - 父窗体的ID

    x, y - 子窗体的左上角,相对于父窗体的原始

    width, height - 子窗体的大小

    父窗体的ID是创建父窗体时的返回值.下面代码显示了关系:

        mainWindow = glutCreateWindow("SnowMen from Lighthouse3D");
        ...
        subWindow1 = glutCreateSubWindow(mainWindow, 10,10,100,100);

    一个子窗体也是变成其它子窗体的父窗体.根据GLUT的说明文档,窗体可以任意嵌套.

    前面说过,一个子窗体有自己的OpenGL上下文,如果我们要用VBOs时,需要为每个窗体和子窗体创建它们.回调函数也一样.

    最低限度我们必须用glutDisplayFunc函数为每个窗体注册显示函数.我们还必须为每个窗体注册光标更改和鼠标事件控制的回调函数,如果我们要用到这些特性的话.弹出菜单也分配给一个特定的窗体.注意的是,空闲函数只有一个.

    假定我们要创建三个视觉.一个主镜头,另一个是顶部视觉,在主镜头的中间,第三个是在旁边,也是在主镜头的中间.下面是例图:

    下面是初始化必需的一个更完整的版本.我们创建了函数来注册回调和演示一些OpenGL初始化,用到所有子窗体中.我们也声明了三个变量来保存窗体和子窗体的ID,稍后会用到.

    int mainWindow, subWindow1,subWindow2,subWindow3;
    ...
    void init() {
    
        glEnable(GL_DEPTH_TEST);
        glEnable(GL_CULL_FACE);
    
        // register callbacks
        glutIgnoreKeyRepeat(1);
        glutKeyboardFunc(processNormalKeys);
        glutSpecialFunc(pressKey);
        glutSpecialUpFunc(releaseKey);
        glutMouseFunc(mouseButton);
        glutMotionFunc(mouseMove);
    }
    
    int main(int argc, char **argv) {
    
        // init GLUT and create main window
        glutInit(&argc, argv);
        glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
        glutInitWindowPosition(100,100);
        glutInitWindowSize(800,800);
        mainWindow = glutCreateWindow("Lighthouse3D - GLUT Tutorial");
    
        // callbacks for main window
        glutDisplayFunc(renderScene);
        glutReshapeFunc(changeSize);
        glutIdleFunc(renderSceneAll);
        init();
    
        // sub windows
        subWindow1 = glutCreateSubWindow(mainWindow, border,border,w-2*border, h/2 - border*3/2);
        glutDisplayFunc(renderScenesw1);
        init();
    
        subWindow2 = glutCreateSubWindow(mainWindow, border,(h+border)/2,w/2-border*3/2, h/2 - border*3/2);
        glutDisplayFunc(renderScenesw2);
        init();
    
        subWindow3 = glutCreateSubWindow(mainWindow, (w+border)/2,(h+border)/2,w/2-border*3/2,h/2 - border*3/2);
        glutDisplayFunc(renderScenesw3);
        init();
    
        // enter GLUT event processing cycle
        glutMainLoop();
        
        return 1;
    }

    上面的代码创建了三个子窗体.每个子窗体都用户显示同一个场景的不同视点.顶部的子窗体显示自由移动的镜头,从顶端观察底部的左边到右边.

    当窗体创建后,无论窗体还是子窗体,都会变成当前窗体(获得焦点).所有回调会被注册到当前新创建窗体,除了空闲函数之外,之前说过该函数是整个应用程序唯一的.

    注意我们要调用initScene函数来为所有子窗体初始化OpenGL上下文.还要注意我们只为主窗体注册一次重整函数.

    子窗体不用时可以关闭.用到的函数是glutDestroyWindow.

    void glutDestroyWindow(int windowIdentifier)

    windowIdentifier - 创建窗体时的返回值

    该函数会关闭窗体和它包含的子窗体,还有它绑定的所有OpenGL上下文.

    下一节我们会探讨重整函数和渲染函数.

  • 相关阅读:
    在Android中,使用Kotlin的 API请求简易方法
    Android开发者的Kotlin:书
    用Kotlin开发Android应用(IV):定制视图和Android扩展
    用Kotlin开发Android应用(III):扩展函数和默认值
    zookeeper应用
    BigDecimal的setScale()方法无效(坑)
    Linux命令详解之—less命令
    jdk10 var定义变量的由来
    Mysql DataPacketTooBigException异常处理
    JDK自带的监控工具方法
  • 原文地址:https://www.cnblogs.com/live41/p/3394810.html
Copyright © 2011-2022 走看看