source: OGRE/trunk/ogrenew/OgreMain/src/OgreTechnique.cpp @ 657

Revision 657, 28.6 KB checked in by mattausch, 18 years ago (diff)

added ogre dependencies and patched ogre sources

Line 
1/*
2-----------------------------------------------------------------------------
3This source file is part of OGRE
4    (Object-oriented Graphics Rendering Engine)
5For the latest info, see http://www.ogre3d.org/
6
7Copyright (c) 2000-2005 The OGRE Team
8Also see acknowledgements in Readme.html
9
10This program is free software you can redistribute it and/or modify it under
11the terms of the GNU Lesser General Public License as published by the Free Software
12Foundation either version 2 of the License, or (at your option) any later
13version.
14
15This program is distributed in the hope that it will be useful, but WITHOUT
16ANY WARRANTY without even the implied warranty of MERCHANTABILITY or FITNESS
17FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
18
19You should have received a copy of the GNU Lesser General Public License along with
20this program if not, write to the Free Software Foundation, Inc., 59 Temple
21Place - Suite 330, Boston, MA 02111-1307, USA, or go to
22http://www.gnu.org/copyleft/lesser.txt.
23-----------------------------------------------------------------------------
24*/
25#include "OgreStableHeaders.h"
26
27#include "OgreTechnique.h"
28#include "OgreMaterial.h"
29#include "OgrePass.h"
30#include "OgreRoot.h"
31#include "OgreRenderSystem.h"
32#include "OgreRenderSystemCapabilities.h"
33#include "OgreGpuProgramManager.h"
34
35
36namespace Ogre {
37    //-----------------------------------------------------------------------------
38    Technique::Technique(Material* parent)
39        : mParent(parent), mIsSupported(false), mIlluminationPassesCompilationPhase(IPS_NOT_COMPILED), mLodIndex(0)
40    {
41        // See above, defaults to unsupported until examined
42    }
43    //-----------------------------------------------------------------------------
44    Technique::Technique(Material* parent, const Technique& oth)
45        : mParent(parent), mLodIndex(0)
46    {
47        // Copy using operator=
48        *this = oth;
49    }
50    //-----------------------------------------------------------------------------
51    Technique::~Technique()
52    {
53        removeAllPasses();
54        clearIlluminationPasses();
55    }
56    //-----------------------------------------------------------------------------
57    bool Technique::isSupported(void) const
58    {
59        return mIsSupported;
60    }
61    //-----------------------------------------------------------------------------
62    void Technique::_compile(bool autoManageTextureUnits)
63    {
64                // assume not supported
65                mIsSupported = false;
66        // Go through each pass, checking requirements
67        Passes::iterator i, iend;
68                size_t passNum = 0;
69        for (i = mPasses.begin(); i != mPasses.end(); ++i, ++passNum)       
70                {
71            Pass* currPass = *i;
72                        // Adjust pass index
73                        currPass->_notifyIndex(passNum);
74            // Check texture unit requirements
75            size_t numTexUnitsRequested = currPass->getNumTextureUnitStates();
76            const RenderSystemCapabilities* caps =
77                Root::getSingleton().getRenderSystem()->getCapabilities();
78            unsigned short numTexUnits = caps->getNumTextureUnits();
79#if defined(OGRE_PRETEND_TEXTURE_UNITS) && OGRE_PRETEND_TEXTURE_UNITS > 0
80                        if (numTexUnits > OGRE_PRETEND_TEXTURE_UNITS)
81                                numTexUnits = OGRE_PRETEND_TEXTURE_UNITS;
82#endif
83                        if (!autoManageTextureUnits && numTexUnitsRequested > numTexUnits)
84                        {
85                                // The user disabled auto pass split
86                                return;
87                        }
88
89                        if (currPass->hasVertexProgram())
90                        {
91                                // Check texture units
92                                if (numTexUnitsRequested > numTexUnits)
93                                {
94                                        // Can't do this one, and can't split a programmable vertex pass
95                                        return;
96                                }
97                                // Check vertex program version
98                                if (!currPass->getVertexProgram()->isSupported() )
99                                {
100                                        // Can't do this one
101                                        return;
102                                }
103                        }
104            if (currPass->hasFragmentProgram())
105            {
106                // Check texture units
107                if (numTexUnitsRequested > numTexUnits)
108                {
109                    // Can't do this one, and can't split a fragment pass
110                    return;
111                }
112                // Check fragment program version
113                if (!currPass->getFragmentProgram()->isSupported())
114                {
115                    // Can't do this one
116                    return;
117                }
118            }
119            else
120            {
121                                // Check a few fixed-function options in texture layers
122                Pass::TextureUnitStateIterator texi = currPass->getTextureUnitStateIterator();
123                                while (texi.hasMoreElements())
124                                {
125                                        TextureUnitState* tex = texi.getNext();
126                                        // Any Cube textures? NB we make the assumption that any
127                                        // card capable of running fragment programs can support
128                                        // cubic textures, which has to be true, surely?
129                                        if (tex->is3D() && !caps->hasCapability(RSC_CUBEMAPPING))
130                                        {
131                                                // Fail
132                                                return;
133                                        }
134                                        // Any 3D textures? NB we make the assumption that any
135                                        // card capable of running fragment programs can support
136                                        // 3D textures, which has to be true, surely?
137                                        if (tex->getTextureType() == TEX_TYPE_3D && !caps->hasCapability(RSC_TEXTURE_3D))
138                                        {
139                                                // Fail
140                                                return;
141                                        }                                       
142                                        // Any Dot3 blending?
143                                        if (tex->getColourBlendMode().operation == LBX_DOTPRODUCT &&
144                                                        !caps->hasCapability(RSC_DOT3))
145                                        {
146                                                // Fail
147                                                return;
148                                        }
149                                }
150                               
151                                // We're ok on operations, now we need to check # texture units
152                                // Keep splitting this pass so long as units requested > gpu units
153                while (numTexUnitsRequested > numTexUnits)
154                {
155                    // chop this pass into many passes
156                    currPass = currPass->_split(numTexUnits);
157                    numTexUnitsRequested = currPass->getNumTextureUnitStates();
158                                        // Advance pass number
159                                        ++passNum;
160                                        // Reset iterator
161                                        i = mPasses.begin() + passNum;
162                                        // Move the new pass to the right place (will have been created
163                                        // at the end, may be other passes in between)
164                                        assert(mPasses.back() == currPass);
165                                        std::copy_backward(i, (mPasses.end()-1), mPasses.end());
166                                        *i = currPass;
167                                        // Adjust pass index
168                                        currPass->_notifyIndex(passNum);               
169                                }
170            }
171
172                }
173        // If we got this far, we're ok
174        mIsSupported = true;
175
176        // Compile for categorised illumination on demand
177        clearIlluminationPasses();
178        mIlluminationPassesCompilationPhase = IPS_NOT_COMPILED;
179
180    }
181    //-----------------------------------------------------------------------------
182    Pass* Technique::createPass(void)
183    {
184                Pass* newPass = new Pass(this, static_cast<unsigned short>(mPasses.size()));
185                mPasses.push_back(newPass);
186                return newPass;
187    }
188    //-----------------------------------------------------------------------------
189    Pass* Technique::getPass(unsigned short index)
190    {
191                assert(index < mPasses.size() && "Index out of bounds");
192                return mPasses[index];
193    }
194    //-----------------------------------------------------------------------------
195    unsigned short Technique::getNumPasses(void) const
196    {
197                return static_cast<unsigned short>(mPasses.size());
198    }
199    //-----------------------------------------------------------------------------
200    void Technique::removePass(unsigned short index)
201    {
202                assert(index < mPasses.size() && "Index out of bounds");
203                Passes::iterator i = mPasses.begin() + index;
204                (*i)->queueForDeletion();
205                i = mPasses.erase(i);
206                // Adjust passes index
207                for (; i != mPasses.end(); ++i, ++index)
208                {
209                        (*i)->_notifyIndex(index);
210                }
211    }
212    //-----------------------------------------------------------------------------
213    void Technique::removeAllPasses(void)
214    {
215        Passes::iterator i, iend;
216        iend = mPasses.end();
217        for (i = mPasses.begin(); i != iend; ++i)
218        {
219            (*i)->queueForDeletion();
220        }
221        mPasses.clear();
222    }
223    //-----------------------------------------------------------------------------
224    const Technique::PassIterator Technique::getPassIterator(void)
225    {
226                return PassIterator(mPasses.begin(), mPasses.end());
227    }
228    //-----------------------------------------------------------------------------
229    Technique& Technique::operator=(const Technique& rhs)
230    {
231                this->mIsSupported = rhs.mIsSupported;
232        this->mLodIndex = rhs.mLodIndex;
233                // copy passes
234                removeAllPasses();
235                Passes::const_iterator i, iend;
236                iend = rhs.mPasses.end();
237                for (i = rhs.mPasses.begin(); i != iend; ++i)
238                {
239                        Pass* p = new Pass(this, (*i)->getIndex(), *(*i));
240                        mPasses.push_back(p);
241                }
242        // Compile for categorised illumination on demand
243        clearIlluminationPasses();
244        mIlluminationPassesCompilationPhase = IPS_NOT_COMPILED;
245                return *this;
246    }
247    //-----------------------------------------------------------------------------
248    bool Technique::isTransparent(void) const
249    {
250        if (mPasses.empty())
251        {
252            return false;
253        }
254        else
255        {
256            // Base decision on the transparency of the first pass
257            return mPasses[0]->isTransparent();
258        }
259    }
260    //-----------------------------------------------------------------------------
261    bool Technique::isDepthWriteEnabled(void) const
262    {
263        if (mPasses.empty())
264        {
265            return false;
266        }
267        else
268        {
269            // Base decision on the depth settings of the first pass
270            return mPasses[0]->getDepthWriteEnabled();
271        }
272    }
273    //-----------------------------------------------------------------------------
274    bool Technique::isDepthCheckEnabled(void) const
275    {
276        if (mPasses.empty())
277        {
278            return false;
279        }
280        else
281        {
282            // Base decision on the depth settings of the first pass
283            return mPasses[0]->getDepthCheckEnabled();
284        }
285    }
286    //-----------------------------------------------------------------------------
287    void Technique::_load(void)
288    {
289                assert (mIsSupported && "This technique is not supported");
290                // Load each pass
291                Passes::iterator i, iend;
292                iend = mPasses.end();
293                for (i = mPasses.begin(); i != iend; ++i)
294                {
295                        (*i)->_load();
296                }
297
298                IlluminationPassList::iterator il, ilend;
299                ilend = mIlluminationPasses.end();
300                for (il = mIlluminationPasses.begin(); il != ilend; ++il)
301                {
302                        if((*il)->pass != (*il)->originalPass)
303                            (*il)->pass->_load();
304                }
305    }
306    //-----------------------------------------------------------------------------
307    void Technique::_unload(void)
308    {
309                // Unload each pass
310                Passes::iterator i, iend;
311                iend = mPasses.end();
312                for (i = mPasses.begin(); i != iend; ++i)
313                {
314                        (*i)->_unload();
315                }
316    }
317    //-----------------------------------------------------------------------------
318    bool Technique::isLoaded(void) const
319    {
320        // Only supported technique will be loaded
321        return mParent->isLoaded() && mIsSupported;
322    }
323    //-----------------------------------------------------------------------
324    void Technique::setAmbient(Real red, Real green, Real blue)
325    {
326        Passes::iterator i, iend;
327        iend = mPasses.end();
328        for (i = mPasses.begin(); i != iend; ++i)
329        {
330            (*i)->setAmbient(red, green, blue);
331        }
332
333    }
334    //-----------------------------------------------------------------------
335    void Technique::setAmbient(const ColourValue& ambient)
336    {
337        setAmbient(ambient.r, ambient.g, ambient.b);
338    }
339    //-----------------------------------------------------------------------
340    void Technique::setDiffuse(Real red, Real green, Real blue, Real alpha)
341    {
342        Passes::iterator i, iend;
343        iend = mPasses.end();
344        for (i = mPasses.begin(); i != iend; ++i)
345        {
346            (*i)->setDiffuse(red, green, blue, alpha);
347        }
348    }
349    //-----------------------------------------------------------------------
350    void Technique::setDiffuse(const ColourValue& diffuse)
351    {
352        setDiffuse(diffuse.r, diffuse.g, diffuse.b, diffuse.a);
353    }
354    //-----------------------------------------------------------------------
355    void Technique::setSpecular(Real red, Real green, Real blue, Real alpha)
356    {
357        Passes::iterator i, iend;
358        iend = mPasses.end();
359        for (i = mPasses.begin(); i != iend; ++i)
360        {
361            (*i)->setSpecular(red, green, blue, alpha);
362        }
363    }
364    //-----------------------------------------------------------------------
365    void Technique::setSpecular(const ColourValue& specular)
366    {
367        setSpecular(specular.r, specular.g, specular.b, specular.a);
368    }
369    //-----------------------------------------------------------------------
370    void Technique::setShininess(Real val)
371    {
372        Passes::iterator i, iend;
373        iend = mPasses.end();
374        for (i = mPasses.begin(); i != iend; ++i)
375        {
376            (*i)->setShininess(val);
377        }
378    }
379    //-----------------------------------------------------------------------
380    void Technique::setSelfIllumination(Real red, Real green, Real blue)
381    {
382        Passes::iterator i, iend;
383        iend = mPasses.end();
384        for (i = mPasses.begin(); i != iend; ++i)
385        {
386            (*i)->setSelfIllumination(red, green, blue);
387        }
388    }
389    //-----------------------------------------------------------------------
390    void Technique::setSelfIllumination(const ColourValue& selfIllum)
391    {
392        setSelfIllumination(selfIllum.r, selfIllum.g, selfIllum.b);
393    }
394    //-----------------------------------------------------------------------
395    void Technique::setDepthCheckEnabled(bool enabled)
396    {
397        Passes::iterator i, iend;
398        iend = mPasses.end();
399        for (i = mPasses.begin(); i != iend; ++i)
400        {
401            (*i)->setDepthCheckEnabled(enabled);
402        }
403    }
404    //-----------------------------------------------------------------------
405    void Technique::setDepthWriteEnabled(bool enabled)
406    {
407        Passes::iterator i, iend;
408        iend = mPasses.end();
409        for (i = mPasses.begin(); i != iend; ++i)
410        {
411            (*i)->setDepthWriteEnabled(enabled);
412        }
413    }
414    //-----------------------------------------------------------------------
415    void Technique::setDepthFunction( CompareFunction func )
416    {
417        Passes::iterator i, iend;
418        iend = mPasses.end();
419        for (i = mPasses.begin(); i != iend; ++i)
420        {
421            (*i)->setDepthFunction(func);
422        }
423    }
424    //-----------------------------------------------------------------------
425        void Technique::setColourWriteEnabled(bool enabled)
426    {
427        Passes::iterator i, iend;
428        iend = mPasses.end();
429        for (i = mPasses.begin(); i != iend; ++i)
430        {
431            (*i)->setColourWriteEnabled(enabled);
432        }
433    }
434    //-----------------------------------------------------------------------
435    void Technique::setCullingMode( CullingMode mode )
436    {
437        Passes::iterator i, iend;
438        iend = mPasses.end();
439        for (i = mPasses.begin(); i != iend; ++i)
440        {
441            (*i)->setCullingMode(mode);
442        }
443    }
444    //-----------------------------------------------------------------------
445    void Technique::setManualCullingMode( ManualCullingMode mode )
446    {
447        Passes::iterator i, iend;
448        iend = mPasses.end();
449        for (i = mPasses.begin(); i != iend; ++i)
450        {
451            (*i)->setManualCullingMode(mode);
452        }
453    }
454    //-----------------------------------------------------------------------
455    void Technique::setLightingEnabled(bool enabled)
456    {
457        Passes::iterator i, iend;
458        iend = mPasses.end();
459        for (i = mPasses.begin(); i != iend; ++i)
460        {
461            (*i)->setLightingEnabled(enabled);
462        }
463    }
464    //-----------------------------------------------------------------------
465    void Technique::setShadingMode( ShadeOptions mode )
466    {
467        Passes::iterator i, iend;
468        iend = mPasses.end();
469        for (i = mPasses.begin(); i != iend; ++i)
470        {
471            (*i)->setShadingMode(mode);
472        }
473    }
474    //-----------------------------------------------------------------------
475    void Technique::setFog(bool overrideScene, FogMode mode, const ColourValue& colour,
476        Real expDensity, Real linearStart, Real linearEnd)
477    {
478        Passes::iterator i, iend;
479        iend = mPasses.end();
480        for (i = mPasses.begin(); i != iend; ++i)
481        {
482            (*i)->setFog(overrideScene, mode, colour, expDensity, linearStart, linearEnd);
483        }
484    }
485    //-----------------------------------------------------------------------
486    void Technique::setDepthBias(ushort bias)
487    {
488        Passes::iterator i, iend;
489        iend = mPasses.end();
490        for (i = mPasses.begin(); i != iend; ++i)
491        {
492            (*i)->setDepthBias(bias);
493        }
494    }
495    //-----------------------------------------------------------------------
496    void Technique::setTextureFiltering(TextureFilterOptions filterType)
497    {
498        Passes::iterator i, iend;
499        iend = mPasses.end();
500        for (i = mPasses.begin(); i != iend; ++i)
501        {
502            (*i)->setTextureFiltering(filterType);
503        }
504    }
505    // --------------------------------------------------------------------
506    void Technique::setTextureAnisotropy(unsigned int maxAniso)
507    {
508        Passes::iterator i, iend;
509        iend = mPasses.end();
510        for (i = mPasses.begin(); i != iend; ++i)
511        {
512            (*i)->setTextureAnisotropy(maxAniso);
513        }
514    }
515    // --------------------------------------------------------------------
516    void Technique::setSceneBlending( const SceneBlendType sbt )
517    {
518        Passes::iterator i, iend;
519        iend = mPasses.end();
520        for (i = mPasses.begin(); i != iend; ++i)
521        {
522            (*i)->setSceneBlending(sbt);
523        }
524    }
525    // --------------------------------------------------------------------
526    void Technique::setSceneBlending( const SceneBlendFactor sourceFactor,
527        const SceneBlendFactor destFactor)
528    {
529        Passes::iterator i, iend;
530        iend = mPasses.end();
531        for (i = mPasses.begin(); i != iend; ++i)
532        {
533            (*i)->setSceneBlending(sourceFactor, destFactor);
534        }
535    }
536
537    //-----------------------------------------------------------------------
538    void Technique::_notifyNeedsRecompile(void)
539    {
540        // Disable require to recompile when splitting illumination passes
541        if (mIlluminationPassesCompilationPhase != IPS_COMPILE_DISABLED)
542        {
543            mParent->_notifyNeedsRecompile();
544        }
545    }
546    //-----------------------------------------------------------------------
547    void Technique::setLodIndex(unsigned short index)
548    {
549        mLodIndex = index;
550        _notifyNeedsRecompile();
551    }
552    //-----------------------------------------------------------------------
553    void Technique::_compileIlluminationPasses(void)
554    {
555        clearIlluminationPasses();
556
557        if (isTransparent())
558        {
559            // Don't need to split transparents since they are rendered separately
560            return;
561        }
562
563        Passes::iterator i, iend;
564        iend = mPasses.end();
565        i = mPasses.begin();
566       
567        IlluminationStage iStage = IS_AMBIENT;
568
569        // Disable requirement to recompile during compile
570
571        bool haveAmbient = false;
572        while (i != iend)
573        {
574            IlluminationPass* iPass;
575            Pass* p = *i;
576            switch(iStage)
577            {
578            case IS_AMBIENT:
579                // Keep looking for ambient only
580                if (p->isAmbientOnly())
581                {
582                    // Add this pass wholesale
583                    iPass = new IlluminationPass();
584                    iPass->destroyOnShutdown = false;
585                    iPass->originalPass = iPass->pass = p;
586                    iPass->stage = iStage;
587                    mIlluminationPasses.push_back(iPass);
588                    haveAmbient = true;
589                    // progress to next pass
590                    ++i;
591                }
592                else
593                {
594                    // Split off any ambient part
595                    if (p->getAmbient() != ColourValue::Black ||
596                        p->getSelfIllumination() != ColourValue::Black)
597                    {
598                        // Copy existing pass
599                        Pass* newPass = new Pass(this, p->getIndex(), *p);
600                        // Remove any texture units
601                        newPass->removeAllTextureUnitStates();
602                        // Remove any fragment program
603                        if (newPass->hasFragmentProgram())
604                            newPass->setFragmentProgram("");
605                        // We have to leave vertex program alone (if any) and
606                        // just trust that the author is using light bindings, which
607                        // we will ensure there are none in the ambient pass
608                        newPass->setDiffuse(ColourValue::Black);
609                        newPass->setSpecular(ColourValue::Black);
610
611                        // If ambient & emissive are zero, then no colour write
612                        if (newPass->getAmbient() == ColourValue::Black &&
613                            newPass->getSelfIllumination() == ColourValue::Black)
614                        {
615                            newPass->setColourWriteEnabled(false);
616                        }
617
618                        iPass = new IlluminationPass();
619                        iPass->destroyOnShutdown = true;
620                        iPass->originalPass = p;
621                        iPass->pass = newPass;
622                        iPass->stage = iStage;
623
624                        mIlluminationPasses.push_back(iPass);
625                        haveAmbient = true;
626                       
627                    }
628                   
629                    if (!haveAmbient)
630                    {
631                        // Make up a new basic pass
632                        Pass* newPass = new Pass(this, p->getIndex());
633                        newPass->setAmbient(ColourValue::Black);
634                        newPass->setDiffuse(ColourValue::Black);
635                        iPass = new IlluminationPass();
636                        iPass->destroyOnShutdown = true;
637                        iPass->originalPass = p;
638                        iPass->pass = newPass;
639                        iPass->stage = iStage;
640                        mIlluminationPasses.push_back(iPass);
641                        haveAmbient = true;
642                    }
643                    // This means we're done with ambients, progress to per-light
644                    iStage = IS_PER_LIGHT;
645                }
646                break;
647            case IS_PER_LIGHT:
648                if (p->getRunOncePerLight())
649                {
650                    // If this is per-light already, use it directly
651                    iPass = new IlluminationPass();
652                    iPass->destroyOnShutdown = false;
653                    iPass->originalPass = iPass->pass = p;
654                    iPass->stage = iStage;
655                    mIlluminationPasses.push_back(iPass);
656                    // progress to next pass
657                    ++i;
658                }
659                else
660                {
661                    // Split off per-light details (can only be done for one)
662                    if (p->getLightingEnabled() &&
663                        (p->getDiffuse() != ColourValue::Black ||
664                        p->getSpecular() != ColourValue::Black))
665                    {
666                        // Copy existing pass
667                        Pass* newPass = new Pass(this, p->getIndex(), *p);
668                        // remove texture units
669                        newPass->removeAllTextureUnitStates();
670                        // remove fragment programs
671                        if (newPass->hasFragmentProgram())
672                            newPass->setFragmentProgram("");
673                        // Cannot remove vertex program, have to assume that
674                        // it will process diffuse lights, ambient will be turned off
675                        newPass->setAmbient(ColourValue::Black);
676                        newPass->setSelfIllumination(ColourValue::Black);
677                        // must be additive
678                        newPass->setSceneBlending(SBF_ONE, SBF_ONE);
679
680                        iPass = new IlluminationPass();
681                        iPass->destroyOnShutdown = true;
682                        iPass->originalPass = p;
683                        iPass->pass = newPass;
684                        iPass->stage = iStage;
685
686                        mIlluminationPasses.push_back(iPass);
687
688                    }
689                    // This means the end of per-light passes
690                    iStage = IS_DECAL;
691                }
692                break;
693            case IS_DECAL:
694                // We just want a 'lighting off' pass to finish off
695                // and only if there are texture units
696                if (p->getNumTextureUnitStates() > 0)
697                {
698                    if (!p->getLightingEnabled())
699                    {
700                        // we assume this pass already combines as required with the scene
701                        iPass = new IlluminationPass();
702                        iPass->destroyOnShutdown = false;
703                        iPass->originalPass = iPass->pass = p;
704                        iPass->stage = iStage;
705                        mIlluminationPasses.push_back(iPass);
706                    }
707                    else
708                    {
709                        // Copy the pass and tweak away the lighting parts
710                        Pass* newPass = new Pass(this, p->getIndex(), *p);
711                        newPass->setAmbient(ColourValue::Black);
712                        newPass->setDiffuse(ColourValue::Black);
713                        newPass->setSpecular(ColourValue::Black);
714                        newPass->setSelfIllumination(ColourValue::Black);
715                        newPass->setLightingEnabled(false);
716                        // modulate
717                        newPass->setSceneBlending(SBF_DEST_COLOUR, SBF_ZERO);
718
719                        // NB there is nothing we can do about vertex & fragment
720                        // programs here, so people will just have to make their
721                        // programs friendly-like if they want to use this technique
722                        iPass = new IlluminationPass();
723                        iPass->destroyOnShutdown = true;
724                        iPass->originalPass = p;
725                        iPass->pass = newPass;
726                        iPass->stage = iStage;
727                        mIlluminationPasses.push_back(iPass);
728
729                    }
730                }
731                ++i; // always increment on decal, since nothing more to do with this pass
732
733                break;
734            }
735        }
736
737    }
738    //-----------------------------------------------------------------------
739    void Technique::clearIlluminationPasses(void)
740    {
741        IlluminationPassList::iterator i, iend;
742        iend = mIlluminationPasses.end();
743        for (i = mIlluminationPasses.begin(); i != iend; ++i)
744        {
745            if ((*i)->destroyOnShutdown)
746            {
747                (*i)->pass->queueForDeletion();
748            }
749            delete *i;
750        }
751        mIlluminationPasses.clear();
752    }
753    //-----------------------------------------------------------------------
754    const Technique::IlluminationPassIterator
755    Technique::getIlluminationPassIterator(void)
756    {
757        if (mIlluminationPassesCompilationPhase == IPS_NOT_COMPILED)
758        {
759            // prevents parent->_notifyNeedsRecompile() call during compile
760            mIlluminationPassesCompilationPhase = IPS_COMPILE_DISABLED;
761            // Splitting the passes into illumination passes
762            _compileIlluminationPasses();
763            // Mark that illumination passes compilation finished
764            mIlluminationPassesCompilationPhase = IPS_COMPILED;
765        }
766
767        return IlluminationPassIterator(mIlluminationPasses.begin(),
768            mIlluminationPasses.end());
769    }
770    //-----------------------------------------------------------------------
771        const String& Technique::getResourceGroup(void) const
772        {
773                return mParent->getGroup();
774        }
775
776
777}
Note: See TracBrowser for help on using the repository browser.