From a55c4b7d70eec0a4d9daa7680f325d6e210f7604 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 2 Jul 2010 12:04:20 +0000 Subject: [PATCH] Added basic ShaderComponent class and beginnings osgshadercomposition example --- examples/CMakeLists.txt | 1 + examples/osgshadercomposition/CMakeLists.txt | 5 ++ .../osgshadercomposition.cpp | 47 +++++++++++++++++++ include/osg/Shader | 25 ++++++++++ include/osg/ShaderAttribute | 15 ++---- include/osg/ShaderComposer | 1 + include/osg/State | 16 ++++++- include/osg/StateAttribute | 10 +++- src/osg/Shader.cpp | 34 ++++++++++++++ src/osg/ShaderAttribute.cpp | 22 ++------- src/osg/State.cpp | 18 +++++++ src/osg/StateAttribute.cpp | 1 - 12 files changed, 163 insertions(+), 32 deletions(-) create mode 100644 examples/osgshadercomposition/CMakeLists.txt create mode 100644 examples/osgshadercomposition/osgshadercomposition.cpp diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index ddc7c9a48..3e89b301a 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -87,6 +87,7 @@ IF(DYNAMIC_OPENSCENEGRAPH) ADD_SUBDIRECTORY(osgscribe) ADD_SUBDIRECTORY(osgsequence) ADD_SUBDIRECTORY(osgshaders) + ADD_SUBDIRECTORY(osgshadercomposition) ADD_SUBDIRECTORY(osgshadergen) ADD_SUBDIRECTORY(osgshaderterrain) # ADD_SUBDIRECTORY(osgshadercompositor) diff --git a/examples/osgshadercomposition/CMakeLists.txt b/examples/osgshadercomposition/CMakeLists.txt new file mode 100644 index 000000000..e06bab83e --- /dev/null +++ b/examples/osgshadercomposition/CMakeLists.txt @@ -0,0 +1,5 @@ +SET(TARGET_SRC + osgshadercomposition.cpp +) + +SETUP_EXAMPLE(osgshadercomposition) diff --git a/examples/osgshadercomposition/osgshadercomposition.cpp b/examples/osgshadercomposition/osgshadercomposition.cpp new file mode 100644 index 000000000..ec759a12d --- /dev/null +++ b/examples/osgshadercomposition/osgshadercomposition.cpp @@ -0,0 +1,47 @@ +/* OpenSceneGraph example, osganimate. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +* THE SOFTWARE. +*/ + +#include +#include +#include + +osg::Node* createSceneGraph(osg::ArgumentParser& arguments) +{ + osg::Node* node = osgDB::readNodeFiles(arguments); + if (!node) return 0; + + osg::StateSet* stateset = node->getOrCreateStateSet(); + osg::ShaderAttribute* sa = new osg::ShaderAttribute; + stateset->setAttribute(sa); + + return node; +} + +int main( int argc, char **argv ) +{ + osg::ArgumentParser arguments(&argc,argv); + + osgViewer::Viewer viewer(arguments); + + osg::ref_ptr scenegraph = createSceneGraph(arguments); + if (!scenegraph) return 1; + + viewer.setSceneData(scenegraph.get()); + + return viewer.run(); +} diff --git a/include/osg/Shader b/include/osg/Shader index 44b96471f..ed6a43835 100644 --- a/include/osg/Shader +++ b/include/osg/Shader @@ -252,6 +252,31 @@ class OSG_EXPORT Shader : public osg::Object Shader& operator=(const Shader&); // disallowed }; + +class OSG_EXPORT ShaderComponent : public osg::Object +{ + public: + + ShaderComponent(); + ShaderComponent(const ShaderComponent& sc,const CopyOp& copyop=CopyOp::SHALLOW_COPY); + + META_Object(osg, ShaderComponent) + + unsigned int addShader(osg::Shader* shader); + void removeShader(unsigned int i); + + osg::Shader* getShader(unsigned int i) { return _shaders[i].get(); } + const osg::Shader* getShader(unsigned int i) const { return _shaders[i].get(); } + + unsigned int getNumShaders() const { return _shaders.size(); } + + protected: + + typedef std::vector< osg::ref_ptr > Shaders; + Shaders _shaders; +}; + + } #endif diff --git a/include/osg/ShaderAttribute b/include/osg/ShaderAttribute index 91848184e..a331acefc 100644 --- a/include/osg/ShaderAttribute +++ b/include/osg/ShaderAttribute @@ -38,12 +38,11 @@ class OSG_EXPORT ShaderAttribute : public StateAttribute void setType(Type type); virtual Type getType() const { return _type; } - unsigned int addShader(Shader* shader); - void removeShader(unsigned int i); - unsigned int getNumShaders() const { return _shaders.size(); } - Shader* getShader(unsigned int i) { return _shaders[i].get(); } - Shader* getShader(unsigned int i) const { return _shaders[i].get(); } - + unsigned int addShader(Shader* shader) { return _shaderComponent->addShader(shader); } + void removeShader(unsigned int i) { _shaderComponent->removeShader(i); } + unsigned int getNumShaders() const { return _shaderComponent->getNumShaders(); } + Shader* getShader(unsigned int i) { return _shaderComponent->getShader(i); } + const Shader* getShader(unsigned int i) const { return _shaderComponent->getShader(i); } unsigned int addUniform(Uniform* uniform); void removeUniform(unsigned int i); @@ -51,7 +50,6 @@ class OSG_EXPORT ShaderAttribute : public StateAttribute Uniform* getUniform(unsigned int i) { return _uniforms[i].get(); } const Uniform* getUniform(unsigned int i) const { return _uniforms[i].get(); } - virtual bool getModeUsage(StateAttribute::ModeUsage& usage) const; virtual void apply(State& state) const; @@ -68,13 +66,10 @@ class OSG_EXPORT ShaderAttribute : public StateAttribute virtual ~ShaderAttribute(); - typedef std::vector< osg::ref_ptr > Shaders; typedef std::vector< osg::ref_ptr > Uniforms; Type _type; - Shaders _shaders; Uniforms _uniforms; - }; } diff --git a/include/osg/ShaderComposer b/include/osg/ShaderComposer index 8a34a2094..fbbd6d404 100644 --- a/include/osg/ShaderComposer +++ b/include/osg/ShaderComposer @@ -31,6 +31,7 @@ class OSG_EXPORT ShaderComposer : public osg::Object ShaderComposer(const ShaderComposer& sa,const CopyOp& copyop=CopyOp::SHALLOW_COPY); META_Object(osg, ShaderComposer) + osg::Program* getOrCreateProgram() { return 0; } protected: diff --git a/include/osg/State b/include/osg/State index 867480632..634f64704 100644 --- a/include/osg/State +++ b/include/osg/State @@ -1351,7 +1351,11 @@ class OSG_EXPORT State : public Referenced, public Observer GraphicsContext* _graphicsContext; unsigned int _contextID; - osg::ref_ptr _shaderComposer; + + bool _shaderCompositionEnabled; + bool _shaderCompositionDirty; + osg::ref_ptr _shaderComposer; + osg::Program* _currentShaderCompositionProgram; ref_ptr _frameStamp; @@ -1413,12 +1417,15 @@ class OSG_EXPORT State : public Referenced, public Observer { changed = false; last_applied_attribute = 0L; + last_applied_shadercomponent = 0L; global_default_attribute = 0L; + } /** apply an attribute if required, passing in attribute and appropriate attribute stack */ bool changed; const StateAttribute* last_applied_attribute; + const ShaderComponent* last_applied_shadercomponent; ref_ptr global_default_attribute; AttributeVec attributeVec; }; @@ -1493,6 +1500,13 @@ class OSG_EXPORT State : public Referenced, public Observer as.last_applied_attribute = attribute; attribute->apply(*this); + const ShaderComponent* sc = attribute->getShaderComponent(); + if (as.last_applied_shadercomponent != sc) + { + as.last_applied_shadercomponent = sc; + _shaderCompositionDirty = true; + } + if (_checkGLErrors==ONCE_PER_ATTRIBUTE) checkGLErrors(attribute); return true; diff --git a/include/osg/StateAttribute b/include/osg/StateAttribute index 826e93a77..f992e2267 100644 --- a/include/osg/StateAttribute +++ b/include/osg/StateAttribute @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -193,7 +194,9 @@ class OSG_EXPORT StateAttribute : public Object StateAttribute(const StateAttribute& sa,const CopyOp& copyop=CopyOp::SHALLOW_COPY): Object(sa,copyop), - _updateCallback(copyop(sa._updateCallback.get())) + _shaderComponent(sa._shaderComponent), + _updateCallback(copyop(sa._updateCallback.get())), + _eventCallback(copyop(sa._eventCallback.get())) {} @@ -262,6 +265,9 @@ class OSG_EXPORT StateAttribute : public Object */ inline unsigned int getNumParents() const { return static_cast(_parents.size()); } + void setShaderComponent(ShaderComponent* sc) { _shaderComponent = sc; } + ShaderComponent* getShaderComponent() { return _shaderComponent.get(); } + const ShaderComponent* getShaderComponent() const { return _shaderComponent.get(); } struct ModeUsage { @@ -341,6 +347,8 @@ class OSG_EXPORT StateAttribute : public Object ParentList _parents; friend class osg::StateSet; + ref_ptr _shaderComponent; + ref_ptr _updateCallback; ref_ptr _eventCallback; }; diff --git a/src/osg/Shader.cpp b/src/osg/Shader.cpp index 2f23525b4..860fcfa17 100644 --- a/src/osg/Shader.cpp +++ b/src/osg/Shader.cpp @@ -36,6 +36,40 @@ using namespace osg; + +/////////////////////////////////////////////////////////////////////////////////// +// +// ShaderComponent +// +ShaderComponent::ShaderComponent() +{ +} + +ShaderComponent::ShaderComponent(const ShaderComponent& sc,const CopyOp& copyop): + osg::Object(sc, copyop), + _shaders(sc._shaders) +{ +} + +unsigned int ShaderComponent::addShader(osg::Shader* shader) +{ + for(unsigned int i=0; i<_shaders.size();++i) + { + if (_shaders[i]==shader) return i; + } + _shaders.push_back(shader); + return _shaders.size()-1; +} + +void ShaderComponent::removeShader(unsigned int i) +{ + _shaders.erase(_shaders.begin()+i); +} + +/////////////////////////////////////////////////////////////////////////////////// +// +// ShaderBinary +// ShaderBinary::ShaderBinary() { } diff --git a/src/osg/ShaderAttribute.cpp b/src/osg/ShaderAttribute.cpp index 80840e4db..b082dc122 100644 --- a/src/osg/ShaderAttribute.cpp +++ b/src/osg/ShaderAttribute.cpp @@ -19,11 +19,13 @@ using namespace osg; ShaderAttribute::ShaderAttribute() { + _shaderComponent = new osg::ShaderComponent; } ShaderAttribute::ShaderAttribute(const ShaderAttribute& sa,const CopyOp& copyop): StateAttribute(sa,copyop), - _type(sa._type) + _type(sa._type), + _uniforms(sa._uniforms) { } @@ -50,24 +52,6 @@ void ShaderAttribute::setType(Type type) _type = type; } -unsigned int ShaderAttribute::addShader(Shader* shader) -{ - // check to see if shader already add, if so return the index of it - for(unsigned int i=0; i<_shaders.size(); ++i) - { - if (_shaders[i] == shader) return i; - } - - // add shader and return it's position - _shaders.push_back(shader); - return _shaders.size()-1; -} - -void ShaderAttribute::removeShader(unsigned int i) -{ - _shaders.erase(_shaders.begin()+i); -} - unsigned int ShaderAttribute::addUniform(Uniform* uniform) { // check to see if uniform already add, if so return the index of it diff --git a/src/osg/State.cpp b/src/osg/State.cpp index f5fb1b7bb..02a2718b3 100644 --- a/src/osg/State.cpp +++ b/src/osg/State.cpp @@ -42,7 +42,10 @@ State::State(): _graphicsContext = 0; _contextID = 0; + _shaderCompositionEnabled = true; + _shaderCompositionDirty = true; _shaderComposer = new ShaderComposer; + _currentShaderCompositionProgram = 0L; _identity = new osg::RefMatrix(); // default RefMatrix constructs to identity. _initialViewMatrix = _identity; @@ -512,6 +515,21 @@ void State::apply(const StateSet* dstate) else if (unit<_textureAttributeMapList.size()) applyAttributeMapOnTexUnit(unit,_textureAttributeMapList[unit]); } + if (_shaderCompositionEnabled) + { + if (_shaderCompositionDirty) + { + // built lits of current ShaderComponents + _currentShaderCompositionProgram = _shaderComposer->getOrCreateProgram(); + } + + if (_currentShaderCompositionProgram) + { + Program::PerContextProgram* pcp = _currentShaderCompositionProgram->getPCP(_contextID); + if (_lastAppliedProgramObject != pcp) applyAttribute(_currentShaderCompositionProgram); + } + } + applyUniformList(_uniformMap,dstate->getUniformList()); } else diff --git a/src/osg/StateAttribute.cpp b/src/osg/StateAttribute.cpp index adbdeb177..105925119 100644 --- a/src/osg/StateAttribute.cpp +++ b/src/osg/StateAttribute.cpp @@ -18,7 +18,6 @@ using namespace osg; - StateAttribute::StateAttribute() :Object(true) {