一、问题的引入:如何筛选,如何绘制,对动态对象该怎么处理
二、四种线程模型.
1,单线程
2,CullDrawThreadPerContext:系统为每个图形设备创建一个线程,每一帧结束前强制同步所有的线程,也就是说每帧前都要绘制完
3,DrawThreadPerContext,系统为每个图形设备创建一个线程,并且在当前帧的所有线程完成工作之前,开始下一帧
4,CullThreadPerCameraDrawThreadPerContext:系统为每个图形设备和每个摄像机创建线程,并且在当前帧的所有线程完成工作之前,开始下一帧。
初始化是在osgViewer::ViewerBase::startThread(),进行判断选择哪种线程模型,并根据阻塞个数,来确定是否添加渲染启动栅栏_startRenderingBarrier和渲染结束栅栏_endRenderingDispatchBarrier
三、筛选和渲染
osgViewer::ViewerBase::renderingTraversals()函数中,在
_startRenderingBarrier->block()和_endRenderingDispatchBarrier->block()之间,
判断筛选renderer->cull()和绘制gc->runOperations()
在第2,3种线程模型中,gc->getGraphicsThread()为真,则在图形上下文绘制,而不是在renderingTraversals()中绘制
在第4种线程模型中,camera->getCameraThread()也为真,则筛选也是由摄像机线程筛选,不用renderingTraversals()筛选。
四、关于动态修改的对象的渲染,
适用于第3,4种模式,即上一帧渲染未结束而下一帧开始的情况。
要确保在渲染这些对象结束之前,不会开始下一帧的数据修改更新工作。
这就需要用到动态对象渲染阻塞器_endDynamicDrawBlock,通过每个渲染叶的状态处理后计数减一,计数为0时completed()冲破阻塞
初始化在
osgViewer::ViewerBase::startThread(),对第3,4模式进行_endDynamicDrawBlock以及各个图形上下文处理阻塞回调函数
起作用在osgViewer::ViewerBase::renderingTraversals()函数中,
_startRenderingBarrier->block()和_endRenderingDispatchBarrier->block()之间, _endDynamicDrawBlock->block();