目标:(七十九)中的问题156
原因一、rex的高程没有通过GPU来绘制,而是CPU生成的(错误,是用GPU绘制的,之所以还要设置TileDrawable的高程栅格,是用于碰撞检测而不是用于绘制)
原因二、帧循环,可以控制帧率,也可以根据需要来绘制,这可以从这里看出
osgViewer/ViewerBase.cpp
int ViewerBase::run()
{
if (!isRealized())
{
realize();
}
unsigned int runTillFrameNumber = osg::UNINITIALIZED_FRAME_NUMBER;
osg::getEnvVar("OSG_RUN_FRAME_COUNT", runTillFrameNumber);
while(!done() && (runTillFrameNumber==osg::UNINITIALIZED_FRAME_NUMBER || 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;
}
原因三、每个瓦片在绘制时会频繁向gpu传数据,详见:
osgEarthDrivers/engine_rex/DrawTileCommand.cpp
void
DrawTileCommand::draw(osg::RenderInfo& ri, DrawState& dsMaster, osg::Referenced* layerData) const
{
。。。
}
原因四、过多设置缓存,见osgEarth的Rex引擎原理分析(一二三)osgEarth的缓存及其结构_hankern的专栏-CSDN博客
1、控制帧速率的方法有:
(1)设置环境变量
osg::getEnvVar("OSG_RUN_MAX_FRAME_RATE", _runMaxFrameRate);
(2)函数设置
osgViewer/ViewerBase
void setRunMaxFrameRate(double frameRate) { _runMaxFrameRate = frameRate; }
2、根据需要绘制,需要重写函数checkNeedToDoFrame(),默认是这样的:
osgViewer/Viewer.cpp
bool Viewer::checkNeedToDoFrame()
{
// check if any event handler has prompted a redraw
if (_requestRedraw) return true;
if (_requestContinousUpdate) return true;
// check if the view needs to update the scene graph
if (requiresUpdateSceneGraph()) return true;
// check if the view needs to be redrawn
if (requiresRedraw()) return true;
// check if events are avai