Added a realize callback to the OsgCameraGroup.

Move osgtexture3D across to using the new realize callback for creating its textures.
This commit is contained in:
Robert Osfield 2003-03-19 12:06:29 +00:00
parent a7bb0126f5
commit 74f8f18ad6
3 changed files with 105 additions and 23 deletions

View File

@ -24,10 +24,10 @@
typedef std::vector< osg::ref_ptr<osg::Image> > ImageList;
class ConstructStateCallback : public osg::NodeCallback
class ConstructStateCallback : public osgProducer::OsgCameraGroup::RealizeCallback
{
public:
ConstructStateCallback() {}
ConstructStateCallback(osg::Node* node):_node(node),_initialized(false) {}
osg::StateSet* constructState()
{
@ -82,6 +82,7 @@ class ConstructStateCallback : public osg::NodeCallback
osg::Texture3D* texture3D = new osg::Texture3D;
texture3D->setFilter(osg::Texture3D::MIN_FILTER,osg::Texture3D::LINEAR);
texture3D->setFilter(osg::Texture3D::MAG_FILTER,osg::Texture3D::LINEAR);
texture3D->setWrap(osg::Texture3D::WRAP_R,osg::Texture3D::REPEAT);
texture3D->setImage(image_3d);
@ -103,6 +104,32 @@ class ConstructStateCallback : public osg::NodeCallback
return stateset;
}
virtual void operator()(const Producer::RenderSurface&, osgProducer::OsgCameraGroup* , osgProducer::OsgSceneHandler* sh)
{
if (!_initialized)
{
// only initialize state once, only need for cases where multiple graphics contexts are
// if which case this callback can get called multiple times.
_initialized = true;
if (_node) _node->setStateSet(constructState());
}
// now safe to con
sh->init();
}
osg::Node* _node;
bool _initialized;
};
class UpdateStateCallback : public osg::NodeCallback
{
public:
UpdateStateCallback() {}
void animateState(osg::StateSet* stateset)
{
// here we simply get any existing texgen, and then increment its
@ -113,7 +140,7 @@ class ConstructStateCallback : public osg::NodeCallback
{
texgen->getPlane(osg::TexGen::R)[3] += 0.001f;
}
}
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
@ -125,14 +152,6 @@ class ConstructStateCallback : public osg::NodeCallback
// we have an exisitng stateset, so lets animate it.
animateState(stateset);
}
else
{
// no state exist yet, so we must be in the first
// pass, so lets create our stateset with all the
// textures in it.
stateset = constructState();
if (stateset) node->setStateSet(stateset);
}
// note, callback is repsonsible for scenegraph traversal so
// should always include call the traverse(node,nv) to ensure
@ -189,7 +208,7 @@ osg::Node* createModel()
// A bit hacky, and my plan is to reimplement the osg::scaleImage and
// osg::Image::copySubImage() without using GLU which will get round
// this current limitation.
geode->setUpdateCallback(new ConstructStateCallback());
geode->setUpdateCallback(new UpdateStateCallback());
return geode;
@ -241,6 +260,11 @@ int main( int argc, char **argv )
// set the scene to render
viewer.setSceneData(rootNode);
// the construct state uses gl commands to resize images so we are forced
// to only call it once a valid graphics context has been established,
// for that we use a realize callback.
viewer.setRealizeCallback(new ConstructStateCallback(rootNode));
// create the windows and run the threads.
viewer.realize(Producer::CameraGroup::ThreadPerCamera);

View File

