Re: [osg-users] How to render the OSG scene to an image file?
OK, the problem was with the bug in the Windows implementation of the PixelBuffer implementation. Checked out the latest version from SVN trunk (development one) and got osgscreencapture working under Windows. Will use it now in my project. -- Read this topic online here: http://forum.openscenegraph.org/viewtopic.php?p=34409#34409 ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
Re: [osg-users] How to render the OSG scene to an image file?
[quote="Frederic Bouvier"]Hi Igor, did you search in the example folder ? I am sure that more than one use a pbuffer. More use framebuffer objects. You can have a look to osgscreencapture [quote] Thanks, Fred, unfortunately osgscreencapture has the same bug. When i call osgscreencapture.exe axes.osg --pbuffer-only 640 480 this produces the same error message and doesn't even create an image: Pixel buffer has been created successfully. PixelBufferWin32::makeCurrentImplementation, wglMakeCurrent error: Die angeforderte Ressource wird bereits verwendet. it somehow fails to make the context current (?) Either i am passing too few parameters or it's just a bug in osgscreencapture, or i don't have something installed on my machine, or something else. I compiled the osgscreencapture example, and the same error. I found a fast solution though: just start the viewer normally and render only 1 frame and then close the window. Normally a person wouldn't notice the window because it's closed in a fraction of a second. This is dirty and i'm not sure if it will have any side-effect somewhere in our project... const char* strFrames = getenv("OSG_RUN_FRAME_COUNT"); if (NULL != strFrames) { int nUsualFramesCount = atoi(strFrames); putenv("OSG_RUN_FRAME_COUNT=1"); // run just 1 frame viewer->run(); ::std::ostringstream oss; oss << "OSG_RUN_FRAME_COUNT=" << nUsualFramesCount; putenv(oss.str().c_str()); // restore settings } else { putenv("OSG_RUN_FRAME_COUNT=1"); // run just 1 frame viewer->run(); putenv("OSG_RUN_FRAME_COUNT="); // "delete" environment variable } -- Read this topic online here: http://forum.openscenegraph.org/viewtopic.php?p=34148#34148 ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
Re: [osg-users] How to render the OSG scene to an image file?
Hi Igor, did you search in the example folder ? I am sure that more than one use a pbuffer. More use framebuffer objects. You can have a look to osgscreencapture Regards, -Fred - "Igor Galochkin" a écrit : > I am still stuck. Guys, any suggestions? > > My colleague tried to solve the problem and came to a conclusion that > Viewer can't render to any offscreen buffer. He tries to render the > OSG scene without using the Viewer, by direct calls to OpenGL. ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
Re: [osg-users] How to render the OSG scene to an image file?
I am still stuck. Guys, any suggestions? My colleague tried to solve the problem and came to a conclusion that Viewer can't render to any offscreen buffer. He tries to render the OSG scene without using the Viewer, by direct calls to OpenGL. The following code just creates an Images filled with dark-blue color which is set by glClearColor(0.1f, 0.1f, 0.5f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); He means now the task would be to find out how Viewer traverses the OSG graph to render it. I took a look inside viewer.renderingTraversals() and other functions. It looks like I might need to re-create a large piece of Viewer functionality which will take just too much time. There must be an easier way! So, the question: can the ::osg::Viewer at all render to the a pbuffer. If yes, how? // test rendering to image using direct OpenGL calls int w = 1024; int h = 768; ::osg::Node* scene = ::osgDB::readNodeFile("axes.osg"); if (!scene) { std::cerr << "Could not load scene file" << std::endl; return; } osg::ref_ptr root = new osg::Group; root->addChild(scene); osg::ref_ptr traits = new osg::GraphicsContext::Traits; traits->readDISPLAY(); if (traits->displayNum<0) traits->displayNum = 0; traits->screenNum = 0; //screenNum; traits->x = 0; traits->y = 0; traits->width = w; traits->height = h; traits->windowDecoration = false; traits->doubleBuffer = false; traits->sharedContext = 0; traits->pbuffer = true; osg::ref_ptr gc = osg::GraphicsContext::createGraphicsContext(traits.get()); if (gc) { std::cout << "have context" << std::endl; } else { std::cerr << "dont have context" << std::endl; } osgViewer::GraphicsWindow* gw = dynamic_cast(gc.get()); if (gw) { std::cout << "have gw" << std::endl; } else { std::cerr << "dont have gw" << std::endl; } osg::ref_ptr cameraRoot = new osg::Group; osg::ref_ptr camera = new osg::Camera; camera->setClearColor(osg::Vec4(0.5f, 0.5f, 0.5f, 1.0f)); camera->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF); // camera->setRenderOrder(osg::Camera::PRE_RENDER); camera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT); camera->setViewport(0, 0, w, h); camera->setProjectionMatrixAsPerspective(30.0f, static_cast(w)/static_cast(h), 1.0f, 1.0f); GLenum buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT; camera->setDrawBuffer(buffer); camera->setReadBuffer(buffer); camera->setGraphicsContext(gc.get()); camera->addChild(scene); cameraRoot->addChild(camera.get()); root->addChild(cameraRoot.get()); osgViewer::Viewer viewer; //viewer.setSceneData(root.get()); //viewer.setUpViewInWindow(100, 100, w, h); //setupView(viewer, w, h); //viewer.frame(); // frame stuff // viewerInit //viewer.viewerInit(); // realize //viewer.realize(); //viewer.setCameraWithFocus(0); //osgViewer::ViewerBase::Contexts contexts; //viewer.getContexts(contexts); //if (contexts.empty()) //{ // std::cerr << "no valid contexts found" << std::endl; //} else { // std::cout << "Contexts: " << contexts.size() << std::endl; //} //for(osgViewer::ViewerBase::Contexts::iterator citr = contexts.begin(); citr != contexts.end(); ++citr) //{ // osg::GraphicsContext* gc = *citr; //gc->realize(); /* if (_realizeOperation.valid() && gc->valid()) { gc->makeCurrent(); (*_realizeOperation)(gc); gc->releaseContext(); } */ //} // advance //xxx //viewer.eventTraversal(); //viewer.updateTraversal(); //viewer.renderingTraversals(); gc->realize(); gc->makeCurrent(); //osg::ref_ptr updateVisitor = new osgUtil::UpdateVisitor; //updateVisitor->setFrameStamp(); //updateVisitor->reset(); //updateVisitor->setFrameStamp(); //updateVisitor->setTraversalNumber(0); //osgViewer::Scene scene2 = osgViewer::Scene::getOrCreateScene(scene); //scene2->updateSceneGraph(*updateVisitor); //osgViewer::Renderer* renderer = dynamic_cast(camera->getRenderer()); //if (renderer) //{ // renderer->setDone(false); // renderer->setCompileOnNextDra
Re: [osg-users] How to render the OSG scene to an image file?
The following piece of code writes the same error to the console: Code: !!! pbuffer is VALID! PixelBufferWin32::makeCurrentImplementation, wglMakeCurrent error: Die angeforde rte Ressource wird bereits verwendet. Error: OpenGL version test failed, requires valid graphics context. PixelBufferWin32::realizeImplementation, wglShareLists error: Die angeforderte R essource wird bereits verwendet. PixelBufferWin32::makeCurrentImplementation, wglMakeCurrent error: Die angeforde rte Ressource wird bereits verwendet. so, wglMakeCurrent(_hdc, _hglrc) fails in bool PixelBufferWin32::makeCurrentImplementation() see http://www.openscenegraph.org/svn/osg/OpenSceneGraph/tags/OpenSceneGraph-2.6.1/src/osgViewer/PixelBufferWin32.cpp May this be a Windows bug or OSG's implementation for Windows bug? ::osgViewer::Viewer * viewer = new ::osgViewer::Viewer(); viewer->setSceneData(pGeode); ::osg::ref_ptr snapImageDrawCallback = new SnapImageDrawCallback(); viewer->getCamera()->setFinalDrawCallback (snapImageDrawCallback.get()); snapImageDrawCallback->setFileName("1.bmp"); snapImageDrawCallback->setSnapImageOnNextFrame(true); ::osg::ref_ptr< ::osg::GraphicsContext> pbuffer; ::osg::ref_ptr< ::osg::GraphicsContext::Traits> traits = new ::osg::GraphicsContext::Traits; traits->x = 0; traits->y = 0; traits->width = 640; traits->height = 480; traits->red = 8; traits->green = 8; traits->blue = 8; traits->alpha = 8; traits->windowDecoration = false; traits->pbuffer = true; traits->doubleBuffer = true; traits->sharedContext = 0; pbuffer = ::osg::GraphicsContext::createGraphicsContext(traits.get()); if (!pbuffer.valid()) { ::std::cout << "\n\n!!! pbuffer is invalid!\n\n" << std::endl; return; } else { ::std::cout << "\n\n!!! pbuffer is VALID!\n\n" << std::endl; } viewer->getCamera()->setGraphicsContext(pbuffer.get()); viewer->getCamera()->setViewport(new osg::Viewport(0,0,640,480)); GLenum buffer = pbuffer->getTraits()->doubleBuffer ? GL_BACK : GL_FRONT; viewer->getCamera()->setDrawBuffer(buffer); viewer->getCamera()->setReadBuffer(buffer); viewer->getCamera()->setRenderTargetImplementation(::osg::CameraNode::FRAME_BUFFER_OBJECT); viewer->frame(); -- Read this topic online here: http://forum.openscenegraph.org/viewtopic.php?p=33995#33995 ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
Re: [osg-users] How to render the OSG scene to an image file?
Thanks a lot for you replies! I tried to use the code but so far without success. At most I get a completely black image, but sometimes the SnapImageDrawcallback's operator() is never even called.. Here is my code. What exactly am I doing wrong here? class SnapImageDrawCallback : public ::osg::CameraNode::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::CameraNode& camera) const { ::osg::notify(::osg::NOTICE) << "Saving screen image to '"<<_filename<<"'"<< std::endl; if (!_snapImageOnNextFrame) return; int x,y,width,height; x = camera.getViewport()->x(); y = camera.getViewport()->y(); width = camera.getViewport()->width(); height = camera.getViewport()->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)) { std::cout << "Saved screen image to '"<<_filename<<"'"<< std::endl; } _snapImageOnNextFrame = false; } protected: ::std::string _filename; mutable bool _snapImageOnNextFrame; }; void renderSceneToImage(::osg::Node* pRoot, const ::std::string& sFileName_) { int nWidth = 640, nHeight = 480; ::osgViewer::Viewer * viewer = new ::osgViewer::Viewer(); viewer->setSceneData(pRoot); viewer->getCamera()->setRenderTargetImplementation(::osg::CameraNode::FRAME_BUFFER_OBJECT); ::osg::ref_ptr snapImageDrawCallback = new SnapImageDrawCallback(); viewer->getCamera()->setPostDrawCallback (snapImageDrawCallback.get()); snapImageDrawCallback->setFileName(sFileName_); snapImageDrawCallback->setSnapImageOnNextFrame(true); ::osg::ref_ptr< ::osg::GraphicsContext> pbuffer; ::osg::ref_ptr< ::osg::GraphicsContext::Traits> traits = new ::osg::GraphicsContext::Traits; traits->x = 0; traits->y = 0; traits->width = nWidth; traits->height = nHeight; traits->red = 8; traits->green = 8; traits->blue = 8; traits->alpha = 8; traits->windowDecoration = false; traits->pbuffer = true; traits->doubleBuffer = true; traits->sharedContext = 0; pbuffer = ::osg::GraphicsContext::createGraphicsContext(traits.get()); if (pbuffer.valid()) { ::osg::ref_ptr< ::osg::Camera> camera2 = new ::osg::Camera(); camera2->setGraphicsContext(pbuffer.get()); GLenum buffer = pbuffer->getTraits()->doubleBuffer ? GL_BACK : GL_FRONT; camera2->setDr
Re: [osg-users] How to render the OSG scene to an image file?
Hi, On 18/11/10 06:07, Ulrich Hertlein wrote: Hi Igor, On 18/11/10 4:15 , Igor Galochkin wrote: I have to write a series of classes wrapping OSG model, which loads OSG graph from an .osg file, uses some data from it, saves the scene back to .osg file etc. I can't find out how (if it's possible) to render an OSG graph into an image file. Yes, it's possible. I don't need to open any windows. ... So, i can't find any way to order the camera to render once. All examples show how to make the camera render to a texture, but when it renders is decided by OpenGL (?). I don't need all that, i just need to grab the picture once and return. You must create a Viewer, attach the camera (or just use 'viewer.setSceneData()') and render a frame by calling 'viewer.frame()'. The post-draw callback that Maxim Gammer sent will take care of saving the screenshot. Since you don't want to have a visible context you'll probably need to setup a pbuffer context. All this can be seen in the osgscreencapture example. Look for the code path for pbuffer-only option. jp HTH, /ulrich ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org -- This message is subject to the CSIR's copyright terms and conditions, e-mail legal notice, and implemented Open Document Format (ODF) standard. The full disclaimer details can be found at http://www.csir.co.za/disclaimer.html. This message has been scanned for viruses and dangerous content by MailScanner, and is believed to be clean. MailScanner thanks Transtec Computers for their support. ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
Re: [osg-users] How to render the OSG scene to an image file?
Hi Igor, On 18/11/10 4:15 , Igor Galochkin wrote: > I have to write a series of classes wrapping OSG model, which loads OSG graph > from an > .osg file, uses some data from it, saves the scene back to .osg file etc. > > I can't find out how (if it's possible) to render an OSG graph into an image > file. Yes, it's possible. > I don't need to open any windows. >... > So, i can't find any way to order the camera to render once. All examples > show how to > make the camera render to a texture, but when it renders is decided by OpenGL > (?). I > don't need all that, i just need to grab the picture once and return. You must create a Viewer, attach the camera (or just use 'viewer.setSceneData()') and render a frame by calling 'viewer.frame()'. The post-draw callback that Maxim Gammer sent will take care of saving the screenshot. Since you don't want to have a visible context you'll probably need to setup a pbuffer context. HTH, /ulrich ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
Re: [osg-users] How to render the OSG scene to an image file?
// Взыто из файла viewer.cpp #include class SnapImageDrawCallback : public osg::CameraNode::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::CameraNode& camera) const { //osg::notify(osg::NOTICE) << "Saved screen image to `"<<_filename<<"`"<< std::endl; if (!_snapImageOnNextFrame) return; int x,y,width,height; x = camera.getViewport()->x(); y = camera.getViewport()->y(); width = camera.getViewport()->width(); height = camera.getViewport()->height(); osg::ref_ptr image = new osg::Image; image->readPixels(x,y,width,height,GL_RGB,GL_UNSIGNED_BYTE); if (osgDB::writeImageFile(*image,_filename)) { std::cout << "Saved screen image to `"<<_filename<<"`"<< std::endl; } _snapImageOnNextFrame = false; } protected: std::string _filename; mutable bool_snapImageOnNextFrame; }; //для screenshot'a osg::ref_ptr snapImageDrawCallback = new SnapImageDrawCallback(); viewer->getCamera()->setPostDrawCallback (snapImageDrawCallback.get()); /// void takeScreenshot(std::string filename) { osg::ref_ptr snapImageDrawCallback = dynamic_cast (viewer->getCamera()->getPostDrawCallback()); if(snapImageDrawCallback.get()) { std::cout << "make screenshot" << std::endl; snapImageDrawCallback->setFileName(filename); snapImageDrawCallback->setSnapImageOnNextFrame(true); } else { std::cout << "Warning: no make screenshot" << std::endl; } } 2010/11/17 Igor Galochkin : > I have to write a series of classes wrapping OSG model, which loads OSG graph > from an .osg file, uses some data from it, saves the scene back to .osg file > etc. > > I can't find out how (if it's possible) to render an OSG graph into an image > file. > > So, what i am trying to do is: > > void renderSceneToImage(::osg::Node* pNode, const ::std::string& sFileName_, > ) > > The function should take the root node of the OSG scene, render it ONCE to an > image (::osg::Image?) and then save the image into the file. > > I don't need to open any windows. > > From what I found on the net so far: > > // > > ::osg::Image* capImage = new ::osg::Image(); > capImage->allocateImage(nWidth, nHeight, 1, GL_RGBA, GL_FLOAT); > capImage->setInternalTextureFormat(GL_RGBA16F_ARB); > > > ::osg::ref_ptr< ::osg::Camera> camera = new ::osg::Camera(); > camera->setRenderTargetImplementation(::osg::CameraNode::FRAME_BUFFER_OBJECT); > camera->setRenderOrder(::osg::Camera::PRE_RENDER); > camera->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); > camera->setViewport(0, 0, nWidth, nHeight); > > camera->attach(::osg::CameraNode::COLOR_BUFFER, capImage); > > // temporarily wrap the whole scene with camera > camera->addChild(pScene->root()); > > ::osg::ref_ptr< ::osg::Group> tempRoot = new ::osg::Group(); > tempRoot->addChild(camera.get()); > > > // HOW TO ORDER THE CAMERA TO RENDER? > > ::osgDB::writeImageFile(*capImage, sFileName_); > > //- > > So, i can't find any way to order the camera to render once. All examples > show how to make the camera render to a texture, but when it renders is > decided by OpenGL (?). I don't need all that, i just need to grab the picture > once and return. > > Is this possible with OSG? > > Thanks! > > -- > Read this topic online here: > http://forum.openscenegraph.org/viewtopic.php?p=33809#33809 > > > > > > ___ > osg-users mailing list > osg-users@lists.openscenegraph.org > http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org > -- Maxim Gammer ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
[osg-users] How to render the OSG scene to an image file?
I have to write a series of classes wrapping OSG model, which loads OSG graph from an .osg file, uses some data from it, saves the scene back to .osg file etc. I can't find out how (if it's possible) to render an OSG graph into an image file. So, what i am trying to do is: void renderSceneToImage(::osg::Node* pNode, const ::std::string& sFileName_, ) The function should take the root node of the OSG scene, render it ONCE to an image (::osg::Image?) and then save the image into the file. I don't need to open any windows. >From what I found on the net so far: // ::osg::Image* capImage = new ::osg::Image(); capImage->allocateImage(nWidth, nHeight, 1, GL_RGBA, GL_FLOAT); capImage->setInternalTextureFormat(GL_RGBA16F_ARB); ::osg::ref_ptr< ::osg::Camera> camera = new ::osg::Camera(); camera->setRenderTargetImplementation(::osg::CameraNode::FRAME_BUFFER_OBJECT); camera->setRenderOrder(::osg::Camera::PRE_RENDER); camera->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); camera->setViewport(0, 0, nWidth, nHeight); camera->attach(::osg::CameraNode::COLOR_BUFFER, capImage); // temporarily wrap the whole scene with camera camera->addChild(pScene->root()); ::osg::ref_ptr< ::osg::Group> tempRoot = new ::osg::Group(); tempRoot->addChild(camera.get()); // HOW TO ORDER THE CAMERA TO RENDER? ::osgDB::writeImageFile(*capImage, sFileName_); //- So, i can't find any way to order the camera to render once. All examples show how to make the camera render to a texture, but when it renders is decided by OpenGL (?). I don't need all that, i just need to grab the picture once and return. Is this possible with OSG? Thanks! -- Read this topic online here: http://forum.openscenegraph.org/viewtopic.php?p=33809#33809 ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org