Processor.h

00001 /***************************************************************************
00002  *   Copyright (c) 2008   Art Tevs                                         *
00003  *                                                                         *
00004  *   This library is free software; you can redistribute it and/or modify  *
00005  *   it under the terms of the GNU Lesser General Public License as        *
00006  *   published by the Free Software Foundation; either version 3 of        *
00007  *   the License, or (at your option) any later version.                   *
00008  *                                                                         *
00009  *   This library is distributed in the hope that it will be useful,       *
00010  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00011  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00012  *   GNU Lesse General Public License for more details.                    *
00013  *                                                                         *
00014  *   The full license is in LICENSE file included with this distribution.  *
00015  ***************************************************************************/
00016 
00017 #ifndef _C_PROCESSOR__H_
00018 #define _C_PROCESSOR__H_
00019 
00020 
00021 //-------------------------------------------------------------------------
00022 // Includes
00023 //-------------------------------------------------------------------------
00024 #include <osgPPU/Unit.h>
00025 #include <osg/Camera>
00026 #include <osg/State>
00027 #include <osg/Geode>
00028 
00029 #include <osgPPU/Export.h>
00030 
00031 
00032 namespace osgPPU
00033 {
00034 
00035 class Visitor;
00036 
00037 //! Main processor used to setup the unit pipeline
00038 /**
00039  * The processor acts as a group node. The underlying graph can contain
00040  * units or other kind of nodes. However only units can be drawed in the apropriate
00041  * way.
00042  * The attached camera must provide a valid viewport and color attachment (texture)
00043  * which will be used as input for the pipeline.
00044  *
00045  * The ppus are applied in a pipeline, so the output of one
00046  * ppu is an input to the next one. At the end of the pipeline there should be
00047  * a bypassout ppu specified which do render the result into the frame buffer.
00048  *
00049  * A processor can also be used to do some multipass computation on input data.
00050  * In that case it is not neccessary to output the resulting data on the screen, but
00051  * you can use the output texture of the last ppu for any other purpose.
00052  **/
00053 class OSGPPU_EXPORT Processor : public osg::Group {
00054     public:
00055 
00056         META_Node(osgPPU, Processor);
00057 
00058         /**
00059          * Initialize the ppu system.
00060         **/
00061         Processor();
00062 
00063         Processor(const Processor&, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY);
00064 
00065         /**
00066          * Release the system. This will free used memory and close all ppus.
00067         **/
00068         virtual ~Processor();
00069 
00070         /**
00071         * Traverse method to traverse the subgraph. The unit pipeline will be updated
00072         * and drawed on the according node visitor types. The visitor has to provide
00073         * valid osg::FrameStamp so that the time get updated too.
00074         **/
00075         virtual void traverse(osg::NodeVisitor& nv);
00076 
00077         /**
00078          * Add a camera which texture attachment can be used as input to the pipeline.
00079          * The camera object must be setted up to render into a texture.
00080          * A bypass ppu (Unit) as first in the pipeline can bypass
00081          * the camera attachment into the pipeline.
00082          * @param camera Camera object to use input from.
00083          **/
00084         void setCamera(osg::Camera* camera);
00085 
00086         /**
00087          * Get camera used for this pipeline. This method returns the camera object
00088          * specified with setCamera().
00089         **/
00090         inline const osg::Camera* getCamera() const { return mCamera.get(); }
00091         inline osg::Camera* getCamera() { return mCamera.get(); }
00092 
00093         /**
00094         * Mark the underlying unit subgraph as dirty. This is required as soon
00095         * as you have changed the unit graph. Call this method to let processor
00096         * initilize  the underlying graph properly (setup all inputs and so on).
00097         **/
00098         inline void dirtyUnitSubgraph() {mbDirtyUnitGraph = true;}
00099 
00100         /**
00101         * Check whenever the subgraph is valid. A subgraph is valid if it can be
00102         * traversed by default osg traversal's, hence if it does not contain any cycles.
00103         * You have to traverse the processor with a
00104         * CullTraverser first to resolve the cycles automatically. Afterwards the subgraph
00105         * became valid.
00106         **/
00107         inline bool isDirtyUnitSubgraph() const {return mbDirtyUnitGraph;}
00108 
00109         /**
00110         * Force to mark the subgraph as non-dirty. It is not recommended to traverse
00111         * the graph without initializing it first. Otherwise there could be
00112         * cycles which will end up in seg faults. Use this method only if
00113         * you know what you are doing.
00114         **/
00115         inline void markUnitSubgraphNonDirty() {mbDirtyUnitGraph = false;}
00116 
00117         /**
00118         * Search in the subgraph for a unit. To be able to find the unit
00119         * you have to use unique names for it, however this is not a strict rule.
00120         * If nothing found return NULL.
00121         * @param name Unique name of the unit.
00122         **/
00123         Unit* findUnit(const std::string& name);
00124 
00125         /**
00126         * Remove a unit from the processor's subgraph. The method will
00127         * use the visitor to remove the unit from the graph. The subgraph of the unit
00128         * will be marked as dirty, so that it gets reorganized on the next traverse. All the
00129         * input units of the removed unit will be afterwards input units for the children
00130         * of the removed unit.
00131         * @param unit Pointer to the unit to remove
00132         * @return true on success otherwise false
00133         **/
00134         bool removeUnit(Unit* unit);
00135 
00136         /**
00137         * Overridden method from osg::Node to allow computation of bounding box.
00138         * This is needed to prevent traversion of this computation down to all childs.
00139         * This method do always returns empty bounding sphere.
00140         **/
00141         inline osg::BoundingSphere computeBound() const
00142         {
00143             return osg::BoundingSphere();
00144         }
00145 
00146         /**
00147         * Set wether or not osg::Clamp should be used in the osgPPU
00148         * pipelines. This can be a problem when a graphics driver does not
00149         * support glClamp. By default osg::Clamp will be used. If you
00150         * do not want osg::Clamp in the pipelines be sure to set to false
00151         * before init() is called.
00152         **/
00153         void useColorClamp( bool useColorClamp = true ) {mUseColorClamp = useColorClamp; mbDirty = true;}
00154 
00155         /**
00156         * Call this method whenever your main viewport of any of the used cameras
00157         * or a size of used external textures has changed. Processor will notify 
00158         * every unit of the viewport change. 
00159         *
00160         * NOTE: You can also use dirtyUnitSubgraph(), however this will run the whole
00161         *       initialization process again, which costs time. A call that just viewport
00162         *       changed require usually less time to complete.
00163         **/
00164         virtual void onViewportChange();
00165 
00166     protected:
00167 
00168         /**
00169         * Init method which will be called automagically if processor became dirty.
00170         **/
00171         virtual void init();
00172 
00173         osg::observer_ptr<osg::Camera> mCamera;
00174 
00175         friend class SetupUnitRenderingVisitor;
00176 
00177         /**
00178         * Callback method which will be called as soon as a unit is get initialized.
00179         * Use this method to catch up the initialization process of a unit.
00180         * @param unit Pointer to the unit which is initialized
00181         **/
00182         virtual void onUnitInit(Unit*) {}
00183 
00184         /**
00185         * Callback method for derived classes to detect whenever a unit is get updated.
00186         * This method is called once per frame for every unit whenever it is updated.
00187         * @param unit Pointer to the unit which is updated
00188         **/
00189         virtual void onUnitUpdate(Unit*) {}
00190 
00191     private:
00192 
00193         bool      mbDirty;
00194         bool      mbDirtyUnitGraph;
00195         bool      mUseColorClamp;
00196 
00197 };
00198 
00199 
00200 };
00201 
00202 #endif

Back to Homepage of osgPPU

Copyright (C) 2008 by Art Tevs (LGPL)