123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162 |
- /* -*-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.
- */
- //osgFX - Copyright (C) 2003 Marco Jez
- #ifndef OSGFX_TECHNIQUE_
- #define OSGFX_TECHNIQUE_
- #include <osgFX/Export>
- #include <osg/Referenced>
- #include <osg/State>
- #include <osg/Group>
- #include <osg/NodeVisitor>
- #include <vector>
- #include <string>
- /**
- An helper macro that defines the methods techniqueName() and
- techniqueDescription() making them return the strings passed as parameters.
- */
- #define META_Technique(name, description) \
- inline virtual const char *techniqueName() { return name; } \
- inline virtual const char *techniqueDescription() { return description; }
- namespace osgFX
- {
- class Effect;
- /**
- This is the base class for effect techniques. A technique represents one
- of the possible ways to implement a special effect. This base class is
- abstract, you will have to subclass your own techniques for your custom
- effects.
- Derived classes will have to implement the define_passes() method to
- configure the rendering pass(es) that make up the technique. Usually
- you will create one StateSet object for each rendering pass and then
- you'll call addPass(stateset).
- The validate() method should return true if the technique is valid within
- the current rendering context, false otherwise. The default implementation
- of validate() calls getRequiredExtensions() and tests whether all required
- extensions are supported or not, returning false if at least one extension
- is not supported.
- */
- class OSGFX_EXPORT Technique: public osg::Referenced {
- public:
- Technique();
- /** get the name of this Technique */
- virtual const char *techniqueName() { return "Default"; }
- /** get a brief description of this Technique */
- virtual const char *techniqueDescription() { return "This is the default technique"; }
- /**
- collect the GL extension strings which are required for this technique
- to work properly. This method is called from the default implementation
- of validate().
- */
- virtual void getRequiredExtensions(std::vector<std::string>& /*extensions*/) const {};
- /**
- tests whether this technique is valid for the current rendering context.
- The default behavior is to call getRequiredExtensions() and check for
- extension availability.
- */
- virtual bool validate(osg::State& ) const;
- /** get the number of rendering passes defined in this Technique */
- inline int getNumPasses() const;
- /** get the StateSet object associated to the i-th pass */
- inline osg::StateSet* getPassStateSet(int i);
- /** get the const StateSet object associated to the i-th pass */
- inline const osg::StateSet* getPassStateSet(int i) const;
- /**
- traverse children with multipass if necessary. By default this method
- simply calls the protected method traverse_implementation(); you can
- override it to change the default behavior.
- Don't call this method directly as it is called by osgFX::Effect
- */
- inline virtual void traverse(osg::NodeVisitor& nv, Effect* fx);
- protected:
- Technique(const Technique &): osg::Referenced() {} // copying is nonsense ;)
- virtual ~Technique() {}
- Technique &operator=(const Technique &) { return *this; }
- /** force rebuilding of pass nodes on next traversal */
- inline void dirtyPasses();
- /** create a new pass node, add it to the technique and associate a StateSet */
- void addPass(osg::StateSet* ss = 0);
- /** optional: return a node that overrides the child node on a specified pass */
- inline virtual osg::Node* getOverrideChild(int) { return 0; }
- /**
- define the rendering passes that make up this technique. You must
- implement this method in derived classes to add the required passes.
- */
- virtual void define_passes() = 0;
- /**
- traverse children with multipass if necessary. Don't call this method
- directly unless you are in a customized version of traverse().
- */
- void traverse_implementation(osg::NodeVisitor& nv, Effect* fx);
- private:
- typedef std::vector<osg::ref_ptr<osg::StateSet> > Pass_list;
- OpenThreads::Mutex _mutex;
- OpenThreads::Atomic _passesDefined;
- Pass_list _passes;
- };
- // INLINE METHODS
- inline int Technique::getNumPasses() const
- {
- return _passesDefined!=0 ? static_cast<int>(_passes.size()) : 0;
- }
- inline osg::StateSet* Technique::getPassStateSet(int i)
- {
- return _passesDefined!=0 ? _passes[i].get() : 0;
- }
- inline const osg::StateSet* Technique::getPassStateSet(int i) const
- {
- return _passesDefined!=0 ? _passes[i].get() : 0;
- }
- inline void Technique::dirtyPasses()
- {
- OpenThreads::ScopedLock<OpenThreads::Mutex> lock( _mutex);
- _passesDefined.exchange(0);
- _passes.clear();
- }
- inline void Technique::traverse(osg::NodeVisitor& nv, Effect* fx)
- {
- traverse_implementation(nv, fx);
- }
- }
- #endif
|