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