[Orxonox-commit 3285] r7976 - in code/branches/usability/src: libraries/tools orxonox/items
landauf at orxonox.net
landauf at orxonox.net
Sun Feb 27 01:06:00 CET 2011
Author: landauf
Date: 2011-02-27 01:05:59 +0100 (Sun, 27 Feb 2011)
New Revision: 7976
Modified:
code/branches/usability/src/libraries/tools/Shader.cc
code/branches/usability/src/libraries/tools/Shader.h
code/branches/usability/src/orxonox/items/Engine.cc
Log:
rewrote parameter changing implementation of Shader
added documentation
Modified: code/branches/usability/src/libraries/tools/Shader.cc
===================================================================
--- code/branches/usability/src/libraries/tools/Shader.cc 2011-02-26 20:53:23 UTC (rev 7975)
+++ code/branches/usability/src/libraries/tools/Shader.cc 2011-02-27 00:05:59 UTC (rev 7976)
@@ -29,14 +29,8 @@
#include "Shader.h"
#include <OgreCompositorManager.h>
-#include <OgreCompositorInstance.h>
-#include <OgreSceneManager.h>
#include <OgreRoot.h>
#include <OgrePlugin.h>
-#include <OgreMaterial.h>
-#include <OgreTechnique.h>
-#include <OgrePass.h>
-#include <OgreMaterialManager.h>
#include "core/CoreIncludes.h"
#include "core/GameMode.h"
@@ -44,9 +38,9 @@
namespace orxonox
{
- bool Shader::bLoadedCgPlugin_s = false;
- Shader::MaterialMap Shader::parameters_s;
-
+ /**
+ @brief Initializes the values and sets the scene manager.
+ */
Shader::Shader(Ogre::SceneManager* scenemanager) : compositorInstance_(0)
{
RegisterObject(Shader);
@@ -54,19 +48,31 @@
this->scenemanager_ = scenemanager;
this->bVisible_ = true;
this->bLoadCompositor_ = GameMode::showsGraphics();
+ this->registeredAsListener_ = false;
static bool hasCgProgramManager = Shader::hasCgProgramManager();
- Shader::bLoadedCgPlugin_s = hasCgProgramManager;
- this->bLoadCompositor_ &= Shader::bLoadedCgPlugin_s;
+ this->bLoadCompositor_ &= hasCgProgramManager;
}
+ /**
+ @brief Removes the compositor and frees the resources.
+ */
Shader::~Shader()
{
if (this->compositorInstance_ && GraphicsManager::getInstance().getViewport())
Ogre::CompositorManager::getSingleton().removeCompositor(GraphicsManager::getInstance().getViewport(), this->compositorName_);
}
+ /**
+ @brief Inherited from ViewportEventListener - called if the camera changes.
+
+ Since the new camera could be in a different scene, the shader has to make sure
+ it deactivates or activates itself accordingly.
+
+ Additionally the shader has to be turned off and on even if the camera stays in
+ the same scene to fix a weird behavior of Ogre.
+ */
void Shader::cameraChanged(Ogre::Viewport* viewport, Ogre::Camera* oldCamera)
{
if (!this->bLoadCompositor_ || !this->scenemanager_)
@@ -94,6 +100,9 @@
Ogre::CompositorManager::getSingleton().setCompositorEnabled(viewport, this->compositorName_, this->isVisible());
}
+ /**
+ @brief Changes the compositor - default viewport.
+ */
void Shader::changedCompositorName()
{
// For the moment, we get the viewport always from the graphics manager
@@ -102,231 +111,122 @@
this->changedCompositorName(GraphicsManager::getInstance().getViewport());
}
+ /**
+ @brief Changes the compositor.
+ */
void Shader::changedCompositorName(Ogre::Viewport* viewport)
{
if (this->bLoadCompositor_)
{
assert(viewport);
- if (!this->oldcompositorName_.empty())
+ if (this->compositorInstance_)
{
+ // remove the old compositor, remove the listener
Ogre::CompositorManager::getSingleton().removeCompositor(viewport, this->oldcompositorName_);
+ this->compositorInstance_->removeListener(this);
this->compositorInstance_ = 0;
}
if (!this->compositorName_.empty())
{
+ // add the new compositor
this->compositorInstance_ = Ogre::CompositorManager::getSingleton().addCompositor(viewport, this->compositorName_);
- if (!this->compositorInstance_)
+ if (this->compositorInstance_)
+ {
+ // register as listener if required
+ if (this->registeredAsListener_)
+ this->compositorInstance_->addListener(this);
+ // set visibility according to the isVisible() and the camera/viewport
+ if (viewport->getCamera())
+ Ogre::CompositorManager::getSingleton().setCompositorEnabled(viewport, this->compositorName_, this->isVisible() && viewport->getCamera() && this->scenemanager_ == viewport->getCamera()->getSceneManager());
+ }
+ else
COUT(2) << "Warning: Couldn't load compositor with name \"" << this->compositorName_ << "\"." << std::endl;
- else if (viewport->getCamera())
- Ogre::CompositorManager::getSingleton().setCompositorEnabled(viewport, this->compositorName_, this->isVisible() && viewport->getCamera() && this->scenemanager_ == viewport->getCamera()->getSceneManager());
}
this->oldcompositorName_ = this->compositorName_;
}
}
+ /**
+ @brief Changes the visibility of the shader. Doesn't free any resources if set to invisible.
+ */
void Shader::updateVisibility()
{
if (this->compositorInstance_)
Ogre::CompositorManager::getSingleton().setCompositorEnabled(GraphicsManager::getInstance().getViewport(), this->compositorName_, this->isVisible());
}
- void Shader::setParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter, float value)
+ /**
+ @brief Defines a new integer value for a given parameter. The parameter will be updated if the compositor is rendered the next time.
+ */
+ void Shader::setParameter(size_t technique, size_t pass, const std::string& parameter, int value)
{
- if (Shader::_setParameter(material, technique, pass, parameter, value))
- {
- if (this->compositorInstance_ && this->isVisible())
- {
- Ogre::CompositorManager::getSingleton().setCompositorEnabled(GraphicsManager::getInstance().getViewport(), this->compositorName_, false);
- Ogre::CompositorManager::getSingleton().setCompositorEnabled(GraphicsManager::getInstance().getViewport(), this->compositorName_, true);
- }
- }
+ ParameterContainer container = {technique, pass, parameter, value, 0.0f, MT_Type::Int};
+ this->parameters_.push_back(container);
+ this->addAsListener();
}
- void Shader::setParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter, int value)
+ /**
+ @brief Defines a new float value for a given parameter. The parameter will be updated if the compositor is rendered the next time.
+ */
+ void Shader::setParameter(size_t technique, size_t pass, const std::string& parameter, float value)
{
- if (Shader::_setParameter(material, technique, pass, parameter, value))
- {
- if (this->compositorInstance_ && this->isVisible())
- {
- Ogre::CompositorManager::getSingleton().setCompositorEnabled(GraphicsManager::getInstance().getViewport(), this->compositorName_, false);
- Ogre::CompositorManager::getSingleton().setCompositorEnabled(GraphicsManager::getInstance().getViewport(), this->compositorName_, true);
- }
- }
+ ParameterContainer container = {technique, pass, parameter, 0, value, MT_Type::Float};
+ this->parameters_.push_back(container);
+ this->addAsListener();
}
- /* static */ bool Shader::_setParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter, float value)
+ /**
+ @brief Registers the shader as CompositorInstance::Listener at the compositor. Used to change parameters.
+ */
+ void Shader::addAsListener()
{
- ParameterPointer* pointer = Shader::getParameterPointer(material, technique, pass, parameter);
- if (pointer)
+ if (!this->registeredAsListener_)
{
- if (pointer->first)
- {
- if ((*static_cast<float*>(pointer->second)) != value)
- {
- (*static_cast<float*>(pointer->second)) = value;
- return true;
- }
- }
- else
- {
- if ((*static_cast<int*>(pointer->second)) != static_cast<int>(value))
- {
- (*static_cast<int*>(pointer->second)) = static_cast<int>(value);
- return true;
- }
- }
+ this->registeredAsListener_ = true;
+ if (this->compositorInstance_)
+ this->compositorInstance_->addListener(this);
}
- return false;
}
- /* static */ bool Shader::_setParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter, int value)
+ /**
+ @brief Inherited by Ogre::CompositorInstance::Listener, called whenever the material is rendered. Used to change parameters.
+ */
+ void Shader::notifyMaterialRender(Ogre::uint32 pass_id, Ogre::MaterialPtr& materialPtr)
{
- ParameterPointer* pointer = Shader::getParameterPointer(material, technique, pass, parameter);
- if (pointer)
+ // iterate through the list of parameters
+ for (std::list<ParameterContainer>::iterator it = this->parameters_.begin(); it != this->parameters_.end(); ++it)
{
- if (pointer->first)
+ Ogre::Technique* techniquePtr = materialPtr->getTechnique(it->technique_);
+ if (techniquePtr)
{
- if ((*static_cast<float*>(pointer->second)) != static_cast<float>(value))
+ Ogre::Pass* passPtr = techniquePtr->getPass(it->pass_);
+ if (passPtr)
{
- (*static_cast<float*>(pointer->second)) = static_cast<float>(value);
- return true;
+ // change the value of the parameter depending on its type
+ switch (it->valueType_)
+ {
+ case MT_Type::Int:
+ passPtr->getFragmentProgramParameters()->setNamedConstant(it->parameter_, it->valueInt_);
+ break;
+ case MT_Type::Float:
+ passPtr->getFragmentProgramParameters()->setNamedConstant(it->parameter_, it->valueFloat_);
+ break;
+ default:
+ break;
+ }
}
- }
- else
- {
- if ((*static_cast<int*>(pointer->second)) != value)
- {
- (*static_cast<int*>(pointer->second)) = value;
- return true;
- }
- }
- }
- return false;
- }
-
- /* static */ float Shader::getParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter)
- {
- ParameterPointer* pointer = Shader::getParameterPointer(material, technique, pass, parameter);
- if (pointer)
- {
- if (pointer->first)
- return (*static_cast<float*>(pointer->second));
- else
- return static_cast<float>(*static_cast<int*>(pointer->second));
- }
- else
- return 0;
- }
-
- /* static */ bool Shader::getParameterIsFloat(const std::string& material, size_t technique, size_t pass, const std::string& parameter)
- {
- ParameterPointer* pointer = Shader::getParameterPointer(material, technique, pass, parameter);
- if (pointer)
- return pointer->first;
- else
- return false;
- }
-
- /* static */ bool Shader::getParameterIsInt(const std::string& material, size_t technique, size_t pass, const std::string& parameter)
- {
- ParameterPointer* pointer = Shader::getParameterPointer(material, technique, pass, parameter);
- if (pointer)
- return (!pointer->first);
- else
- return false;
- }
-
- /* static */ Shader::ParameterPointer* Shader::getParameterPointer(const std::string& material, size_t technique, size_t pass, const std::string& parameter)
- {
- if (!GameMode::showsGraphics() || !Shader::bLoadedCgPlugin_s)
- return 0;
-
- MaterialMap::iterator material_iterator = Shader::parameters_s.find(material);
- if (material_iterator != Shader::parameters_s.end())
- {
- TechniqueVector& technique_vector = material_iterator->second;
- if (technique < technique_vector.size())
- {
- PassVector& pass_vector = technique_vector[technique];
- if (pass < pass_vector.size())
- {
- ParameterMap& parameter_map = pass_vector[pass];
- ParameterMap::iterator parameter_iterator = parameter_map.find(parameter);
-
- if (parameter_iterator != parameter_map.end())
- return (¶meter_iterator->second);
- else
- COUT(2) << "Warning: No shader parameter \"" << parameter << "\" in pass " << pass << " in technique " << technique << " in material \"" << material << "\"." << std::endl;
- }
else
- COUT(2) << "Warning: No pass " << pass << " in technique " << technique << " in material \"" << material << "\" or pass has no shader." << std::endl;
+ COUT(2) << "Warning: No pass " << it->pass_ << " in technique " << it->technique_ << " in compositor \"" << this->compositorName_ << "\" or pass has no shader." << std::endl;
}
else
- COUT(2) << "Warning: No technique " << technique << " in material \"" << material << "\" or technique has no pass with shader." << std::endl;
+ COUT(2) << "Warning: No technique " << it->technique_ << " in compositor \"" << this->compositorName_ << "\" or technique has no pass with shader." << std::endl;
}
- else
- {
- bool foundAtLeastOneShaderParameter = false;
- Ogre::MaterialManager::ResourceMapIterator iterator = Ogre::MaterialManager::getSingleton().getResourceIterator();
- Ogre::Material* material_pointer = 0;
-
- while (iterator.hasMoreElements())
- {
- Ogre::Resource* resource = iterator.getNext().get();
- if (resource->getName() == material)
- material_pointer = (Ogre::Material*)resource;
- }
-
- if (!material_pointer)
- {
- COUT(2) << "Warning: No material with name \"" << material << "\" found." << std::endl;
- return 0;
- }
-
- for (unsigned int t = 0; t < material_pointer->getNumTechniques(); ++t)
- {
- Ogre::Technique* technique_pointer = material_pointer->getTechnique(t);
- if (!technique_pointer)
- continue;
-
- for (unsigned int p = 0; p < technique_pointer->getNumPasses(); ++p)
- {
- Ogre::Pass* pass_pointer = technique_pointer->getPass(p);
- if (!pass_pointer)
- continue;
-
- if (!pass_pointer->getFragmentProgramName().empty())
- {
- Ogre::GpuProgramParameters* parameter_pointer = pass_pointer->getFragmentProgramParameters().get();
- if (!parameter_pointer)
- continue;
-
- const Ogre::GpuConstantDefinitionMap& constant_definitions = parameter_pointer->getConstantDefinitions().map;
- for (Ogre::GpuConstantDefinitionMap::const_iterator definition_iterator = constant_definitions.begin(); definition_iterator != constant_definitions.end(); ++definition_iterator)
- {
- void* temp = (definition_iterator->second.isFloat())
- ? static_cast<void*>(parameter_pointer->getFloatPointer(definition_iterator->second.physicalIndex))
- : static_cast<void*>(parameter_pointer->getIntPointer(definition_iterator->second.physicalIndex));
- ParameterPointer parameter_pointer = ParameterPointer(definition_iterator->second.isFloat(), temp);
-
- TechniqueVector& technique_vector = Shader::parameters_s[material];
- technique_vector.resize(technique + 1);
- PassVector& pass_vector = technique_vector[technique];
- pass_vector.resize(pass + 1);
- pass_vector[pass][definition_iterator->first] = parameter_pointer;
- foundAtLeastOneShaderParameter = true;
- }
- }
- }
- }
-
- // recursive call if the material was added to the map
- if (foundAtLeastOneShaderParameter)
- return Shader::getParameterPointer(material, technique, pass, parameter);
- }
- return 0;
+ this->parameters_.clear();
}
+ /**
+ @brief Detects if the Cg program manager plugin is active.
+ */
/* static */ bool Shader::hasCgProgramManager()
{
if (Ogre::Root::getSingletonPtr())
Modified: code/branches/usability/src/libraries/tools/Shader.h
===================================================================
--- code/branches/usability/src/libraries/tools/Shader.h 2011-02-26 20:53:23 UTC (rev 7975)
+++ code/branches/usability/src/libraries/tools/Shader.h 2011-02-27 00:05:59 UTC (rev 7976)
@@ -35,23 +35,24 @@
#include <string>
#include <vector>
+#include <OgreCompositorInstance.h>
+
#include "util/OgreForwardRefs.h"
#include "core/ViewportEventListener.h"
namespace orxonox
{
- class _ToolsExport Shader : public ViewportEventListener
+ /**
+ @brief Shader is a wrapper class around Ogre::CompositorInstance. It provides some
+ functions to easily change the visibility and parameters for shader programs.
+ */
+ class _ToolsExport Shader : public ViewportEventListener, public Ogre::CompositorInstance::Listener
{
- typedef std::pair<bool, void*> ParameterPointer;
- typedef std::map<std::string, ParameterPointer> ParameterMap;
- typedef std::vector<ParameterMap> PassVector;
- typedef std::vector<PassVector> TechniqueVector;
- typedef std::map<std::string, TechniqueVector> MaterialMap;
-
public:
Shader(Ogre::SceneManager* scenemanager = 0);
virtual ~Shader();
+ /// Defines if the shader is visible or not.
inline void setVisible(bool bVisible)
{
if (this->bVisible_ != bVisible)
@@ -60,10 +61,12 @@
this->updateVisibility();
}
}
+ /// Returns whether or not the shader is visible.
inline bool isVisible() const
{ return this->bVisible_; }
void updateVisibility();
+ /// Defines the compositor's name (located in a .compositor file).
inline void setCompositorName(const std::string& name)
{
if (this->compositorName_ != name)
@@ -72,40 +75,54 @@
this->changedCompositorName();
}
}
+ /// Returns the compositor's name.
inline const std::string& getCompositorName() const
{ return this->compositorName_; }
void changedCompositorName();
void changedCompositorName(Ogre::Viewport* viewport);
+ /// Sets the scenemanager (usually provided in the constructor, but can be set later). Shouldn't be changed once it's set.
inline void setSceneManager(Ogre::SceneManager* scenemanager)
{ this->scenemanager_ = scenemanager; }
+ /// Returns the scene manager.
inline Ogre::SceneManager* getSceneManager() const
{ return this->scenemanager_; }
virtual void cameraChanged(Ogre::Viewport* viewport, Ogre::Camera* oldCamera);
- void setParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter, float value);
- void setParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter, int value);
+ void setParameter(size_t technique, size_t pass, const std::string& parameter, float value);
+ void setParameter(size_t technique, size_t pass, const std::string& parameter, int value);
- static bool _setParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter, float value);
- static bool _setParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter, int value);
- static float getParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter);
- static bool getParameterIsFloat(const std::string& material, size_t technique, size_t pass, const std::string& parameter);
- static bool getParameterIsInt (const std::string& material, size_t technique, size_t pass, const std::string& parameter);
- static ParameterPointer* getParameterPointer(const std::string& material, size_t technique, size_t pass, const std::string& parameter);
+ virtual void notifyMaterialRender(Ogre::uint32 pass_id, Ogre::MaterialPtr& materialPtr);
private:
static bool hasCgProgramManager();
- Ogre::SceneManager* scenemanager_;
- Ogre::CompositorInstance* compositorInstance_;
- bool bVisible_;
- bool bLoadCompositor_;
- std::string compositorName_;
- std::string oldcompositorName_;
+ Ogre::SceneManager* scenemanager_; ///< The scenemanager for which the shader is active
+ Ogre::CompositorInstance* compositorInstance_; ///< The compositor instance representing the wrapped compositor
+ bool bVisible_; ///< True if the shader should be visible
+ bool bLoadCompositor_; ///< True if the compositor should be loaded (usually false if no graphics)
+ std::string compositorName_; ///< The name of the current compositor
+ std::string oldcompositorName_; ///< The name of the previous compositor (used to unregister)
- static MaterialMap parameters_s;
- static bool bLoadedCgPlugin_s;
+ private:
+ void addAsListener();
+
+ /// Helper struct to store parameters for shader programs.
+ struct ParameterContainer
+ {
+ size_t technique_; ///< The ID of the technique
+ size_t pass_; ///< The ID of the pass
+ std::string parameter_; ///< The name of the parameter
+
+ int valueInt_; ///< The desired int value of the parameter
+ float valueFloat_; ///< The desired float value of the parameter
+
+ MT_Type::Value valueType_; ///< The type of the parameter (currently only int or float)
+ };
+
+ std::list<ParameterContainer> parameters_; ///< The list of parameters that should be set on the next update
+ bool registeredAsListener_; ///< True if the shader should register itself as listener at the compositor
};
}
Modified: code/branches/usability/src/orxonox/items/Engine.cc
===================================================================
--- code/branches/usability/src/orxonox/items/Engine.cc 2011-02-26 20:53:23 UTC (rev 7975)
+++ code/branches/usability/src/orxonox/items/Engine.cc 2011-02-27 00:05:59 UTC (rev 7976)
@@ -206,11 +206,11 @@
if (!this->boostBlur_ && this->ship_->hasLocalController() && this->ship_->hasHumanController())
{
this->boostBlur_ = new Shader(this->ship_->getScene()->getSceneManager());
- this->boostBlur_->setCompositor("Radial Blur");
+ this->boostBlur_->setCompositorName("Radial Blur");
}
if (this->boostBlur_ && this->maxSpeedFront_ != 0 && this->boostFactor_ != 1)
- this->boostBlur_->setParameter("Ogre/Compositor/Radial_Blur", 0, 0, "sampleStrength", this->blurStrength_ * clamp((-velocity.z - this->maxSpeedFront_) / ((this->boostFactor_ - 1) * this->maxSpeedFront_), 0.0f, 1.0f));
+ this->boostBlur_->setParameter(0, 0, "sampleStrength", this->blurStrength_ * clamp((-velocity.z - this->maxSpeedFront_) / ((this->boostFactor_ - 1) * this->maxSpeedFront_), 0.0f, 1.0f));
}
void Engine::changedActivity()
More information about the Orxonox-commit
mailing list