I have made some investigation, the hud that make the software freeze contains 
objects with a "DYNAMIC" data variance. I'am able to reproduce the freeze with 
a little code. Can somebody tell me what's wrong please ?

osgBuilder.cpp :

Code:

#include "osgBuilder.h"

void    cowUpdateCallback::operator()(osg::Node* node, osg::NodeVisitor *nv)
{
        osg::MatrixTransform    *mt = dynamic_cast<osg::MatrixTransform 
*>(node);
        osg::Matrix                             mrt, mpos;

        mpos.makeTranslate(osg::Vec3f(-6., 0., 0.));
        mrt.makeRotate(angle, osg::Vec3(-0.5, 2., 1.));
        mt->setMatrix(mrt * mpos);

        angle += 0.005;
        traverse(node, nv);
}

osgBuilder::osgBuilder(void)
{
}

osgBuilder::~osgBuilder(void)
{
}

osg::ref_ptr<osg::Group>        osgBuilder::createScene()
{
        // Load the cow model.
        osg::ref_ptr<osg::Node> cow = osgDB::readNodeFile( "../data/cow.osg" );
        // Data variance is STATIC because we won't modify it.
        cow->setDataVariance( osg::Object::STATIC );
        // Create a MatrixTransform to display the cow on the left.
        osg::ref_ptr<osg::MatrixTransform> mtLeft = new osg::MatrixTransform;
        mtLeft->setName( "Left Cow\nDYNAMIC" );
        // Set data variance to DYNAMIC to let OSG know that we
        // will modify this node during the update traversal.
        mtLeft->setDataVariance( osg::Object::DYNAMIC );
        // Set the update callback.
        mtLeft->setUpdateCallback( new cowUpdateCallback );
        osg::Matrix m;
        m.makeTranslate( -6.f, 0.f, 0.f );
        mtLeft->setMatrix( m );
        mtLeft->addChild( cow );
        // Create a MatrixTransform to display the cow on the right.
        osg::ref_ptr<osg::MatrixTransform> mtRight =
        new osg::MatrixTransform;
        mtRight->setName( "Right Cow\nSTATIC" );
        // Data variance is STATIC because we won't modify it.
        mtRight->setDataVariance( osg::Object::STATIC );
        m.makeTranslate( 6.f, 0.f, 0.f );
        mtRight->setMatrix( m );
        mtRight->addChild( cow );
        // Create the Group root node.
        osg::ref_ptr<osg::Group> root = new osg::Group;
        root->setName( "Root Node" );
        // Data variance is STATIC because we won't modify it.
        root->setDataVariance( osg::Object::STATIC );
        root->addChild( mtLeft.get() );
        root->addChild( mtRight.get() );
        return root.get();
}

