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
Copyright (C) 2008 by Art Tevs (LGPL)