From aa43b3c8a686164b57d6db0423048b49b7b11a2b Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 29 Feb 2008 15:25:57 +0000 Subject: [PATCH] Added Camera::g/setIntialDrawCallback and g/setFinalDrawCallback(), and added screen snapshot example code to osghud. --- examples/osghud/osghud.cpp | 86 +++++++++++++++++++ include/osg/Camera | 30 ++++++- include/osg/RenderInfo | 2 +- src/osg/Camera.cpp | 18 +++- src/osgUtil/RenderStage.cpp | 33 ++++--- src/osgWrappers/osg/Camera.cpp | 47 +++++++++- src/osgWrappers/osg/Matrixd.cpp | 4 +- src/osgWrappers/osg/Matrixf.cpp | 4 +- .../osgViewer/ViewerEventHandlers.cpp | 44 ++++++++++ 9 files changed, 247 insertions(+), 21 deletions(-) diff --git a/examples/osghud/osghud.cpp b/examples/osghud/osghud.cpp index c69e2de59..e64b11152 100644 --- a/examples/osghud/osghud.cpp +++ b/examples/osghud/osghud.cpp @@ -31,6 +31,9 @@ #include #include #include +#include + +#include #include @@ -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"<getViewport() : 0; + + osg::notify(osg::NOTICE)<<"Camera callback "<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<<"'"< _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"<_snapImage = true; + return true; + } + + break; + } + default: + break; + } + + return false; + } + + int _key; + osg::ref_ptr _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 group = new osg::Group; diff --git a/include/osg/Camera b/include/osg/Camera index ba52364fa..84bff9af0 100644 --- a/include/osg/Camera +++ b/include/osg/Camera @@ -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 _renderer; ref_ptr _renderingCache; + ref_ptr _initialDrawCallback; ref_ptr _preDrawCallback; ref_ptr _postDrawCallback; + ref_ptr _finalDrawCallback; }; } diff --git a/include/osg/RenderInfo b/include/osg/RenderInfo index 3ba9a45c2..e2611d505 100644 --- a/include/osg/RenderInfo +++ b/include/osg/RenderInfo @@ -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(); } diff --git a/src/osg/Camera.cpp b/src/osg/Camera.cpp index ab5c8ce75..7bb0775d8 100644 --- a/src/osg/Camera.cpp +++ b/src/osg/Camera.cpp @@ -11,6 +11,7 @@ * OpenSceneGraph Public License for more details. */ #include +#include #include 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."<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) diff --git a/src/osgWrappers/osg/Camera.cpp b/src/osgWrappers/osg/Camera.cpp index bf24827ad..0cd2f1de8 100644 --- a/src/osgWrappers/osg/Camera.cpp +++ b/src/osgWrappers/osg/Camera.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -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); diff --git a/src/osgWrappers/osg/Matrixd.cpp b/src/osgWrappers/osg/Matrixd.cpp index 7934a5ce7..3f1245c32 100644 --- a/src/osgWrappers/osg/Matrixd.cpp +++ b/src/osgWrappers/osg/Matrixd.cpp @@ -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, diff --git a/src/osgWrappers/osg/Matrixf.cpp b/src/osgWrappers/osg/Matrixf.cpp index 48045be2a..53efbd1eb 100644 --- a/src/osgWrappers/osg/Matrixf.cpp +++ b/src/osgWrappers/osg/Matrixf.cpp @@ -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, diff --git a/src/osgWrappers/osgViewer/ViewerEventHandlers.cpp b/src/osgWrappers/osgViewer/ViewerEventHandlers.cpp index 2676f4e81..e233481e3 100644 --- a/src/osgWrappers/osgViewer/ViewerEventHandlers.cpp +++ b/src/osgWrappers/osgViewer/ViewerEventHandlers.cpp @@ -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);