osg::Camera* osgBuilder::createHUD()
{
    // create a camera to set up the projection and model view matrices, and 
the subgraph to drawn in the HUD
    osg::Camera* camera = new osg::Camera;
 
    // set the projection matrix
    camera->setProjectionMatrix(osg::Matrix::ortho2D(0,1280,0,1024));
 
    // set the view matrix    
    camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
    camera->setViewMatrix(osg::Matrix::identity());
 
    // only clear the depth buffer
    camera->setClearMask(GL_DEPTH_BUFFER_BIT);
 
    // draw subgraph after main camera view.
    camera->setRenderOrder(osg::Camera::POST_RENDER);
 
    // we don't want the camera to grab event focus from the viewers main 
camera(s).
    camera->setAllowEventFocus(false);
    
 
 
    // add to this camera a subgraph to render
    {
 
        osg::Geode* geode = new osg::Geode();
 
        // turn lighting off for the text and disable depth test to ensure its 
always ontop.
        osg::StateSet* stateset = geode->getOrCreateStateSet();
        stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
 
                osg::Vec3 position(30.0f,1000.0f,0.0f);
                osg::Vec3 delta(0.0f, -50.0f,0.0f);
 
 
        {
            osgText::Text* text = new  osgText::Text;
            geode->addDrawable( text );
 
                        text->setAxisAlignment(osgText::Text::SCREEN);
            text->setPosition(position);
            text->setText(" SOME TEXT ");
                        text->setDataVariance(osg::Object::DYNAMIC);
            position += delta;
        }    
 
 
        {
            osgText::Text* text = new  osgText::Text;
            geode->addDrawable( text );
 
                        text->setAxisAlignment(osgText::Text::SCREEN);
            text->setPosition(position);
            text->setText("2nd text");
                        text->setDataVariance(osg::Object::DYNAMIC);
            position += delta;
        }    
 
        {
            osg::BoundingBox bb;
            for(unsigned int i=0;i<geode->getNumDrawables();++i)
            {
                bb.expandBy(geode->getDrawable(i)->getBound());
            }
 
            osg::Geometry* geom = new osg::Geometry;
 
            osg::Vec3Array* vertices = new osg::Vec3Array;
            float depth = bb.zMin()-0.1;
            vertices->push_back(osg::Vec3(bb.xMin(), bb.yMax(), depth));
            vertices->push_back(osg::Vec3(bb.xMin(), bb.yMin(), depth));
            vertices->push_back(osg::Vec3(bb.xMax(), bb.yMin(), depth));
            vertices->push_back(osg::Vec3(bb.xMax(), bb.yMax(), depth));
            geom->setVertexArray(vertices);
 
            osg::Vec3Array* normals = new osg::Vec3Array;
            normals->push_back(osg::Vec3(0.0f, 0.0f, 1.0f));
            geom->setNormalArray(normals);
            geom->setNormalBinding(osg::Geometry::BIND_OVERALL);
 
            osg::Vec4Array* colors = new osg::Vec4Array;
            colors->push_back(osg::Vec4(1.0f,1.0,0.8f,0.2f));
            geom->setColorArray(colors);
            geom->setColorBinding(osg::Geometry::BIND_OVERALL);
 
            geom->addPrimitiveSet(new osg::DrawArrays(GL_QUADS,0,4));
 
            osg::StateSet* stateset = geom->getOrCreateStateSet();
            stateset->setMode(GL_BLEND,osg::StateAttribute::ON);
            //stateset->setAttribute(new 
osg::PolygonOffset(1.0f,1.0f),osg::StateAttribute::ON);
            stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
 
            geode->addDrawable(geom);
        }
 
        camera->addChild(geode);
                
    }
        camera->setNodeMask(0x203);
    return camera;
}

bool    osgHUDCallback::handle(const osgGA::GUIEventAdapter &ea, 
osgGA::GUIActionAdapter &aa)
{
        return (false);
}

int     osgBuilder::start()
{
        osg::ref_ptr<osgViewer::Viewer>                         viewer = new 
osgViewer::Viewer;
        osg::Matrix                                                             
        cameraPosition;
        osg::ref_ptr<osg::GraphicsContext::Traits>      traits = new 
osg::GraphicsContext::Traits;
        osg::ref_ptr<osgViewer::CompositeViewer>        compView = new 
osgViewer::CompositeViewer;

        compView->setThreadingModel(osgViewer::Viewer::DrawThreadPerContext);
        compView->addView(viewer);

        cameraPosition.translate(0., -100., 0.);

        viewer->getCamera()->setViewMatrix(cameraPosition);
        viewer->getCamera()->setClearColor(osg::Vec4(0.3, 0.2, 0.5, 1.));

        traits->x = 200;
        traits->y = 200;
        traits->width = 800;
        traits->height = 600;
        traits->windowDecoration = true;
        traits->doubleBuffer = true;
        traits->sharedContext = 0;
        viewer->getCamera()->setViewport(new osg::Viewport(0, 0, traits->width, 
traits->height));
        GLenum buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT;
        viewer->getCamera()->setDrawBuffer(buffer);
        viewer->getCamera()->setReadBuffer(buffer);

        
viewer->getCamera()->setGraphicsContext(osg::GraphicsContext::createGraphicsContext(traits));

        osg::ref_ptr<osg::Group>        root = new osg::Group;
        osg::ref_ptr<osg::Group>        worldParent = new osg::Group;
        osg::ref_ptr<osg::Group>        world = this->createScene();
        root->addChild(worldParent);
        world->addChild(this->createHUD());
        worldParent->addChild(world);

        VideoRecorder*                                                  vr = 
new VideoRecorder(root, world, 
viewer->getCamera()->getGraphicsContext()->getTraits());
        osg::ref_ptr<SnapImage>                                 si = new 
SnapImage(vr);
        osg::ref_ptr<SnapImageHandler>                  kbHdl = new 
SnapImageHandler(vr);

        viewer->addEventHandler(new osgHUDCallback);
        viewer->addEventHandler(kbHdl);
        viewer->getCamera()->setPostDrawCallback(si);
        viewer->setSceneData(root);

        return (compView->run());
}




