• [原][OSG]整理osg渲染一帧的流程


    参考:最长的一帧

    先看下frame

    void ViewerBase::frame(double simulationTime)
    {
      advance(simulationTime);//记录仿真时间,帧数,收集弃用对象
      eventTraversal();//处理键鼠响应,VPW矩阵,交互回调
      updateTraversal();//更新节点访问器,分页数据,更新回调,相机操作,设置cullseting 
      renderingTraversals();//遍历渲染
    }

    eventTraversal()流程

      1、取得事件队列的状态事件(EventQueue::getCurrentEventState鼠标键盘操作等);

      2、取得主摄像机的视口范围(如果它存在的话,正如我们在前面所论述的,主摄像机并不一定存在Viewport视口也不一定存在GraphicsContext图形设备),并设置为事件队列的“响应范围”(EventQueue::setInputRange);

      3、计算主摄像机的 VPW 矩阵。

        观察矩阵(View Matrix),投影矩阵(Projection Matrix),视口矩阵(Window Matrix)

    updateTraversal()流程

    1、使用预设的更新访问器_updateVisitor,访问场景图形的根节点并遍历其子节点,实现各个节点和 Drawable 对象的更新回调。

    2、使用DatabasePager::updateSceneGraph函数以及ImagePager::updateSceneGraph函数, 分别更新场景的分页数据库和分页图像库。

    3、处理用户定义的更新工作队列_updateOperations。

    4、执行主摄像机_camera 以及从摄像机组_slaves的更新回调(但是不会遍历到它们的子节点),像机回调的执行时机与场景节点有所区别的。

    5、根据漫游器_cameraManipulator的位置姿态矩阵,更新主摄像机_camera的观察矩阵。

    6、使用 View::updateSlaves 函数更新从摄像机组_slaves中所有摄像机的投影矩阵,观察矩阵和场景筛选设置(CullSettings,之后renderingTraversals会调用cull遍历)。

    renderingTraversals()流程:

    (题外话:OSG 中为精华也为复杂的组成部分,含有大量线程操作)

    单线程模式下:

    1、遍历视景器对应的所有 Scene 场景(Viewer 单视景器只存在一个场景),记录分页数据库的更新启动帧(使用 DatabasePager::signalBeginFrame,这将决定 DatabasePager 中的数据请求是否过期),并计算场景节点的边界球。

    2、获取当前所有的图形设备(GraphicsContext)和摄像机。

    3、遍历所有摄像机的渲染器(Renderer),执行 Renderer::cull 场景筛选的操作!

    4、遍历所有的图形设备,设置渲染上下文(使用ViewerBase::makeCurrent)并执行 GraphicsContext::runOperations,实现场景绘制的操作!

    5、再次遍历所有的图形设备,执行双缓存交换操作(GraphicsContext::swapBuffers)。

    6、遍历视景器中的场景,告知分页数据库更新已经结束(DatabasePager::signalEndFrame, 目前这个函数没有作用)。

        第3和4是重点。

    特别关注

    1. 场景筛选的操作Renderer::cull 函数
    2. 执行图形设备GraphicsContext::runOperations 函数

    场景筛选的操作Renderer::cull 函数流程:

    1、首先从_availableQueue 队列中获取一个可用的场景视图(SceneView)。

    2、执行 Renderer::updateSceneView 函数,更新这个场景视图的全局渲染状态

    3、更新场景视图(SceneView)的融合距离(Fusion Distance)和筛选设置(CullSettings)。

    4、执行 SceneView::cull 函数,这才是真正的场景筛选(裁减)工作的所在!!

    5、将这个渲染视图添加到绘制队列_drawQueue 中,以便绘制

    重点关注SceneView::cull 函数

  • 相关阅读:
    cocos2dx图片加密解密(npk方式)
    C#吾日三省吾身
    重写窗体的Enter事件(可对窗口的Enter事件做自己想做的事情)
    c#中显示Excel控件使用说明
    c# datagridview合并单元格
    AxSpreadsheet属性与方法说明
    c#实现货币转中文大写类
    jquery常用的插件1000收集
    [原创]站长自助平台一个帮助站长全自动实现一键采集、发贴(伪原创)、会员注册、交换连接的平台
    c#操作XML常用方法
  • 原文地址:https://www.cnblogs.com/lyggqm/p/6635341.html
Copyright © 2020-2023  润新知