技术标签: osg多线程
再次回到viewer的realize函数中(/src/osgViewer/Viewer.cpp第525行)
通过前一个的介绍我们知道了当用户没有设定context的时候,osg会自动的根据系统类型创建适宜的context,所以一下代码做了这么两件事情
1.如果没有创建成功,那么,将会因为contexts为空,realize失败而退出。
2.再往下就是来得到DisplaySetting,并根据这个DisplaySetting来得到窗口系统的接口,(DisplaySetting以及WindowingSystemInterface我们在上几节都有说明。)
下面一段for循环我们需要进行详细讲解
for(Contexts::iterator citr = contexts.begin();
citr != contexts.end();
++citr)
{
osg::GraphicsContext* gc = *citr;
if (ds->getSyncSwapBuffers()) gc->setSwapCallback(new osg::SyncSwapBuffersCallback);
// set the pool sizes, 0 the default will result in no GL object pools.
gc->getState()->setMaxTexturePoolSize(maxTexturePoolSize);
gc->getState()->setMaxBufferObjectPoolSize(maxBufferObjectPoolSize);
gc->realize();
if (_realizeOperation.valid() && gc->valid())
{
gc->makeCurrent();
(*_realizeOperation)(gc);
gc->releaseContext();
}
}
这段代码做了一下几个事情遍历所有的GraphicsContext,然后判断是否设置了同步交换缓冲区(这一般是渲染的最后一步),这是osg提供的多机同步swapbuffer机制,他会默认调用内置的swapbuffer的回调函数(osg::SyncSwapBuffersCallback中,作用主要是等待client端的同步锁,实现多机同步执行swapbuffer)。如果developer想干预的话 可以调用 osg::GraphicsContext::setSwapCallback(SwapCallback* rc)来设置自定义的缓存交换回调。自定义的回调必须调用GraphicsContext::swapBuffersImplementation()函数.
定义gc中最大的纹理层数以及最大缓冲池的大小
3.进行GraphicsContext的realize动作,他其实就是调用了GraphicsContext中realizeImplementation(),它是一个被重载的函数,我们可以在GraphicsWindowX11.cpp中找到linux下的实现方法,我们可以从中看出主要就是针对linux窗口程序中gc以及event的初始化工作。结合上一日的讲解我们可以总结从操作系统底层到创建出graphiccontext,以及交给camera使用的步骤
a.viewer中主从相机使用的setGraphicContext设置对应的显示上下文其实就是对应的显示窗口。
b.GraphicContext的创建是由平台相关的抽象类WindowingSystemInterface负责,对于linux来说。这个类是有GraphicsWindowX11.cpp中的X11WindowingSystem类具体实现的,它创建了osgViewer::GraphicsWindowX11的实例
c.进一步讲,如果窗口特性Traits中开启了pbuffer选项,则OSG将尝试创建osgViewer::PixelBufferX11设备,以实现离屏渲染、纹理烘焙等工作,否则只创建普通的opengl窗口。
4.完成用户指定一些在realize时执行的动作。其中_realizeOperation是通过osgViewer::ViewerBase中setRealizeOperation来设置,其主要作用是在执行 realize 函数时,顺便完成用户指定的一些工作。您自己的工作内容可以通过继承 osg::Operation 类,并重载 operator()操作符来添加。
5.相比较而言,GraphicContext::makeCurrent以及GraphicContext::releaseContext函数也是使用相同的方法实现多态的针对不同的操作系统平台,那么他们两个的主要工作就是完成类似opengl的wglMakeCurrent完成的工作,即将渲染的上下文RC对应到正确的窗口绘制句柄上。在其中穿插用户自定义的动作。
再次聚焦到realize函数上(/src/osgViewer/Viewer.cpp第567行),_incrementalCompileOperation,用于预编译GraphicContext,主要作用是,想在程序运行开始时就加在一个资源文件但是又不想或者没有到显示到界面的时机,则会用到这个预加载操作。具体的用法如下:
//从Viewer获取 osgUtil::IncrementalCompileOperation的指针:
osgUtil::IncrementalCompileOperation* pIcompOperation = viewer.getIncrementalCompileOperation();//从Viewer获取 osgUtil::IncrementalCompileOperation的指针:
// 创建compileSet:
osg::ref_ptr<:incrementalcompileoperation::compileset> compileSet = osgUtil::IncrementalCompileOperation::CompileSet(NODE,true);
//从CompileCompletedCallback派生新类,然后重写Completed函数,在内部隐藏节点:
//将 派生类 绑定到 compileSet。
compileSet->compileSet->_compileCompletedCallback = newCompileCompletedCallback;
//设置 IncrementalCompileOperation 过期策略
pIcompOperation->setCompileAllTillFrameNumber(50);
再往下就是使鼠标聚焦到osg的绘制窗口上这个一个功能。
osg::Timer::instance()->setStartTick();
setStartTick(osg::Timer::instance()->getStartTick());
setUpThreading();
首先调用 osg::Timer::setStartTick 函数,启动 OSG 内部定时器并开始计时。
随后, Viewer::setStartTick 函数的工作是找到当前视景器和所有 GraphicsContext 设备的
事件队列_eventQueue,并设定它们的启动时刻为当前时间。
下一行是调用 ViewerBase::setUpThreading 函数(这个多线程问题我们以后再深入讨论)
请回到 realize 函数,现在这个函数的执
行已经接近了尾声,不过我们又遇到了一个问题:编译上下文(也就是 Compile Contexts,
暂时就这样翻译吧)?如果要启用它的话并不困难,只需要在调用 realize 之前执行:
osg::DisplaySettings::instance()->setCompileContextsHint(true);
随后,正如您在 realize 函数的 491-503 行之间看到的,系统将设法遍历所有可能的
GraphicsContext 设备,针对它们分别再各自添加一个新的 GraphicsContext 设备(也就是说,
如果系统中已经有了数个图形上下文,那么现在又将新增同样数量的图形上下文与之对应),
所用的函数为 GraphicsContext::getOrCreateCompileContext。这之后,分别执行了创建图形
线程,设置 CPU 依赖性,以及启动图形线程的工作,具体的实现内容可以暂时忽略。观察 getOrCreateCompileContext 函数的内容,很快我们就可以发现其中的重点:这些新
增的 GraphicsContext 对象使用了 pBuffer 的特性,并与对应的已有对象共享同一个图形上下
文(Traits::sharedContext 特性)。事实上,这是 OSG 利用 OpenGL 的像素缓存(Pixel Buffer)
技术,为图形上下文的后台编译提供的一种新的解决方案。这样不仅可以提高图形刷新的速
度,还可以方便用户为某一特定的 GraphicsContext 设备添加特殊的处理动作,方法是使用
osg::GraphicsContext::getCompileContext 获取后台图形上下文,再使用 GraphicsContext::add
函数向其中追加 osg::Operation 对象,类似的例子可以参看 osgterrain。
当一个项目完成了,你是否想过把它发布到服务器上去呢?那么下面就来告诉你如何去部署它吧!(Visual Studio版本:2019)首先要准备好你的项目 然后进行如下操作第一大步骤1.打开你需要发布的网站,然后点击生成--->发布即可2.在打开的窗口中选择发布的位置为文件夹--->下一步3.选择存放的位置点击浏览选择本地路径最后点击完成即可4.最后再点击发布就完成了第二大步骤在计算机中添加IIS1.回到桌面使...
TWRP(Team Win Recovery Project )是一款非常强大的Recovery刷机工具。刷机有风险,操作之前请备份重要数据。方法一:通过fastboot刷入TWRP的方式首先去TWRP官网下载TWRP安装文件https://twrp.me/Devices/选择你需要刷入TWRP的设备,然后下载相应的刷机文件,比如选择的是Google Nexus5, twrp-3.0.2...
2019独角兽企业重金招聘Python工程师标准>>> ...
博主近来发现之前学习过很多东西,都没有留下什么资料供后面回顾时参考,感觉自己总是在寻找一条路,一条可以让自己走的更远的路。今天在新的电脑上安装Git 客户端,所以就做一个分享吧!一、下载并安装客户端 下载地址:git 客户端下载,下载链接中可以看到不同操作系统的客户端下载链接,这里我们以Windows来做示例,下载过程省略....(网速影响下载速度,我怕你们等不及...
--方法一sqlserver汉字转拼音首字母--调用方法 select dbo.procGetPY ('中國')Create FUNCTION dbo.procGetPY ( @str NVARCHAR(4000) ) /*select dbo. procGetPYFirstLetter ('中國')*/RETURNS NVARCHAR(4000) --WI
Timer实际上是个线程,它可以定时调度一个TimerTask对象。一个TimerTask实际上就是一个拥有run方法的类,需要定时执行的代码放到run方法体内。 方式一:使用配置文件1.写一个类,实现定时任务:
Mac上的虚拟机推荐安装 ParallelDesktopFor Mac1、安装ParallelDesktop 2、下载Windows7 3、用ParallelDesktop安装Windows71、-软件获取方式-喜欢折腾的选择以下方法下载,不喜欢折腾的在闲鱼或者某宝上搜一个最便宜的拍下来全程解疑(十五元左右)。友情下载链接友情链接...
mysql> use information_schemaReading table information for completion of table and column namesYou can turn off this feature to get a quicker startup with -ADatabase changed 当切换到某个库时,经常会出现上面
参考地址https://www.mathworks.com/matlabcentral/answers/386196-trying-to-display-a-lbp-image-from-extractlbpfeatures记录一下,以防网址打不开…clc; % Clear the command window.close all; % Close all figures (except those of imtool.)imtool close all; % Close all imto
radio&&radioGroup、table、modal
1、检查一下系统中的jdk版本[[email protected] software]# java -version显示:openjdk version "1.8.0_102"OpenJDK Runtime Environment (build 1.8.0_102-b14)OpenJDK 64-Bit Server VM (build 25.102-b14, mixed mode)...
问题:项目中发现在setUserVisibleHint中给textview 赋值报空指针.解决:最后定位发现是因为 setUserVisibleHint 在生命周期中是 运行在 onCreateView 之前。所以导致textview没有被实例化。@Overridepublic void setUserVisibleHint(boolean isVisibleToUser) ...