Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/questsystem5/src/orxonox/tools/Shader.cc @ 2987

Last change on this file since 2987 was 2908, checked in by dafrick, 16 years ago

Reverted to revision 2906 (because I'm too stupid to merge correctly, 2nd try will follow shortly. ;))

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