美文网首页
案例分析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