Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Mar 15, 2011, 9:47:11 PM (13 years ago)
Author:
landauf
Message:

merged usability branch back to trunk

incomplete summary of the changes in this branch:

  • enhanced keyboard navigation in GUIs
  • implemented new graphics menu and changeable window size at runtime
  • added developer mode
  • HUD shows if game is paused, game pauses if ingame menu is opened
  • removed a few obsolete commands and hid some that are more for internal use
  • numpad works in console and gui
  • faster loading of level info
  • enhanced usage of compositors (Shader class)
  • improved camera handling, configurable FOV and aspect ratio
Location:
code/trunk
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • code/trunk

  • code/trunk/src/libraries/tools/ResourceLocation.cc

    r7709 r8079  
    3030
    3131#include <OgreResourceGroupManager.h>
     32#include <OgreException.h>
    3233#include <boost/filesystem.hpp>
    3334
  • code/trunk/src/libraries/tools/Shader.cc

    r6417 r8079  
    3030
    3131#include <OgreCompositorManager.h>
    32 #include <OgreCompositorInstance.h>
    33 #include <OgreSceneManager.h>
    3432#include <OgreRoot.h>
    3533#include <OgrePlugin.h>
    36 #include <OgreMaterial.h>
    37 #include <OgreTechnique.h>
    38 #include <OgrePass.h>
    39 #include <OgreMaterialManager.h>
    4034
    4135#include "core/CoreIncludes.h"
     
    4539namespace orxonox
    4640{
    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    */
    5044    Shader::Shader(Ogre::SceneManager* scenemanager) : compositorInstance_(0)
    5145    {
     
    5347
    5448        this->scenemanager_ = scenemanager;
    55         this->compositorInstance_ = 0;
    5649        this->bVisible_ = true;
    5750        this->bLoadCompositor_ = GameMode::showsGraphics();
    58         this->bViewportInitialized_ = false;
    59 
    60         if (this->bLoadCompositor_ && Ogre::Root::getSingletonPtr())
    61         {
    62             Shader::bLoadedCgPlugin_s = false;
     51        this->registeredAsListener_ = false;
     52
     53        static bool hasCgProgramManager = Shader::hasCgProgramManager();
     54
     55        this->bLoadCompositor_ &= hasCgProgramManager;
     56    }
     57
     58    /**
     59        @brief Removes the compositor and frees the resources.
     60    */
     61    Shader::~Shader()
     62    {
     63        if (this->compositorInstance_ && GraphicsManager::getInstance().getViewport())
     64            Ogre::CompositorManager::getSingleton().removeCompositor(GraphicsManager::getInstance().getViewport(), this->compositorName_);
     65    }
     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    */
     76    void Shader::cameraChanged(Ogre::Viewport* viewport, Ogre::Camera* oldCamera)
     77    {
     78        if (!this->bLoadCompositor_ || !this->scenemanager_)
     79            return;
     80
     81        // load the compositor if not already done
     82        if (!this->compositorName_.empty() && !this->compositorInstance_)
     83            this->changedCompositorName(viewport);
     84
     85        // update compositor in viewport (shader should only be active if the current camera is in the same scene as the shader)
     86
     87        // Note:
     88        // The shader needs also to be switched off and on after changing the camera in the
     89        // same scene to avoid weird behaviour with active compositors while switching the
     90        // camera (like freezing the image)
     91        //
     92        // Last known Ogre version needing this workaround:
     93        // 1.4.8
     94        // 1.7.2
     95
     96        if (oldCamera && this->scenemanager_ == oldCamera->getSceneManager())
     97            Ogre::CompositorManager::getSingleton().setCompositorEnabled(viewport, this->compositorName_, false);
     98
     99        if (viewport->getCamera() && this->scenemanager_ == viewport->getCamera()->getSceneManager())
     100            Ogre::CompositorManager::getSingleton().setCompositorEnabled(viewport, this->compositorName_, this->isVisible());
     101    }
     102
     103    /**
     104        @brief Changes the compositor - default viewport.
     105    */
     106    void Shader::changedCompositorName()
     107    {
     108        // For the moment, we get the viewport always from the graphics manager
     109        // TODO: Try to support multiple viewports - note however that scenemanager_->getCurrentViewport() returns NULL
     110        //       after switching to a camera in a different scene (only for the first time this scene is displayed though)
     111        this->changedCompositorName(GraphicsManager::getInstance().getViewport());
     112    }
     113
     114    /**
     115        @brief Changes the compositor.
     116    */
     117    void Shader::changedCompositorName(Ogre::Viewport* viewport)
     118    {
     119        if (this->bLoadCompositor_)
     120        {
     121            assert(viewport);
     122            if (this->compositorInstance_)
     123            {
     124                // remove the old compositor, remove the listener
     125                Ogre::CompositorManager::getSingleton().removeCompositor(viewport, this->oldcompositorName_);
     126                this->compositorInstance_->removeListener(this);
     127                this->compositorInstance_ = 0;
     128            }
     129            if (!this->compositorName_.empty())
     130            {
     131                // add the new compositor
     132                this->compositorInstance_ = Ogre::CompositorManager::getSingleton().addCompositor(viewport, this->compositorName_);
     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
     143                    COUT(2) << "Warning: Couldn't load compositor with name \"" << this->compositorName_ << "\"." << std::endl;
     144            }
     145            this->oldcompositorName_ = this->compositorName_;
     146        }
     147    }
     148
     149    /**
     150        @brief Changes the visibility of the shader. Doesn't free any resources if set to invisible.
     151    */
     152    void Shader::updateVisibility()
     153    {
     154        if (this->compositorInstance_)
     155            Ogre::CompositorManager::getSingleton().setCompositorEnabled(GraphicsManager::getInstance().getViewport(), this->compositorName_, this->isVisible());
     156    }
     157
     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)
     201            {
     202                Ogre::Pass* passPtr = techniquePtr->getPass(it->pass_);
     203                if (passPtr)
     204                {
     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                    }
     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;
     220            }
     221            else
     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    */
     230    /* static */ bool Shader::hasCgProgramManager()
     231    {
     232        if (Ogre::Root::getSingletonPtr())
     233        {
    63234            const Ogre::Root::PluginInstanceList& plugins = Ogre::Root::getSingleton().getInstalledPlugins();
    64235            for (size_t i = 0; i < plugins.size(); ++i)
    65             {
    66236                if (plugins[i]->getName() == "Cg Program Manager")
    67                 {
    68                     Shader::bLoadedCgPlugin_s = true;
    69                     break;
    70                 }
    71             }
    72         }
    73 
    74         this->bLoadCompositor_ &= Shader::bLoadedCgPlugin_s;
    75     }
    76 
    77     Shader::~Shader()
    78     {
    79         if (this->compositorInstance_ && this->bLoadCompositor_)
    80         {
    81             Ogre::Viewport* viewport = GraphicsManager::getInstance().getViewport();
    82             assert(viewport);
    83             Ogre::CompositorManager::getSingleton().removeCompositor(viewport, this->compositor_);
    84         }
    85 
    86     }
    87 
    88     void Shader::setSceneManager(Ogre::SceneManager* scenemanager)
    89     {
    90         this->scenemanager_ = scenemanager;
    91         this->bViewportInitialized_ = false;
    92     }
    93 
    94     void Shader::tick(float dt)
    95     {
    96         SUPER(Shader, tick, dt);
    97 
    98         if (this->bLoadCompositor_ && !this->bViewportInitialized_ && this->scenemanager_ && this->scenemanager_->getCurrentViewport())
    99         {
    100             this->bViewportInitialized_ = true;
    101             this->updateVisibility();
    102         }
    103     }
    104 
    105     void Shader::changedCompositor()
    106     {
    107         if (this->bLoadCompositor_)
    108         {
    109             Ogre::Viewport* viewport = GraphicsManager::getInstance().getViewport();
    110             assert(viewport);
    111             if (!this->oldcompositor_.empty())
    112             {
    113                 Ogre::CompositorManager::getSingleton().removeCompositor(viewport, this->oldcompositor_);
    114                 this->compositorInstance_ = 0;
    115             }
    116             if (!this->compositor_.empty())
    117             {
    118                 this->compositorInstance_ = Ogre::CompositorManager::getSingleton().addCompositor(viewport, this->compositor_);
    119                 if (!this->compositorInstance_)
    120                     COUT(2) << "Warning: Couldn't load compositor with name \"" << this->compositor_ << "\"." << std::endl;
    121                 Ogre::CompositorManager::getSingleton().setCompositorEnabled(viewport, this->compositor_, this->bViewportInitialized_ && this->isVisible());
    122             }
    123             this->oldcompositor_ = this->compositor_;
    124         }
    125     }
    126 
    127     void Shader::updateVisibility()
    128     {
    129         if (this->compositorInstance_ && this->scenemanager_)
    130             this->compositorInstance_->setEnabled(this->scenemanager_->getCurrentViewport() && this->isVisible());
    131     }
    132 
    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->bViewportInitialized_ && this->compositorInstance_ && this->isVisible())
    138             {
    139                 this->compositorInstance_->setEnabled(false);
    140                 this->compositorInstance_->setEnabled(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->bViewportInitialized_ && this->compositorInstance_ && this->isVisible())
    150             {
    151                 this->compositorInstance_->setEnabled(false);
    152                 this->compositorInstance_->setEnabled(true);
    153             }
    154         }
    155     }
    156 
    157     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)
    165                 {
    166                     (*static_cast<float*>(pointer->second)) = value;
    167237                    return true;
    168                 }
    169             }
    170             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             }
    178238        }
    179239        return false;
    180240    }
    181 
    182     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     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     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     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     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 (&parameter_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     }
    329241}
  • code/trunk/src/libraries/tools/Shader.h

    r5781 r8079  
    3636#include <vector>
    3737
     38#include <OgreCompositorInstance.h>
     39
     40#include "util/MultiType.h"
    3841#include "util/OgreForwardRefs.h"
    39 #include "tools/interfaces/Tickable.h"
     42#include "core/ViewportEventListener.h"
    4043
    4144namespace orxonox
    4245{
    43     class _ToolsExport Shader : public Tickable
     46    /**
     47        @brief Shader is a wrapper class around Ogre::CompositorInstance. It provides some
     48        functions to easily change the visibility and parameters for shader programs.
     49    */
     50    class _ToolsExport Shader : public ViewportEventListener, public Ogre::CompositorInstance::Listener
    4451    {
    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 
    5152        public:
    5253            Shader(Ogre::SceneManager* scenemanager = 0);
    5354            virtual ~Shader();
    5455
    55             virtual void tick(float dt);
    56 
     56            /// Defines if the shader is visible or not.
    5757            inline void setVisible(bool bVisible)
    5858            {
     
    6363                }
    6464            }
     65            /// Returns whether or not the shader is visible.
    6566            inline bool isVisible() const
    6667                { return this->bVisible_; }
    6768            void updateVisibility();
    6869
    69             inline void setCompositor(const std::string& compositor)
     70            /// Defines the compositor's name (located in a .compositor file).
     71            inline void setCompositorName(const std::string& name)
    7072            {
    71                 if (this->compositor_ != compositor)
     73                if (this->compositorName_ != name)
    7274                {
    73                     this->compositor_ = compositor;
    74                     this->changedCompositor();
     75                    this->compositorName_ = name;
     76                    this->changedCompositorName();
    7577                }
    7678            }
    77             inline const std::string& getCompositor() const
    78                 { return this->compositor_; }
    79             void changedCompositor();
     79            /// Returns the compositor's name.
     80            inline const std::string& getCompositorName() const
     81                { return this->compositorName_; }
     82            void changedCompositorName();
     83            void changedCompositorName(Ogre::Viewport* viewport);
    8084
    81             void setSceneManager(Ogre::SceneManager* scenemanager);
     85            /// Sets the scenemanager (usually provided in the constructor, but can be set later). Shouldn't be changed once it's set.
     86            inline void setSceneManager(Ogre::SceneManager* scenemanager)
     87                { this->scenemanager_ = scenemanager; }
     88            /// Returns the scene manager.
    8289            inline Ogre::SceneManager* getSceneManager() const
    8390                { return this->scenemanager_; }
    8491
    85             void setParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter, float value);
    86             void setParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter, int value);
     92            virtual void cameraChanged(Ogre::Viewport* viewport, Ogre::Camera* oldCamera);
    8793
    88             static bool _setParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter, float value);
    89             static bool _setParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter, int value);
    90             static float getParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter);
    91             static bool  getParameterIsFloat(const std::string& material, size_t technique, size_t pass, const std::string& parameter);
    92             static bool  getParameterIsInt  (const std::string& material, size_t technique, size_t pass, const std::string& parameter);
    93             static ParameterPointer* getParameterPointer(const std::string& material, size_t technique, size_t pass, const std::string& parameter);
     94            void setParameter(size_t technique, size_t pass, const std::string& parameter, float value);
     95            void setParameter(size_t technique, size_t pass, const std::string& parameter, int value);
     96
     97            virtual void notifyMaterialRender(Ogre::uint32 pass_id, Ogre::MaterialPtr& materialPtr);
    9498
    9599        private:
    96             Ogre::SceneManager* scenemanager_;
    97             Ogre::CompositorInstance* compositorInstance_;
    98             bool bVisible_;
    99             bool bLoadCompositor_;
    100             bool bViewportInitialized_;
    101             std::string compositor_;
    102             std::string oldcompositor_;
     100            static bool hasCgProgramManager();
    103101
    104             static MaterialMap parameters_s;
    105             static bool bLoadedCgPlugin_s;
     102            Ogre::SceneManager* scenemanager_;              ///< The scenemanager for which the shader is active
     103            Ogre::CompositorInstance* compositorInstance_;  ///< The compositor instance representing the wrapped compositor
     104            bool bVisible_;                                 ///< True if the shader should be visible
     105            bool bLoadCompositor_;                          ///< True if the compositor should be loaded (usually false if no graphics)
     106            std::string compositorName_;                    ///< The name of the current compositor
     107            std::string oldcompositorName_;                 ///< The name of the previous compositor (used to unregister)
     108
     109        private:
     110            void addAsListener();
     111
     112            /// Helper struct to store parameters for shader programs.
     113            struct ParameterContainer
     114            {
     115                size_t technique_;          ///< The ID of the technique
     116                size_t pass_;               ///< The ID of the pass
     117                std::string parameter_;     ///< The name of the parameter
     118
     119                int valueInt_;              ///< The desired int value of the parameter
     120                float valueFloat_;          ///< The desired float value of the parameter
     121
     122                MT_Type::Value valueType_;  ///< The type of the parameter (currently only int or float)
     123            };
     124
     125            std::list<ParameterContainer> parameters_;  ///< The list of parameters that should be set on the next update
     126            bool registeredAsListener_;                 ///< True if the shader should register itself as listener at the compositor
    106127    };
    107128}
  • code/trunk/src/libraries/tools/Timer.cc

    r7401 r8079  
    3535
    3636#include <set>
     37
     38#include <boost/bimap.hpp>
    3739
    3840#include "util/Clock.h"
     
    4143#include "core/command/CommandExecutor.h"
    4244#include "core/command/Functor.h"
     45#include "tools/interfaces/TimeFactorListener.h"
    4346
    4447namespace orxonox
    4548{
    4649    SetConsoleCommand("delay", &delay).argumentCompleter(1, autocompletion::command());
     50    SetConsoleCommand("delayreal", &delayreal).argumentCompleter(1, autocompletion::command());
     51    SetConsoleCommand("killdelay", &killdelay);
    4752    SetConsoleCommand("killdelays", &killdelays);
    4853
    49     static std::set<Timer*> delaytimerset;
    50 
    51     /**
    52         @brief Console-command: Calls another console command after @a delay seconds.
     54    static boost::bimap<unsigned int, Timer*> delaytimers;
     55    static unsigned int delayHandleCounter = 0;
     56
     57    /**
     58        @brief Console-command: Calls another console command after @a delay seconds (game time).
    5359        @param delay The delay in seconds
    5460        @param command The console command
    55     */
    56     void delay(float delay, const std::string& command)
    57     {
    58         Timer* delaytimer = new Timer();
    59         delaytimerset.insert(delaytimer);
     61        @return The handle of the delayed command, can be used as argument for killdelay()
     62    */
     63    unsigned int delay(float delay, const std::string& command)
     64    {
     65        return addDelayedCommand(new Timer(), delay, command);
     66    }
     67
     68    /**
     69        @brief Console-command: Calls another console command after @a delay seconds (real time)
     70        @param delay The delay in seconds
     71        @param command The console command
     72        @return The handle of the delayed command, can be used as argument for killdelay()
     73    */
     74    unsigned int delayreal(float delay, const std::string& command)
     75    {
     76        return addDelayedCommand(new RealTimer(), delay, command);
     77    }
     78
     79    /**
     80        @brief Helper function, used by delay() and delayreal() to add a delayed command.
     81        @param timer The timer which will execute the command
     82        @param delay The delay in seconds
     83        @param command The console command
     84        @return The handle of the delayed command, can be used as argument for killdelay()
     85    */
     86    unsigned int addDelayedCommand(Timer* timer, float delay, const std::string& command)
     87    {
     88        delaytimers.insert(boost::bimap<unsigned int, Timer*>::value_type(++delayHandleCounter, timer));
    6089
    6190        const ExecutorStaticPtr& delayexecutor = createExecutor(createFunctor(&executeDelayedCommand));
    62         delayexecutor->setDefaultValues(delaytimer, command);
    63         delaytimer->setTimer(delay, false, delayexecutor);
     91        delayexecutor->setDefaultValues(timer, command);
     92        timer->setTimer(delay, false, delayexecutor);
     93
     94        return delayHandleCounter;
    6495    }
    6596
     
    73104        CommandExecutor::execute(command);
    74105        timer->destroy();
    75         delaytimerset.erase(timer);
     106        delaytimers.right.erase(timer);
    76107    }
    77108
     
    81112    void killdelays()
    82113    {
    83         for (std::set<Timer*>::iterator it = delaytimerset.begin(); it != delaytimerset.end(); ++it)
    84             (*it)->destroy();
    85 
    86         delaytimerset.clear();
     114        for (boost::bimap<unsigned int, Timer*>::left_map::iterator it = delaytimers.left.begin(); it != delaytimers.left.end(); ++it)
     115            it->second->destroy();
     116
     117        delaytimers.clear();
     118    }
     119
     120    /**
     121        @brief Console-command: Kills a delayed command with given handle.
     122    */
     123    void killdelay(unsigned int handle)
     124    {
     125        boost::bimap<unsigned int, Timer*>::left_map::iterator it = delaytimers.left.find(handle);
     126        if (it != delaytimers.left.end())
     127        {
     128            it->second->destroy();
     129            delaytimers.left.erase(it);
     130        }
    87131    }
    88132
     
    93137    {
    94138        this->init();
    95         RegisterObject(Timer);
     139        RegisterRootObject(Timer);
    96140    }
    97141
     
    106150    {
    107151        this->init();
    108         RegisterObject(Timer);
     152        RegisterRootObject(Timer);
    109153
    110154        this->setTimer(interval, bLoop, executor, bKillAfterCall);
     
    123167
    124168        this->time_ = 0;
     169    }
     170
     171    /**
     172        @brief Returns the current time factor of the game.
     173    */
     174    float Timer::getTimeFactor()
     175    {
     176        return TimeFactorListener::getTimeFactor();
    125177    }
    126178
     
    168220        }
    169221    }
     222
     223    ///////////////
     224    // RealTimer //
     225    ///////////////
     226    /// @copydoc Timer::Timer
     227    RealTimer::RealTimer()
     228    {
     229        RegisterObject(RealTimer);
     230    }
     231
     232    /// @copydoc Timer::Timer(float, bool, const ExecutorPtr&, bool)
     233    RealTimer::RealTimer(float interval, bool bLoop, const ExecutorPtr& executor, bool bKillAfterCall) : Timer(interval, bLoop, executor, bKillAfterCall)
     234    {
     235        RegisterObject(RealTimer);
     236    }
     237
     238    /// Returns always 1 because RealTimer doesn't depend on the game time.
     239    float RealTimer::getTimeFactor()
     240    {
     241        return 1;
     242    }
    170243}
  • code/trunk/src/libraries/tools/Timer.h

    r7851 r8079  
    8181#include "core/OrxonoxClass.h"
    8282#include "core/command/Executor.h"
    83 #include "tools/interfaces/TimeFactorListener.h"
    8483
    8584namespace orxonox
    8685{
    87     void delay(float delay, const std::string& command);
    88     void killdelays();
     86    unsigned int delay(float delay, const std::string& command);
     87    unsigned int delayreal(float delay, const std::string& command);
     88
     89    unsigned int addDelayedCommand(Timer* timer, float delay, const std::string& command);
    8990    void executeDelayedCommand(Timer* timer, const std::string& command);
    9091
     92    void killdelay(unsigned int handle);
     93    void killdelays();
     94
    9195    /**
    92         @brief Timer is a helper class that executes a function after a given amount of time.
     96        @brief Timer is a helper class that executes a function after a given amount of seconds in game-time.
    9397
    9498        @see See @ref TimerExample "Timer.h" for an example.
     99
     100        The time interval of Timer depends on the game time, hence it stops if the game is paused or runs
     101        slower/faster if the game-speed is modified. See RealTimer for a timer class which doesn't depend
     102        on the game time.
    95103    */
    96     class _ToolsExport Timer : public TimeFactorListener
     104    class _ToolsExport Timer : virtual public OrxonoxClass
    97105    {
    98106        public:
     
    123131            void run();
    124132
    125             /// Re-starts the Timer: The executor will be called after @a interval seconds.
     133            /// Re-starts the timer: The executor will be called after @a interval seconds.
    126134            inline void startTimer()
    127135                { this->bActive_ = true; this->time_ = this->interval_; }
    128             /// Stops the Timer.
     136            /// Stops the timer.
    129137            inline void stopTimer()
    130138                { this->bActive_ = false; this->time_ = this->interval_; }
    131             /// Pauses the Timer - it will continue with the actual state if you call unpauseTimer().
     139            /// Pauses the timer - it will continue with the actual state if you call unpauseTimer().
    132140            inline void pauseTimer()
    133141                { this->bActive_ = false; }
    134             /// Unpauses the Timer - continues with the given state.
     142            /// Unpauses the timer - continues with the given state.
    135143            inline void unpauseTimer()
    136144                { this->bActive_ = true; }
    137             /// Returns true if the Timer is active (neither stopped nor paused).
     145            /// Returns true if the timer is active (neither stopped nor paused).
    138146            inline bool isActive() const
    139147                { return this->bActive_; }
    140             /// Returns the remaining time until the Timer calls the executor.
     148            /// Returns the remaining time until the timer calls the executor.
    141149            inline float getRemainingTime() const
    142150                { return static_cast<float>(this->time_ / 1000000.0f); }
    143             /// Increases the remaining time of the Timer by the given amount of time (in seconds).
     151            /// Increases the remaining time of the timer by the given amount of time (in seconds).
    144152            inline void addTime(float time)
    145153                { if (time > 0.0f) this->time_ += static_cast<long long>(time * 1000000.0f); }
    146             /// Decreases the remaining time of the Timer by the given amount of time (in seconds)
     154            /// Decreases the remaining time of the timer by the given amount of time (in seconds)
    147155            inline void removeTime(float time)
    148156                { if (time > 0.0f) this->time_ -= static_cast<long long>(time * 1000000.0f); }
     
    156164            void tick(const Clock& time);
    157165
     166        protected:
     167            virtual float getTimeFactor();
     168
    158169        private:
    159170            void init();
     
    163174            long long interval_;    //!< The time-interval in micro seconds
    164175            bool bLoop_;            //!< If true, the executor gets called every @a interval seconds
    165             bool bActive_;          //!< If true, the Timer ticks and calls the executor if the time's up
     176            bool bActive_;          //!< If true, the timer ticks and calls the executor if the time's up
    166177            bool bKillAfterCall_;   //!< If true the timer gets deleted after it expired and called the executor
    167178
    168179            long long time_;        //!< Internal variable, counting the time untill the next executor-call
    169180    };
     181
     182    /**
     183        @brief RealTimer is a helper class that executes a function after a given amount of seconds in real-time.
     184
     185        The time interval of RealTimer doesn't depend on the game time, it will also call the function
     186        if the game is paused. See Timer for a timer class that depends on the game time.
     187    */
     188    class _ToolsExport RealTimer : public Timer
     189    {
     190        public:
     191            RealTimer();
     192            RealTimer(float interval, bool bLoop, const ExecutorPtr& executor, bool bKillAfterCall = false);
     193
     194        protected:
     195            virtual float getTimeFactor();
     196    };
    170197}
    171198
  • code/trunk/src/libraries/tools/ToolsPrereqs.h

    r7163 r8079  
    8585    class Mesh;
    8686    class ParticleInterface;
     87    class RealTimer;
    8788    class ResourceCollection;
    8889    class ResourceLocation;
Note: See TracChangeset for help on using the changeset viewer.