• OpenGL代码学习(14)--了解正投影矩阵


    注意:需要在配置好OpenGL的编程环境中运行下列代码,环境配置文章可参考:

    OpenGL在Mac项目上的配置

    下面的代码,直接放置在main.cpp文件中即可:

    #include "GLTools.h"
    #include "GLMatrixStack.h"
    #include "GLFrame.h"
    #include "GLFrustum.h"
    #include "GLGeometryTransform.h"
    #include "GLBatch.h"
    #include "math.h"
    #include <GLUT/GLUT.h>
    
    GLShaderManager shaderManager;
    GLMatrixStack modelViewMatrix;
    GLMatrixStack projectionMatrix;
    GLGeometryTransform transformPipeline;
    GLBatch tubeBatch;
    GLBatch innerBatch;
    GLFrustum viewFrustum;
    GLFrame viewFrame;
    
    float fZ = 100.f;
    float bZ = -100.f;
    
    // 窗口渲染调用
    void RenderScene(void) {
        // 清除缓存区
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        
        // 压栈,物体矩阵
        modelViewMatrix.PushMatrix(viewFrame);
        
        // 默认红色光源着色
        GLfloat vRed[] = {1.0f, 0.0f, 0.0f, 1.0f};
        shaderManager.UseStockShader(GLT_SHADER_DEFAULT_LIGHT, transformPipeline.GetModelViewMatrix(), transformPipeline.GetProjectionMatrix(), vRed);
        tubeBatch.Draw();
        
        // 默认灰色光源着色
        GLfloat vGray[] = {0.75f, 0.75f, 0.75f, 1.0f};
        shaderManager.UseStockShader(GLT_SHADER_DEFAULT_LIGHT, transformPipeline.GetModelViewMatrix(), transformPipeline.GetProjectionMatrix(), vGray);
        innerBatch.Draw();
        
        // 出栈,还原为单位矩阵
        modelViewMatrix.PopMatrix();
        
        // 双缓存模式,后台缓存切换到前台进行显示
        glutSwapBuffers();
    }
    
    void SetupTubeBatch() {
        tubeBatch.Begin(GL_QUADS, 200);
        tubeBatch.Color4f(1.0f, 0.0f, 0.0f, 1.0f);
        // 后面
        GLfloat vBack[] = {
            // Left Pannel
            -50.0f, 50.0f, fZ,
            -50.0f, -50.0f, fZ,
            -35.0f, -50.0f, fZ,
            -35.0f, 50.0f, fZ,
            // Right Panel
            50.0f, 50.0f, fZ,
            35.0f, 50.0f, fZ,
            35.0f, -50.0f, fZ,
            50.0f,-50.0f, fZ,
            // Top Panel
            -35.0f, 50.0f, fZ,
            -35.0f, 35.0f, fZ,
            35.0f, 35.0f, fZ,
            35.0f, 50.0f, fZ,
            // Bottom Panel
            -35.0f, -35.0f, fZ,
            -35.0f, -50.0f, fZ,
            35.0f, -50.0f, fZ,
            35.0f, -35.0f, fZ
        };
        for (int i = 0; i < 16; i++) {
            int index = i * 3;
            tubeBatch.Normal3f(0.0f, 0.0f, 1.0f);
            tubeBatch.Vertex3f(vBack[index], vBack[index+1], vBack[index+2]);
        }
        // 前面
        GLfloat vFront[] = {
            // Left Pannel
            -35.0f, 50.0f, bZ,
            -35.0f, -50.0f, bZ,
            -50.0f, -50.0f, bZ,
            -50.0f, 50.0f, bZ,
            // Right Panel
            50.0f, -50.0f, bZ,
            35.0f, -50.0f, bZ,
            35.0f, 50.0f, bZ,
            50.0f, 50.0f, bZ,
            // Top Panel
            35.0f, 50.0f, bZ,
            35.0f, 35.0f, bZ,
            -35.0f, 35.0f, bZ,
            -35.0f, 50.0f, bZ,
            // Bottom Panel
            35.0f, -35.0f, bZ,
            35.0f, -50.0f, bZ,
            -35.0f, -50.0f, bZ,
            -35.0f, -35.0f, bZ
        };
        for(int i = 0; i < 16; i++) {
            int index = i * 3;
            tubeBatch.Normal3f(0.0f, 0.0f, -1.0f);
            tubeBatch.Vertex3f(vFront[index], vFront[index+1], vFront[index+2]);
        }
        
        // 上面
        GLfloat vTop[] = {
            -50.0f, 50.0f, fZ,
            50.0f, 50.0f, fZ,
            50.0f, 50.0f, bZ,
            -50.0f, 50.0f, bZ
        };
        for(int i = 0; i < 4; i++) {
            int index = i * 3;
            tubeBatch.Normal3f(0.0f, 1.0f, 0.0f);
            tubeBatch.Vertex3f(vTop[index], vTop[index+1], vTop[index+2]);
        }
        
        // 下面
        GLfloat vBottom[] = {
            -50.0f, -50.0f, fZ,
            -50.0f, -50.0f, bZ,
            50.0f, -50.0f, bZ,
            50.0f, -50.0f, fZ
        };
        for(int i = 0; i < 4; i++) {
            int index = i * 3;
            tubeBatch.Normal3f(0.0f, -1.0f, 0.0f);
            tubeBatch.Vertex3f(vBottom[index], vBottom[index+1], vBottom[index+2]);
        }
        
        // 左面
        GLfloat vLeft[] = {
            50.0f, 50.0f, fZ,
            50.0f, -50.0f, fZ,
            50.0f, -50.0f, bZ,
            50.0f, 50.0f, bZ
        };
        for(int i = 0; i < 4; i++) {
            int index = i * 3;
            tubeBatch.Normal3f(1.0f, 0.0f, 0.0f);
            tubeBatch.Vertex3f(vLeft[index], vLeft[index+1], vLeft[index+2]);
        }
        
        // 右面
        GLfloat vRight[] = {
            -50.0f, 50.0f, fZ,
            -50.0f, 50.0f, bZ,
            -50.0f, -50.0f, bZ,
            -50.0f, -50.0f, fZ
        };
        for(int i = 0; i < 4; i++) {
            int index = i * 3;
            tubeBatch.Normal3f(-1.0f, 0.0f, 0.0f);
            tubeBatch.Vertex3f(vRight[index], vRight[index+1], vRight[index+2]);
        }
        tubeBatch.End();
    }
    
    void SetupInnerBatch() {
        innerBatch.Begin(GL_QUADS, 40);
        innerBatch.Color4f(0.75f, 0.75f, 0.75f, 1.0f);
        // 上面
        GLfloat innerTop[] = {
            -35.0f, 35.0f, fZ,
            35.0f, 35.0f, fZ,
            35.0f, 35.0f, bZ,
            -35.0f, 35.0f, bZ
        };
        for(int i = 0; i < 4; i++) {
            int index = i * 3;
            innerBatch.Normal3f(0.0f, -1.0f, 0.0f);
            innerBatch.Vertex3f(innerTop[index], innerTop[index+1], innerTop[index+2]);
        }
        
        // 下面
        GLfloat innerBottom[] = {
            -35.0f, -35.0f, fZ,
            -35.0f, -35.0f, bZ,
            35.0f, -35.0f, bZ,
            35.0f, -35.0f, fZ
        };
        for(int i = 0; i < 4; i++) {
            int index = i * 3;
            innerBatch.Normal3f(0.0f, 1.0f, 0.0f);
            innerBatch.Vertex3f(innerBottom[index], innerBottom[index+1], innerBottom[index+2]);
        }
        
        // 左面
        GLfloat innerLeft[] = {
            35.0f, 35.0f, fZ,
            35.0f, -35.0f, fZ,
            35.0f, -35.0f, bZ,
            35.0f, 35.0f, bZ
        };
        for(int i = 0; i < 4; i++) {
            int index = i * 3;
            innerBatch.Normal3f(-1.0f, 0.0f, 0.0f);
            innerBatch.Vertex3f(innerLeft[index], innerLeft[index+1], innerLeft[index+2]);
        }
        
        // 右面
        GLfloat innerRight[] = {
            -35.0f, 35.0f, fZ,
            -35.0f, 35.0f, bZ,
            -35.0f, -35.0f, bZ,
            -35.0f, -35.0f, fZ
        };
        for(int i = 0; i < 4; i++) {
            int index = i * 3;
            innerBatch.Normal3f(1.0f, 0.0f, 0.0f);
            innerBatch.Vertex3f(innerRight[index], innerRight[index+1], innerRight[index+2]);
        }
        
        innerBatch.End();
    }
    
    // 程序初始化环境
    void SetupRC() {
        // 设置背景颜色为淡蓝色
        glClearColor(0.0f, 0.0f, 0.75f, 1.0f );
        
        // 开启深度测试
        glEnable(GL_DEPTH_TEST);
        
        // 着色器初始化
        shaderManager.InitializeStockShaders();
        
        // 创建长方体暴露在外面的红色面
        SetupTubeBatch();
        
        // 创建长方体里面的灰色面
        SetupInnerBatch();
    }
    
    void SpecialKeys(int key, int x, int y) {
        // 按下上、下、左、右方向键,对物体进行旋转,m3dDegToRad = 角度 -> 弧度
        switch(key) {
            case GLUT_KEY_UP:
                // angle=-5, x=1, y=0, z=0 表示绕x轴正方向顺时针旋转(从x轴正方向看去)
                viewFrame.RotateWorld(m3dDegToRad(-5.0f), 1.0f, 0.0f, 0.0f);
                break;
            case GLUT_KEY_DOWN:
                // angle=5, x=1, y=0, z=0 表示绕x轴正方向逆时针旋转(从x轴正方向看去)
                viewFrame.RotateWorld(m3dDegToRad(5.0f), 1.0f, 0.0f, 0.0f);
                break;
            case GLUT_KEY_LEFT:
                // angle=-5, x=0, y=1, z=0 表示绕y轴正方向顺时针旋转(从y轴正方向看去)
                viewFrame.RotateWorld(m3dDegToRad(-5.0f), 0.0f, 1.0f, 0.0f);
                break;
            case GLUT_KEY_RIGHT:
                // angle=5, x=0, y=1, z=0 表示绕y轴正方向逆时针旋转(从y轴正方向看去)
                viewFrame.RotateWorld(m3dDegToRad(5.0f), 0.0f, 1.0f, 0.0f);
                break;
        }
        
        // 重写渲染窗口
        glutPostRedisplay();
    }
    
    // 窗口变化回调
    void ChangeSize(int width, int height) {
    
        // 设置视口
        glViewport(0, 0, width, height);
        
        // 设置正投影,(xMin, xMax, yMin, yMax, zMin, zMax)
        viewFrustum.SetOrthographic(-130.0f, 130.0f, -130.0f, 130.0f, -130.0f, 130.0f);
        
        // 获得到的正投影矩阵载入堆栈中
        projectionMatrix.LoadMatrix(viewFrustum.GetProjectionMatrix());
        
        // 变换管线,管理2个堆栈
        transformPipeline.SetMatrixStacks(modelViewMatrix, projectionMatrix);
    }
    
    // 程序入口
    int main(int argc, char* argv[]) {
        // 针对 Mac OS 设置工作目录路径
        gltSetWorkingDirectory(argv[0]);
        
        // 初始化 GLUT
        glutInit(&argc, argv);
        
        // 初始化渲染模式
        glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_STENCIL);
        
        // 初始化窗口大小
        glutInitWindowSize(800, 720);
        
        // 创建窗口并命名
        glutCreateWindow("Orthographic Projection Example");
        
        // 检测驱动程序是否初始化成功
        GLenum err = glewInit();
        if (GLEW_OK != err) {
            fprintf(stderr, "GLEW Error: %s
    ", glewGetErrorString(err));
            return 1;
        }
        
        // 窗口大小改变回调函数设置
        glutReshapeFunc(ChangeSize);
        
        // 特殊按键点击回调函数设置
        glutSpecialFunc(SpecialKeys);
        
        // 窗口渲染回调函数设置
        glutDisplayFunc(RenderScene);
        
        // 程序初始化环境
        SetupRC();
        
        // 主消息循环
        glutMainLoop();
        
        return 0;
    }

    效果图如下所示:

     

     

  • 相关阅读:
    P1092 虫食算
    P1040 加分二叉树
    cfER76 abcd
    cf599 div2 a/b1/b2/c
    AtCoder Contest 144 DE
    Round G 2019
    luogu3084 Photo 单调队列优化DP
    luogu4234 最小差值生成树
    luogu1373 小a和uim之大逃离
    luogu1070 道路游戏 单调队列
  • 原文地址:https://www.cnblogs.com/cchHers/p/14726423.html
Copyright © 2020-2023  润新知