Added Camera::g/setIntialDrawCallback and g/setFinalDrawCallback(), and added

screen snapshot example code to osghud.
This commit is contained in:
Robert Osfield 2008-02-29 15:25:57 +00:00
parent ca513efc1d
commit aa43b3c8a6
9 changed files with 247 additions and 21 deletions

View File

@ -31,6 +31,9 @@
#include <osg/PolygonOffset>
#include <osg/MatrixTransform>
#include <osg/Camera>
#include <osg/RenderInfo>
#include <osgDB/WriteFile>
#include <osgText/Text>
@ -187,6 +190,81 @@ osg::Camera* createHUD()
return camera;
}
struct SnapImage : public osg::Camera::DrawCallback
{
SnapImage(const std::string& filename):
_filename(filename),
_snapImage(false)
{
_image = new osg::Image;
}
virtual void operator () (osg::RenderInfo& renderInfo) const
{
if (!_snapImage) return;
osg::notify(osg::NOTICE)<<"Camera callback"<<std::endl;
osg::Camera* camera = renderInfo.getCurrentCamera();
osg::Viewport* viewport = camera ? camera->getViewport() : 0;
osg::notify(osg::NOTICE)<<"Camera callback "<<camera<<" "<<viewport<<std::endl;
if (viewport && _image.valid())
{
_image->readPixels(int(viewport->x()),int(viewport->y()),int(viewport->width()),int(viewport->height()),
GL_RGBA,
GL_UNSIGNED_BYTE);
osgDB::writeImageFile(*_image, _filename);
osg::notify(osg::NOTICE)<<"Taken screenshot, and written to '"<<_filename<<"'"<<std::endl;
}
_snapImage = false;
}
std::string _filename;
mutable bool _snapImage;
mutable osg::ref_ptr<osg::Image> _image;
};
struct SnapeImageHandler : public osgGA::GUIEventHandler
{
SnapeImageHandler(int key,SnapImage* si):
_key(key),
_snapImage(si) {}
bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa)
{
if (ea.getHandled()) return false;
switch(ea.getEventType())
{
case(osgGA::GUIEventAdapter::KEYUP):
{
if (ea.getKey() == _key)
{
osg::notify(osg::NOTICE)<<"event handler"<<std::endl;
_snapImage->_snapImage = true;
return true;
}
break;
}
default:
break;
}
return false;
}
int _key;
osg::ref_ptr<SnapImage> _snapImage;
};
int main( int argc, char **argv )
{
// use an ArgumentParser object to manage the program arguments.
@ -273,6 +351,14 @@ int main( int argc, char **argv )
{
// construct the viewer.
osgViewer::Viewer viewer;
SnapImage* preDrawCallback = new SnapImage("preDrawCallback.png");
viewer.getCamera()->setPostDrawCallback(preDrawCallback);
viewer.addEventHandler(new SnapeImageHandler('p',preDrawCallback));
SnapImage* finalDrawCallback = new SnapImage("finalDrawCallback.png");
viewer.getCamera()->setFinalDrawCallback(finalDrawCallback);
viewer.addEventHandler(new SnapeImageHandler('f',finalDrawCallback));
osg::ref_ptr<osg::Group> group = new osg::Group;

View File

@ -29,6 +29,7 @@ namespace osg {
// forward declare View to allow Camera to point back to the View that its within
class View;
class RenderInfo;
/** Camera - is a subclass of Transform which represents encapsulates the settings of a Camera.
*/
@ -401,10 +402,22 @@ class OSG_EXPORT Camera : public Transform, public CullSettings
META_Object(osg,DrawCallback)
virtual void operator () (osg::RenderInfo& renderInfo) const;
virtual void operator () (const osg::Camera& /*camera*/) const {}
};
/** Set the pre draw callback for custom operations to be done before the drawing of the camera's subgraph has been completed.*/
/** Set the initial draw callback for custom operations to be done before the drawing of the camera's subgraph and pre render stages.*/
void setIntialDrawCallback(DrawCallback* cb) { _preDrawCallback = cb; }
/** Get the initial draw callback.*/
DrawCallback* getInitialDrawCallback() { return _initialDrawCallback.get(); }
/** Get the const initial draw callback.*/
const DrawCallback* getUnitialDrawCallback() const { return _initialDrawCallback.get(); }
/** Set the pre draw callback for custom operations to be done before the drawing of the camera's subgraph but after any pre render stages have been completed.*/
void setPreDrawCallback(DrawCallback* cb) { _preDrawCallback = cb; }
/** Get the pre draw callback.*/
@ -414,7 +427,7 @@ class OSG_EXPORT Camera : public Transform, public CullSettings
const DrawCallback* getPreDrawCallback() const { return _preDrawCallback.get(); }
/** Set the post draw callback for custom operations to be done after the drawing of the camera's subgraph has been completed.*/
/** Set the post draw callback for custom operations to be done after the drawing of the camera's subgraph but before the any post render stages have been completed.*/
void setPostDrawCallback(DrawCallback* cb) { _postDrawCallback = cb; }
/** Get the post draw callback.*/
@ -422,6 +435,17 @@ class OSG_EXPORT Camera : public Transform, public CullSettings
/** Get the const post draw callback.*/
const DrawCallback* getPostDrawCallback() const { return _postDrawCallback.get(); }
/** Set the final draw callback for custom operations to be done after the drawing of the camera's subgraph and all of the post render stages has been completed.*/
void setFinalDrawCallback(DrawCallback* cb) { _finalDrawCallback = cb; }
/** Get the final draw callback.*/
DrawCallback* getFinalDrawCallback() { return _finalDrawCallback.get(); }
/** Get the const final draw callback.*/
const DrawCallback* getFinalDrawCallback() const { return _finalDrawCallback.get(); }
OpenThreads::Mutex* getDataChangeMutex() const { return &_dataChangeMutex; }
@ -484,8 +508,10 @@ class OSG_EXPORT Camera : public Transform, public CullSettings
ref_ptr<GraphicsOperation> _renderer;
ref_ptr<Object> _renderingCache;
ref_ptr<DrawCallback> _initialDrawCallback;
ref_ptr<DrawCallback> _preDrawCallback;
ref_ptr<DrawCallback> _postDrawCallback;
ref_ptr<DrawCallback> _finalDrawCallback;
};
}