osgBuilder.h

Code:

#ifndef __OSGBUILDER_H__
#define __OSGBUILDER_H__

#include <osgViewer/Viewer>
#include <osgViewer/CompositeViewer>
#include <osgGA/TrackballManipulator>
#include <osg/NodeCallback>
#include <osg/Camera>
#include <osg/Group>
#include <osg/MatrixTransform>
#include <osgDB/ReadFile>
#include <osgText/Text>

#include <iostream>

#include "snapImage.h"

#include <osg/NodeCallback>
#include <osg/MatrixTransform>

class cowUpdateCallback : public osg::NodeCallback
{
private:
        double angle;
public:
        cowUpdateCallback(void) : angle(0)
        {}
        ~cowUpdateCallback(void){}
        virtual void operator()( osg::Node* node, osg::NodeVisitor* nv );
};

class osgBuilder
{
private:
        osg::ref_ptr<osg::Group>        createScene();
        osg::Camera                                     *createHUD();

public:
        osgBuilder(void);
        ~osgBuilder(void);

        int     start();

};

class osgHUDCallback : public osgGA::GUIEventHandler
{
        virtual bool                                            handle(const 
osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter&);
};

#endif




snapImage.cpp :

Code:

#include "snapImage.h"


VideoRecorder::VideoRecorder(osg::ref_ptr<osg::Group> rootNode, 
osg::ref_ptr<osg::Group> sceneNode, const osg::GraphicsContext::Traits* traits) 
: _filenameVideo("testV.avi"), _filenameImage("testI.png"), 
_screenSize(traits->width, traits->height), _outputImageSize(traits->width, 
traits->height),
_rootNode(rootNode), _sceneNode(sceneNode), _takeSCBegin(false)
{
}

//=======================================================================//

SnapImage::SnapImage(VideoRecorder *videoRecorder) : _vr(videoRecorder)
{
}

void    SnapImage::operator()(const osg::Camera& camera) const
{
        return;
}

//=======================================================================//

SnapImageHandler::SnapImageHandler(VideoRecorder *vr) : _vr(vr), 
_takeSCEnd(false), _rtt(0)
{
}

SnapImageHandler::~SnapImageHandler(void)
{
}

