美文网首页
OpenGL基础变换

OpenGL基础变换

作者: 东旭39 | 来源:发表于2020-07-09 23:16 被阅读0次

本章的主要目的是通过修改键盘是的上下左右键,来旋转点、线、三角形,观察形状的变化。 ——视角不动,物体动
opengl平面图形的透视投影,要了解以下知识

  1. 坐标转换


    坐标转换计算

    OpenGL在进行透视投影要经过 model matrix->view matrix -> projection matrix ->viewport transform 这几个矩阵变换,才能看到我们想要的形状。

  2. 需要用到的类
  • GLMatrixStack:矩阵堆栈,用于存放矩阵数据并进行矩阵的变换。
  • GLFrame:表示世界坐标系中的任意物体的位置和方向。存储了值:当前位置点,向前方向向量,向上方向向量。可以表示camera和model
  • GLFrustum:透视矩阵
  • GLGeometryTransform: 几何变换管道,提供了矩阵相乘的方法

平面图形透视投影

  1. 准备工作,运行环境xcode,导入OpenGL、GLTool、libGLTool及相关头文件
  2. 导入头文件
#include "GLShaderManager.h"
#include "GLTools.h"
#include <glut/glut.h>
#include "GLFrame.h"
#include "GLMatrixStack.h" //变换管线的矩阵堆栈
#include "GLFrustum.h"
#include "GLGeometryTransform.h" //集合变换的管道

#include <math.h>
#ifdef __APPLE__
#include <glut/glut.h>
#else
#define FREEGLUT_STATIC
#include <GL/glut.h>
#endif
  1. main函数模板
//程序入口
int main(int argc, char* argv[])
{
    //设置当前工作目录,针对MAC OS X
    gltSetWorkingDirectory(argv[0]);
    //初始化GLUT库
    glutInit(&argc, argv);
    /*初始化双缓冲窗口,其中标志GLUT_DOUBLE、GLUT_RGBA、GLUT_DEPTH、GLUT_STENCIL分别指
     双缓冲窗口、RGBA颜色模式、深度测试、模板缓冲区*/
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_STENCIL);
    //初始化窗口大小
    glutInitWindowSize(800,600);
    //创建窗口
    glutCreateWindow("Triangle");
    //注册回调函数
    glutReshapeFunc(ChangeSize);
    //点击空格时,调用的函数
    glutKeyboardFunc(KeyPressFunc);
    //特殊键位函数(上下左右)
    glutSpecialFunc(SpecialKeys);
    //渲染函数
    glutDisplayFunc(RenderScene);
    //确保驱动程序的初始化中没有出现任何问题。
    GLenum err = glewInit();
    if(GLEW_OK != err) {
        fprintf(stderr, "glew error:%s\n", glewGetErrorString(err));
        return 1;
    }
    //初始化设置
    SetupRC();
    //进入调用循环
    glutMainLoop();
    return 0;
}

相关函数:

  • KeyPressFunc: 按空格键切换点、线、三角形的回调函数
  • SpecialKeys:按上下左右键,改变物体的方向的回调函数
  • ChangeSize: 窗口发生变化的回调函数
  • RenderScene:渲染函数,窗口大小、物体形状发生改变就会调用该还是重新渲染,就是上面三个回调函数触发, 该函数也会触发。
  • SetupRC:初始化配置
  1. 需要的对象
GLShaderManager shaderManager;
GLMatrixStack   modelViewMatrix; //模型矩阵堆栈
GLMatrixStack   projectionMatrix; //投影矩阵堆栈 
GLFrame         cameraFrame;     //视角 ; 对应上图的view matrix
GLFrame         objectFrame;      //物体 ;对应上图的 model matrix
GLFrustum       viewFrustum;     //投影矩阵 对应上图的projection matrix
//几何变换的管线
GLGeometryTransform     transformPipeline; //提供了矩阵相乘
GLBatch                pointBatch; //点
GLBatch                lineBatch; //线
GLBatch                lineLoopBatch;三角形
  1. setupRC
void SetupRC()
{
    //设置背影颜色
    glClearColor(0.7f, 0.7f, 0.7f, 1.0f);
    //初始化着色管理器
    shaderManager.InitializeStockShaders();
    //设置三角形,其中数组vVert包含所有3个顶点的x,y,笛卡尔坐标对。
    GLfloat vVerts[] = {
        -3.f,0.0f,0.0f,
        3.f,0.0f,0.0f,
        0.0f,3.f,0.0f,
    };
    //投影变换矩阵+ 移动变换矩阵 ->  几何变换管道GLGeometryTransform,作用进行矩阵相乘

    transformPipeline.SetMatrixStacks(modelViewMatrix,projectionMatrix);
    //视角离物体原来越远,
    cameraFrame.MoveForward(-15.0f);

    //1.点
    pointBatch.Begin(GL_POINTS, 3);      //开始批次处理
    pointBatch.CopyVertexData3f(vVerts);//拷贝顶点数据
    pointBatch.End();    //结束批次处理
    
    //2.线
    lineBatch.Begin(GL_LINES, 3);
    lineBatch.CopyVertexData3f(vVerts);
    lineBatch.End();
    
    //3.三角形
    lineLoopBatch.Begin(GL_LINE_LOOP, 3);
    lineLoopBatch.CopyVertexData3f(vVerts);
    lineLoopBatch.End();
}
  1. ChangeSize中使用窗口维度设置视口和投影矩阵