View File

@ -57,7 +57,7 @@ public:
const View* getView() const { return _view.get(); }
void pushCamera(Camera* camera) { _cameras.push_back(camera); }
void popCamera() { if (_cameras.empty()) _cameras.pop_back(); }
void popCamera() { if (!_cameras.empty()) _cameras.pop_back(); }
Camera* getCurrentCamera() { return _cameras.empty() ? 0 : _cameras.back(); }

View File

@ -11,6 +11,7 @@
* OpenSceneGraph Public License for more details.
*/
#include <osg/Camera>
#include <osg/RenderInfo>
#include <osg/Notify>
using namespace osg;
@ -53,8 +54,10 @@ Camera::Camera(const Camera& camera,const CopyOp& copyop):
_renderTargetImplementation(camera._renderTargetImplementation),
_renderTargetFallback(camera._renderTargetFallback),
_bufferAttachmentMap(camera._bufferAttachmentMap),
_initialDrawCallback(camera._initialDrawCallback),
_preDrawCallback(camera._preDrawCallback),
_postDrawCallback(camera._postDrawCallback)
_postDrawCallback(camera._postDrawCallback),
_finalDrawCallback(camera._finalDrawCallback)
{
// need to copy/share graphics context?
}
@ -67,6 +70,19 @@ Camera::~Camera()
if (_graphicsContext.valid()) _graphicsContext->removeCamera(this);
}
void Camera::DrawCallback::operator () (osg::RenderInfo& renderInfo) const
{
if (renderInfo.getCurrentCamera())
{
operator()(*(renderInfo.getCurrentCamera()));
}
else
{
osg::notify(osg::WARN)<<"Error: Camera::DrawCallback called without valid camera."<<std::endl;
}
}
void Camera::setGraphicsContext(GraphicsContext* context)
{
if (_graphicsContext == context) return;

View File

@ -826,8 +826,17 @@ void RenderStage::draw(osg::RenderInfo& renderInfo,RenderLeaf*& previous)
{
if (_stageDrawnThisFrame) return;
// push the stages camera so that drawing code can query it
if (_camera) renderInfo.pushCamera(_camera);
_stageDrawnThisFrame = true;
if (_camera && _camera->getInitialDrawCallback())
{
// if we have a camera with a intial draw callback invoke it.
(*(_camera->getInitialDrawCallback()))(renderInfo);
}
// note, SceneView does call to drawPreRenderStages explicitly
// so there is no need to call it here.
drawPreRenderStages(renderInfo,previous);
@ -880,8 +889,8 @@ void RenderStage::draw(osg::RenderInfo& renderInfo,RenderLeaf*& previous)
if (_camera && _camera->getPreDrawCallback())
{
// if we have a camera with a post draw callback invoke it.
(*(_camera->getPreDrawCallback()))(*_camera);
// if we have a camera with a pre draw callback invoke it.
(*(_camera->getPreDrawCallback()))(renderInfo);
}
bool doCopyTexture = _texture.valid() ?
@ -942,7 +951,7 @@ void RenderStage::draw(osg::RenderInfo& renderInfo,RenderLeaf*& previous)
if (_camera && _camera->getPostDrawCallback())
{
// if we have a camera with a post draw callback invoke it.
(*(_camera->getPostDrawCallback()))(*_camera);
(*(_camera->getPostDrawCallback()))(renderInfo);
}
if (_graphicsContext.valid() && _graphicsContext != callingContext)
@ -974,9 +983,17 @@ void RenderStage::draw(osg::RenderInfo& renderInfo,RenderLeaf*& previous)
callingContext->makeCurrent();
}
// place the post draw here temprorarily while we figure out how
// best to do SceneView.
// render all the post draw callbacks
drawPostRenderStages(renderInfo,previous);
if (_camera && _camera->getFinalDrawCallback())
{
// if we have a camera with a final callback invoke it.
(*(_camera->getFinalDrawCallback()))(renderInfo);
}
// pop the render stages camera.
if (_camera) renderInfo.popCamera();
}
void RenderStage::drawImplementation(osg::RenderInfo& renderInfo,RenderLeaf*& previous)
@ -989,9 +1006,6 @@ void RenderStage::drawImplementation(osg::RenderInfo& renderInfo,RenderLeaf*& pr
return;
}
// push the stages camera so that drawing code can query it
if (_camera) renderInfo.pushCamera(_camera);
// set up the back buffer.
state.applyAttribute(_viewport.get());
@ -1052,9 +1066,6 @@ void RenderStage::drawImplementation(osg::RenderInfo& renderInfo,RenderLeaf*& pr
state.apply();
// pop the render stages camera.
if (_camera) renderInfo.popCamera();
}
void RenderStage::drawPostRenderStages(osg::RenderInfo& renderInfo,RenderLeaf*& previous)

