美文网首页
案例分析1:OpenGL图元_点/线/线段/线环/⾦字塔/六边形

案例分析1:OpenGL图元_点/线/线段/线环/⾦字塔/六边形

作者: 致青春_bf42 | 来源:发表于2020-07-10 13:33 被阅读0次
    该案例主要是对常见的图元连接方式的运用,常见的基本图元连接方式见此链接

    最终实现的效果如图所示:


    2251862-2704e73125622d2c.gif

    如图所示,整体的绘制流程如下


    2251862-21f85926f0eeca0d.png
    • main函数:程序入口
    • ChangeSize 函数:⾃定义函数,通过glutReshaperFunc(函数名)注册为重塑函数.当屏幕⼤⼩发⽣变化/或者第⼀次创建窗⼝时,会调⽤该函数调整窗⼝⼤⼩/视⼝⼤⼩.
    • SetupRC函数:⾃定义函数,图形数据配置,主要是顶点数据及图元连接方式 ,设置你需要渲染的图形的相关顶点数据/颜⾊数据等数据装备⼯作
    • RenderScene 函数:⾃定义函数.通过glutDisplayFunc(函数名)注册为显示渲染函数.当屏幕发⽣变化/或者开发者主动渲染会调⽤此函数,⽤来实现数据->渲染过程
    • SpecialKeys函数:对特殊键位的回调处理(上、下、左、右移动)
    • KeyPressFunc函数:针对空格键的回调处理
    • DrawWireFrameBatch函数:用于立体图形的填充及边框绘制

    ChangeSize 函数

    通过glutReshaperFunc(函数名)注册为重塑函数.当屏幕⼤⼩发⽣变化/或者第⼀次创建窗⼝时,会调⽤该函数调整窗⼝⼤⼩/视⼝⼤⼩.

    // 窗口已更改大小,或刚刚创建。无论哪种情况,我们都需要
    // 使用窗口维度设置视口和投影矩阵.
    void ChangeSize(int w, int h)
    {
        glViewport(0, 0, w, h);
        //创建投影矩阵,并将它载入投影矩阵堆栈中
        //参数1:垂直方向上的视场角度
        //参数2:视口纵横比 = w/h
        //参数3:近裁剪面距离
        //参数4:远裁剪面距离
        viewFrustum.SetPerspective(35.0f, float(w) / float(h), 1.0f, 500.0f);
        //通过设置的投影方式获得投影矩阵,并将其存入投影矩阵中
        projectionMatrix.LoadMatrix(viewFrustum.GetProjectionMatrix());
        
        //调用顶部载入单元矩阵,压入一个单元矩阵
        modelViewMatrix.LoadIdentity();
    }
    

    SetupRC函数

    从流程图上可以看出,除了基本的背景色设置,存储着色器初始化以及顶点数据的创建及传输外,还需要对阵矩阵及观察者做一下设置

     //设置变换管线以使用两个矩阵堆栈 将模型视图矩阵和投影矩阵放到变换管道中,变换管道的作用是能帮助快速进行矩阵相乘,在RenderScene函数中可以直接通过变换管道的Get方法得到相应的矩阵
        transformPipeline.SetMatrixStacks(modelViewMatrix, projectionMatrix);
      //设置观察者位置
        cameraFrame.MoveForward(-15.0f);
    

    其中,变换管道通过get可获得的矩阵有4种

    方法 说明
    GetProjectionMatrix() 投影矩阵
    GetNormalMatrix() 法线矩阵
    GetModelViewMatrix() 模型视图矩阵,简称mv
    GetModelViewProjectionMatrix() 模型视图投影矩阵,简称mvp

    观察者位置的设置有三种

    方法 说明
    void MoveForward(float fDelta) 向外移动的像素点,修改z
    void MoveUp(float fDelta) 向上移动的像素点,修改y
    void MoveRight(float fDelta) 向右移动的像素点,修改x

    RenderScene函数

    主要用于场景的绘制

    // 召唤场景
    void RenderScene(void)
    {
        // Clear the window with current clearing color
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
       
        //压栈
        modelViewMatrix.PushMatrix();
        M3DMatrix44f mCamera;
        cameraFrame.GetCameraMatrix(mCamera);
        
        //矩阵乘以矩阵堆栈的顶部矩阵,相乘的结果随后简存储在堆栈的顶部
        modelViewMatrix.MultMatrix(mCamera);
        
        M3DMatrix44f mObjectFrame;
        //只要使用 GetMatrix 函数就可以获取矩阵堆栈顶部的值,这个函数可以进行2次重载。用来使用GLShaderManager 的使用。或者是获取顶部矩阵的顶点副本数据
        objectFrame.GetMatrix(mObjectFrame);
        
        //矩阵乘以矩阵堆栈的顶部矩阵,相乘的结果随后简存储在堆栈的顶部
        modelViewMatrix.MultMatrix(mObjectFrame);
        
        /* GLShaderManager 中的Uniform 值——平面着色器
         参数1:平面着色器
         参数2:运行为几何图形变换指定一个 4 * 4变换矩阵
         --transformPipeline.GetModelViewProjectionMatrix() 获取的
         GetMatrix函数就可以获得矩阵堆栈顶部的值
         参数3:颜色值(黑色)
         */
        shaderManager.UseStockShader(GLT_SHADER_FLAT, transformPipeline.GetModelViewProjectionMatrix(), vBlack);
        
        switch(nStep) {
            case 0:
                //设置点的大小
                glPointSize(4.0f);
                pointBatch.Draw();
                glPointSize(1.0f);
                break;
            case 1:
                //设置线的宽度
                glLineWidth(2.0f);
                lineBatch.Draw();
                glLineWidth(1.0f);
                break;
            case 2:
                glLineWidth(2.0f);
                lineStripBatch.Draw();
                glLineWidth(1.0f);
                break;
            case 3:
                glLineWidth(2.0f);
                lineLoopBatch.Draw();
                glLineWidth(1.0f);
                break;
            case 4:
                DrawWireFramedBatch(&triangleBatch);
                break;
            case 5:
                DrawWireFramedBatch(&triangleStripBatch);
                break;
            case 6:
                DrawWireFramedBatch(&triangleFanBatch);
                break;
        }
        
        //还原到以前的模型视图矩阵(单位矩阵)
        modelViewMatrix.PopMatrix();
        
        // 进行缓冲区交换
        glutSwapBuffers();
    }
    

    具体代码地址:https://gitee.com/lijiang.com/openGLDemo2.git

    相关文章

      网友评论

          本文标题:案例分析1:OpenGL图元_点/线/线段/线环/⾦字塔/六边形

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