|
- // Poster arguments
- bool activeMode = true;
- bool outputPoster = true;
- //bool outputTiles = false;
- int tileWidth = 640, tileHeight = 480;
- int posterWidth = 640*5, posterHeight = 480*5;
- unsigned int slaveCameraCount=posterWidth/tileWidth*posterHeight/tileHeight;
- std::string posterName = "poster.bmp", extName = "bmp";
- osg::Vec4 bgColor(0.2f, 0.2f, 0.6f, 1.0f);
- osg::Camera::RenderTargetImplementation renderImplementation = osg::Camera::FRAME_BUFFER_OBJECT;
- // Create camera for rendering tiles offscreen. FrameBuffer is recommended because it requires less memory.
- for (unsigned int slaveNum=0;slaveNum<slaveCameraCount;slaveNum++)
- {
- osg::ref_ptr<osg::Camera> prerender_camera = new osg::Camera;
- prerender_camera->setClearColor( bgColor );
- prerender_camera->setClearMask( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
- prerender_camera->setReferenceFrame( osg::Transform::ABSOLUTE_RF );
- prerender_camera->setRenderOrder( osg::Camera::PRE_RENDER );
- prerender_camera->setRenderTargetImplementation( renderImplementation );
- prerender_camera->setViewport( 0, 0, tileWidth, tileHeight );
- //prerender_camera->addChild( geode_nc);
- view1->addSlave(prerender_camera);
- }
-
- // Set the printer
- osg::ref_ptr<PosterPrinter> printer = new PosterPrinter;
- printer->setTileSize( tileWidth, tileHeight );
- printer->setPosterSize( posterWidth, posterHeight );
- printer->setCamera( view1->getCamera() );
- osg::ref_ptr<osg::Image> posterImage = 0;
- if ( outputPoster )
- {
- posterImage = new osg::Image;
- posterImage->allocateImage( posterWidth, posterHeight, 1, GL_RGBA, GL_UNSIGNED_BYTE );
- printer->setFinalPoster( posterImage.get() );
- printer->setOutputPosterName( posterName );
- }
- view1->getCamera()->setPreDrawCallback(new WindowCaptureRealtimeCallback(printer.get()));
- ////////////////////////////////
- // 回调函数类,在绘制的时候回调
- // 每帧都截出一张大图
- /** Capture the frame buffer and write image to disk*/
- class WindowCaptureRealtimeCallback : public osg::Camera::DrawCallback
- {
- public:
- WindowCaptureRealtimeCallback( PosterPrinter* printer)
- : _printer(printer)
- {
- _fileBaseName="D:/work_bak/OSG_research/3DModel_common/123";
- _fileName=_fileBaseName+"_"+ConvertToString(1)+".bmp";
- _printer->setContinuousOutput(true);
- _printer->setPosterMainName(_fileBaseName);
- _printer->setPosterExtName("bmp");
- //renderInfo.getCurrentCamera();
- //_printer->setOutputPosterName( _fileName );
- }
- virtual void operator () (osg::RenderInfo& renderInfo) const
- {
- osgViewer::View* view = dynamic_cast<osgViewer::View*>(renderInfo.getView());
-
-
- if ( !view ) return;
- if ( _printer.valid() )
- {
- osg::Switch* root = dynamic_cast<osg::Switch*>( view->getSceneData() );
- if ( root )
- {
- // Assume child 0 is the loaded model and 1 is the poster camera
- root->setValue( 0, false );
- root->setValue( 1, true );
- }
- _printer->init( view->getCamera() );
- //_started = true;
- }
- if ( view->getDatabasePager() )
- {
- // Wait until all paged nodes are processed
- while( view->getDatabasePager()->getRequestsInProgress() )
- {}
- }
- if ( _printer.valid() )
- {
- //开始每帧输出一张图了
- _printer->eachPicForEachFrame( view );
-
- }
- }
- public:
- std::string _fileName;
- //int _fileCount;
- std::string _fileBaseName;
- osg::ref_ptr<PosterPrinter> _printer;
- bool _started;//=true
- };
- //////////////////////////////////////////////////////////////////////////
- //每帧都输出一张图片,预计等待的时间会很长
- void PosterPrinter::eachPicForEachFrame( osgViewer::View * view)
- {
- const osg::FrameStamp* fs=view->getFrameStamp();
- osg::Node* node=view->getSceneData();
- // Add cull callbacks to all existing paged nodes,
- // and advance frame when all callbacks are dispatched.
- if ( addCullCallbacks(fs, node) )
- return;
-
- // Record images and the final poster
- recordImages();
- if ( _isRunning )
- {
- // Every "copy-to-image" process seems to be finished in 2 frames.
- // So record them and dispatch camera to next tiles.
-
- // Record images and unref them to free memory
- //recordImages();
- // Release all cull callbacks to free unused paged nodes
- removeCullCallbacks( node);
- _visitor->clearNames();
- while( _camera.valid() && !_isFinishing)
- {
- std::cout << "Binding sub-camera " << _currentRow << "_" << _currentColumn
- << " to image..." << std::endl;
- //从相机的计数器
- unsigned int i=0;
- ;
- bindCameraToImage( view->getSlave(i)._camera.get(), _currentRow, _currentColumn );
- if ( _currentColumn<_tileColumns-1 )
- {
- _currentColumn++;
- i++;
- }
- else
- {
- if ( _currentRow<_tileRows-1 )
- {
- _currentRow++;
- _currentColumn = 0;
- i++;
- }
- else
- {
- _isRunning = false;
- _isFinishing = true;
- i=0;
- }
- }
- }
- _lastBindingFrame = fs->getFrameNumber();
- //view->;
- // Record images and the final poster
- recordImages();
- if ( _finalPoster.valid() )
- {
- std::cout << "Writing final result to file..." << std::endl;
- if (_isContinuousOutput)//需要连续出图
- {
- _outputPosterName=_outputPosterMainName+"_"+ConvertToString(_lastBindingFrame)+"."+_outputPosterExtName;
- }
- else
- {
- }
- osgDB::writeImageFile( *_finalPoster, _outputPosterName );
- }
- // Release all cull callbacks to free unused paged nodes
- removeCullCallbacks( node );
- _visitor->clearNames();
- _isFinishing = false;
- std::cout << "Recording images finished." << std::endl;
- }
- }
复制代码 截图相关的代码,本意是想每帧截出一副超大图,采用的方式是
设置:
采用一堆slave相机
每个相机对应一个tile的viewport
每一帧时:
在主相机的postdrawcallback中调整每个相机的矩阵
attach每个slave相机到小的tile
直接将每个tile拷贝到大图像中,输出
问题:
输出的图像都是灰的
疑问和测试:
attach的时候并没有绘制,由于改了slave相机的视图矩阵,slave的render信息发生变化了?所以才是空白的
用sceneview强制输出是不是解决途径?我new了sceneview来获取每个slave的displaysetting,但是在draw的时候报错了
- //bindCameraToImage里面最后几行
- // Reattach cameras and new allocated images
- camera->setRenderingCache( NULL ); // FIXME: Uses for reattaching camera with image, maybe inefficient?
- camera->detach( osg::Camera::COLOR_BUFFER );
- camera->attach( osg::Camera::COLOR_BUFFER, image.get(), 0, 0 );
- //osgUtil::SceneView* eachSceneView=new osgUtil::SceneView(camera->getDisplaySettings());
- //eachSceneView->draw();
复制代码 |
|