参考:最长的一帧

先看下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 函数

[原][OSG]整理osg渲染一帧的流程的更多相关文章

  1. [原][资料整理][osg]osgDB文件读取插件,工作机制,支持格式,自定义插件

    参考: osgPlugins相关 osg读取文件的原理(插件工作机制) 当使用osgDB读取文件时,会自动根据文件的扩展名来到插件目录中寻找相应的插件,来实现. 比如: osgviewer cow.o ...

  2. 探索未知种族之osg类生物---渲染遍历之认识SceneView

    前言 我们在进行osg程序的开发时,最常用到的场景管理方式是“场景节点树”的结构,     a 场景树底端的叶节点(osg::Geode)包含了各种需要渲染的几何体的顶点和渲染状态信息:     b  ...

  3. [原][OSG]深入osg函数----SceneView::cull 函数

    参考:最长一帧 先介绍几个类: osgUtil::CullVisitor:“筛选访问器” 当我们使用它遍历场景图形的各个节点时, CullVisitor 将会对每一个遇到的节点执行场景筛选的工作,判断 ...

  4. OSG 3D场景渲染编程概述

    OSG是Open Scene Graphic的缩写,是基于C++平台的使用OpenGL技术的开源3D场景开发. vs环境安装或者是在Ubuntu中环境的安装网上教程很多,都是大同小异的,认真操作容易成 ...

  5. 探索未知种族之osg类生物---渲染遍历之器官协作

    好了,现在我们经过三节的介绍我们已经大体上明确了单线程模型(SingleThreaded)下 OSG 渲染遍历的工作流程.事实上无论是场景的筛选render还是绘制cull工作,最后都要归结到场景视图 ...

  6. 探索未知种族之osg类生物---渲染遍历之Renderer::draw()简介

    我们今天进入上一节的遗留问题Renderer::draw()的探究. 1.从_drawQueue中取出其中一个sceneView对象.SceneView是对scene和view类的封装,通过他可以方便 ...

  7. [原][osg][QT]osg与QT界面结合的简单例子二

    //main.cpp #include "VREObliqueEditorQTWindow.h" #include <QtWidgets/QApplication> # ...

  8. [OSG][转]osg格式文件

    转自:http://blog.csdn.net/timothyfly/article/details/7826139 osg格式文件中如何处理多个节点共享一个子节点 下面一段程序中,共有三个Group ...

  9. [转][osg][QT]osg与QT界面结合的简单例子

    //QT += core gui opengl //LIBS += -losgViewer -losgDB -losgUtil -losg -lOpenThreads -losgGA -losgQt ...

随机推荐

  1. windows上备份mysql数据库

    方案一:采用mysql自带的工具mysqldump. 脚本文件backup.bat如下: set  "YMD=%date:~,4%%date:~5,2%%date:~8,2%"cd ...

  2. SV搭建验证环境

    1)首先定义纯虚类Sv_object,主要实现下边两个function: 定义local static 变量nextobjectID; 虚方法 virtual function void copy(S ...

  3. [转]mac上安装android sdk

    一.先下载android sdk for mac 给二个靠谱的网址: a). http://down.tech.sina.com.cn/page/45703.html b). http://mac.s ...

  4. Java(1-15)

    1.方法参数是引用类型,传递的是内存地址!2.方法的重载特性:在同一个类中,允许方法同名,只要方法的参数列表不同即可!3.Stirng特殊在如果静态数据区中存在,那么不创建新的对象,而是指向这个对象. ...

  5. thinkphp标签实现bootsrtap轮播carousel实例

    thinkphp标签实现bootsrtap轮播carousel实例由于轮播carousel第一个div需要设置active样式才能正常显示,上面的圆点也同样需要数字,使用volist标签在循环的同时可 ...

  6. 2016NOI冬令营day0

    上午写了一道题. 中午收拾好东西后兴高采烈地坐老司机开的出租车来到了美丽的南山中学!!!:) 志愿者太多了,弄得我们有点不好意思......:) 来到寝室,看到了传闻中的被子&空(kong4) ...

  7. 《网络攻防》实验八:Web基础

    适逢多事之际,下周二的课设答辩.全国信安竞赛初赛作品筹备.协会密码沙龙比肩接踵,这些"案牍"不仅劳形还影响了我的复习计划."甘蔗没有两头甜的"还是要有所舍得了, ...

  8. 上周日选拔题部分write up

    ---恢复内容开始--- 第一题.平淡无奇的签到题,“百度一下,你就知道”,打开之后会弹出一个百度的网页页面.网页题第一步,先查看它的源代码.从上往下看,发现了这样一行字 看起来有点像base编码,于 ...

  9. 2018-2019-1 20189218《Linux内核原理与分析》第四周作业

    构造简单的Linux内核 显然用实验楼配好的环境做这个实验太简单了,按照没有困难制造困难也要上的原则,在自己的64位虚拟机上做这个实验. 按照课本(视频)上的步骤一直做下去,到编译生成init时出现了 ...

  10. 关于Session的概念和测试点

    Session概要 Session 是用于保持状态的基于 Web 服务器的方法,在 Web 服务器上保持用户的状态信息供在任何时间从任何页访问. Session 允许通过将对象存储在 Web 服务器的 ...