上一节我们对完成了对osg生物内部非常重要器官graphicsContext的初始化工作。这样就可保证我们场景中至少有一个graphicContext存在,不至于刚出生就面临夭折。我们根据上一节中osg代码的研究也就知道了,在我们正常使用osg时,是怎么完成对camera以及graphicContext的创建的了。

回到Viewer::realize()中我们继续向下看,现在我们对osg::DisplaySettings以及osg::GraphicsContext::WindowingSystemInterface,有了新的认识,我在这里再补充一张camera,graphicContext以及windowingSystemInterface的关系图有利于大家进一步了解osg的内部组成。

回到Viewer::realize()中我们继续向下看,得到所有的GraphicsContext,遍历所有的GraphicsContext,然后判断是否设置了同步交换缓冲区(这一般是渲染的最后一步),这是osg提供的多机同步swapbuffer机制,他会默认调用内置的swapbuffer的回调函数(osg::SyncSwapBuffersCallback中,作用主要是等待client端的同步锁,实现多机同步执行swapbuffer)。如果developer想干预的话 可以调用 osg::GraphicsContext::setSwapCallback(SwapCallback* rc)来设置自定义的缓存交换回调。自定义的回调必须调用GraphicsContext::swapBuffersImplementation()函数.

再根据所依据的平台(windows,linux,mac等)默认制定的,或者用户后期修改的最大纹理池和最大对象缓冲池的大小,进一步对各个graphicsContext的相应属性值进行设置。然后正式完成对graphicsContext的初始化定义,下一步就是通过调用gc.realize()来使graphicsContext处于可用的状态。Osg::GraphicsContext::realize()函数的实现都是在它的继承类中通过realizeImplementation()函数完成的。

特别是windows平台的实现,使用windows+opengl的同学对这一段GraphicsWindowWin32::realizeImplementation()函数肯定非常了解,因为这里会涉及到很多windows平台特有的一些属性,就不做过多的介绍了,以后有机会我会再写一份opengl的入门教程,其中肯定会提到函数中涉及的东西。敬请期待。

当GraphicsContext可用了,就需要更新上下文gc->makeCurrent()。那我们就看看GraphicsContext::makeCurrent()完成了什么工作。

gc->makeCurrent()