View File

@ -24,6 +24,7 @@
#include <osg/NodeVisitor>
#include <osg/Object>
#include <osg/OperationThread>
#include <osg/RenderInfo>
#include <osg/State>
#include <osg/Stats>
#include <osg/Texture>
@ -507,10 +508,25 @@ BEGIN_OBJECT_REFLECTOR(osg::Camera)
__C5_osg_Object_P1__getRenderingCache,
"Get the const Rendering cache that is used for cached objects associated with rendering of subgraphs. ",
"");
I_Method1(void, setIntialDrawCallback, IN, osg::Camera::DrawCallback *, cb,
Properties::NON_VIRTUAL,
__void__setIntialDrawCallback__DrawCallback_P1,
"Set the initial draw callback for custom operations to be done before the drawing of the camera's subgraph and pre render stages. ",
"");
I_Method0(osg::Camera::DrawCallback *, getInitialDrawCallback,
Properties::NON_VIRTUAL,
__DrawCallback_P1__getInitialDrawCallback,
"Get the initial draw callback. ",
"");
I_Method0(const osg::Camera::DrawCallback *, getUnitialDrawCallback,
Properties::NON_VIRTUAL,
__C5_DrawCallback_P1__getUnitialDrawCallback,
"Get the const initial draw callback. ",
"");
I_Method1(void, setPreDrawCallback, IN, osg::Camera::DrawCallback *, cb,
Properties::NON_VIRTUAL,
__void__setPreDrawCallback__DrawCallback_P1,
"Set the pre draw callback for custom operations to be done before the drawing of the camera's subgraph has been completed. ",
"Set the pre draw callback for custom operations to be done before the drawing of the camera's subgraph but after any pre render stages have been completed. ",
"");
I_Method0(osg::Camera::DrawCallback *, getPreDrawCallback,
Properties::NON_VIRTUAL,
@ -525,7 +541,7 @@ BEGIN_OBJECT_REFLECTOR(osg::Camera)
I_Method1(void, setPostDrawCallback, IN, osg::Camera::DrawCallback *, cb,
Properties::NON_VIRTUAL,
__void__setPostDrawCallback__DrawCallback_P1,
"Set the post draw callback for custom operations to be done after the drawing of the camera's subgraph has been completed. ",
"Set the post draw callback for custom operations to be done after the drawing of the camera's subgraph but before the any post render stages have been completed. ",
"");
I_Method0(osg::Camera::DrawCallback *, getPostDrawCallback,
Properties::NON_VIRTUAL,
@ -537,6 +553,21 @@ BEGIN_OBJECT_REFLECTOR(osg::Camera)
__C5_DrawCallback_P1__getPostDrawCallback,
"Get the const post draw callback. ",
"");
I_Method1(void, setFinalDrawCallback, IN, osg::Camera::DrawCallback *, cb,
Properties::NON_VIRTUAL,
__void__setFinalDrawCallback__DrawCallback_P1,
"Set the final draw callback for custom operations to be done after the drawing of the camera's subgraph and all of the post render stages has been completed. ",
"");
I_Method0(osg::Camera::DrawCallback *, getFinalDrawCallback,
Properties::NON_VIRTUAL,
__DrawCallback_P1__getFinalDrawCallback,
"Get the final draw callback. ",
"");
I_Method0(const osg::Camera::DrawCallback *, getFinalDrawCallback,
Properties::NON_VIRTUAL,
__C5_DrawCallback_P1__getFinalDrawCallback,
"Get the const final draw callback. ",
"");
I_Method0(OpenThreads::Mutex *, getDataChangeMutex,
Properties::NON_VIRTUAL,
__OpenThreads_Mutex_P1__getDataChangeMutex,
@ -589,9 +620,18 @@ BEGIN_OBJECT_REFLECTOR(osg::Camera)
I_SimpleProperty(GLenum, DrawBuffer,
__GLenum__getDrawBuffer,
__void__setDrawBuffer__GLenum);
I_SimpleProperty(osg::Camera::DrawCallback *, FinalDrawCallback,
__DrawCallback_P1__getFinalDrawCallback,
__void__setFinalDrawCallback__DrawCallback_P1);
I_SimpleProperty(osg::GraphicsContext *, GraphicsContext,
__GraphicsContext_P1__getGraphicsContext,
__void__setGraphicsContext__GraphicsContext_P1);
I_SimpleProperty(osg::Camera::DrawCallback *, InitialDrawCallback,
__DrawCallback_P1__getInitialDrawCallback,
0);
I_SimpleProperty(osg::Camera::DrawCallback *, IntialDrawCallback,
0,
__void__setIntialDrawCallback__DrawCallback_P1);
I_SimpleProperty(osg::Matrixd, InverseViewMatrix,
__Matrixd__getInverseViewMatrix,
0);
@ -634,6 +674,9 @@ BEGIN_OBJECT_REFLECTOR(osg::Camera)
I_SimpleProperty(osg::Camera::TransformOrder, TransformOrder,
__TransformOrder__getTransformOrder,
__void__setTransformOrder__TransformOrder);
I_SimpleProperty(const osg::Camera::DrawCallback *, UnitialDrawCallback,
__C5_DrawCallback_P1__getUnitialDrawCallback,
0);
I_SimpleProperty(osg::View *, View,
__View_P1__getView,
__void__setView__View_P1);

View File

@ -332,8 +332,8 @@ BEGIN_VALUE_REFLECTOR(osg::Matrixd)
I_Method0(osg::Quat, getRotate,
Properties::NON_VIRTUAL,
__Quat__getRotate,
"",
"");
"Get the matrix rotation as a Quat. ",
"Note that this function assumes a non-scaled matrix and will return incorrect results for scaled matrixces. Consider decompose() instead. ");
I_Method3(void, setTrans, IN, osg::Matrixd::value_type, tx, IN, osg::Matrixd::value_type, ty, IN, osg::Matrixd::value_type, tz,
Properties::NON_VIRTUAL,
__void__setTrans__value_type__value_type__value_type,

View File

@ -332,8 +332,8 @@ BEGIN_VALUE_REFLECTOR(osg::Matrixf)
I_Method0(osg::Quat, getRotate,
Properties::NON_VIRTUAL,
__Quat__getRotate,
"",
"");
"Get the matrix rotation as a Quat. ",
"Note that this function assumes a non-scaled matrix and will return incorrect results for scaled matrixces. Consider decompose() instead. ");
I_Method3(void, setTrans, IN, osg::Matrixf::value_type, tx, IN, osg::Matrixf::value_type, ty, IN, osg::Matrixf::value_type, tz,
Properties::NON_VIRTUAL,
__void__setTrans__value_type__value_type__value_type,

View File

@ -105,6 +105,50 @@ BEGIN_OBJECT_REFLECTOR(osgViewer::HelpHandler)
__void__setKeyEventTogglesOnScreenHelp__int);
END_REFLECTOR
BEGIN_OBJECT_REFLECTOR(osgViewer::LODScaleHandler)
I_DeclaringFile("osgViewer/ViewerEventHandlers");
I_BaseType(osgGA::GUIEventHandler);
I_Constructor0(____LODScaleHandler,
"",
"");
I_Method1(void, setKeyEventIncreaseLODScale, IN, int, key,
Properties::NON_VIRTUAL,
__void__setKeyEventIncreaseLODScale__int,
"",
"");
I_Method0(int, getKeyEventIncreaseLODScale,
Properties::NON_VIRTUAL,
__int__getKeyEventIncreaseLODScale,
"",
"");
I_Method1(void, setKeyEventDecreaseLODScale, IN, int, key,
Properties::NON_VIRTUAL,
__void__setKeyEventDecreaseLODScale__int,
"",
"");
I_Method0(int, getKeyEventDecreaseLODScale,
Properties::NON_VIRTUAL,
__int__getKeyEventDecreaseLODScale,
"",
"");
I_Method2(bool, handle, IN, const osgGA::GUIEventAdapter &, ea, IN, osgGA::GUIActionAdapter &, aa,
Properties::VIRTUAL,
__bool__handle__C5_osgGA_GUIEventAdapter_R1__osgGA_GUIActionAdapter_R1,
"Deprecated, Handle events, return true if handled, false otherwise. ",
"");
I_Method1(void, getUsage, IN, osg::ApplicationUsage &, usage,
Properties::VIRTUAL,
__void__getUsage__osg_ApplicationUsage_R1,
"Get the keyboard and mouse usage of this manipulator. ",
"");
I_SimpleProperty(int, KeyEventDecreaseLODScale,
__int__getKeyEventDecreaseLODScale,
__void__setKeyEventDecreaseLODScale__int);
I_SimpleProperty(int, KeyEventIncreaseLODScale,
__int__getKeyEventIncreaseLODScale,
__void__setKeyEventIncreaseLODScale__int);
END_REFLECTOR
BEGIN_OBJECT_REFLECTOR(osgViewer::RecordCameraPathHandler)
I_DeclaringFile("osgViewer/ViewerEventHandlers");
I_BaseType(osgGA::GUIEventHandler);