From dbb7c3c74ca70222ddc6a2016119b5e331d35537 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 15 Feb 2007 22:28:32 +0000 Subject: [PATCH] Added support for using the new osgShadow plugin as a psuedo loader such that: osgviewer cow.osg.shadow Or to ShadowVolume rechnique specifically: osgviewer cow.osg.sv.shadow --- .../osgPlugins/osgShadow/dot_osgShadow.dsp | 16 +- examples/osgshadow/osgshadow.cpp | 5 + examples/osgshadowtexture/GNUmakefile | 2 +- .../osgshadowtexture/osgshadowtexture.cpp | 43 +++++- include/osgShadow/ShadowMap | 4 +- include/osgShadow/ShadowTexture | 4 +- src/osgDB/Registry.cpp | 2 + src/osgPlugins/osgShadow/GNUmakefile | 3 +- .../osgShadow/ReaderWriterOsgShadow.cpp | 144 ++++++++++++++++++ 9 files changed, 204 insertions(+), 19 deletions(-) create mode 100644 src/osgPlugins/osgShadow/ReaderWriterOsgShadow.cpp diff --git a/VisualStudio/osgPlugins/osgShadow/dot_osgShadow.dsp b/VisualStudio/osgPlugins/osgShadow/dot_osgShadow.dsp index 05b330c81..566640feb 100644 --- a/VisualStudio/osgPlugins/osgShadow/dot_osgShadow.dsp +++ b/VisualStudio/osgPlugins/osgShadow/dot_osgShadow.dsp @@ -158,27 +158,31 @@ LIB32=link.exe -lib # Begin Source File -SOURCE=..\..\..\src\osgPlugins\osgShadow\ParallelSplitShadowMap.cpp.cpp +SOURCE=..\..\..\src\osgPlugins\osgShadow\ParallelSplitShadowMap.cpp # End Source File # Begin Source File -SOURCE=..\..\..\src\osgPlugins\osgShadow\ShadowedScene.cpp.cpp +SOURCE=..\..\..\src\osgPlugins\osgShadow\ShadowedScene.cpp # End Source File # Begin Source File -SOURCE=..\..\..\src\osgPlugins\osgShadow\ShadowMap.cpp.cpp +SOURCE=..\..\..\src\osgPlugins\osgShadow\ShadowMap.cpp # End Source File # Begin Source File -SOURCE=..\..\..\src\osgPlugins\osgShadow\ShadowTechnique.cpp.cpp +SOURCE=..\..\..\src\osgPlugins\osgShadow\ShadowTechnique.cpp # End Source File # Begin Source File -SOURCE=..\..\..\src\osgPlugins\osgShadow\ShadowTexture.cpp.cpp +SOURCE=..\..\..\src\osgPlugins\osgShadow\ShadowTexture.cpp # End Source File # Begin Source File -SOURCE=..\..\..\src\osgPlugins\osgShadow\ShadowVolume.cpp.cpp +SOURCE=..\..\..\src\osgPlugins\osgShadow\ShadowVolume.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\osgPlugins\osgShadow\ReaderWriterOsgShadow.cpp # End Source File # End Group # Begin Group "Header Files" diff --git a/examples/osgshadow/osgshadow.cpp b/examples/osgshadow/osgshadow.cpp index 08fb5ad50..702747db7 100644 --- a/examples/osgshadow/osgshadow.cpp +++ b/examples/osgshadow/osgshadow.cpp @@ -453,9 +453,14 @@ int main(int argc, char** argv) osg::ref_ptr ls = new osg::LightSource; ls->getLight()->setPosition(lightpos); + ls->getLight()->setAmbient(osg::Vec4(1.0,0.0,0.0,1.0)); + ls->getLight()->setDiffuse(osg::Vec4(0.0,1.0,0.0,1.0)); shadowedScene->addChild(model.get()); shadowedScene->addChild(ls.get()); + + osgDB::writeNodeFile(*shadowedScene, "shadow.osg"); + viewer.setSceneData(shadowedScene.get()); diff --git a/examples/osgshadowtexture/GNUmakefile b/examples/osgshadowtexture/GNUmakefile index 7a0c797dd..d429adea8 100644 --- a/examples/osgshadowtexture/GNUmakefile +++ b/examples/osgshadowtexture/GNUmakefile @@ -5,7 +5,7 @@ CXXFILES =\ CreateShadowedScene.cpp\ osgshadowtexture.cpp\ -LIBS += -losgViewer -losgText -losgGA -losgDB -losgUtil -losg $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS) +LIBS += -losgShadow -losgViewer -losgText -losgGA -losgDB -losgUtil -losg $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS) INSTFILES = \ $(CXXFILES)\ diff --git a/examples/osgshadowtexture/osgshadowtexture.cpp b/examples/osgshadowtexture/osgshadowtexture.cpp index b694f08bf..e6c07af6a 100644 --- a/examples/osgshadowtexture/osgshadowtexture.cpp +++ b/examples/osgshadowtexture/osgshadowtexture.cpp @@ -13,6 +13,8 @@ #include +#include +#include // include the call which creates the shadowed subgraph. #include "CreateShadowedScene.h" @@ -133,7 +135,7 @@ osg::Node* createMovingModel(const osg::Vec3& center, float radius) positioned->addChild(cessna); osg::MatrixTransform* xform = new osg::MatrixTransform; - xform->setUpdateCallback(new osg::AnimationPathCallback(animationPath,0.0f,2.0)); + //xform->setUpdateCallback(new osg::AnimationPathCallback(animationPath,0.0f,2.0)); xform->addChild(positioned); model->addChild(xform); @@ -145,7 +147,7 @@ osg::Node* createMovingModel(const osg::Vec3& center, float radius) -osg::Node* createModel() +osg::Node* createModel(osg::ArgumentParser& arguments) { osg::Vec3 center(0.0f,0.0f,0.0f); float radius = 100.0f; @@ -156,21 +158,48 @@ osg::Node* createModel() // the shadowed model osg::Node* shadowed = createBase(center-osg::Vec3(0.0f,0.0f,radius*0.25),radius); + + if (arguments.read("--osgShadow")) + { + osgShadow::ShadowedScene* shadowedScene = new osgShadow::ShadowedScene; + + osg::ref_ptr shadowVolume = new osgShadow::ShadowVolume; + shadowedScene->setShadowTechnique(shadowVolume.get()); + shadowVolume->setDynamicShadowVolumes(true); - // combine the models together to create one which has the shadower and the shadowed with the required callback. - osg::Group* root = createShadowedScene(shadower,shadowed,lightPosition,radius/100.0f,1); + osg::ref_ptr ls = new osg::LightSource; + ls->getLight()->setPosition(osg::Vec4(0,1,1,0.0)); + ls->getLight()->setAmbient(osg::Vec4(0.0,0.0,1.0,1.0)); + ls->getLight()->setDiffuse(osg::Vec4(0.0,1.0,0.0,1.0)); - return root; + shadowedScene->addChild(shadower); + shadowedScene->addChild(shadowed); + shadowedScene->addChild(ls.get()); + + return shadowedScene; + + } + else + { + // combine the models together to create one which has the shadower and the shadowed with the required callback. + osg::Group* root = createShadowedScene(shadower,shadowed,lightPosition,radius/100.0f,1); + return root; + } + } -int main(int, char **) +int main(int argc, char ** argv) { + osg::ArgumentParser arguments(&argc,argv); + // construct the viewer. osgViewer::Viewer viewer; // pass the model to the viewer. - viewer.setSceneData( createModel() ); + viewer.setSceneData( createModel(arguments) ); + + viewer.setThreadingModel(osgViewer::Viewer::SingleThreaded); return viewer.run(); } diff --git a/include/osgShadow/ShadowMap b/include/osgShadow/ShadowMap index e76da5e41..987354812 100644 --- a/include/osgShadow/ShadowMap +++ b/include/osgShadow/ShadowMap @@ -11,8 +11,8 @@ * OpenSceneGraph Public License for more details. */ -#ifndef OSGSHADOW_SHADOWEDTEXTURE -#define OSGSHADOW_SHADOWEDTEXTURE 1 +#ifndef OSGSHADOW_SHADOWEMAP +#define OSGSHADOW_SHADOWEMAP 1 #include diff --git a/include/osgShadow/ShadowTexture b/include/osgShadow/ShadowTexture index a6bdec253..d6ed50bd5 100644 --- a/include/osgShadow/ShadowTexture +++ b/include/osgShadow/ShadowTexture @@ -11,8 +11,8 @@ * OpenSceneGraph Public License for more details. */ -#ifndef OSGSHADOW_SHADOWEDTEXTURE -#define OSGSHADOW_SHADOWEDTEXTURE 1 +#ifndef OSGSHADOW_SHADOWETEXTURE +#define OSGSHADOW_SHADOWETEXTURE 1 #include diff --git a/src/osgDB/Registry.cpp b/src/osgDB/Registry.cpp index 37c950779..0439f7a17 100644 --- a/src/osgDB/Registry.cpp +++ b/src/osgDB/Registry.cpp @@ -155,6 +155,8 @@ Registry::Registry() #endif } + addFileExtensionAlias("shadow", "osgShadow"); + addFileExtensionAlias("sgi", "rgb"); addFileExtensionAlias("rgba", "rgb"); addFileExtensionAlias("int", "rgb"); diff --git a/src/osgPlugins/osgShadow/GNUmakefile b/src/osgPlugins/osgShadow/GNUmakefile index 2408ffa76..173473e8a 100644 --- a/src/osgPlugins/osgShadow/GNUmakefile +++ b/src/osgPlugins/osgShadow/GNUmakefile @@ -7,7 +7,8 @@ CXXFILES =\ ShadowTechnique.cpp\ ShadowTexture.cpp\ ShadowVolume.cpp\ - ShadowedScene.cpp + ShadowedScene.cpp\ + ReaderWriterOsgShadow.cpp LIBS += -losgShadow -losgUtil -losg $(OTHER_LIBS) diff --git a/src/osgPlugins/osgShadow/ReaderWriterOsgShadow.cpp b/src/osgPlugins/osgShadow/ReaderWriterOsgShadow.cpp new file mode 100644 index 000000000..84340a944 --- /dev/null +++ b/src/osgPlugins/osgShadow/ReaderWriterOsgShadow.cpp @@ -0,0 +1,144 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2007 Robert Osfield + * + * This application is open source and may be redistributed and/or modified + * freely and without restriction, both in commericial and non commericial + * applications, as long as this copyright notice is maintained. + * + * This application is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * +*/ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#define EXTENSION_NAME "osgShadow" + +static bool getFilenameAndParams(const std::string& input, std::string& filename, std::string& params) +{ + // find the start of the params list, accounting for nesting of [] and () brackets, + // note, we are working backwards. + int noNestedBrackets = 0; + std::string::size_type pos = input.size(); + for(; pos>0; ) + { + --pos; + char c = input[pos]; + if (c==']') ++noNestedBrackets; + else if (c=='[') --noNestedBrackets; + else if (c==')') ++noNestedBrackets; + else if (c=='(') --noNestedBrackets; + else if (c=='.' && noNestedBrackets==0) break; + } + + // get the next "extension", which actually contains the pseudo-loader parameters + params = input.substr(pos+1, std::string::npos ); + if( params.empty() ) + { + osg::notify(osg::WARN) << "Missing parameters for " EXTENSION_NAME " pseudo-loader" << std::endl; + return false; + } + + // clear the params sting of any brackets. + std::string::size_type params_pos = params.size(); + for(; params_pos>0; ) + { + --params_pos; + char c = params[params_pos]; + if (c==']' || c=='[' || c==')' || c=='(') + { + params.erase(params_pos,1); + } + } + + // strip the "params extension", which must leave a sub-filename. + filename = input.substr(0, pos ); + + return true; +} + +/////////////////////////////////////////////////////////////////////////// + +class ReaderWriterShadow : public osgDB::ReaderWriter +{ +public: + ReaderWriterOsgShadow() { } + + virtual const char* className() const { return "osgShadow pseudo-loader"; } + + virtual bool acceptsExtension(const std::string& extension) const + { + return osgDB::equalCaseInsensitive( extension, "osgShadow" ) || osgDB::equalCaseInsensitive( extension, "shadow" ) ; + } + + virtual ReadResult readNode(const std::string& fileName, const osgDB::ReaderWriter::Options* options) const + { + std::string ext = osgDB::getLowerCaseFileExtension(fileName); + if( !acceptsExtension(ext) ) + return ReadResult::FILE_NOT_HANDLED; + + // strip the pseudo-loader extension + std::string tmpName = osgDB::getNameLessExtension( fileName ); + + if (tmpName.empty()) + return ReadResult::FILE_NOT_HANDLED; + + std::string subFileName, params; + if (!getFilenameAndParams(tmpName, subFileName, params)) + { + return ReadResult::FILE_NOT_HANDLED; + } + + if( subFileName.empty()) + { + osg::notify(osg::WARN) << "Missing subfilename for " EXTENSION_NAME " pseudo-loader" << std::endl; + return ReadResult::FILE_NOT_HANDLED; + } + + osg::notify(osg::INFO) << " params = \"" << params << "\"" << std::endl; + osg::notify(osg::INFO) << " subFileName = \"" << subFileName << "\"" << std::endl; + + osg::ref_ptr technique; + if (!params.empty()) + { + if (params=="ShadowVolume" || params=="sv") technique = new osgShadow::ShadowVolume; + else if (params=="ShadowTexture" || params=="st") technique = new osgShadow::ShadowTexture; + else if (params=="ShadowMap" || params=="sm") technique = new osgShadow::ShadowMap; + else if (params=="ParallelSplitShadowMap" || params=="pssm") technique = new osgShadow::ParallelSplitShadowMap; + else subFileName += std::string(".") + params; + } + + // default fallback to using ShadowVolume + if (!technique) technique = new osgShadow::ShadowVolume; + + // recursively load the subfile. + osg::Node *node = osgDB::readNodeFile( subFileName, options ); + if( !node ) + { + // propagate the read failure upwards + osg::notify(osg::WARN) << "Subfile \"" << subFileName << "\" could not be loaded" << std::endl; + return ReadResult::FILE_NOT_HANDLED; + } + + osgShadow::ShadowedScene* shadowedScene = new osgShadow::ShadowedScene; + shadowedScene->setShadowTechnique(technique.get()); + shadowedScene->addChild( node ); + return shadowedScene; + } +}; + + +// Add ourself to the Registry to instantiate the reader/writer. +osgDB::RegisterReaderWriterProxy g_readerWriter_OsgShadow_Proxy; +