Changeset 7976 for code/branches/usability/src/libraries/tools
- Timestamp:
- Feb 27, 2011, 1:05:59 AM (14 years ago)
- Location:
- code/branches/usability/src/libraries/tools
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
code/branches/usability/src/libraries/tools/Shader.cc
r7972 r7976 30 30 31 31 #include <OgreCompositorManager.h> 32 #include <OgreCompositorInstance.h>33 #include <OgreSceneManager.h>34 32 #include <OgreRoot.h> 35 33 #include <OgrePlugin.h> 36 #include <OgreMaterial.h>37 #include <OgreTechnique.h>38 #include <OgrePass.h>39 #include <OgreMaterialManager.h>40 34 41 35 #include "core/CoreIncludes.h" … … 45 39 namespace orxonox 46 40 { 47 bool Shader::bLoadedCgPlugin_s = false;48 Shader::MaterialMap Shader::parameters_s;49 41 /** 42 @brief Initializes the values and sets the scene manager. 43 */ 50 44 Shader::Shader(Ogre::SceneManager* scenemanager) : compositorInstance_(0) 51 45 { … … 55 49 this->bVisible_ = true; 56 50 this->bLoadCompositor_ = GameMode::showsGraphics(); 51 this->registeredAsListener_ = false; 57 52 58 53 static bool hasCgProgramManager = Shader::hasCgProgramManager(); 59 Shader::bLoadedCgPlugin_s = hasCgProgramManager; 60 61 this->bLoadCompositor_ &= Shader::bLoadedCgPlugin_s; 62 } 63 54 55 this->bLoadCompositor_ &= hasCgProgramManager; 56 } 57 58 /** 59 @brief Removes the compositor and frees the resources. 60 */ 64 61 Shader::~Shader() 65 62 { … … 68 65 } 69 66 67 /** 68 @brief Inherited from ViewportEventListener - called if the camera changes. 69 70 Since the new camera could be in a different scene, the shader has to make sure 71 it deactivates or activates itself accordingly. 72 73 Additionally the shader has to be turned off and on even if the camera stays in 74 the same scene to fix a weird behavior of Ogre. 75 */ 70 76 void Shader::cameraChanged(Ogre::Viewport* viewport, Ogre::Camera* oldCamera) 71 77 { … … 95 101 } 96 102 103 /** 104 @brief Changes the compositor - default viewport. 105 */ 97 106 void Shader::changedCompositorName() 98 107 { … … 103 112 } 104 113 114 /** 115 @brief Changes the compositor. 116 */ 105 117 void Shader::changedCompositorName(Ogre::Viewport* viewport) 106 118 { … … 108 120 { 109 121 assert(viewport); 110 if ( !this->oldcompositorName_.empty())122 if (this->compositorInstance_) 111 123 { 124 // remove the old compositor, remove the listener 112 125 Ogre::CompositorManager::getSingleton().removeCompositor(viewport, this->oldcompositorName_); 126 this->compositorInstance_->removeListener(this); 113 127 this->compositorInstance_ = 0; 114 128 } 115 129 if (!this->compositorName_.empty()) 116 130 { 131 // add the new compositor 117 132 this->compositorInstance_ = Ogre::CompositorManager::getSingleton().addCompositor(viewport, this->compositorName_); 118 if (!this->compositorInstance_) 133 if (this->compositorInstance_) 134 { 135 // register as listener if required 136 if (this->registeredAsListener_) 137 this->compositorInstance_->addListener(this); 138 // set visibility according to the isVisible() and the camera/viewport 139 if (viewport->getCamera()) 140 Ogre::CompositorManager::getSingleton().setCompositorEnabled(viewport, this->compositorName_, this->isVisible() && viewport->getCamera() && this->scenemanager_ == viewport->getCamera()->getSceneManager()); 141 } 142 else 119 143 COUT(2) << "Warning: Couldn't load compositor with name \"" << this->compositorName_ << "\"." << std::endl; 120 else if (viewport->getCamera())121 Ogre::CompositorManager::getSingleton().setCompositorEnabled(viewport, this->compositorName_, this->isVisible() && viewport->getCamera() && this->scenemanager_ == viewport->getCamera()->getSceneManager());122 144 } 123 145 this->oldcompositorName_ = this->compositorName_; … … 125 147 } 126 148 149 /** 150 @brief Changes the visibility of the shader. Doesn't free any resources if set to invisible. 151 */ 127 152 void Shader::updateVisibility() 128 153 { … … 131 156 } 132 157 133 void Shader::setParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter, float value) 134 { 135 if (Shader::_setParameter(material, technique, pass, parameter, value)) 136 { 137 if (this->compositorInstance_ && this->isVisible()) 158 /** 159 @brief Defines a new integer value for a given parameter. The parameter will be updated if the compositor is rendered the next time. 160 */ 161 void Shader::setParameter(size_t technique, size_t pass, const std::string& parameter, int value) 162 { 163 ParameterContainer container = {technique, pass, parameter, value, 0.0f, MT_Type::Int}; 164 this->parameters_.push_back(container); 165 this->addAsListener(); 166 } 167 168 /** 169 @brief Defines a new float value for a given parameter. The parameter will be updated if the compositor is rendered the next time. 170 */ 171 void Shader::setParameter(size_t technique, size_t pass, const std::string& parameter, float value) 172 { 173 ParameterContainer container = {technique, pass, parameter, 0, value, MT_Type::Float}; 174 this->parameters_.push_back(container); 175 this->addAsListener(); 176 } 177 178 /** 179 @brief Registers the shader as CompositorInstance::Listener at the compositor. Used to change parameters. 180 */ 181 void Shader::addAsListener() 182 { 183 if (!this->registeredAsListener_) 184 { 185 this->registeredAsListener_ = true; 186 if (this->compositorInstance_) 187 this->compositorInstance_->addListener(this); 188 } 189 } 190 191 /** 192 @brief Inherited by Ogre::CompositorInstance::Listener, called whenever the material is rendered. Used to change parameters. 193 */ 194 void Shader::notifyMaterialRender(Ogre::uint32 pass_id, Ogre::MaterialPtr& materialPtr) 195 { 196 // iterate through the list of parameters 197 for (std::list<ParameterContainer>::iterator it = this->parameters_.begin(); it != this->parameters_.end(); ++it) 198 { 199 Ogre::Technique* techniquePtr = materialPtr->getTechnique(it->technique_); 200 if (techniquePtr) 138 201 { 139 Ogre::CompositorManager::getSingleton().setCompositorEnabled(GraphicsManager::getInstance().getViewport(), this->compositorName_, false); 140 Ogre::CompositorManager::getSingleton().setCompositorEnabled(GraphicsManager::getInstance().getViewport(), this->compositorName_, true); 141 } 142 } 143 } 144 145 void Shader::setParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter, int value) 146 { 147 if (Shader::_setParameter(material, technique, pass, parameter, value)) 148 { 149 if (this->compositorInstance_ && this->isVisible()) 150 { 151 Ogre::CompositorManager::getSingleton().setCompositorEnabled(GraphicsManager::getInstance().getViewport(), this->compositorName_, false); 152 Ogre::CompositorManager::getSingleton().setCompositorEnabled(GraphicsManager::getInstance().getViewport(), this->compositorName_, true); 153 } 154 } 155 } 156 157 /* static */ bool Shader::_setParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter, float value) 158 { 159 ParameterPointer* pointer = Shader::getParameterPointer(material, technique, pass, parameter); 160 if (pointer) 161 { 162 if (pointer->first) 163 { 164 if ((*static_cast<float*>(pointer->second)) != value) 202 Ogre::Pass* passPtr = techniquePtr->getPass(it->pass_); 203 if (passPtr) 165 204 { 166 (*static_cast<float*>(pointer->second)) = value; 167 return true; 205 // change the value of the parameter depending on its type 206 switch (it->valueType_) 207 { 208 case MT_Type::Int: 209 passPtr->getFragmentProgramParameters()->setNamedConstant(it->parameter_, it->valueInt_); 210 break; 211 case MT_Type::Float: 212 passPtr->getFragmentProgramParameters()->setNamedConstant(it->parameter_, it->valueFloat_); 213 break; 214 default: 215 break; 216 } 168 217 } 218 else 219 COUT(2) << "Warning: No pass " << it->pass_ << " in technique " << it->technique_ << " in compositor \"" << this->compositorName_ << "\" or pass has no shader." << std::endl; 169 220 } 170 221 else 171 { 172 if ((*static_cast<int*>(pointer->second)) != static_cast<int>(value)) 173 { 174 (*static_cast<int*>(pointer->second)) = static_cast<int>(value); 175 return true; 176 } 177 } 178 } 179 return false; 180 } 181 182 /* static */ bool Shader::_setParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter, int value) 183 { 184 ParameterPointer* pointer = Shader::getParameterPointer(material, technique, pass, parameter); 185 if (pointer) 186 { 187 if (pointer->first) 188 { 189 if ((*static_cast<float*>(pointer->second)) != static_cast<float>(value)) 190 { 191 (*static_cast<float*>(pointer->second)) = static_cast<float>(value); 192 return true; 193 } 194 } 195 else 196 { 197 if ((*static_cast<int*>(pointer->second)) != value) 198 { 199 (*static_cast<int*>(pointer->second)) = value; 200 return true; 201 } 202 } 203 } 204 return false; 205 } 206 207 /* static */ float Shader::getParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter) 208 { 209 ParameterPointer* pointer = Shader::getParameterPointer(material, technique, pass, parameter); 210 if (pointer) 211 { 212 if (pointer->first) 213 return (*static_cast<float*>(pointer->second)); 214 else 215 return static_cast<float>(*static_cast<int*>(pointer->second)); 216 } 217 else 218 return 0; 219 } 220 221 /* static */ bool Shader::getParameterIsFloat(const std::string& material, size_t technique, size_t pass, const std::string& parameter) 222 { 223 ParameterPointer* pointer = Shader::getParameterPointer(material, technique, pass, parameter); 224 if (pointer) 225 return pointer->first; 226 else 227 return false; 228 } 229 230 /* static */ bool Shader::getParameterIsInt(const std::string& material, size_t technique, size_t pass, const std::string& parameter) 231 { 232 ParameterPointer* pointer = Shader::getParameterPointer(material, technique, pass, parameter); 233 if (pointer) 234 return (!pointer->first); 235 else 236 return false; 237 } 238 239 /* static */ Shader::ParameterPointer* Shader::getParameterPointer(const std::string& material, size_t technique, size_t pass, const std::string& parameter) 240 { 241 if (!GameMode::showsGraphics() || !Shader::bLoadedCgPlugin_s) 242 return 0; 243 244 MaterialMap::iterator material_iterator = Shader::parameters_s.find(material); 245 if (material_iterator != Shader::parameters_s.end()) 246 { 247 TechniqueVector& technique_vector = material_iterator->second; 248 if (technique < technique_vector.size()) 249 { 250 PassVector& pass_vector = technique_vector[technique]; 251 if (pass < pass_vector.size()) 252 { 253 ParameterMap& parameter_map = pass_vector[pass]; 254 ParameterMap::iterator parameter_iterator = parameter_map.find(parameter); 255 256 if (parameter_iterator != parameter_map.end()) 257 return (¶meter_iterator->second); 258 else 259 COUT(2) << "Warning: No shader parameter \"" << parameter << "\" in pass " << pass << " in technique " << technique << " in material \"" << material << "\"." << std::endl; 260 } 261 else 262 COUT(2) << "Warning: No pass " << pass << " in technique " << technique << " in material \"" << material << "\" or pass has no shader." << std::endl; 263 } 264 else 265 COUT(2) << "Warning: No technique " << technique << " in material \"" << material << "\" or technique has no pass with shader." << std::endl; 266 } 267 else 268 { 269 bool foundAtLeastOneShaderParameter = false; 270 Ogre::MaterialManager::ResourceMapIterator iterator = Ogre::MaterialManager::getSingleton().getResourceIterator(); 271 Ogre::Material* material_pointer = 0; 272 273 while (iterator.hasMoreElements()) 274 { 275 Ogre::Resource* resource = iterator.getNext().get(); 276 if (resource->getName() == material) 277 material_pointer = (Ogre::Material*)resource; 278 } 279 280 if (!material_pointer) 281 { 282 COUT(2) << "Warning: No material with name \"" << material << "\" found." << std::endl; 283 return 0; 284 } 285 286 for (unsigned int t = 0; t < material_pointer->getNumTechniques(); ++t) 287 { 288 Ogre::Technique* technique_pointer = material_pointer->getTechnique(t); 289 if (!technique_pointer) 290 continue; 291 292 for (unsigned int p = 0; p < technique_pointer->getNumPasses(); ++p) 293 { 294 Ogre::Pass* pass_pointer = technique_pointer->getPass(p); 295 if (!pass_pointer) 296 continue; 297 298 if (!pass_pointer->getFragmentProgramName().empty()) 299 { 300 Ogre::GpuProgramParameters* parameter_pointer = pass_pointer->getFragmentProgramParameters().get(); 301 if (!parameter_pointer) 302 continue; 303 304 const Ogre::GpuConstantDefinitionMap& constant_definitions = parameter_pointer->getConstantDefinitions().map; 305 for (Ogre::GpuConstantDefinitionMap::const_iterator definition_iterator = constant_definitions.begin(); definition_iterator != constant_definitions.end(); ++definition_iterator) 306 { 307 void* temp = (definition_iterator->second.isFloat()) 308 ? static_cast<void*>(parameter_pointer->getFloatPointer(definition_iterator->second.physicalIndex)) 309 : static_cast<void*>(parameter_pointer->getIntPointer(definition_iterator->second.physicalIndex)); 310 ParameterPointer parameter_pointer = ParameterPointer(definition_iterator->second.isFloat(), temp); 311 312 TechniqueVector& technique_vector = Shader::parameters_s[material]; 313 technique_vector.resize(technique + 1); 314 PassVector& pass_vector = technique_vector[technique]; 315 pass_vector.resize(pass + 1); 316 pass_vector[pass][definition_iterator->first] = parameter_pointer; 317 foundAtLeastOneShaderParameter = true; 318 } 319 } 320 } 321 } 322 323 // recursive call if the material was added to the map 324 if (foundAtLeastOneShaderParameter) 325 return Shader::getParameterPointer(material, technique, pass, parameter); 326 } 327 return 0; 328 } 329 222 COUT(2) << "Warning: No technique " << it->technique_ << " in compositor \"" << this->compositorName_ << "\" or technique has no pass with shader." << std::endl; 223 } 224 this->parameters_.clear(); 225 } 226 227 /** 228 @brief Detects if the Cg program manager plugin is active. 229 */ 330 230 /* static */ bool Shader::hasCgProgramManager() 331 231 { -
code/branches/usability/src/libraries/tools/Shader.h
r7972 r7976 36 36 #include <vector> 37 37 38 #include <OgreCompositorInstance.h> 39 38 40 #include "util/OgreForwardRefs.h" 39 41 #include "core/ViewportEventListener.h" … … 41 43 namespace orxonox 42 44 { 43 class _ToolsExport Shader : public ViewportEventListener 45 /** 46 @brief Shader is a wrapper class around Ogre::CompositorInstance. It provides some 47 functions to easily change the visibility and parameters for shader programs. 48 */ 49 class _ToolsExport Shader : public ViewportEventListener, public Ogre::CompositorInstance::Listener 44 50 { 45 typedef std::pair<bool, void*> ParameterPointer;46 typedef std::map<std::string, ParameterPointer> ParameterMap;47 typedef std::vector<ParameterMap> PassVector;48 typedef std::vector<PassVector> TechniqueVector;49 typedef std::map<std::string, TechniqueVector> MaterialMap;50 51 51 public: 52 52 Shader(Ogre::SceneManager* scenemanager = 0); 53 53 virtual ~Shader(); 54 54 55 /// Defines if the shader is visible or not. 55 56 inline void setVisible(bool bVisible) 56 57 { … … 61 62 } 62 63 } 64 /// Returns whether or not the shader is visible. 63 65 inline bool isVisible() const 64 66 { return this->bVisible_; } 65 67 void updateVisibility(); 66 68 69 /// Defines the compositor's name (located in a .compositor file). 67 70 inline void setCompositorName(const std::string& name) 68 71 { … … 73 76 } 74 77 } 78 /// Returns the compositor's name. 75 79 inline const std::string& getCompositorName() const 76 80 { return this->compositorName_; } … … 78 82 void changedCompositorName(Ogre::Viewport* viewport); 79 83 84 /// Sets the scenemanager (usually provided in the constructor, but can be set later). Shouldn't be changed once it's set. 80 85 inline void setSceneManager(Ogre::SceneManager* scenemanager) 81 86 { this->scenemanager_ = scenemanager; } 87 /// Returns the scene manager. 82 88 inline Ogre::SceneManager* getSceneManager() const 83 89 { return this->scenemanager_; } … … 85 91 virtual void cameraChanged(Ogre::Viewport* viewport, Ogre::Camera* oldCamera); 86 92 87 void setParameter( const std::string& material,size_t technique, size_t pass, const std::string& parameter, float value);88 void setParameter( const std::string& material,size_t technique, size_t pass, const std::string& parameter, int value);93 void setParameter(size_t technique, size_t pass, const std::string& parameter, float value); 94 void setParameter(size_t technique, size_t pass, const std::string& parameter, int value); 89 95 90 static bool _setParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter, float value); 91 static bool _setParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter, int value); 92 static float getParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter); 93 static bool getParameterIsFloat(const std::string& material, size_t technique, size_t pass, const std::string& parameter); 94 static bool getParameterIsInt (const std::string& material, size_t technique, size_t pass, const std::string& parameter); 95 static ParameterPointer* getParameterPointer(const std::string& material, size_t technique, size_t pass, const std::string& parameter); 96 virtual void notifyMaterialRender(Ogre::uint32 pass_id, Ogre::MaterialPtr& materialPtr); 96 97 97 98 private: 98 99 static bool hasCgProgramManager(); 99 100 100 Ogre::SceneManager* scenemanager_; 101 Ogre::CompositorInstance* compositorInstance_; 102 bool bVisible_; 103 bool bLoadCompositor_; 104 std::string compositorName_; 105 std::string oldcompositorName_; 101 Ogre::SceneManager* scenemanager_; ///< The scenemanager for which the shader is active 102 Ogre::CompositorInstance* compositorInstance_; ///< The compositor instance representing the wrapped compositor 103 bool bVisible_; ///< True if the shader should be visible 104 bool bLoadCompositor_; ///< True if the compositor should be loaded (usually false if no graphics) 105 std::string compositorName_; ///< The name of the current compositor 106 std::string oldcompositorName_; ///< The name of the previous compositor (used to unregister) 106 107 107 static MaterialMap parameters_s; 108 static bool bLoadedCgPlugin_s; 108 private: 109 void addAsListener(); 110 111 /// Helper struct to store parameters for shader programs. 112 struct ParameterContainer 113 { 114 size_t technique_; ///< The ID of the technique 115 size_t pass_; ///< The ID of the pass 116 std::string parameter_; ///< The name of the parameter 117 118 int valueInt_; ///< The desired int value of the parameter 119 float valueFloat_; ///< The desired float value of the parameter 120 121 MT_Type::Value valueType_; ///< The type of the parameter (currently only int or float) 122 }; 123 124 std::list<ParameterContainer> parameters_; ///< The list of parameters that should be set on the next update 125 bool registeredAsListener_; ///< True if the shader should register itself as listener at the compositor 109 126 }; 110 127 }
Note: See TracChangeset
for help on using the changeset viewer.