Ogre版本: 1.9.0: 操作系统: Linux 4.8.0-58-通用#63〜16.04.1-Ubuntu x86_64
大家好,
我正在尝试为RViz(罗斯可视化)构建一个插件,以直接从使用Ogre渲染的窗口重新录制视频。如果我依次遍历所有打开的场景管理器并从渲染目标获取当前帧,则一切正常。录制完成后,从缓冲的图像生成视频。但是,当两个以上的窗口正在主动渲染内容时,帧速率会明显下降。请参见下面的代码。为了清楚起见,我省略了错误处理和其他不需要的代码行。每30毫秒调用一次 update()函数。
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="testCtrl">
<select style="width: 199px;margin-top: -9px;" id="ddlTypeCode" ng-model="selectedCountryCode" ng-change="locationChange(selectedCountryCode)" name="ddlTypeCode" class="form-control">
<option style="display:none;"></option>
<option ng-repeat="Country in CountryList " value="{{Country}}"ng-selected="Country == 'India'">
{{Country}}
</option>
</div>
我尝试使用Boost库生成线程,以便异步捕获帧,但是返回的帧始终为黑色(或一些奇怪的像素混乱)。为此,我将每个活动场景管理器的grabAllFrames函数拆分为单独的函数,并将每个函数附加到一个线程。
void VideoRecorderDisplay::update()
{
if (m_recording)
{
grabAllFrames();
}
}
void VideoRecorderDisplay::grabAllFrames()
{
// TODO: start thread for each manager and parallelize
const size_t sceneManagerSize = m_sceneManagers.size();
for(size_t i = 0; i < sceneManagerSize; i++)
{
Ogre::Viewport* viewPort = m_sceneManagers[i]->getCurrentViewport();
if(viewPort != nullptr)
{
Ogre::Image ogreImage = getOgreImageFromRenderTarget(viewPort->getTarget());
m_ogreImageList.push_back(ogreImage);
}
}
}
Ogre::Image VideoRecorderDisplay::getOgreImageFromRenderTarget(Ogre::RenderTarget* const renderTarget)
{
try
{
// create PixelBox and get data from target
Ogre::PixelFormat pf = renderTarget->suggestPixelFormat();
const uint32_t targetWidth = renderTarget->getWidth();
const uint32_t targetHeight = renderTarget->getHeight();
const size_t boxSize = targetWidth * targetHeight * Ogre::PixelUtil::getNumElemBytes(pf);
unsigned char* ogrePixelData = new unsigned char[boxSize];
Ogre::PixelBox pixelBox(targetWidth, targetHeight, 1, pf, ogrePixelData);
renderTarget->copyContentsToMemory(pixelBox);
// load data into Ogre::Image
Ogre::Image ogreImage = Ogre::Image().loadDynamicImage(ogrePixelData, targetWidth, targetHeight, 1, pf);
return ogreImage;
}
}
我不知道这是什么问题。指向场景管理器的指针与顺序版本相同。视口相同。但是以某种方式 getTarget()不会返回任何有用的信息。当我使用
static boost::shared_ptr<boost::thread> grabberThread0;
static boost::shared_ptr<boost::thread> grabberThread1;
static boost::shared_ptr<boost::thread> grabberThread2;
static boost::shared_ptr<boost::thread> grabberThread3;
void VideoRecorderDisplay::update()
{
if (m_recording)
{
grabberThread0 = boost::shared_ptr<boost::thread>(new boost::thread(boost::bind(&VideoRecorderDisplay::grabAllFramesParallelized, this, m_sceneManagers[0], boost::ref(m_dataListPerThread[0]))));
grabberThread1 = boost::shared_ptr<boost::thread>(new boost::thread(boost::bind(&VideoRecorderDisplay::grabAllFramesParallelized, this, m_sceneManagers[1], boost::ref(m_dataListPerThread[1]))));
grabberThread2 = boost::shared_ptr<boost::thread>(new boost::thread(boost::bind(&VideoRecorderDisplay::grabAllFramesParallelized, this, m_sceneManagers[2], boost::ref(m_dataListPerThread[2]))));
grabberThread3 = boost::shared_ptr<boost::thread>(new boost::thread(boost::bind(&VideoRecorderDisplay::grabAllFramesParallelized, this, m_sceneManagers[3], boost::ref(m_dataListPerThread[3]))));
grabberThread0->join();
grabberThread1->join();
grabberThread2->join();
grabberThread3->join();
}
}
void VideoRecorderDisplay::grabAllFramesParallelized(Ogre::SceneManager* scnMngr, std::vector<Ogre::Image> dataList)
{
Ogre::Viewport* viewPort = scnMngr->getCurrentViewport();
if(viewPort != nullptr)
{
Ogre::Image ogreImage = getOgreImageFromRenderTarget(viewPort->getTarget());
dataList.push_back(ogreImage);
}
}
图像也是黑色的。因此,我认为问题出在 getTarget()函数之内。
我很感谢任何提示。如果有人对另一个多线程库感到幸运,我也欢迎其他解决方案。
谢谢
电车!