void    SnapImageHandler::screenShotInit()
{
        _rtt = new rttCameraImage;
        _rtt->_outputImage = new osg::Image;
        if (_vr->getFilenameImage().find(".jpg") != std::string::npos || 
_vr->getFilenameImage().find(".jpeg") != std::string::npos)
                
_rtt->_outputImage->allocateImage(_vr->getOutputImageSize().x(), 
_vr->getOutputImageSize().y(), 1, GL_RGB, GL_UNSIGNED_BYTE);
        else
                
_rtt->_outputImage->allocateImage(_vr->getOutputImageSize().x(), 
_vr->getOutputImageSize().y(), 1, GL_RGBA, GL_UNSIGNED_BYTE);
        _rtt->_rttCamera = new osg::Camera;
        _rtt->_rttCamera->setViewMatrix(_vr->getCurrentViewMatrix());
        
_rtt->_rttCamera->setProjectionMatrix(_vr->getCurrentProjectionMatrix());
        _rtt->_rttCamera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
        _rtt->_rttCamera->setClearMask(GL_COLOR_BUFFER_BIT | 
GL_DEPTH_BUFFER_BIT);
        _rtt->_rttCamera->setViewport(0, 0, _vr->getOutputImageSize().x(), 
_vr->getOutputImageSize().y());
        
_rtt->_rttCamera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);
        _rtt->_rttCamera->setRenderOrder(osg::Camera::PRE_RENDER);
        _rtt->_rttCamera->setRenderingCache( 0 );
        _rtt->_rttCamera->attach( osg::Camera::COLOR_BUFFER, 
_rtt->_outputImage.get(), 0, 0);
        _rtt->_rttCamera->addChild(_vr->getSceneNode());
        _vr->getRootNode()->addChild(_rtt->_rttCamera);
        _vr->takeScreenShot(false);
        _takeSCEnd = true;
}

void    SnapImageHandler::screenShotRecord()
{
        osgDB::writeImageFile(*_rtt->_outputImage, std::string("test.bmp"));
        _vr->getRootNode()->removeChild(_rtt->_rttCamera.get());
        _rtt->_outputImage->releaseGLObjects();
        _rtt->_rttCamera->detach(osg::Camera::COLOR_BUFFER);
        _rtt->_rttCamera = 0;
        _rtt->_outputImage = 0;
        delete (_rtt);
        _rtt = 0;
        _takeSCEnd = false;
}

bool    SnapImageHandler::handle(const osgGA::GUIEventAdapter& 
ea,osgGA::GUIActionAdapter& aa)
 {
         osgViewer::Viewer *viewer = dynamic_cast<osgViewer::Viewer *>(&aa);

         switch(ea.getEventType())
         {
         case (osgGA::GUIEventAdapter::FRAME):
                 {
                        if (_takeSCEnd)
                                this->screenShotRecord();
                        if (_vr->isTakingAScreenshot())
                                this->screenShotInit();
                 }
         case (osgGA::GUIEventAdapter::KEYDOWN):
                 {
                         if (ea.getKey() == 'p' || ea.getKey() == 'P')
                         {
                                 if (!_vr->isTakingAScreenshot() && !_takeSCEnd)
                                 {
                                         
_vr->setCurrentViewMatrix(viewer->getCamera()->getViewMatrix());
                                         
_vr->setCurrentProjectionMatrix(viewer->getCamera()->getProjectionMatrix());
                                         _vr->takeScreenShot(true);
                                        return (true);
                                 }
                         }
                         return (false);
                 }
        default:
                return (false);
         }
         return (false);
}




snapImage.h

Code:

#ifndef __MYKEYBOARDEVENTHANDLER_H__
#define __MYKEYBOARDEVENTHANDLER_H__

#include <osgViewer/Viewer>
#include <osg/Camera>
#include <osg/ref_ptr>
#include <osg/Image>
#include <osgDB/WriteFile>

#include <iostream>

class VideoRecorder
{
private:
        bool                                            _takeSCBegin; 
//screenshot initialisation flag
        osg::Matrix                                     
_currentViewMatrix;//the view matrix who will be applied to the screenshot 
camera
        osg::Matrix                                     
_currentProjectionMatrix;//the projection matrix who will be applied to the 
screenshot camera
        std::string                                     _filenameImage;
        std::string                                     _filenameVideo;
        osg::Vec2                                       _screenSize;//the 
current screen resolution
        osg::Vec2                                       _outputImageSize;//the 
screenshot size
        osg::ref_ptr<osg::Group>        _rootNode;//the root node that have to 
be 2 level upper than the scene node
        osg::ref_ptr<osg::Group>        _sceneNode;//the scene node

public:
        VideoRecorder(osg::ref_ptr<osg::Group> rootNode, 
osg::ref_ptr<osg::Group> sceneNode, const osg::GraphicsContext::Traits* traits);

