美文网首页
OpenGL-MVP模式的六种图元绘制

OpenGL-MVP模式的六种图元绘制

作者: 过气的程序员DZ | 来源:发表于2020-07-10 01:18 被阅读0次

开场白


这篇文章主要聊聊使用MVP模式的图元绘制,先来看看效果


运行效果

1.空格切换绘制模式:


main函数中增加键盘的回调函数,用来响应‘空格’按键:

int main(int argc, char* argv[]){
    ...
    glutKeyboardFunc(KeyPressFunc);
    ...
}

然后我们来看看KeyPressFunc实现

void KeyPressFunc(unsigned char key, int x, int y) {
    if(key == 32)
    {
        nStep++;
        
        if(nStep > 6)
            nStep = 0;
    }
    
    switch(nStep)
    {
        case 0:
            glutSetWindowTitle("GL_POINTS");
            break;
        case 1:
            glutSetWindowTitle("GL_LINES");
            break;
        case 2:
            glutSetWindowTitle("GL_LINE_STRIP");
            break;
        case 3:
            glutSetWindowTitle("GL_LINE_LOOP");
            break;
        case 4:
            glutSetWindowTitle("GL_TRIANGLES");
            break;
        case 5:
            glutSetWindowTitle("GL_TRIANGLE_STRIP");
            break;
        case 6:
            glutSetWindowTitle("GL_TRIANGLE_FAN");
            break;
    }
    
    glutPostRedisplay();
}
  1. key == 32是判断是否为空格键,32是ascll码
  2. 当点击空格键后,修改全局变量nStep
  3. switch判断当前的nStep,显示不同的窗口title
  4. 调用glut的重绘函数

2.SetupRC实现


void SetupRC()
{
    //设置背景色
    glClearColor(0.7f, 0.7f, 0.7f, 1.0f );
    //初始化着色管理器
    shaderManager.InitializeStockShaders();
    //开启深度测试
    glEnable(GL_DEPTH_TEST);
    //设置变化管线的矩阵堆栈
    transformPipeline.SetMatrixStacks(modelViewMatrix, projectionMatrix);
    //设置camera位置
    cameraFrame.MoveForward(-15.0f);
    
    //后续代码是设置一些顶点信息,不是本文章的重点。   
    ...
}

本段代码主要设置了管线transformPipeline,并且设置了矩阵堆栈,目的是使用MVP模式进行绘图。MVP模式就是model-view-projection的三个矩阵变换,来渲染图片。
设置了camera的位置,cameraFrame.MoveForward为-15的位置,这个可以理解为在屏幕前,距离屏幕15的位置。

3.ChangeSize实现


void ChangeSize(int w,int h)
{
    glViewport(0, 0, w, h);
    //视图椎体变量设置观察者位置
    viewFrustum.SetPerspective(35.0f, float(w) / float(h), 1.0f, 500.0f);
    //从视图椎体中加载投影矩阵
    projectionMatrix.LoadMatrix(viewFrustum.GetProjectionMatrix());
    //模型视图矩阵设置为单元矩阵
    modelViewMatrix.LoadIdentity();
}
  1. 设置视口,
  2. 视图椎体viewFrustum,设置观察者的位置。视图椎体:以camera(观察者)在的位置为顶点,以Far clip plane(远端平截面)为底的几何椎体。请参考下图:


    视图椎体示意[图片上传中...(image.png-c04e57-1594315058378-0)]
  1. 设置视图矩阵projectionMatrix和模型视图矩阵modelViewMatrix,视图矩阵初始值是单元矩阵,该单元矩阵乘以从视图椎体中取出视图矩阵,将值赋值给视图矩阵projectionMatrix。模型视图矩阵设置为单元矩阵(默认值就是单元矩阵,所以此行代码可以不写。),因为当前还没有模型视图,所以设置为初始值。


    坐标系转换

4.RenderScene


本文的重点部分

void RenderScene(void) {
    //1.清除一个或一组特定的缓冲区
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
    
    //2.记录当前模型视图矩阵,当前的值是单元矩阵,所以入栈的是单元矩阵。目的是本次改变后,调用出栈方法,将模型视图矩阵重新复制成单元矩阵,下面有对应PopMatrix函数调用
    modelViewMatrix.PushMatrix();
    
    //3.将camera frame转换成矩阵
    M3DMatrix44f mCamera;
    cameraFrame.GetCameraMatrix(mCamera);
    //modelViewMatrix矩阵乘以camera矩阵栈,相乘的结果存放到modelViewMatrix
    modelViewMatrix.MultMatrix(mCamera);
    
    //4.将object frame转换成矩阵,objectFrame在键盘上下左右时设置的值
    M3DMatrix44f mObjectFrame;
    objectFrame.GetMatrix(mObjectFrame);
    //modelViewMatrix矩阵乘以object矩阵栈,相乘的结果存放到modelViewMatrix
    modelViewMatrix.MultMatrix(mObjectFrame);
    
    //5.使用平面着色器,参数2是从变换管线transformPipeline中获取MVP(ModelViewProjectionMatrix)矩阵
    shaderManager.UseStockShader(GLT_SHADER_FLAT, transformPipeline.GetModelViewProjectionMatrix(), vBlack);
    
    //6.
    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;
            
    }
    
    //7.出栈,将modelViewMatrix还原成单元矩阵
    modelViewMatrix.PopMatrix();
    
    //8.将在后台缓冲区进行渲染,然后在结束时交换到前台
    glutSwapBuffers();
}
  1. 清除缓冲区
  2. modelViewMatrix.PushMatrix();入栈处理。此时modelViewMatrix还是单元矩阵(矩阵的初始值,任何矩阵✖️单元矩阵,还是等于本身),目的是本次修改后还可以恢复到原来的初始值。
  3. 获取camera的矩阵,并将camera矩阵与modelView矩阵,也就是将camera的位置信息混入modelView矩阵中。
  4. 将objectFrame也转换成矩阵,并和第三步一样,混入到modelView矩阵中。objectFrame的变化是在‘空格键’响应函数中进行修改的(KeyPressFunc)。
  5. 调用平面着色器,参数2是从变换管线transformPipeline中获取MVP(ModelViewProjectionMatrix)矩阵
  6. 根据当前nStep,获取不同的容器批次类进行绘制。
  7. 出栈。对应第2步
  8. 交换缓冲区。

