第14天的有个错误
关于一开始用的这个pagedLod结构,既然setFileName和setrange()了,就不该addChild()了,这才是动态加载。也就是只需设置各个子节点的文件名和出现范围即可。
继续调试,先看总体流程
这一节主要是总结了,再把大图拷过来
左上角还没有调试
跟着电子书走一走,抄一抄
1,首先osg::PagedLOD节点或者osg::ProxyNode节点使用setFileName函数,请求运行时加载模型文件为子节点。
初始化时已经设置了
2,在SceneView::cullStage()中,场景筛选时,启用cullvisitor,遍历至PagedLOD节点,检查视点距离并请求加载子节点;遍历至ProxyNode节点,请求加载未载入的代理子节点
3,在场景的筛选(cull)过程中,OSG将自动取出PagedLOD和ProxyNode中保存的文件名数据,并使用DatabasePager::requestNodeFile函数,将其保存到数据请求列表RequestQueue::_requestList中。并尝试释放数据线程。如果还没开启数据线程,则开启网络和本地两个线程
这是并行堆栈中可以看到数据处理线程。
在DatabaseThread::run()中先阻塞,有两种情况下可以释放,删除弃用(updateSceneGraph)和数据请求(requestNodeFile)。这两种情况下可以往下走。
不论是数据请求还是删除弃用,发送后总是block自己,而分页数据库处理线程可以在处理后updateBlock(),唤醒主线程。
4,正如3所讲,DatabasePager内置了两个数据处理线程DatabaseThread,分别用于处理本地文件和HTTP数据,现成的主要工作是删除已弃用队列RequestQueue::_childrenToDeleteList中的对象,并从数据请求列表中获取新的请求.
5,线程中如果取得新的数据请求,则尝试加载新的模型,判断是否需要预编译模型,并送入等待编译列表_dataToCompileList。预编译的含义是执行显示列表的创建、纹理绑定、GLSL数据绑定等OpenGL动作,通常情况下,预编译模型可以避免它在显示时出现帧延迟。
6,对于编译完成或者无需编译的数据请求,首先创建其KDTree包围体,(用于k-dop Tree碰撞检测计算),然后送入“等待合并列表”_dataToMergeList,线程让出控制权
7,场景的每次更新遍历均会执行UpdateScenegraph函数,于其中将一段时间内没有进入用户视野的节点送入已弃用队列(只限于PagedLOD节点的子节点),并将等待合并列表中的新数据使用addChild送入当前的场景图形
电子书简介了下ImagePager,这个类接近于DatabasePager,主要负责纹理图片文件的运行时加载。
osg::ImageSequence可以使用图片数据库来执行工作,主要使用自身包含的Image图片对象序列,实现一种动画纹理效果
ImagePager也内置了一个处理线程ImagePager::ImageThread,其中随时读取图片加载请求ImagePager::ImageRequest的内容,并根据其中的文件名使用osgDB::readImageFile加载osg::Image对象。加载之后的图片数据将被加入到申请它的ImageSequence对象中,暂时不具备分页功能,即,不删除长时间不用的图片。
就到这里吧