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

    Lighthouse3d.com >> GLUT Tutorial >> Subwindows >> Rendering to Subwindows

    先回顾一下之前的回调函数定义,当窗体和子窗体创建时定义的:

    空闲函数 - renderSceneAll

    主窗体的显示函数 - renderScene

    子窗体1的显示函数 - renderScenesw1

    子窗体2的显示函数 - renderScenesw2

    子窗体3的显示函数 - renderScenesw3

    我们会从各个窗体的显示函数开始.主窗体被子窗体覆盖,所以我们只想将它涂黑.当我们同时操作多个窗体的时候,第一步是用合适的窗体的ID调用glutSetWindow函数,接着我们用默认颜色黑色来清空颜色缓冲.

    void renderScene() {
        glutSetWindow(mainWindow);
        glClear(GL_COLOR_BUFFER_BIT);
        glutSwapBuffers();
    }

    我们必须为每个窗体定义显示函数.在我们的示例中,所有窗体的几何图形都相同,唯一不同的是视点,或者说镜头,随你习惯.

    通用几何图形渲染的函数叫renderScene2.然而,在调用该函数之前,我们要设置当前窗体到各个子窗体,读取ID矩阵来整理MODELVIEW矩阵,并用gluLookAt函数来设置镜头.

    本章第一节讨论了子窗体,我们可以从不同的视角观看同一个场景.第一个子窗体显示当前视点,作为主镜头.第二个从顶部显示,就好像镜头从当前位置的头顶往下看,用相同的方向作为视线.第三个子窗体像镜头在当前位置的右边望向当前位置.

    下面代码为每个窗体定义了显示函数.是之前代码的扩充.如果你需要更多细节你可以回头去看上一节. 关于键盘移动的Moving the Camera II, 关于文本显示的Bitmaps and the Orthogonal View, 或者关于回复计算的Frames per Second.

    注意,这里窗体的内容略有不同.顶部窗体会用位图字符串来显示fpt计数.两个底部窗体会在主镜头的位置显示两个红色圆锥形.

    // Common render items for all subwindows
    void renderScene2() {
    
    // Draw ground
    
        glColor3f(0.9f, 0.9f, 0.9f);
        glBegin(GL_QUADS);
            glVertex3f(-100.0f, 0.0f, -100.0f);
            glVertex3f(-100.0f, 0.0f,  100.0f);
            glVertex3f( 100.0f, 0.0f,  100.0f);
            glVertex3f( 100.0f, 0.0f, -100.0f);
        glEnd();
    
    // Draw 36 SnowMen
        char number[3];
        for(int i = -3; i < 3; i++)
            for(int j=-3; j < 3; j++) {
    
                glPushMatrix();
                glTranslatef(i*10.0f, 0.0f, j * 10.0f);
                drawSnowMan();
                glPopMatrix();
            }
    }
    
    // Display func for main window
    void renderScene() {
        glutSetWindow(mainWindow);
        glClear(GL_COLOR_BUFFER_BIT);
        glutSwapBuffers();
    }
    
    // Display func for sub window 1
    void renderScenesw1() {
    
        glutSetWindow(subWindow1);
    
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
        glLoadIdentity();
        gluLookAt(x, y, z,
              x + lx,y + ly,z + lz,
              0.0f,1.0f,0.0f);
    
        renderScene2();
    
        // display fps in the top window
         frame++;
    
        time=glutGet(GLUT_ELAPSED_TIME);
        if (time - timebase > 1000) {
            sprintf(s,"Lighthouse3D - FPS:%4.2f",
                frame*1000.0/(time-timebase));
            timebase = time;
            frame = 0;
        }
    
        setOrthographicProjection();
    
        glPushMatrix();
        glLoadIdentity();
        renderBitmapString(5,30,0,GLUT_BITMAP_HELVETICA_12,s);
        glPopMatrix();
    
        restorePerspectiveProjection();
    
        glutSwapBuffers();
    }
    
    // Display func for sub window 2
    void renderScenesw2() {
    
        glutSetWindow(subWindow2);
    
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
        glLoadIdentity();
        gluLookAt(x, y+15, z,
              x ,y - 1,z,
              lx,0,lz);
    
        // Draw red cone at the location of the main camera
        glPushMatrix();
        glColor3f(1.0,0.0,0.0);
        glTranslatef(x,y,z);
        glRotatef(180-(angle+deltaAngle)*180.0/3.14,0.0,1.0,0.0);
        glutSolidCone(0.2,0.8f,4,4);
        glPopMatrix();
    
        renderScene2();
    
        glutSwapBuffers();
    }
    
    // Display func for sub window 3
    void renderScenesw3() {
    
        glutSetWindow(subWindow3);
    
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
        glLoadIdentity();
        gluLookAt(x-lz*10 , y, z+lx*10,
              x ,y ,z ,
              0.0f,1.0f,0.0f);
    
        // Draw red cone at the location of the main camera
        glPushMatrix();
        glColor3f(1.0,0.0,0.0);
        glTranslatef(x,y,z);
        glRotatef(180-(angle+deltaAngle)*180.0/3.14,0.0,1.0,0.0);
        glutSolidCone(0.2,0.8f,4,4);
        glPopMatrix();
    
        renderScene2();
    
        glutSwapBuffers();
    }

    现在剩下要做的是定义全局空闲函数.在我们的示例中,该函数是renderSceneAll.该函数检查deltaMove或deltaAngle是否为非零,并更新当前位置的值和视线向量.

    然后我们让各个子窗体调用显示函数.注意我们不会调用主窗体的显示函数,因为它一直不会做任何修改.

    // Global idle func
    void renderSceneAll() {
    
        // check for keyboard movement
        if (deltaMove)
            computePos(deltaMove);
    
        renderScenesw1();
        renderScenesw2();
        renderScenesw3();
    }
  • 相关阅读:
    Easy | LeetCode 108. 将有序数组转换为二叉搜索树
    Medium | LeetCode 105 | 剑指 Offer 07. 从前序与中序遍历序列构造二叉树
    Easy | LeetCode 543. 二叉树的直径
    Easy | LeetCode 235 | 剑指 Offer 68
    Easy | LeetCode 236 | 剑指 Offer 68
    Medium | LeetCode 114. 二叉树展开为链表 | 先序遍历 | 递归 | 迭代
    Medium | LeetCode 538,1038. 把二叉搜索树转换为累加树
    Medium | LeetCode 230. 二叉搜索树中第K小的元素
    Easy | 剑指 Offer 54. 二叉搜索树的第k大节点
    stl(5)vector容器
  • 原文地址:https://www.cnblogs.com/live41/p/3394952.html
Copyright © 2011-2022 走看看