diff --git a/include/osg/ShaderAttribute b/include/osg/ShaderAttribute new file mode 100644 index 000000000..91848184e --- /dev/null +++ b/include/osg/ShaderAttribute @@ -0,0 +1,82 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2004 Robert Osfield + * + * This library is open source and may be redistributed and/or modified under + * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or + * (at your option) any later version. The full license is in LICENSE file + * included with this distribution, and on the openscenegraph.org website. + * + * This library 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. See the + * OpenSceneGraph Public License for more details. +*/ + +#ifndef OSG_SHADERATTRIBUTE +#define OSG_SHADERATTRIBUTE 1 + +#include +#include +#include + +namespace osg { + +class OSG_EXPORT ShaderAttribute : public StateAttribute +{ + public : + + ShaderAttribute(); + + /** Copy constructor using CopyOp to manage deep vs shallow copy. */ + ShaderAttribute(const ShaderAttribute& sa,const CopyOp& copyop=CopyOp::SHALLOW_COPY); + + META_Object(osg, ShaderAttribute); + + /** return -1 if *this < *rhs, 0 if *this==*rhs, 1 if *this>*rhs. */ + virtual int compare(const StateAttribute& sa) const; + + + 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 addUniform(Uniform* uniform); + void removeUniform(unsigned int i); + unsigned int getNumUniforms() const { return _uniforms.size(); } + 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; + + virtual void compose(ShaderComposer& composer) const; + + virtual void compileGLObjects(State& state) const; + + virtual void resizeGLObjectBuffers(unsigned int maxSize); + + virtual void releaseGLObjects(State* state=0) const; + + protected : + + virtual ~ShaderAttribute(); + + typedef std::vector< osg::ref_ptr > Shaders; + typedef std::vector< osg::ref_ptr > Uniforms; + + Type _type; + Shaders _shaders; + Uniforms _uniforms; + +}; + +} + +#endif diff --git a/include/osg/ShaderComposer b/include/osg/ShaderComposer new file mode 100644 index 000000000..8a34a2094 --- /dev/null +++ b/include/osg/ShaderComposer @@ -0,0 +1,43 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield + * + * This library is open source and may be redistributed and/or modified under + * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or + * (at your option) any later version. The full license is in LICENSE file + * included with this distribution, and on the openscenegraph.org website. + * + * This library 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. See the + * OpenSceneGraph Public License for more details. +*/ + +#ifndef OSG_SHADERCOMPOSER +#define OSG_SHADERCOMPOSER 1 + +#include +#include +#include + +namespace osg { + +// forward declare osg::State +class State; + +class OSG_EXPORT ShaderComposer : public osg::Object +{ + public: + + ShaderComposer(); + ShaderComposer(const ShaderComposer& sa,const CopyOp& copyop=CopyOp::SHALLOW_COPY); + META_Object(osg, ShaderComposer) + + + protected: + + virtual ~ShaderComposer(); + +}; + +} + +#endif diff --git a/include/osg/State b/include/osg/State index a2fb20886..867480632 100644 --- a/include/osg/State +++ b/include/osg/State @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -140,6 +141,17 @@ class OSG_EXPORT State : public Referenced, public Observer /** Get the current OpenGL context unique ID.*/ inline unsigned int getContextID() const { return _contextID; } + + /** Set the ShaderComposor object that implements shader composition.*/ + void setShaderComposer(ShaderComposer* sc) { _shaderComposer = sc; } + + /** Get the ShaderComposor object.*/ + ShaderComposer* getShaderComposer() { return _shaderComposer.get(); } + + /** Get the const ShaderComposor object.*/ + const ShaderComposer* getShaderComposer() const { return _shaderComposer.get(); } + + /** Push stateset onto state stack.*/ void pushStateSet(const StateSet* dstate); @@ -1339,6 +1351,8 @@ class OSG_EXPORT State : public Referenced, public Observer GraphicsContext* _graphicsContext; unsigned int _contextID; + osg::ref_ptr _shaderComposer; + ref_ptr _frameStamp; ref_ptr _identity; diff --git a/include/osg/StateAttribute b/include/osg/StateAttribute index 42f617616..826e93a77 100644 --- a/include/osg/StateAttribute +++ b/include/osg/StateAttribute @@ -35,6 +35,7 @@ namespace osg { // forward declare NodeVisitor, State & StateSet class NodeVisitor; class State; +class ShaderComposer; class StateSet; class Texture; @@ -315,6 +316,9 @@ class OSG_EXPORT StateAttribute : public Object */ virtual void apply(State&) const {} + /* compose associated shaders via the ShaderComposer. */ + virtual void compose(ShaderComposer& composer) const {} + /** Default to nothing to compile - all state is applied immediately. */ virtual void compileGLObjects(State&) const {} diff --git a/src/osg/CMakeLists.txt b/src/osg/CMakeLists.txt index a99dfb5c2..51862cde2 100644 --- a/src/osg/CMakeLists.txt +++ b/src/osg/CMakeLists.txt @@ -137,6 +137,8 @@ SET(LIB_PUBLIC_HEADERS ${HEADER_PATH}/Sequence ${HEADER_PATH}/ShadeModel ${HEADER_PATH}/Shader + ${HEADER_PATH}/ShaderAttribute + ${HEADER_PATH}/ShaderComposer ${HEADER_PATH}/ShadowVolumeOccluder ${HEADER_PATH}/Shape ${HEADER_PATH}/ShapeDrawable @@ -301,6 +303,8 @@ ADD_LIBRARY(${LIB_NAME} Sequence.cpp ShadeModel.cpp Shader.cpp + ShaderAttribute.cpp + ShaderComposer.cpp ShadowVolumeOccluder.cpp Shape.cpp ShapeDrawable.cpp diff --git a/src/osg/ShaderAttribute.cpp b/src/osg/ShaderAttribute.cpp new file mode 100644 index 000000000..80840e4db --- /dev/null +++ b/src/osg/ShaderAttribute.cpp @@ -0,0 +1,118 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2004 Robert Osfield + * + * This library is open source and may be redistributed and/or modified under + * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or + * (at your option) any later version. The full license is in LICENSE file + * included with this distribution, and on the openscenegraph.org website. + * + * This library 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. See the + * OpenSceneGraph Public License for more details. +*/ + +#include +#include + +using namespace osg; + + +ShaderAttribute::ShaderAttribute() +{ +} + +ShaderAttribute::ShaderAttribute(const ShaderAttribute& sa,const CopyOp& copyop): + StateAttribute(sa,copyop), + _type(sa._type) +{ +} + +ShaderAttribute::~ShaderAttribute() +{ +} + +int ShaderAttribute::compare(const StateAttribute& sa) const +{ + // check the types are equal and then create the rhs variable + // used by the COMPARE_StateAttribute_Parameter macros below. + COMPARE_StateAttribute_Types(ShaderAttribute,sa) + + // check if types are same + if (_type < rhs._type) return -1; + if (_type > rhs._type) return 1; + + // all properties are the equal so return 0. + return 0; +} + +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 + for(unsigned int i=0; i<_uniforms.size(); ++i) + { + if (_uniforms[i] == uniform) return i; + } + + // add uniform and return it's position + _uniforms.push_back(uniform); + return _uniforms.size()-1; +} + +void ShaderAttribute::removeUniform(unsigned int i) +{ + _uniforms.erase(_uniforms.begin()+i); +} + +bool ShaderAttribute::getModeUsage(StateAttribute::ModeUsage& usage) const +{ + OSG_NOTICE<<"ShaderAttribute::getModeUsage(..)"<