Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/orxonox/tools/Shader.cc @ 3149

Last change on this file since 3149 was 3110, checked in by rgrieder, 15 years ago

Removed old msvc specific support for precompiled header files.

  • Property svn:eol-style set to native
File size: 12.7 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
37#include "core/GameMode.h"
38#include "core/CoreIncludes.h"
39#include "core/Executor.h"
40#include "GraphicsManager.h"
41#include "util/Exception.h"
42
43#include <OgreMaterial.h>
44#include <OgreTechnique.h>
45#include <OgrePass.h>
46#include <OgreMaterialManager.h>
47
48namespace orxonox
49{
50    bool Shader::bLoadedCgPlugin_s = false;
51    Shader::MaterialMap Shader::parameters_s;
52
53    Shader::Shader(Ogre::SceneManager* scenemanager) : compositorInstance_(0)
54    {
55        RegisterObject(Shader);
56
57        this->scenemanager_ = scenemanager;
58        this->compositorInstance_ = 0;
59        this->bVisible_ = true;
60        this->bLoadCompositor_ = GameMode::showsGraphics();
61        this->bViewportInitialized_ = false;
62        this->compositor_ = "";
63        this->oldcompositor_ = "";
64
65        if (this->bLoadCompositor_ && Ogre::Root::getSingletonPtr())
66        {
67            Shader::bLoadedCgPlugin_s = false;
68            const Ogre::Root::PluginInstanceList& plugins = Ogre::Root::getSingleton().getInstalledPlugins();
69            for (size_t i = 0; i < plugins.size(); ++i)
70            {
71                if (plugins[i]->getName() == "Cg Program Manager")
72                {
73                    Shader::bLoadedCgPlugin_s = true;
74                    break;
75                }
76            }
77        }
78
79        this->bLoadCompositor_ &= Shader::bLoadedCgPlugin_s;
80    }
81
82    Shader::~Shader()
83    {
84
85        if (this->bLoadCompositor_ && this->compositorInstance_)
86        {
87            Ogre::Viewport* viewport = GraphicsManager::getInstance().getViewport();
88            assert(viewport);
89            Ogre::CompositorManager::getSingleton().removeCompositor(viewport, this->compositor_);
90        }
91
92    }
93
94    void Shader::setSceneManager(Ogre::SceneManager* scenemanager)
95    {
96        this->scenemanager_ = scenemanager;
97        this->bViewportInitialized_ = false;
98    }
99
100    void Shader::tick(float dt)
101    {
102        SUPER(Shader, tick, dt);
103
104        if (this->bLoadCompositor_ && !this->bViewportInitialized_ && this->scenemanager_ && this->scenemanager_->getCurrentViewport())
105        {
106            this->bViewportInitialized_ = true;
107            this->updateVisibility();
108        }
109    }
110
111    void Shader::changedCompositor()
112    {
113        if (this->bLoadCompositor_)
114        {
115            Ogre::Viewport* viewport = GraphicsManager::getInstance().getViewport();
116            assert(viewport);
117            if (this->oldcompositor_ != "")
118            {
119                Ogre::CompositorManager::getSingleton().removeCompositor(viewport, this->oldcompositor_);
120                this->compositorInstance_ = 0;
121            }
122            if (this->compositor_ != "")
123            {
124                this->compositorInstance_ = Ogre::CompositorManager::getSingleton().addCompositor(viewport, this->compositor_);
125                if (!this->compositorInstance_)
126                    COUT(2) << "Warning: Couldn't load compositor with name \"" << this->compositor_ << "\"." << std::endl;
127                Ogre::CompositorManager::getSingleton().setCompositorEnabled(viewport, this->compositor_, this->bViewportInitialized_ && this->isVisible());
128            }
129            this->oldcompositor_ = this->compositor_;
130        }
131    }
132
133    void Shader::updateVisibility()
134    {
135        if (this->compositorInstance_ && this->scenemanager_)
136            this->compositorInstance_->setEnabled(this->scenemanager_->getCurrentViewport() && this->isVisible());
137    }
138
139    void Shader::setParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter, float value)
140    {
141        if (Shader::_setParameter(material, technique, pass, parameter, value))
142        {
143            if (this->bViewportInitialized_ && this->compositorInstance_ && this->isVisible())
144            {
145                this->compositorInstance_->setEnabled(false);
146                this->compositorInstance_->setEnabled(true);
147            }
148        }
149    }
150
151    void Shader::setParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter, int value)
152    {
153        if (Shader::_setParameter(material, technique, pass, parameter, value))
154        {
155            if (this->bViewportInitialized_ && this->compositorInstance_ && this->isVisible())
156            {
157                this->compositorInstance_->setEnabled(false);
158                this->compositorInstance_->setEnabled(true);
159            }
160        }
161    }
162
163    bool Shader::_setParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter, float value)
164    {
165        ParameterPointer* pointer = Shader::getParameterPointer(material, technique, pass, parameter);
166        if (pointer)
167        {
168            if (pointer->first)
169            {
170                if ((*((float*)pointer->second)) != value)
171                {
172                    (*((float*)pointer->second)) = value;
173                    return true;
174                }
175            }
176            else
177            {
178                if ((*((int*)pointer->second)) != (int)value)
179                {
180                    (*((int*)pointer->second)) = (int)value;
181                    return true;
182                }
183            }
184        }
185        return false;
186    }
187
188    bool Shader::_setParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter, int value)
189    {
190        ParameterPointer* pointer = Shader::getParameterPointer(material, technique, pass, parameter);
191        if (pointer)
192        {
193            if (pointer->first)
194            {
195                if ((*((float*)pointer->second)) != (float)value)
196                {
197                    (*((float*)pointer->second)) = (float)value;
198                    return true;
199                }
200            }
201            else
202            {
203                if ((*((int*)pointer->second)) != value)
204                {
205                    (*((int*)pointer->second)) = value;
206                    return true;
207                }
208            }
209        }
210        return false;
211    }
212
213    float Shader::getParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter)
214    {
215        ParameterPointer* pointer = Shader::getParameterPointer(material, technique, pass, parameter);
216        if (pointer)
217        {
218            if (pointer->first)
219                return (*((float*)pointer->second));
220            else
221                return (*((int*)pointer->second));
222        }
223        else
224            return 0;
225    }
226
227    bool Shader::getParameterIsFloat(const std::string& material, size_t technique, size_t pass, const std::string& parameter)
228    {
229        ParameterPointer* pointer = Shader::getParameterPointer(material, technique, pass, parameter);
230        if (pointer)
231            return pointer->first;
232        else
233            return false;
234    }
235
236    bool Shader::getParameterIsInt(const std::string& material, size_t technique, size_t pass, const std::string& parameter)
237    {
238        ParameterPointer* pointer = Shader::getParameterPointer(material, technique, pass, parameter);
239        if (pointer)
240            return (!pointer->first);
241        else
242            return false;
243    }
244
245    Shader::ParameterPointer* Shader::getParameterPointer(const std::string& material, size_t technique, size_t pass, const std::string& parameter)
246    {
247        if (!GameMode::showsGraphics() || !Shader::bLoadedCgPlugin_s)
248            return 0;
249
250        MaterialMap::iterator material_iterator = Shader::parameters_s.find(material);
251        if (material_iterator != Shader::parameters_s.end())
252        {
253            TechniqueVector& technique_vector = material_iterator->second;
254            if (technique < technique_vector.size())
255            {
256                PassVector& pass_vector = technique_vector[technique];
257                if (pass < pass_vector.size())
258                {
259                    ParameterMap& parameter_map = pass_vector[pass];
260                    ParameterMap::iterator parameter_iterator = parameter_map.find(parameter);
261
262                    if (parameter_iterator != parameter_map.end())
263                        return (&parameter_iterator->second);
264                    else
265                        COUT(2) << "Warning: No shader parameter \"" << parameter << "\" in pass " << pass << " in technique " << technique << " in material \"" << material << "\"." << std::endl;
266                }
267                else
268                    COUT(2) << "Warning: No pass " << pass << " in technique " << technique << " in material \"" << material << "\" or pass has no shader." << std::endl;
269            }
270            else
271                COUT(2) << "Warning: No technique " << technique << " in material \"" << material << "\" or technique has no pass with shader." << std::endl;
272        }
273        else
274        {
275            bool foundAtLeastOneShaderParameter = false;
276            Ogre::MaterialManager::ResourceMapIterator iterator = Ogre::MaterialManager::getSingleton().getResourceIterator();
277            Ogre::Material* material_pointer = 0;
278
279            while (iterator.hasMoreElements())
280            {
281                Ogre::Resource* resource = iterator.getNext().get();
282                if (resource->getName() == material)
283                    material_pointer = (Ogre::Material*)resource;
284            }
285
286            if (!material_pointer)
287            {
288                COUT(2) << "Warning: No material with name \"" << material << "\" found." << std::endl;
289                return 0;
290            }
291
292            for (unsigned int t = 0; t < material_pointer->getNumTechniques(); ++t)
293            {
294                Ogre::Technique* technique_pointer = material_pointer->getTechnique(t);
295                if (!technique_pointer)
296                    continue;
297
298                for (unsigned int p = 0; p < technique_pointer->getNumPasses(); ++p)
299                {
300                    Ogre::Pass* pass_pointer = technique_pointer->getPass(p);
301                    if (!pass_pointer)
302                        continue;
303
304                    if (pass_pointer->getFragmentProgramName() != "")
305                    {
306                        Ogre::GpuProgramParameters* parameter_pointer = pass_pointer->getFragmentProgramParameters().get();
307                        if (!parameter_pointer)
308                            continue;
309
310                        const Ogre::GpuConstantDefinitionMap& constant_definitions = parameter_pointer->getConstantDefinitions().map;
311                        for (Ogre::GpuConstantDefinitionMap::const_iterator definition_iterator = constant_definitions.begin(); definition_iterator != constant_definitions.end(); ++definition_iterator)
312                        {
313                            void* temp = (definition_iterator->second.isFloat())
314                                            ? (void*)parameter_pointer->getFloatPointer(definition_iterator->second.physicalIndex)
315                                            : (void*)parameter_pointer->getIntPointer(definition_iterator->second.physicalIndex);
316                            ParameterPointer parameter_pointer = ParameterPointer(definition_iterator->second.isFloat(), temp);
317
318                            TechniqueVector& technique_vector = Shader::parameters_s[material];
319                            technique_vector.resize(technique + 1);
320                            PassVector& pass_vector = technique_vector[technique];
321                            pass_vector.resize(pass + 1);
322                            pass_vector[pass][definition_iterator->first] = parameter_pointer;
323                            foundAtLeastOneShaderParameter = true;
324                        }
325                    }
326                }
327            }
328
329            // recursive call if the material was added to the map
330            if (foundAtLeastOneShaderParameter)
331                return Shader::getParameterPointer(material, technique, pass, parameter);
332        }
333        return 0;
334    }
335}
Note: See TracBrowser for help on using the repository browser.