5. DrawWireFramedBatch


在RenderScene的实现中的switch case 4-6中调用了DrawWireFramedBatch函数,该函数作用是为了渲染复杂3d几何图形时需要进行的一些处理,我们先来看看实现

void DrawWireFramedBatch(GLBatch* pBatch)
{
    //1.上色
    shaderManager.UseStockShader(GLT_SHADER_FLAT, transformPipeline.GetModelViewProjectionMatrix(), vBlue);
    pBatch->Draw();
    
    //2.设置线相关内容
    
    // 偏移深度,在同一位置要绘制填充和边线,会产生z冲突,所以要偏移
    glPolygonOffset(-1.0f, -1.0f);
    //根据glPolygonOffset的设置,启用线的深度偏移
    glEnable(GL_POLYGON_OFFSET_LINE);
    
    //启用锯齿
    glEnable(GL_LINE_SMOOTH);
    //启用颜色混合
    glEnable(GL_BLEND);
    //混合方式,使用alpha,1-alpha方式混合
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    
    //多边形模式,正反面都用画线模式
    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
    glLineWidth(2.5f);
    
    //画线
    shaderManager.UseStockShader(GLT_SHADER_FLAT, transformPipeline.GetModelViewProjectionMatrix(), vBlack);
    pBatch->Draw();
    
    //3.复原状态
    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
    glDisable(GL_POLYGON_OFFSET_LINE);
    glLineWidth(1.0f);
    glDisable(GL_BLEND);
    glDisable(GL_LINE_SMOOTH);
}
  1. 填充颜色,使用平面着色器进行图形内部颜色填充
  2. 设置线相关内容
    • glEnable()用于启用各种功能
    • GL_POLYGON_OFFSET_LINE:偏移深度,在同一位置要绘制填充和边线,会产生z冲突,所以要偏移
    • GL_LINE_SMOOTH:启用锯齿
    • GL_BLEND:启用颜色混合
    • glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA):混合方式,使用alpha,1-alpha方式混合
    • glPolygonMode多边形模式,正反面都用画线模式
    • 画线,用定义好的黑色
  3. 复原相关设置

代码地址


OpenGL_MVP_demo

相关文章

  • OpenGL-MVP模式的六种图元绘制

    开场白 这篇文章主要聊聊使用MVP模式的图元绘制,先来看看效果 1.空格切换绘制模式: main函数中增加键盘的回...

  • 使⽤固定存储着⾊器渲染多种图元

    OpenGL下的图形都是由图元构成的,图元告诉了所有顶点以何种方式去绘制渲染。主要有以下7种图元: 图元描述GL_...

  • Matplotlib图元与容器

    Matplotlib实现绘图的基本工具是图元(Primitive)和容器(Container)。图元是绘制的基本图...

  • OpenGL(四) OpenGL图元绘制

    我们知道点、线、三角形是OpenGL的基本图元。在绘制图元之前,我们先来了解下OpenGL常见的图元连接方式 图元...

  • OpenGL-基础渲染

    目录 OpenGL渲染架构 投影方式设置 固定管线解析 OpenGL基本图元解析 图元绘制 GLBatch Ope...

  • OpenGL ES 3.0(四)图元、VBO、VAO

    图元 OpenGL ES 3.0 可供绘制的图元类型有:1) Triangles,三角形2) Lines,线3) ...

  • OpenGL图元绘制

    基础的图元连接方式 基础设置 main函数设置 特殊键位处理(上、下、左、右移动) 用来控制图像的旋转变换 根据空...

  • OpenGL ES 3.0编程指南:第七章. Primitive

    [TOC] 摘要 本章描述了OpenGL ES支持的图元类型和几何对象,并且解释了如何绘制它们。然后描述了图元装配...

  • CAD_学习_02

    图形的绘制与编辑 掌握基本图元的绘制和图形的编辑修改 能够独立绘制相对复杂的图形 合理运用绘图命令和编辑命令绘制...

  • OpenGL--图元绘制

    前言 这篇文章的目的是了解OpenGL中图形渲染的基本图元以及如何绘制基本图元,真正从原理入手,了解图形渲染的基本...

网友评论

      本文标题:OpenGL-MVP模式的六种图元绘制

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