|
这几天在处理如何稳定帧速的过程中基本上看遍了论坛的帖子,但是基本上都达不到我的要求,但是也有些问题没有搞明白,在这里看看有没有大神理解,希望能为小弟解惑:
1.我希望的是将场景的帧速稳定在100,最开始是按照FreeSouth视频中的处理方法,即在while循环里的frame前后记录它的时间,在决定是否睡眠,可是这个的效果实在不怎么好,在看视频时也发现了这个问题,就是最开始FreeSouth将帧速稳定在10时效果也还可以,但是他后来将帧速稳定在30时效果就不怎么好了,误差已经有2-3左右了,在我将帧速稳定在100的测试过程中有些时候即时帧速到90了。
2.然后在论坛中搜索与帧稳定性相关的帖子,有两个帖子的解决方法是通过设置setRunMaxFrameRate函数:
http://www.osgchina.org/forum.ph ... amp;_dsign=3aed1ada
http://www.osgchina.org/forum.ph ... amp;_dsign=fdf5b991
最开始我使用setRunMaxFrameRate函数后没效果,后来查看OSG的源码,发现这个函数是在ViewBase类的run函数中调用的,而我的工程是使用while循环里加入frame函数实现的,所以设置这个函数没用,然后看setRunMaxFrameRate函数的源码,发现和1中FreeSouth的方法基本上是一样的,甚至处理的更粗糙一些。
3.然后发现了一个同样需要定时刷新的帖子,我这个要稳定帧速的需求和定时刷新感觉是一样的:
http://www.osgchina.org/forum.ph ... amp;_dsign=9b5eaf3f
array在里面说使用on demand模式,然后我在OSG的源码中也发现了这个模式,这个模式也是在ViewBase类的run函数中调用的,这是这个枚举变量的定义:
- enum FrameScheme
- {
- ON_DEMAND,
- CONTINUOUS
- };
复制代码
然后在ViewBase类的run函数的使用方法如下:
- int ViewerBase::run()
- {
- if (!isRealized())
- {
- realize();
- }
- const char* run_frame_count_str = getenv("OSG_RUN_FRAME_COUNT");
- unsigned int runTillFrameNumber = run_frame_count_str==0 ? osg::UNINITIALIZED_FRAME_NUMBER : atoi(run_frame_count_str);
- while(!done() && (run_frame_count_str==0 || getViewerFrameStamp()->getFrameNumber()<runTillFrameNumber))
- {
- double minFrameTime = _runMaxFrameRate>0.0 ? 1.0/_runMaxFrameRate : 0.0;
- osg::Timer_t startFrameTick = osg::Timer::instance()->tick();
- if (_runFrameScheme==ON_DEMAND)
- {
- if (checkNeedToDoFrame())
- {
- frame();
- }
- else
- {
- // we don't need to render a frame but we don't want to spin the run loop so make sure the minimum
- // loop time is 1/100th of second, if not otherwise set, so enabling the frame microSleep below to
- // avoid consume excessive CPU resources.
- if (minFrameTime==0.0) minFrameTime=0.01;
- }
- }
- else
- {
- frame();
- }
- // work out if we need to force a sleep to hold back the frame rate
- osg::Timer_t endFrameTick = osg::Timer::instance()->tick();
- double frameTime = osg::Timer::instance()->delta_s(startFrameTick, endFrameTick);
- if (frameTime < minFrameTime) OpenThreads::Thread::microSleep(static_cast<unsigned int>(1000000.0*(minFrameTime-frameTime)));
- }
- return 0;
复制代码
然后去看checkNeedToDoFrame这个函数的源码,发现它与我想象的不一样,它不是那种类似回调的实现,就是发送一个信号后就进入下一帧,这样就不知道如何使用定时刷新了,FrameScheme和checkNeedToDoFrame的含义是什么?array说使用ON_DEMAND模式到底是什么意思?
4.最后就是这个帖子了:
http://www.osgchina.org/forum.ph ... amp;_dsign=8dad14e5
这里面最开始说的是使用OnTimer函数,这个函数和MFC的定时器是一个原理吗?可是如何让这个函数来控制仿真的时间?
然后FlySky在下面的答复中是可以使用simulationTime时间来控制帧速,我又查看源码发现这个变量是很多函数的形参,并且有默认值0,可是如何通过这个变量来控制帧率?
FreeSouth在下面的说法是使用硬招,于是我尝试可不可以把垂直同步打开,然后修改显示器的刷新频率为100,这样要是能成功的话帧速应该可以稳定在100,可是显示器里的刷新频率没法手动设置啊?还有就是这种设置方法是1s渲染100帧后休息,还是平均0.01s渲染一帧?这两个概念对我而言是完全不同的。
最后array回复是不是表示显示器的刷新频率没法手动设置了?
问题有点多,希望大家懂的能帮忙解决下,谢谢! |
|