void ChangeSize(int w, int h)
{
    glViewport(0, 0, w, h);
    //创建投影矩阵,设置维度
    viewFrustum.SetPerspective(35.0f, float(w) / float(h), 1.0f, 500.0f);
    //1.获取投影矩阵,并设置到投影矩阵堆栈
    projectionMatrix.LoadMatrix(viewFrustum.GetProjectionMatrix());
    //调用顶部载入单元矩阵
    modelViewMatrix.LoadIdentity();
}

投影矩阵堆栈主要在这里获取投影矩阵,并在transformPipeline中与视图矩阵相乘。

  1. SpecialKeys旋转物体
void SpecialKeys(int key,int x,int y){
    if (key == GLUT_KEY_UP) {
        objectFrame.RotateWorld(m3dDegToRad(-5.0f), 1.0f, 0.0f, 0.0f);
    }
    if(key == GLUT_KEY_DOWN){
        objectFrame.RotateWorld(m3dDegToRad(5.0f), 1.0f, 0.0f, 0.0f);
    }
    if(key == GLUT_KEY_LEFT)
        objectFrame.RotateWorld(m3dDegToRad(-5.0f), 0.0f, 1.0f, 0.0f);
    
    if(key == GLUT_KEY_RIGHT)
        objectFrame.RotateWorld(m3dDegToRad(5.0f), 0.0f, 1.0f, 0.0f);
    
    glutPostRedisplay();
}
  1. RenderSence渲染
void RenderScene(void)
{
    //清除一个或一组特定的缓冲区
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
    
    modelViewMatrix.PushMatrix();//栈中压入单元矩阵
    
    //观察者矩阵mCamera
    M3DMatrix44f mCamera;
    cameraFrame.GetCameraMatrix(mCamera); //mCamera的到一个矩阵
    modelViewMatrix.MultMatrix(mCamera);  //栈顶中的模型矩阵与mCamera相乘得到一个新的矩阵
    //物体矩阵坐标系
    M3DMatrix44f mObject;
    objectFrame.GetMatrix(mObject);
    //矩阵相乘->模型视图矩阵
    modelViewMatrix.MultMatrix(mObject);
    
    //设置一组浮点数来表示红色
    GLfloat vRed[] = {1.0f, 0.0f, 0.0f, 1.0f};
    shaderManager.UseStockShader(GLT_SHADER_FLAT,transformPipeline.GetModelViewProjectionMatrix(),vRed);
    
    //提交着色器
    switch (nStep) {
        case 0:
            glPointSize(10.f);
            pointBatch.Draw();
            glPointSize(1.f);
            break;
        case 1:
            glPointSize(10.f);
            lineBatch.Draw();
            glPointSize(1.f);
            break;
        case 2:
              glPointSize(10.f);
              lineLoopBatch.Draw();
              glPointSize(1.f);
              break;
        default:
            break;
    }
    
    //移除堆栈
    modelViewMatrix.PopMatrix();
    
    //将在后台缓冲区进行渲染,然后在结束时交换到前台
    glutSwapBuffers();
}

效果图


截屏2020-07-09 23.11.15.png 截屏2020-07-09 23.11.04.png

关于矩阵堆栈可以参考下图


矩阵堆栈

总结:

  1. 透视投影要经过 model matrix->view matrix -> projection matrix ->viewport transform
  2. modelViewMatrix:用于处理视角矩阵cameraFrame、模型矩阵objectFrame的矩阵变换
  3. projectionMatrix:处理透视矩阵viewFrustum
  4. transformPipeline对projectionMatrix堆栈和modelViewMatrix堆栈处理,最后transformPipeline获取ModelViewProjectionMatrix交给我们的管理者。

参考:

视觉Demo——CC老师
OpenGL基础变化综合练习实践总结——凡几多

相关文章

  • OpenGL基础变换

    OpenGL ⾥的基础变换 OpenGL中涉及的基础变化主要有以下5种: 变换解释视图变换指定观察者位置模型变换在...

  • OpenGL基础变换

    1. 视觉坐标 视觉可以理解为屏幕坐标。是一个虚拟的固定的坐标系。 2. 视图变换 视图变化是当观察者移动位置时视...

  • OpenGL基础变换

    本章的主要目的是通过修改键盘是的上下左右键,来旋转点、线、三角形,观察形状的变化。 ——视角不动,物体动openg...

  • OpenGL基础变换

    1.理解变换 变换应用视图指定观察者或照相机的位置模型在场景中移动物体模型视图描述视图和模型变换的二元性投影改变视...

  • OpenGL基础变换

    第四章 OpenGL基础变换 向量和矩阵 在第三章,我们讨论了如何绘制3D点、线和三角形。为了将一系列图形转换到连...

  • OpenGL基础变换

    第四章 OpenGL基础变换 向量和矩阵 在第三章,我们讨论了如何绘制3D点、线和三角形。为了将一系列图形转换到连...

  • 五、OpenGL - 基础变换

    向量 向量:既有大小又有方向的量,在3D笛卡尔坐标系中,一个顶点就可以表示向量(x,y,z) 标量:只有大小没有方...

  • 七、OpenGL中的基础变换和矩阵堆栈

    基础变换 OpenGL中设计的变换主要有以下几种: 变换说明视图变换指定观察者位置模型变换在场景中移动物体模型视图...

  • 九、OpenGL 基础变化与矩阵堆栈

    基础变化 OpenGL中涉及的基础变化主要有以下5种 变换说明视图变换指定观察者位置模型变换在场景中移动物体模型视...

  • 七、OpenGL 基础变化与矩阵堆栈

    基础变化 OpenGL中涉及的基础变化主要有以下5种 变换说明视图变换指定观察者位置模型变换在场景中移动物体模型视...

网友评论

      本文标题:OpenGL基础变换

      本文链接:https://www.haomeiwen.com/subject/lldecktx.html