Hi, I’m developing app on iOS using OpenSceneGraph with GLES 2, my app have a feature capture photo from osgviewer to save image file. I try to use some class i found in some topic below but the image i get is total black
Code: class SnapImageDrawCallback : public osg::Camera::DrawCallback { public: SnapImageDrawCallback() { _snapImageOnNextFrame = false; } void setFileName(const std::string& filename) { _filename = filename; } const std::string& getFileName() const { return _filename; } void setSnapImageOnNextFrame(bool flag) { _snapImageOnNextFrame = flag; } bool getSnapImageOnNextFrame() const { return _snapImageOnNextFrame; } virtual void operator () (const osg::Camera& camera) const { //osg::notify(osg::NOTICE) << "Saved screen image to `"<<_filename<<"`"<< std::endl; if (!_snapImageOnNextFrame) return; //int x,y,width,height; //int x =0,y=0,width=768*2,height=709*2; int x,y,width,height; x = camera.getViewport()->x(); y = camera.getViewport()->y(); width = camera.getViewport()->width(); height = camera.getViewport()->height(); //camera.getViewport() getViewport(x,y,width,height); osg::ref_ptr<osg::Image> image = new osg::Image; image->readPixels(x,y,width,height,GL_RGB,GL_UNSIGNED_BYTE); if (osgDB::writeImageFile(*image,_filename)) { osg::notify(osg::NOTICE) << "Saved screen image to `"<<_filename<<"`"<< std::endl; } _snapImageOnNextFrame = false; } protected: std::string _filename; mutable bool _snapImageOnNextFrame; }; class WindowCaptureCallback : public osg::Camera::DrawCallback { public: WindowCaptureCallback(GLenum readBuffer, const std::string& name): _readBuffer(readBuffer), _fileName(name) { _image = new osg::Image; } virtual void operator () (osg::RenderInfo& renderInfo) const { #if !defined(OSG_GLES1_AVAILABLE) && !defined(OSG_GLES2_AVAILABLE) glReadBuffer(_readBuffer); #else osg::notify(osg::NOTICE)<<"Error: GLES unable to do glReadBuffer"<<std::endl; #endif OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex); osg::GraphicsContext* gc = renderInfo.getState()->getGraphicsContext(); if (gc->getTraits()) { GLenum pixelFormat; if (gc->getTraits()->alpha) pixelFormat = GL_RGBA; else pixelFormat = GL_RGB; #if defined(OSG_GLES1_AVAILABLE) || defined(OSG_GLES2_AVAILABLE) if (pixelFormat == GL_RGB) { GLint value = 0; #ifndef GL_IMPLEMENTATION_COLOR_READ_FORMAT #define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B #endif glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &value); if ( value != GL_RGB || value != GL_UNSIGNED_BYTE ) { pixelFormat = GL_RGBA;//always supported } } #endif int width = gc->getTraits()->width; int height = gc->getTraits()->height; std::cout<<"Capture: size="<<width<<"x"<<height<<", format="<<(pixelFormat == GL_RGBA ? "GL_RGBA":"GL_RGB")<<std::endl; _image->readPixels(0, 0, width, height, pixelFormat, GL_UNSIGNED_BYTE); } if (!_fileName.empty()) { std::cout << "Writing to: " << _fileName << std::endl; osgDB::writeImageFile(*_image, _fileName); } } protected: GLenum _readBuffer; std::string _fileName; osg::ref_ptr<osg::Image> _image; mutable OpenThreads::Mutex _mutex; }; @implementation CreateGroupViewController - (void)viewDidLoad { [super viewDidLoad]; OSGAdapter *osgAdapter = [[OSGAdapter alloc] init]; //osg::setNotifyLevel(osg::DEBUG_INFO); //get the screen size unsigned int w = sceneView.frame.size.width; unsigned int h = sceneView.frame.size.height; //create root _root = new osg::MatrixTransform(); //create the viewer _viewer = new osgViewer::Viewer(); _viewer->getCamera()->setClearColor(osg::Vec4(0.25,0.4,0.0,0.0)); // try msaa. available for iOS >= 4.0 osg::ref_ptr<osg::DisplaySettings> settings = osg::DisplaySettings::instance(); settings->setNumMultiSamples(4); if(1) { //create our graphics context directly so we can pass our own window osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits(); // Init the Windata Variable that holds the handle for the Window to display OSG in. osg::ref_ptr<osg::Referenced> windata = new osgViewer::GraphicsWindowIOS::WindowData(self.sceneView); // Setup the traits parameters traits->x = 0; traits->y = 0; traits->width = w*2 - 0; traits->height = h*2 - 0; traits->depth = 16; //keep memory down, default is currently 24 traits->windowDecoration = false; traits->doubleBuffer = true; traits->sharedContext = NULL; traits->setInheritedWindowPixelFormat = true; traits->samples = 4; traits->sampleBuffers = 1; traits->supportsResize = true; traits->inheritedWindowData = windata; //Create the Graphics Context osg::ref_ptr<osg::GraphicsContext> graphicsContext = osg::GraphicsContext::createGraphicsContext(traits.get()); // if the context was created then attach to our viewer if(graphicsContext) { _viewer->getCamera()->setGraphicsContext(graphicsContext); _viewer->getCamera()->setViewport(new osg::Viewport(0, 0, traits->width, traits->height)); _viewer->getCamera()->setProjectionMatrixAsPerspective(30.0f, static_cast<double>(traits->width)/static_cast<double>(traits->height), 1.0f, 10000.0f); } } _root = [osgAdapter loadData]; osg::Camera* hud_camera = [osgAdapter createHUD: (w * 2) : (h * 2)]; _root->addChild(hud_camera); _viewer->setSceneData(_root.get()); _viewer->setCameraManipulator(new osgGA::MultiTouchTrackballManipulator()); //_viewer->addEventHandler(new TestMultiTouchEventHandler(hud_camera)); // sun single-threaded _viewer->setThreadingModel(osgViewer::Viewer::SingleThreaded); _viewer->realize(); // render a frame so the window-manager shows some content and not only an empty + black window _viewer->frame(); // create a display link, which will update our scene on every screen-refresh _displayLink = [[UIScreen mainScreen] displayLinkWithTarget:self selector:@selector(updateScene)]; [_displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; osg::ref_ptr<SnapImageDrawCallback> snapImageDrawCallback = new SnapImageDrawCallback(); _viewer->getCamera()->setPostDrawCallback (snapImageDrawCallback.get()); } // //Timer called function to update our scene and render the viewer // - (void)updateScene { _viewer->frame(); } - (IBAction)createImage:(id)sender { NSString* imageName = @"screenshot.png" _viewer->getViewerBase()->stopThreading(); // use SnapImageDrawCallback class osg::ref_ptr<SnapImageDrawCallback> snapImageDrawCallback = dynamic_cast<SnapImageDrawCallback*> (_viewer->getCamera()->getPostDrawCallback()); if(snapImageDrawCallback.get()) { std::cout << "make screenshot" << std::endl; NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentsDirectory = [paths objectAtIndex:0]; NSString *fullPath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"%@", imageName]]; snapImageDrawCallback->setFileName([fullPath UTF8String]); snapImageDrawCallback->setSnapImageOnNextFrame(true); } else { std::cout << "Warning: no make screenshot" << std::endl; } // use WindowCaptureCallback class // GLenum buffer = _viewer->getCamera()->getGraphicsContext()->getTraits()->doubleBuffer ? GL_BACK : GL_FRONT; // _viewer->getCamera()->setFinalDrawCallback(new WindowCaptureCallback(buffer, [fullPath UTF8String])); } Could you please help me resolve that. ... Thank you! Cheers, duc ------------------ Read this topic online here: http://forum.openscenegraph.org/viewtopic.php?p=69771#69771 _______________________________________________ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org