        inline void                                                     
takeScreenShot(bool sc){ _takeSCBegin = sc; }
        inline bool                                                     
isTakingAScreenshot() const {return (_takeSCBegin);}
        inline void                                                     
setCurrentViewMatrix(const osg::Matrix& cvm) { _currentViewMatrix = cvm; }
        inline const osg::Matrix&                       getCurrentViewMatrix() 
const { return (this->_currentViewMatrix); }
        inline void                                                     
setCurrentProjectionMatrix(const osg::Matrix& cpm) { 
this->_currentProjectionMatrix = cpm; }
        inline const osg::Matrix&                       
getCurrentProjectionMatrix() const { return (this->_currentProjectionMatrix); }
        inline void                                                     
setFilenameVideo(const std::string& fnV) { _filenameVideo = fnV; }
        inline const std::string&                       getFilenameVideo() 
const { return (this->_filenameVideo); }
        inline void                                                     
setFilenameImage(const std::string& fnI) { _filenameImage = fnI; }
        inline const std::string&                       getFilenameImage() 
const { return (this->_filenameImage); }
        inline void                                                     
setScreenSize(const int w, const int h){ _screenSize.set(w, h); }
        inline const osg::Vec2&                         getScreenSize() const { 
return (this->_screenSize); }
        inline void                                                     
setOutputImageSize(const int w, const int h) { _outputImageSize.set(w, h); }
        inline const osg::Vec2&                         getOutputImageSize() 
const { return (this->_outputImageSize); }
        inline void                                                     
setRootNode(osg::ref_ptr<osg::Group> rn) { this->_rootNode = rn; }
        inline osg::ref_ptr<osg::Group>         getRootNode() const { return 
(this->_rootNode); }
        inline void                                                     
setSceneNode(osg::ref_ptr<osg::Group> sn) { this->_sceneNode = sn; }
        inline osg::ref_ptr<osg::Group>         getSceneNode() const { return 
(this->_sceneNode); }
};

typedef struct          s_rttCameraImage
{
        osg::ref_ptr<osg::Camera>       _rttCamera;
        osg::ref_ptr<osg::Image>        _outputImage;
}                                       rttCameraImage;

class SnapImage : public osg::Camera::DrawCallback
{
private:
        VideoRecorder*                                          _vr;

public:
        SnapImage(VideoRecorder* vr);

        virtual void operator() (const osg::Camera& camera) const;
};

class SnapImageHandler : public osgGA::GUIEventHandler
{
private:
        int                                                     _keyImage;//key 
use to take a screenshot
        int                                                     _keyVideo;//key 
use to start/stop record a video
        VideoRecorder*                          _vr;
        rttCameraImage                          *_rtt;
        bool                                            _takeSCEnd; 
//screenshot register flag

        //Create the image and the rtt camera and attach it to the scene
        void                                            screenShotInit();
        //Save the image on the disk and remove the rtt camera to the scene
        void                                            screenShotRecord();

public:
        SnapImageHandler(VideoRecorder *vr);
        ~SnapImageHandler(void);

        //getter & setter
        inline void                                                     
setKeyVideo(const int kv) { this->_keyVideo = kv; }
        inline const int                                        getKeyVideo() 
const { return (this->_keyVideo); }
        inline void                                                     
setKeyImage(const int ki) { this->_keyImage = ki; }
        inline const int                                        getKeyImage() 
const { return (this->_keyImage); }

        //overload method

        virtual bool                                            handle(const 
osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter&);
};


#endif




ps : The both code of the cow and the hud are not mine.

------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=27552#27552





_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to