@ -105,12 +105,40 @@ class OSGPRODUCER_EXPORT OsgCameraGroup : public Producer::CameraGroup
void setFusionDistance( osgUtil::SceneView::FusionDistanceMode mode,float value=1.0f);
/** RealizeCallback class one should override to provide an the implemention of realize callbacks.
* Note, this callback overrides the normal call to OsgSceneHandler::init() so it become the your
* responisibility to call this within your callback if required, it is a safe assumption to
* always call OsgSceneHandler::init() within your callback..*/
class OSGPRODUCER_EXPORT RealizeCallback : public osg::Referenced
{
public:
virtual void operator()( const Producer::RenderSurface & rs, OsgCameraGroup* cg, OsgSceneHandler* sh) = 0;
protected:
virtual ~RealizeCallback() {}
};
/** Set the realize callback to use when once the render surfaces are realized.*/
void setRealizeCallback( RealizeCallback* cb) { _realizeCallback = cb; }
/** Get the realize callback.*/
RealizeCallback* getRealizeCallback() { return _realizeCallback.get(); }
/** Get the const realize callback.*/
const RealizeCallback* getRealizeCallback() const { return _realizeCallback.get(); }
void advance();
/** Realize the render surfaces (OpenGL graphics) and various threads, and call any realize callbacks.*/
virtual void realize( ThreadingModel thread_model= SingleThreaded );
/** Dispatch the cull and draw for each of the Camera's for this frame.*/
virtual void frame();
@ -130,6 +158,9 @@ class OSGPRODUCER_EXPORT OsgCameraGroup : public Producer::CameraGroup
float _fusionDistanceValue;
SceneHandlerList _shvec;
osg::ref_ptr<RealizeCallback> _realizeCallback;
osg::ref_ptr<osg::DisplaySettings> _ds;
bool _initialized;
osg::ref_ptr<osg::FrameStamp> _frameStamp;

View File

@ -19,6 +19,37 @@
using namespace Producer;
using namespace osgProducer;
class RenderSurfaceRealizeCallback : public Producer::RenderSurface::Callback
{
public:
RenderSurfaceRealizeCallback(OsgCameraGroup* cameraGroup,OsgSceneHandler* sceneHandler):
_cameraGroup(cameraGroup),
_sceneHandler(sceneHandler) {}
virtual void operator()( const RenderSurface & rs)
{
if (_cameraGroup)
{
if (_cameraGroup->getRealizeCallback())
{
(*(_cameraGroup->getRealizeCallback()))(rs,_cameraGroup,_sceneHandler);
}
else if (_sceneHandler) _sceneHandler->init();
}
else if (_sceneHandler) _sceneHandler->init();
}
OsgCameraGroup* _cameraGroup;
OsgSceneHandler* _sceneHandler;
};
std::string findCameraConfigFile(const std::string& configFile)
{
std::string foundFile = osgDB::findDataFile(configFile);
@ -191,29 +222,25 @@ void OsgCameraGroup::realize( ThreadingModel thread_model)
if (!_ds) _ds = osg::DisplaySettings::instance();
_ds->setMaxNumberOfGraphicsContexts( _cfg->getNumberOfCameras() );
_shvec.clear();
for( unsigned int i = 0; i < _cfg->getNumberOfCameras(); i++ )
{
Producer::Camera *cam = _cfg->getCamera(i);
osgProducer::OsgSceneHandler *sh = new osgProducer::OsgSceneHandler(_ds.get());
sh->setDefaults();
if( _global_stateset != NULL )
sh->setGlobalStateSet( _global_stateset.get() );
if( _scene_data != NULL )
sh->setSceneData( _scene_data.get() );
sh->setBackgroundColor( _background_color);
sh->getState()->setContextID(i);
sh->setFrameStamp( _frameStamp.get() );
_shvec.push_back( sh );
cam->setSceneHandler( sh );
RenderSurface* rs = cam->getRenderSurface();
rs->setRealizeCallback( new RenderSurfaceRealizeCallback(this, sh));
}
if( _global_stateset == NULL && _shvec.size() > 0 )
{
{
SceneHandlerList::iterator p = _shvec.begin();
_global_stateset = (*p)->getGlobalStateSet();
}
_global_stateset = (*p)->getGlobalStateSet();
}
setUpSceneViewsWithData();