Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/resource/src/orxonox/tools/Shader.cc @ 5740

Last change on this file since 5740 was 3346, checked in by rgrieder, 15 years ago

Moved GraphicsManager and GUIManager to the core. Almost no actual code changes though, just moving (here was that Map-hack I had to move to GSGraphics).

  • Property svn:eol-style set to native
File size: 12.9 KB
Line 
1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *                    > www.orxonox.net <
4 *
5 *
6 *   License notice:
7 *
8 *   This program is free software; you can redistribute it and/or
9 *   modify it under the terms of the GNU General Public License
10 *   as published by the Free Software Foundation; either version 2
11 *   of the License, or (at your option) any later version.
12 *
13 *   This program is distributed in the hope that it will be useful,
14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *   GNU General Public License for more details.
17 *
18 *   You should have received a copy of the GNU General Public License
19 *   along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 *
22 *   Author:
23 *      Fabian 'x3n' Landau
24 *   Co-authors:
25 *      ...
26 *
27 */
28
29#include "Shader.h"
30
31#include <OgreCompositorManager.h>
32#include <OgreCompositorInstance.h>
33#include <OgreSceneManager.h>
34#include <OgreRoot.h>
35#include <OgrePlugin.h>
36#include <OgreMaterial.h>
37#include <OgreTechnique.h>
38#include <OgrePass.h>
39#include <OgreMaterialManager.h>
40
41#include "core/CoreIncludes.h"
42#include "core/GameMode.h"
43#include "core/GraphicsManager.h"
44
45namespace orxonox
46{
47    bool Shader::bLoadedCgPlugin_s = false;
48    Shader::MaterialMap Shader::parameters_s;
49
50    Shader::Shader(Ogre::SceneManager* scenemanager) : compositorInstance_(0)
51    {
52        RegisterObject(Shader);
53
54        this->scenemanager_ = scenemanager;
55        this->compositorInstance_ = 0;
56        this->bVisible_ = true;
57        this->bLoadCompositor_ = GameMode::showsGraphics();
58        this->bViewportInitialized_ = false;
59        this->compositor_ = "";
60        this->oldcompositor_ = "";
61
62        if (this->bLoadCompositor_ && Ogre::Root::getSingletonPtr())
63        {
64            Shader::bLoadedCgPlugin_s = false;
65            const Ogre::Root::PluginInstanceList& plugins = Ogre::Root::getSingleton().getInstalledPlugins();
66            for (size_t i = 0; i < plugins.size(); ++i)
67            {
68                if (plugins[i]->getName() == "Cg Program Manager")
69                {
70                    Shader::bLoadedCgPlugin_s = true;
71                    break;
72                }
73            }
74        }
75
76        this->bLoadCompositor_ &= Shader::bLoadedCgPlugin_s;
77    }
78
79    Shader::~Shader()
80    {
81
82        if (this->bLoadCompositor_ && this->compositorInstance_)
83        {
84            Ogre::Viewport* viewport = GraphicsManager::getInstance().getViewport();
85            assert(viewport);
86            Ogre::CompositorManager::getSingleton().removeCompositor(viewport, this->compositor_);
87        }
88
89    }
90
91    void Shader::setSceneManager(Ogre::SceneManager* scenemanager)
92    {
93        this->scenemanager_ = scenemanager;
94        this->bViewportInitialized_ = false;
95    }
96
97    void Shader::tick(float dt)
98    {
99        SUPER(Shader, tick, dt);
100
101        if (this->bLoadCompositor_ && !this->bViewportInitialized_ && this->scenemanager_ && this->scenemanager_->getCurrentViewport())
102        {
103            this->bViewportInitialized_ = true;
104            this->updateVisibility();
105        }
106    }
107
108    void Shader::changedCompositor()
109    {
110        if (this->bLoadCompositor_)
111        {
112            Ogre::Viewport* viewport = GraphicsManager::getInstance().getViewport();
113            assert(viewport);
114            if (this->oldcompositor_ != "")
115            {
116                Ogre::CompositorManager::getSingleton().removeCompositor(viewport, this->oldcompositor_);
117                this->compositorInstance_ = 0;
118            }
119            if (this->compositor_ != "")
120            {
121                this->compositorInstance_ = Ogre::CompositorManager::getSingleton().addCompositor(viewport, this->compositor_);
122                if (!this->compositorInstance_)
123                    COUT(2) << "Warning: Couldn't load compositor with name \"" << this->compositor_ << "\"." << std::endl;
124                Ogre::CompositorManager::getSingleton().setCompositorEnabled(viewport, this->compositor_, this->bViewportInitialized_ && this->isVisible());
125            }
126            this->oldcompositor_ = this->compositor_;
127        }
128    }
129
130    void Shader::updateVisibility()
131    {
132        if (this->compositorInstance_ && this->scenemanager_)
133            this->compositorInstance_->setEnabled(this->scenemanager_->getCurrentViewport() && this->isVisible());
134    }
135
136    void Shader::setParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter, float value)
137    {
138        if (Shader::_setParameter(material, technique, pass, parameter, value))
139        {
140            if (this->bViewportInitialized_ && this->compositorInstance_ && this->isVisible())
141            {
142                this->compositorInstance_->setEnabled(false);
143                this->compositorInstance_->setEnabled(true);
144            }
145        }
146    }
147
148    void Shader::setParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter, int value)
149    {
150        if (Shader::_setParameter(material, technique, pass, parameter, value))
151        {
152            if (this->bViewportInitialized_ && this->compositorInstance_ && this->isVisible())
153            {
154                this->compositorInstance_->setEnabled(false);
155                this->compositorInstance_->setEnabled(true);
156            }
157        }
158    }
159
160    bool Shader::_setParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter, float value)
161    {
162        ParameterPointer* pointer = Shader::getParameterPointer(material, technique, pass, parameter);
163        if (pointer)
164        {
165            if (pointer->first)
166            {
167                if ((*static_cast<float*>(pointer->second)) != value)
168                {
169                    (*static_cast<float*>(pointer->second)) = value;
170                    return true;
171                }
172            }
173            else
174            {
175                if ((*static_cast<int*>(pointer->second)) != static_cast<int>(value))
176                {
177                    (*static_cast<int*>(pointer->second)) = static_cast<int>(value);
178                    return true;
179                }
180            }
181        }
182        return false;
183    }
184
185    bool Shader::_setParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter, int value)
186    {
187        ParameterPointer* pointer = Shader::getParameterPointer(material, technique, pass, parameter);
188        if (pointer)
189        {
190            if (pointer->first)
191            {
192                if ((*static_cast<float*>(pointer->second)) != static_cast<float>(value))
193                {
194                    (*static_cast<float*>(pointer->second)) = static_cast<float>(value);
195                    return true;
196                }
197            }
198            else
199            {
200                if ((*static_cast<int*>(pointer->second)) != value)
201                {
202                    (*static_cast<int*>(pointer->second)) = value;
203                    return true;
204                }
205            }
206        }
207        return false;
208    }
209
210    float Shader::getParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter)
211    {
212        ParameterPointer* pointer = Shader::getParameterPointer(material, technique, pass, parameter);
213        if (pointer)
214        {
215            if (pointer->first)
216                return (*static_cast<float*>(pointer->second));
217            else
218                return static_cast<float>(*static_cast<int*>(pointer->second));
219        }
220        else
221            return 0;
222    }
223
224    bool Shader::getParameterIsFloat(const std::string& material, size_t technique, size_t pass, const std::string& parameter)
225    {
226        ParameterPointer* pointer = Shader::getParameterPointer(material, technique, pass, parameter);
227        if (pointer)
228            return pointer->first;
229        else
230            return false;
231    }
232
233    bool Shader::getParameterIsInt(const std::string& material, size_t technique, size_t pass, const std::string& parameter)
234    {
235        ParameterPointer* pointer = Shader::getParameterPointer(material, technique, pass, parameter);
236        if (pointer)
237            return (!pointer->first);
238        else
239            return false;
240    }
241
242    Shader::ParameterPointer* Shader::getParameterPointer(const std::string& material, size_t technique, size_t pass, const std::string& parameter)
243    {
244        if (!GameMode::showsGraphics() || !Shader::bLoadedCgPlugin_s)
245            return 0;
246
247        MaterialMap::iterator material_iterator = Shader::parameters_s.find(material);
248        if (material_iterator != Shader::parameters_s.end())
249        {
250            TechniqueVector& technique_vector = material_iterator->second;
251            if (technique < technique_vector.size())
252            {
253                PassVector& pass_vector = technique_vector[technique];
254                if (pass < pass_vector.size())
255                {
256                    ParameterMap& parameter_map = pass_vector[pass];
257                    ParameterMap::iterator parameter_iterator = parameter_map.find(parameter);
258
259                    if (parameter_iterator != parameter_map.end())
260                        return (&parameter_iterator->second);
261                    else
262                        COUT(2) << "Warning: No shader parameter \"" << parameter << "\" in pass " << pass << " in technique " << technique << " in material \"" << material << "\"." << std::endl;
263                }
264                else
265                    COUT(2) << "Warning: No pass " << pass << " in technique " << technique << " in material \"" << material << "\" or pass has no shader." << std::endl;
266            }
267            else
268                COUT(2) << "Warning: No technique " << technique << " in material \"" << material << "\" or technique has no pass with shader." << std::endl;
269        }
270        else
271        {
272            bool foundAtLeastOneShaderParameter = false;
273            Ogre::MaterialManager::ResourceMapIterator iterator = Ogre::MaterialManager::getSingleton().getResourceIterator();
274            Ogre::Material* material_pointer = 0;
275
276            while (iterator.hasMoreElements())
277            {
278                Ogre::Resource* resource = iterator.getNext().get();
279                if (resource->getName() == material)
280                    material_pointer = (Ogre::Material*)resource;
281            }
282
283            if (!material_pointer)
284            {
285                COUT(2) << "Warning: No material with name \"" << material << "\" found." << std::endl;
286                return 0;
287            }
288
289            for (unsigned int t = 0; t < material_pointer->getNumTechniques(); ++t)
290            {
291                Ogre::Technique* technique_pointer = material_pointer->getTechnique(t);
292                if (!technique_pointer)
293                    continue;
294
295                for (unsigned int p = 0; p < technique_pointer->getNumPasses(); ++p)
296                {
297                    Ogre::Pass* pass_pointer = technique_pointer->getPass(p);
298                    if (!pass_pointer)
299                        continue;
300
301                    if (pass_pointer->getFragmentProgramName() != "")
302                    {
303                        Ogre::GpuProgramParameters* parameter_pointer = pass_pointer->getFragmentProgramParameters().get();
304                        if (!parameter_pointer)
305                            continue;
306
307                        const Ogre::GpuConstantDefinitionMap& constant_definitions = parameter_pointer->getConstantDefinitions().map;
308                        for (Ogre::GpuConstantDefinitionMap::const_iterator definition_iterator = constant_definitions.begin(); definition_iterator != constant_definitions.end(); ++definition_iterator)
309                        {
310                            void* temp = (definition_iterator->second.isFloat())
311                                            ? static_cast<void*>(parameter_pointer->getFloatPointer(definition_iterator->second.physicalIndex))
312                                            : static_cast<void*>(parameter_pointer->getIntPointer(definition_iterator->second.physicalIndex));
313                            ParameterPointer parameter_pointer = ParameterPointer(definition_iterator->second.isFloat(), temp);
314
315                            TechniqueVector& technique_vector = Shader::parameters_s[material];
316                            technique_vector.resize(technique + 1);
317                            PassVector& pass_vector = technique_vector[technique];
318                            pass_vector.resize(pass + 1);
319                            pass_vector[pass][definition_iterator->first] = parameter_pointer;
320                            foundAtLeastOneShaderParameter = true;
321                        }
322                    }
323                }
324            }
325
326            // recursive call if the material was added to the map
327            if (foundAtLeastOneShaderParameter)
328                return Shader::getParameterPointer(material, technique, pass, parameter);
329        }
330        return 0;
331    }
332}
Note: See TracBrowser for help on using the repository browser.