GraphicsContext::makeCurrent()首先判断opengl与osg是否是同一个线程,(使用qt5+osg3.x的同学一定遇到过osg的threadmode只能设置singlethread。其他三种threadmode都会报一个同样的错误,错误的原因就是这里。至于怎么完美的结合qt5与osg3,请移步到我的github下 https://github.com/JimmieKJ/osgQTWidget 有具体的实现细节)。其实GraphicsContext::makeCurrent()的根本是通过调用子类的makeCurrentImplementation()实现。

当我们移步到bool GraphicsWindowWin32::makeCurrentImplementation()同样会发现,这里和使用opengl的程序有很大的相同之处,其实就是把dc和rc进行绑定。当makeCurrentImplementation返回true的时候,就代表graphicsContext更新成功。然后就是opengl的思路,需要解绑hc和rc防止资源浪费,这就需要调用gc->releaseContext(),其实就是调用子类的releaseContextImplementation()函数。

再次聚焦到realize函数上(/src/osgViewer/Viewer.cpp::realize()函数),_incrementalCompileOperation,用于预编译GraphicContext,主要作用是,想在程序运行开始时就加在一个资源文件但是又不想或者没有到显示到界面的时机,则会用到这个预加载操作。具体的用法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
//从Viewer获取 osgUtil::IncrementalCompileOperation的指针:
osgUtil::IncrementalCompileOperation* pIcompOperation = viewer.getIncrementalCompileOperation();//从Viewer获取 osgUtil::IncrementalCompileOperation的指针:
// 创建compileSet:
osg::ref_ptr compileSet = osgUtil::IncrementalCompileOperation::CompileSet(NODE,true);
//从CompileCompletedCallback派生新类,然后重写Completed函数,在内部隐藏节点:
  
//将 派生类 绑定到 compileSet。
compileSet->compileSet->_compileCompletedCallback =  newCompileCompletedCallback;
//设置 IncrementalCompileOperation 过期策略
pIcompOperation->setCompileAllTillFrameNumber(50);
再往下就是使鼠标聚焦到osg的绘制窗口上这个一个功能。
// initialize the global timer to be relative to the current time.
osg::Timer::instance()->setStartTick();
// pass on the start tick to all the associated event queues
setStartTick(osg::Timer::instance()->getStartTick());
// configure threading.
setUpThreading();

首先调用 osg::Timer::setStartTick 函数,启动 OSG 内部定时器并开始计时

随后, Viewer::setStartTick 函数的工作是找到当前视景器和所有 GraphicsContext 设备的事件队列_eventQueue,并设定它们的启动时刻为当前时间。下一行是调用 ViewerBase::setUpThreading 函数(这个多线程问题我们以后再深入讨论)

请回到 realize 函数,现在这个函数的执行已经接近了尾声,不过我们又遇到了一个问题:编译上下文(也就是 Compile Contexts,)如果要启用它的话并不困难,只需要在调用 realize 之前执行:osg::DisplaySettings::instance()->setCompileContextsHint(true);随后,正如您在 realize 函数的 最后一个for循环看到的,系统将设法遍历所有可能的GraphicsContext 设备,针对它们分别再各自添加一个新的 GraphicsContext 设备(也就是说如果系统中已经有了数个图形上下文,那么现在又将新增同样数量的图形上下文与之对应),所用的函数为 GraphicsContext::getOrCreateCompileContext

这之后,分别执行了创建图形线程,设置 CPU 依赖性,以及启动图形线程的工作,具体的实现内容可以暂时忽略。观察 getOrCreateCompileContext 函数的内容,很快我们就可以发现其中的重点:这些新增的 GraphicsContext 对象使用了 pBuffer 的特性,并与对应的已有对象共享同一个图形上下文(Traits::sharedContext 特性)。事实上,这是 OSG 利用 OpenGL 的像素缓存(Pixel Buffer)技术,为图形上下文的后台编译提供的一种新的解决方案。这样不仅可以提高图形刷新的速度,还可以方便用户为某一特定的 GraphicsContext 设备添加特殊的处理动作,方法是使用osg::GraphicsContext::getCompileContext 获取后台图形上下文,再使用 GraphicsContext::add函数向其中追加 osg::Operation 对象,类似的例子可以参看 osgterrain。

欢迎大家来我的新家看一看 3wwang个人博客-记录走过的技术之路

转载于:https://www.cnblogs.com/wang985850293/p/10436510.html

探索未知种族之osg类生物---器官初始化四相关推荐

  1. 探索未知种族之osg类生物---器官初始化一

    我们把ViewerBase::frame()比作osg这类生物的肺,首先我们先来大概的看一下'肺'长什么样子,有哪几部分组成.在这之前得对一些固定的零件进行说明,例如_done代表osg的viewer ...

  2. 类的初始化列表_探索未知种族之osg类生物---渲染遍历之draw函数二

    我们今天今天真是进入SceneView::draw()函数. 1.判断主相机是否为隐藏状态也就是(camera->getNodeMask()==0),隐藏状态就会退出这个draw函数. 2.开始 ...

  3. 退出所有循环_探索未知种族之osg类生物---呼吸分解之事件循环三

    那我们就开始处理这些事件中得到的所有的交互事件,首先我们要判断这些事件是否包含osg的退出事件,那什么情况下会触发这个退出事件呢?如果您运行过osg中example中的小例子的,聪明的你一定就会发现当 ...

  4. osg动态加载模型不显示_探索未知种族之osg类生物---渲染遍历之Renderer::draw()简介...

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

  5. 探索未知种族之osg类生物---起源

    任何程序都是有生命的,是生命就需要呼吸.例如普通的windows程序,当运行完main()函数后,就需要进入消息循环,来监听用户的各种操作,以便做出及时的回应.这样的每次循环就像生命的每次呼吸,来维持 ...

  6. 探索未知种族之osg类生物---呼吸分解之更新循环一

    上节总结 前几天我们大体上介绍完成了osg的事件循环的介绍,总结一下osg的时间循环主要就是得到平台(windows)的所有消息,并遍历所有的node的eventCallback,并对他们进行处理.接 ...

  7. 【乘风破浪的开发者】丁一超:从AI实战营出发探索未知的AI世界

    摘要:从年初的不知不觉进入AI学习的道路,到认识并熟练使用ModelArts平台.虽然只有短短的半年,但这半年的探索学习,让丁一超看清了未来的路在何方. 从招聘网站上输入"人工智能工程技术人 ...

  8. 大学英语(第六册)复习(原文及全文翻译)——Unit 10 - Debating The Unknowable(探索未知世界)

    Unit 10 - Debating The Unknowable Do animals think? How could the earth show so many signs of design ...

  9. 「镁客早报」人类首次在太空3D打印生物器官;中国学者研制出高性能低成本的电解“水制氢”催化剂...

    SpaceX公司Dragon飞船油漆可能是造成国际空间站污染的罪魁祸首:谷歌公布将在加州山景城进行大规模开发. 1.SpaceX公司Dragon飞船油漆可能是造成国际空间站污染的罪魁祸首 12月10日 ...

最新文章

  1. 关于服务器启动慢的问题
  2. 探索 Swift 中的 MVC-N 模式
  3. anaconda卸载重装matplotlib
  4. python单选按钮重置_python – Tkinter单选按钮初始化错误
  5. eval函数 php_PHP的一句话木马代码和函数eval的简介
  6. 与0xf2值相等的是python_腾讯笔试题涵盖的基础知识
  7. React项目build之后资源文件路径不正确或打开空白页的问题及简易解决方法
  8. LeetCode 386. Lexicographical Numbers
  9. 远程成桌面的链接计算机名,连接远程服务器计算机名称
  10. java怎么定义_java怎么定义方法
  11. 新疆财大计算机科学,新疆财经大学计算机科学与工程学院学生参加了多项专业赛事...
  12. 天地图JS API制作专题图
  13. H13-531 华为HCIE云计算笔试题库整理
  14. HDU - 2567 寻梦
  15. ant design vue table 高度自适应_对比1万2千个Vue.js开源项目发现最实用的 TOP45!火速拿来用!...
  16. 电商扣减库存_经验分享:电商库存体系设计笔记
  17. Word - Word 文档如何切换简体字和繁体字?
  18. 使用ventoy制作PE(可同时存在多个PE)——(有图文)
  19. 《Hadoop篇》------HDFS与MapReduce
  20. python分类预测模型总结

热门文章

  1. C/C++ 编程规范(02)— 标识符命名
  2. python内置库之学习configparser库(一)
  3. leetcode 30. Substring with Concatenation of All Words 与所有单词相关联的字串 滑动窗口法
  4. Error: Module build failed: TypeError: this.getResolve is not a function at Object.loader
  5. 使用Spring容器
  6. LeetCode简单题之Excel表列名称
  7. LeetCode简单题之图像渲染
  8. Python3.8.5最新版安装教程(含老版本卸载教程)
  9. 自动生成低精度深度学习算子
  10. 微信架构 支付架构(下)