查看: 2147|回复: 3

在每一帧截图,截图分辨率超过窗口分辨率,怎么设置?

[复制链接]

该用户从未签到

发表于 2012-1-9 10:43:56 | 显示全部楼层 |阅读模式
  1. // Poster arguments
  2.                 bool activeMode = true;
  3.                 bool outputPoster = true;
  4.                 //bool outputTiles = false;
  5.                 int tileWidth = 640, tileHeight = 480;
  6.                 int posterWidth = 640*5, posterHeight = 480*5;
  7.                 unsigned int slaveCameraCount=posterWidth/tileWidth*posterHeight/tileHeight;
  8.                 std::string posterName = "poster.bmp", extName = "bmp";
  9.                 osg::Vec4 bgColor(0.2f, 0.2f, 0.6f, 1.0f);
  10.                 osg::Camera::RenderTargetImplementation renderImplementation = osg::Camera::FRAME_BUFFER_OBJECT;

  11.                 // Create camera for rendering tiles offscreen. FrameBuffer is recommended because it requires less memory.
  12.                 for (unsigned int slaveNum=0;slaveNum<slaveCameraCount;slaveNum++)
  13.                 {
  14.                         osg::ref_ptr<osg::Camera> prerender_camera = new osg::Camera;
  15.                         prerender_camera->setClearColor( bgColor );
  16.                         prerender_camera->setClearMask( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
  17.                         prerender_camera->setReferenceFrame( osg::Transform::ABSOLUTE_RF );
  18.                         prerender_camera->setRenderOrder( osg::Camera::PRE_RENDER );
  19.                         prerender_camera->setRenderTargetImplementation( renderImplementation );
  20.                         prerender_camera->setViewport( 0, 0, tileWidth, tileHeight );
  21.                         //prerender_camera->addChild( geode_nc);

  22.                         view1->addSlave(prerender_camera);
  23.                 }
  24.                

  25.                 // Set the printer
  26.                 osg::ref_ptr<PosterPrinter> printer = new PosterPrinter;
  27.                 printer->setTileSize( tileWidth, tileHeight );
  28.                 printer->setPosterSize( posterWidth, posterHeight );

  29.                 printer->setCamera( view1->getCamera() );

  30.                 osg::ref_ptr<osg::Image> posterImage = 0;
  31.                 if ( outputPoster )
  32.                 {
  33.                         posterImage = new osg::Image;
  34.                         posterImage->allocateImage( posterWidth, posterHeight, 1, GL_RGBA, GL_UNSIGNED_BYTE );
  35.                         printer->setFinalPoster( posterImage.get() );
  36.                         printer->setOutputPosterName( posterName );
  37.                 }



  38. view1->getCamera()->setPreDrawCallback(new WindowCaptureRealtimeCallback(printer.get()));



  39. ////////////////////////////////
  40. // 回调函数类,在绘制的时候回调
  41. // 每帧都截出一张大图
  42. /** Capture the frame buffer and write image to disk*/
  43. class WindowCaptureRealtimeCallback : public osg::Camera::DrawCallback
  44. {
  45. public:  
  46.         WindowCaptureRealtimeCallback( PosterPrinter* printer)
  47.                 : _printer(printer)
  48.         {
  49.                 _fileBaseName="D:/work_bak/OSG_research/3DModel_common/123";
  50.                 _fileName=_fileBaseName+"_"+ConvertToString(1)+".bmp";
  51.                 _printer->setContinuousOutput(true);
  52.                 _printer->setPosterMainName(_fileBaseName);
  53.                 _printer->setPosterExtName("bmp");
  54.                 //renderInfo.getCurrentCamera();                 
  55.                 //_printer->setOutputPosterName( _fileName );
  56.         }

  57.         virtual void operator () (osg::RenderInfo& renderInfo) const
  58.         {  

  59.                 osgViewer::View* view = dynamic_cast<osgViewer::View*>(renderInfo.getView());
  60.                

  61.        
  62.                 if ( !view ) return;

  63.                 if ( _printer.valid() )
  64.                 {
  65.                         osg::Switch* root = dynamic_cast<osg::Switch*>( view->getSceneData() );
  66.                         if ( root )
  67.                         {
  68.                                 // Assume child 0 is the loaded model and 1 is the poster camera
  69.                                 root->setValue( 0, false );
  70.                                 root->setValue( 1, true );
  71.                         }
  72.                         _printer->init( view->getCamera() );
  73.                         //_started = true;
  74.                 }

  75.                 if ( view->getDatabasePager() )
  76.                 {
  77.                         // Wait until all paged nodes are processed
  78.                         while( view->getDatabasePager()->getRequestsInProgress() )
  79.                         {}
  80.                 }

  81.                 if ( _printer.valid() )
  82.                 {
  83.                         //开始每帧输出一张图了
  84.                         _printer->eachPicForEachFrame( view );
  85.                        
  86.                 }
  87.         }

  88. public:   
  89.         std::string _fileName;
  90.         //int _fileCount;
  91.         std::string _fileBaseName;
  92.         osg::ref_ptr<PosterPrinter> _printer;
  93.         bool _started;//=true
  94. };



  95. //////////////////////////////////////////////////////////////////////////
  96. //每帧都输出一张图片,预计等待的时间会很长
  97. void PosterPrinter::eachPicForEachFrame(  osgViewer::View * view)
  98. {
  99.         const osg::FrameStamp* fs=view->getFrameStamp();
  100.         osg::Node* node=view->getSceneData();
  101.         // Add cull callbacks to all existing paged nodes,
  102.         // and advance frame when all callbacks are dispatched.
  103.         if ( addCullCallbacks(fs, node) )
  104.                 return;
  105.        
  106.         // Record images and the final poster
  107.         recordImages();

  108.         if ( _isRunning )
  109.         {
  110.                 // Every "copy-to-image" process seems to be finished in 2 frames.
  111.                 // So record them and dispatch camera to next tiles.
  112.                
  113.                 // Record images and unref them to free memory
  114.                 //recordImages();

  115.                 // Release all cull callbacks to free unused paged nodes
  116.                 removeCullCallbacks( node);
  117.                 _visitor->clearNames();

  118.                 while( _camera.valid() && !_isFinishing)
  119.                 {
  120.                         std::cout << "Binding sub-camera " << _currentRow << "_" << _currentColumn
  121.                                 << " to image..." << std::endl;
  122.                         //从相机的计数器
  123.                         unsigned int i=0;
  124.                         ;
  125.                         bindCameraToImage( view->getSlave(i)._camera.get(), _currentRow, _currentColumn );
  126.                         if ( _currentColumn<_tileColumns-1 )
  127.                         {
  128.                                 _currentColumn++;
  129.                                 i++;
  130.                         }
  131.                         else
  132.                         {
  133.                                 if ( _currentRow<_tileRows-1 )
  134.                                 {
  135.                                         _currentRow++;
  136.                                         _currentColumn = 0;
  137.                                         i++;
  138.                                 }
  139.                                 else
  140.                                 {
  141.                                         _isRunning = false;
  142.                                         _isFinishing = true;
  143.                                         i=0;
  144.                                 }
  145.                         }
  146.                 }
  147.                 _lastBindingFrame = fs->getFrameNumber();
  148.                 //view->;
  149.                 // Record images and the final poster
  150.                 recordImages();
  151.                 if ( _finalPoster.valid() )
  152.                 {
  153.                         std::cout << "Writing final result to file..." << std::endl;
  154.                         if (_isContinuousOutput)//需要连续出图
  155.                         {
  156.                                 _outputPosterName=_outputPosterMainName+"_"+ConvertToString(_lastBindingFrame)+"."+_outputPosterExtName;
  157.                         }
  158.                         else
  159.                         {
  160.                         }

  161.                         osgDB::writeImageFile( *_finalPoster, _outputPosterName );
  162.                 }

  163.                 // Release all cull callbacks to free unused paged nodes
  164.                 removeCullCallbacks(  node );
  165.                 _visitor->clearNames();

  166.                 _isFinishing = false;
  167.                 std::cout << "Recording images finished." << std::endl;
  168.         }
  169. }

复制代码
截图相关的代码,本意是想每帧截出一副超大图,采用的方式是
设置:
采用一堆slave相机
每个相机对应一个tile的viewport
每一帧时:
在主相机的postdrawcallback中调整每个相机的矩阵
attach每个slave相机到小的tile
直接将每个tile拷贝到大图像中,输出
问题:
输出的图像都是灰的
疑问和测试:
attach的时候并没有绘制,由于改了slave相机的视图矩阵,slave的render信息发生变化了?所以才是空白的
用sceneview强制输出是不是解决途径?我new了sceneview来获取每个slave的displaysetting,但是在draw的时候报错了

  1. //bindCameraToImage里面最后几行
  2.         // Reattach cameras and new allocated images
  3.         camera->setRenderingCache( NULL );  // FIXME: Uses for reattaching camera with image, maybe inefficient?
  4.         camera->detach( osg::Camera::COLOR_BUFFER );
  5.         camera->attach( osg::Camera::COLOR_BUFFER, image.get(), 0, 0 );

  6.         //osgUtil::SceneView* eachSceneView=new osgUtil::SceneView(camera->getDisplaySettings());
  7.         //eachSceneView->draw();
复制代码

该用户从未签到

发表于 2012-1-11 20:52:15 | 显示全部楼层
我认为您可以直接参考以下osgposter,可以输出超大海报级图片

该用户从未签到

 楼主| 发表于 2012-1-15 15:30:43 | 显示全部楼层
osgposter。。。是我们直接修改的基础,发现每个rtt相机对应的小图都不是在一帧里渲染出来,而是至少要在设置矩阵后两帧才能渲染出来。造成的问题是,渲染出来的小图不反映动画的变化,比如粒子效果
所以才想要在一帧的循环里,阻断(?)或者延迟帧渲染,然后绘制帧显存里面的内容到一个(或多个)图片里,fbo的内在渲染流程是什么呢?或者我们不用fbo,用gl的函数截图?
我们的目的是输出连续的帧画面,后期拼接成视频,场景里有很多路径,粒子系统需要展示?

该用户从未签到

发表于 2012-1-17 16:58:46 | 显示全部楼层
那么就连续fbo就可以了,没有问题
您需要登录后才可以回帖 登录 | 注册

本版积分规则

OSG中国官方论坛-有您OSG在中国才更好

网站简介:osgChina是国内首个三维相关技术开源社区,旨在为国内更多的技术开发人员提供最前沿的技术资讯,为更多的三维从业者提供一个学习、交流的技术平台。

联系我们

  • 工作时间:09:00--18:00
  • 反馈邮箱:1315785073@qq.com
快速回复 返回顶部 返回列表