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

上一节我们对完成了对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,主要作用是,想在程序运行开始时就加在一个资源文件但是又不想或者没有到显示到界面的时机,则会用到这个预加载操作。具体的用法如下:

//从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个人博客-记录走过的技术之路

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342

推荐阅读更多精彩内容