ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2021-05-02 21:01:14  阅读:215  来源: 互联网

标签:index 14 正投影 OpenGL 0.0 35.0 fZ 50.0 bZ


注意:需要在配置好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\n", glewGetErrorString(err));
        return 1;
    }
    
    // 窗口大小改变回调函数设置
    glutReshapeFunc(ChangeSize);
    
    // 特殊按键点击回调函数设置
    glutSpecialFunc(SpecialKeys);
    
    // 窗口渲染回调函数设置
    glutDisplayFunc(RenderScene);
    
    // 程序初始化环境
    SetupRC();
    
    // 主消息循环
    glutMainLoop();
    
    return 0;
}

效果图如下所示:

 

 

 

 

 

标签:index,14,正投影,OpenGL,0.0,35.0,fZ,50.0,bZ
来源: https://www.cnblogs.com/cchHers/p/14726423.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有