source: OGRE/trunk/ogre_changes/Ogre1.2/OgreMain/src/OgrePass.cpp @ 768

Revision 768, 48.0 KB checked in by szirmay, 18 years ago (diff)
Line 
1/*
2-----------------------------------------------------------------------------
3This source file is part of OGRE
4    (Object-oriented Graphics Rendering Engine)
5For the latest info, see http://ogre.sourceforge.net/
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 "OgrePass.h"
28#include "OgreTechnique.h"
29#include "OgreException.h"
30#include "OgreGpuProgramUsage.h"
31#include "OgreTextureUnitState.h"
32#include "OgreStringConverter.h"
33
34namespace Ogre {
35       
36    //-----------------------------------------------------------------------------
37        Pass::PassSet Pass::msDirtyHashList;
38    Pass::PassSet Pass::msPassGraveyard;
39    //-----------------------------------------------------------------------------
40        Pass::Pass(Technique* parent, unsigned short index)
41        : mParent(parent), mIndex(index), mPassIterationCount(0)
42    {
43#ifdef GAMETOOLS_ILLUMINATION_MODULE
44                mActive = true;
45#endif
46        // Default to white ambient & diffuse, no specular / emissive
47            mAmbient = mDiffuse = ColourValue::White;
48            mSpecular = mEmissive = ColourValue::Black;
49            mShininess = 0;
50        mPointSize = 1.0f;
51                mPointMinSize = 0.0f;
52                mPointMaxSize = 0.0f;
53                mPointSpritesEnabled = false;
54                mPointAttenuationEnabled = false;
55                mPointAttenuationCoeffs[0] = 1.0f;
56                mPointAttenuationCoeffs[1] = mPointAttenuationCoeffs[2] = 0.0f;
57        mTracking = TVC_NONE;
58        mHash = 0;
59
60        // By default, don't override the scene's fog settings
61        mFogOverride = false;
62        mFogMode = FOG_NONE;
63        mFogColour = ColourValue::White;
64        mFogStart = 0.0;
65        mFogEnd = 1.0;
66        mFogDensity = 0.001;
67
68            // Default blending (overwrite)
69            mSourceBlendFactor = SBF_ONE;
70            mDestBlendFactor = SBF_ZERO;
71
72            mDepthCheck = true;
73            mDepthWrite = true;
74        mColourWrite = true;
75            mDepthFunc = CMPF_LESS_EQUAL;
76        mDepthBias = 0;
77                mAlphaRejectFunc = CMPF_ALWAYS_PASS;
78                mAlphaRejectVal = 0;
79            mCullMode = CULL_CLOCKWISE;
80            mManualCullMode = MANUAL_CULL_BACK;
81            mLightingEnabled = true;
82        mMaxSimultaneousLights = OGRE_MAX_SIMULTANEOUS_LIGHTS;
83                mIteratePerLight = false;
84        mRunOnlyForOneLightType = true;
85        mOnlyLightType = Light::LT_POINT;
86            mShadeOptions = SO_GOURAUD;
87                mPolygonMode = PM_SOLID;
88
89                mVertexProgramUsage = NULL;
90        mShadowCasterVertexProgramUsage = NULL;
91        mShadowReceiverVertexProgramUsage = NULL;
92                mShadowReceiverFragmentProgramUsage = NULL;
93                mFragmentProgramUsage = NULL;
94
95        mQueuedForDeletion = false;
96
97        // default name to index
98        mName = StringConverter::toString(mIndex);
99
100        _dirtyHash();
101   }
102       
103    //-----------------------------------------------------------------------------
104        Pass::Pass(Technique *parent, unsigned short index, const Pass& oth)
105        :mParent(parent), mIndex(index), mQueuedForDeletion(false), mPassIterationCount(0)
106    {
107#ifdef GAMETOOLS_ILLUMINATION_MODULE
108                mActive = true;
109#endif
110        *this = oth;
111        mParent = parent;
112        mIndex = index;
113        mQueuedForDeletion = false;
114        _dirtyHash();
115    }
116    //-----------------------------------------------------------------------------
117    Pass::~Pass()
118    {
119
120    }
121    //-----------------------------------------------------------------------------
122    Pass& Pass::operator=(const Pass& oth)
123    {
124#ifdef GAMETOOLS_ILLUMINATION_MODULE
125                mActive = oth.mActive;
126#endif
127        mName = oth.mName;
128            mAmbient = oth.mAmbient;
129        mDiffuse = oth.mDiffuse;
130            mSpecular = oth.mSpecular;
131        mEmissive = oth.mEmissive;
132            mShininess = oth.mShininess;
133        mTracking = oth.mTracking;
134
135        // Copy fog parameters
136        mFogOverride = oth.mFogOverride;
137        mFogMode = oth.mFogMode;
138        mFogColour = oth.mFogColour;
139        mFogStart = oth.mFogStart;
140        mFogEnd = oth.mFogEnd;
141        mFogDensity = oth.mFogDensity;
142
143            // Default blending (overwrite)
144            mSourceBlendFactor = oth.mSourceBlendFactor;
145            mDestBlendFactor = oth.mDestBlendFactor;
146
147            mDepthCheck = oth.mDepthCheck;
148            mDepthWrite = oth.mDepthWrite;
149                mAlphaRejectFunc = oth.mAlphaRejectFunc;
150                mAlphaRejectVal = oth.mAlphaRejectVal;
151        mColourWrite = oth.mColourWrite;
152            mDepthFunc = oth.mDepthFunc;
153        mDepthBias = oth.mDepthBias;
154            mCullMode = oth.mCullMode;
155            mManualCullMode = oth.mManualCullMode;
156            mLightingEnabled = oth.mLightingEnabled;
157        mMaxSimultaneousLights = oth.mMaxSimultaneousLights;
158                mIteratePerLight = oth.mIteratePerLight;
159        mRunOnlyForOneLightType = oth.mRunOnlyForOneLightType;
160        mOnlyLightType = oth.mOnlyLightType;
161            mShadeOptions = oth.mShadeOptions;
162                mPolygonMode = oth.mPolygonMode;
163        mPassIterationCount = oth.mPassIterationCount;
164                mPointSize = oth.mPointSize;
165                mPointMinSize = oth.mPointMinSize;
166                mPointMaxSize = oth.mPointMaxSize;
167                mPointSpritesEnabled = oth.mPointSpritesEnabled;
168                mPointAttenuationEnabled = oth.mPointAttenuationEnabled;
169                memcpy(mPointAttenuationCoeffs, oth.mPointAttenuationCoeffs, sizeof(Real)*3);
170
171
172                if (oth.mVertexProgramUsage)
173                {
174                        mVertexProgramUsage = new GpuProgramUsage(*(oth.mVertexProgramUsage));
175                }
176                else
177                {
178                    mVertexProgramUsage = NULL;
179                }
180        if (oth.mShadowCasterVertexProgramUsage)
181        {
182            mShadowCasterVertexProgramUsage = new GpuProgramUsage(*(oth.mShadowCasterVertexProgramUsage));
183        }
184        else
185        {
186            mShadowCasterVertexProgramUsage = NULL;
187        }
188        if (oth.mShadowReceiverVertexProgramUsage)
189        {
190            mShadowReceiverVertexProgramUsage = new GpuProgramUsage(*(oth.mShadowReceiverVertexProgramUsage));
191        }
192        else
193        {
194            mShadowReceiverVertexProgramUsage = NULL;
195        }
196                if (oth.mFragmentProgramUsage)
197                {
198                    mFragmentProgramUsage = new GpuProgramUsage(*(oth.mFragmentProgramUsage));
199        }
200        else
201        {
202                    mFragmentProgramUsage = NULL;
203        }
204                if (oth.mShadowReceiverFragmentProgramUsage)
205                {
206                        mShadowReceiverFragmentProgramUsage = new GpuProgramUsage(*(oth.mShadowReceiverFragmentProgramUsage));
207                }
208                else
209                {
210                        mShadowReceiverFragmentProgramUsage = NULL;
211                }
212
213                TextureUnitStates::const_iterator i, iend;
214
215        // Clear texture units but doesn't notify need recompilation in the case
216        // we are cloning, The parent material will take care of this.
217        iend = mTextureUnitStates.end();
218        for (i = mTextureUnitStates.begin(); i != iend; ++i)
219        {
220            delete *i;
221        }
222
223        mTextureUnitStates.clear();
224
225                // Copy texture units
226                iend = oth.mTextureUnitStates.end();
227                for (i = oth.mTextureUnitStates.begin(); i != iend; ++i)
228                {
229                        TextureUnitState* t = new TextureUnitState(this, *(*i));
230                        mTextureUnitStates.push_back(t);
231                }
232
233        _dirtyHash();
234
235                return *this;
236    }
237    //-----------------------------------------------------------------------
238    void Pass::setName(const String& name)
239    {
240        mName = name;
241    }
242    //-----------------------------------------------------------------------
243    void Pass::setPointSize(Real ps)
244    {
245            mPointSize = ps;
246    }
247    //-----------------------------------------------------------------------
248        void Pass::setPointSpritesEnabled(bool enabled)
249        {
250                mPointSpritesEnabled = enabled;
251        }
252    //-----------------------------------------------------------------------
253        bool Pass::getPointSpritesEnabled(void) const
254        {
255                return mPointSpritesEnabled;
256        }
257    //-----------------------------------------------------------------------
258        void Pass::setPointAttenuation(bool enabled,
259                Real constant, Real linear, Real quadratic)
260        {
261                mPointAttenuationEnabled = enabled;
262                mPointAttenuationCoeffs[0] = constant;
263                mPointAttenuationCoeffs[1] = linear;
264                mPointAttenuationCoeffs[2] = quadratic;
265        }
266    //-----------------------------------------------------------------------
267        bool Pass::isPointAttenuationEnabled(void) const
268        {
269                return mPointAttenuationEnabled;
270        }
271    //-----------------------------------------------------------------------
272        Real Pass::getPointAttenuationConstant(void) const
273        {
274                return mPointAttenuationCoeffs[0];
275        }
276    //-----------------------------------------------------------------------
277        Real Pass::getPointAttenuationLinear(void) const
278        {
279                return mPointAttenuationCoeffs[1];
280        }
281    //-----------------------------------------------------------------------
282        Real Pass::getPointAttenuationQuadratic(void) const
283        {
284                return mPointAttenuationCoeffs[2];
285        }
286    //-----------------------------------------------------------------------
287        void Pass::setPointMinSize(Real min)
288        {
289                mPointMinSize = min;
290        }
291    //-----------------------------------------------------------------------
292        Real Pass::getPointMinSize(void) const
293        {
294                return mPointMinSize;
295        }
296    //-----------------------------------------------------------------------
297        void Pass::setPointMaxSize(Real max)
298        {
299                mPointMaxSize = max;
300        }
301    //-----------------------------------------------------------------------
302        Real Pass::getPointMaxSize(void) const
303        {
304                return mPointMaxSize;
305        }
306    //-----------------------------------------------------------------------
307    void Pass::setAmbient(Real red, Real green, Real blue)
308    {
309            mAmbient.r = red;
310            mAmbient.g = green;
311            mAmbient.b = blue;
312
313    }
314    //-----------------------------------------------------------------------
315    void Pass::setAmbient(const ColourValue& ambient)
316    {
317            mAmbient = ambient;
318    }
319    //-----------------------------------------------------------------------
320    void Pass::setDiffuse(Real red, Real green, Real blue, Real alpha)
321    {
322            mDiffuse.r = red;
323            mDiffuse.g = green;
324            mDiffuse.b = blue;
325                mDiffuse.a = alpha;
326    }
327    //-----------------------------------------------------------------------
328    void Pass::setDiffuse(const ColourValue& diffuse)
329    {
330            mDiffuse = diffuse;
331    }
332    //-----------------------------------------------------------------------
333    void Pass::setSpecular(Real red, Real green, Real blue, Real alpha)
334    {
335            mSpecular.r = red;
336            mSpecular.g = green;
337            mSpecular.b = blue;
338                mSpecular.a = alpha;
339    }
340    //-----------------------------------------------------------------------
341    void Pass::setSpecular(const ColourValue& specular)
342    {
343            mSpecular = specular;
344    }
345    //-----------------------------------------------------------------------
346    void Pass::setShininess(Real val)
347    {
348            mShininess = val;
349    }
350    //-----------------------------------------------------------------------
351    void Pass::setSelfIllumination(Real red, Real green, Real blue)
352    {
353            mEmissive.r = red;
354            mEmissive.g = green;
355            mEmissive.b = blue;
356
357    }
358    //-----------------------------------------------------------------------
359    void Pass::setSelfIllumination(const ColourValue& selfIllum)
360    {
361            mEmissive = selfIllum;
362    }
363    //-----------------------------------------------------------------------
364    void Pass::setVertexColourTracking(TrackVertexColourType tracking)
365    {
366        mTracking = tracking;
367    }
368    //-----------------------------------------------------------------------
369    Real Pass::getPointSize(void) const
370    {
371            return mPointSize;
372    }
373    //-----------------------------------------------------------------------
374    const ColourValue& Pass::getAmbient(void) const
375    {
376            return mAmbient;
377    }
378    //-----------------------------------------------------------------------
379    const ColourValue& Pass::getDiffuse(void) const
380    {
381            return mDiffuse;
382    }
383    //-----------------------------------------------------------------------
384    const ColourValue& Pass::getSpecular(void) const
385    {
386            return mSpecular;
387    }
388    //-----------------------------------------------------------------------
389    const ColourValue& Pass::getSelfIllumination(void) const
390    {
391            return mEmissive;
392    }
393    //-----------------------------------------------------------------------
394    Real Pass::getShininess(void) const
395    {
396            return mShininess;
397    }
398    //-----------------------------------------------------------------------
399    TrackVertexColourType Pass::getVertexColourTracking(void) const
400    {
401        return mTracking;
402    }
403    //-----------------------------------------------------------------------
404    TextureUnitState* Pass::createTextureUnitState(void)
405    {
406        TextureUnitState *t = new TextureUnitState(this);
407        addTextureUnitState(t);
408            return t;
409    }
410    //-----------------------------------------------------------------------
411    TextureUnitState* Pass::createTextureUnitState(
412        const String& textureName, unsigned short texCoordSet)
413    {
414        TextureUnitState *t = new TextureUnitState(this);
415            t->setTextureName(textureName);
416            t->setTextureCoordSet(texCoordSet);
417        addTextureUnitState(t);
418            return t;
419    }
420    //-----------------------------------------------------------------------
421        void Pass::addTextureUnitState(TextureUnitState* state)
422        {
423        assert(state && "state is 0 in Pass::addTextureUnitState()");
424        if (state)
425        {
426            // only attach TUS to pass if TUS does not belong to another pass
427            if ((state->getParent() == 0) || (state->getParent() == this))
428            {
429                        mTextureUnitStates.push_back(state);
430                                // Notify state
431                                state->_notifyParent(this);
432                // if texture unit state name is empty then give it a default name based on its index
433                if (state->getName().empty())
434                {
435                    // its the last entry in the container so its index is size - 1
436                    size_t idx = mTextureUnitStates.size() - 1;
437                    state->setName( StringConverter::toString(idx) );
438                }
439                // Needs recompilation
440                mParent->_notifyNeedsRecompile();
441                _dirtyHash();
442            }
443            else
444            {
445                            OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "TextureUnitState already attached to another pass",
446                                    "Pass:addTextureUnitState");
447
448            }
449        }
450        }
451    //-----------------------------------------------------------------------
452    TextureUnitState* Pass::getTextureUnitState(unsigned short index)
453    {
454        assert (index < mTextureUnitStates.size() && "Index out of bounds");
455            return mTextureUnitStates[index];
456    }
457    //-----------------------------------------------------------------------------
458    TextureUnitState* Pass::getTextureUnitState(const String& name)
459    {
460        TextureUnitStates::iterator i    = mTextureUnitStates.begin();
461        TextureUnitStates::iterator iend = mTextureUnitStates.end();
462        TextureUnitState* foundTUS = 0;
463
464        // iterate through TUS Container to find a match
465        while (i != iend)
466        {
467            if ( (*i)->getName() == name )
468            {
469                foundTUS = (*i);
470                break;
471            }
472
473            ++i;
474        }
475
476        return foundTUS;
477    }
478        //-----------------------------------------------------------------------
479        const TextureUnitState* Pass::getTextureUnitState(unsigned short index) const
480        {
481                assert (index < mTextureUnitStates.size() && "Index out of bounds");
482                return mTextureUnitStates[index];
483        }
484        //-----------------------------------------------------------------------------
485        const TextureUnitState* Pass::getTextureUnitState(const String& name) const
486        {
487                TextureUnitStates::const_iterator i    = mTextureUnitStates.begin();
488                TextureUnitStates::const_iterator iend = mTextureUnitStates.end();
489                const TextureUnitState* foundTUS = 0;
490
491                // iterate through TUS Container to find a match
492                while (i != iend)
493                {
494                        if ( (*i)->getName() == name )
495                        {
496                                foundTUS = (*i);
497                                break;
498                        }
499
500                        ++i;
501                }
502
503                return foundTUS;
504        }
505
506    //-----------------------------------------------------------------------
507    unsigned short Pass::getTextureUnitStateIndex(const TextureUnitState* state)
508    {
509        assert(state && "state is 0 in Pass::addTextureUnitState()");
510        unsigned short idx = 0;
511
512        // only find index for state attached to this pass
513        if (state->getParent() == this)
514        {
515            // iterate through TUS container and find matching pointer to state
516            TextureUnitStates::iterator i    = mTextureUnitStates.begin();
517            TextureUnitStates::iterator iend = mTextureUnitStates.end();
518            while (i != iend)
519            {
520                if ( (*i) == state )
521                {
522                    // calculate index
523                    idx = static_cast<unsigned short>(i - mTextureUnitStates.begin());
524                    break;
525                }
526
527                ++i;
528            }
529        }
530        else
531        {
532                        OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "TextureUnitState is not attached to this pass",
533                                "Pass:getTextureUnitStateIndex");
534        }
535
536        return idx;
537    }
538
539    //-----------------------------------------------------------------------
540    Pass::TextureUnitStateIterator
541        Pass::getTextureUnitStateIterator(void)
542    {
543        return TextureUnitStateIterator(mTextureUnitStates.begin(), mTextureUnitStates.end());
544    }
545        //-----------------------------------------------------------------------
546        Pass::ConstTextureUnitStateIterator
547                Pass::getTextureUnitStateIterator(void) const
548        {
549                return ConstTextureUnitStateIterator(mTextureUnitStates.begin(), mTextureUnitStates.end());
550        }
551    //-----------------------------------------------------------------------
552    void Pass::removeTextureUnitState(unsigned short index)
553    {
554        assert (index < mTextureUnitStates.size() && "Index out of bounds");
555
556        TextureUnitStates::iterator i = mTextureUnitStates.begin() + index;
557        delete *i;
558            mTextureUnitStates.erase(i);
559        if (!mQueuedForDeletion)
560        {
561            // Needs recompilation
562            mParent->_notifyNeedsRecompile();
563        }
564        _dirtyHash();
565    }
566    //-----------------------------------------------------------------------
567    void Pass::removeAllTextureUnitStates(void)
568    {
569        TextureUnitStates::iterator i, iend;
570        iend = mTextureUnitStates.end();
571        for (i = mTextureUnitStates.begin(); i != iend; ++i)
572        {
573            delete *i;
574        }
575        mTextureUnitStates.clear();
576        if (!mQueuedForDeletion)
577        {       
578            // Needs recompilation
579            mParent->_notifyNeedsRecompile();
580        }
581        _dirtyHash();
582    }
583    //-----------------------------------------------------------------------
584    void Pass::setSceneBlending(SceneBlendType sbt)
585    {
586            // Turn predefined type into blending factors
587            switch (sbt)
588            {
589            case SBT_TRANSPARENT_ALPHA:
590                    setSceneBlending(SBF_SOURCE_ALPHA, SBF_ONE_MINUS_SOURCE_ALPHA);
591                    break;
592            case SBT_TRANSPARENT_COLOUR:
593                    setSceneBlending(SBF_SOURCE_COLOUR, SBF_ONE_MINUS_SOURCE_COLOUR);
594                    break;
595                case SBT_MODULATE:
596                        setSceneBlending(SBF_DEST_COLOUR, SBF_ZERO);
597                        break;
598            case SBT_ADD:
599                    setSceneBlending(SBF_ONE, SBF_ONE);
600                    break;
601        case SBT_REPLACE:
602            setSceneBlending(SBF_ONE, SBF_ZERO);
603            break;
604            // TODO: more
605            }
606
607    }
608    //-----------------------------------------------------------------------
609    void Pass::setSceneBlending(SceneBlendFactor sourceFactor, SceneBlendFactor destFactor)
610    {
611            mSourceBlendFactor = sourceFactor;
612            mDestBlendFactor = destFactor;
613    }
614    //-----------------------------------------------------------------------
615    SceneBlendFactor Pass::getSourceBlendFactor(void) const
616    {
617            return mSourceBlendFactor;
618    }
619    //-----------------------------------------------------------------------
620    SceneBlendFactor Pass::getDestBlendFactor(void) const
621    {
622            return mDestBlendFactor;
623    }
624    //-----------------------------------------------------------------------
625    bool Pass::isTransparent(void) const
626    {
627                // Transparent if any of the destination colour is taken into account
628                if (mDestBlendFactor == SBF_ZERO &&
629                        mSourceBlendFactor != SBF_DEST_COLOUR &&
630                        mSourceBlendFactor != SBF_ONE_MINUS_DEST_COLOUR &&
631                        mSourceBlendFactor != SBF_DEST_ALPHA &&
632                        mSourceBlendFactor != SBF_ONE_MINUS_DEST_ALPHA)
633                {
634                    return false;
635                }
636            else
637                {
638                    return true;
639                }
640    }
641    //-----------------------------------------------------------------------
642    void Pass::setDepthCheckEnabled(bool enabled)
643    {
644            mDepthCheck = enabled;
645    }
646    //-----------------------------------------------------------------------
647    bool Pass::getDepthCheckEnabled(void) const
648    {
649            return mDepthCheck;
650    }
651    //-----------------------------------------------------------------------
652    void Pass::setDepthWriteEnabled(bool enabled)
653    {
654            mDepthWrite = enabled;
655    }
656    //-----------------------------------------------------------------------
657    bool Pass::getDepthWriteEnabled(void) const
658    {
659            return mDepthWrite;
660    }
661    //-----------------------------------------------------------------------
662    void Pass::setDepthFunction( CompareFunction func)
663    {
664            mDepthFunc = func;
665    }
666    //-----------------------------------------------------------------------
667    CompareFunction Pass::getDepthFunction(void) const
668    {
669            return mDepthFunc;
670    }
671        //-----------------------------------------------------------------------
672        void Pass::setAlphaRejectSettings(CompareFunction func, unsigned char value)
673        {
674                mAlphaRejectFunc = func;
675                mAlphaRejectVal = value;
676        }
677        //-----------------------------------------------------------------------
678        void Pass::setAlphaRejectFunction(CompareFunction func)
679        {
680                mAlphaRejectFunc = func;
681        }
682        //-----------------------------------------------------------------------
683        void Pass::setAlphaRejectValue(unsigned char val)
684        {
685                mAlphaRejectVal = val;
686        }
687    //-----------------------------------------------------------------------
688        void Pass::setColourWriteEnabled(bool enabled)
689        {
690                mColourWrite = enabled;
691        }
692    //-----------------------------------------------------------------------
693        bool Pass::getColourWriteEnabled(void) const
694        {
695                return mColourWrite;
696        }
697    //-----------------------------------------------------------------------
698    void Pass::setCullingMode( CullingMode mode)
699    {
700            mCullMode = mode;
701    }
702    //-----------------------------------------------------------------------
703    CullingMode Pass::getCullingMode(void) const
704    {
705            return mCullMode;
706    }
707    //-----------------------------------------------------------------------
708    void Pass::setLightingEnabled(bool enabled)
709    {
710            mLightingEnabled = enabled;
711    }
712    //-----------------------------------------------------------------------
713    bool Pass::getLightingEnabled(void) const
714    {
715            return mLightingEnabled;
716    }
717    //-----------------------------------------------------------------------
718    void Pass::setMaxSimultaneousLights(unsigned short maxLights)
719    {
720        mMaxSimultaneousLights = maxLights;
721    }
722    //-----------------------------------------------------------------------
723    unsigned short Pass::getMaxSimultaneousLights(void) const
724    {
725        return mMaxSimultaneousLights;
726    }
727    //-----------------------------------------------------------------------
728    void Pass::setIteratePerLight(bool enabled,
729            bool onlyForOneLightType, Light::LightTypes lightType)
730    {
731        mIteratePerLight = enabled;
732        mRunOnlyForOneLightType = onlyForOneLightType;
733        mOnlyLightType = lightType;
734    }
735    //-----------------------------------------------------------------------
736    void Pass::setShadingMode(ShadeOptions mode)
737    {
738            mShadeOptions = mode;
739    }
740    //-----------------------------------------------------------------------
741    ShadeOptions Pass::getShadingMode(void) const
742    {
743            return mShadeOptions;
744    }
745        //-----------------------------------------------------------------------
746        void Pass::setPolygonMode(PolygonMode mode)
747        {
748                mPolygonMode = mode;
749        }
750        //-----------------------------------------------------------------------
751        PolygonMode Pass::getPolygonMode(void) const
752        {
753                return mPolygonMode;
754        }
755    //-----------------------------------------------------------------------
756    void Pass::setManualCullingMode(ManualCullingMode mode)
757    {
758            mManualCullMode = mode;
759    }
760    //-----------------------------------------------------------------------
761    ManualCullingMode Pass::getManualCullingMode(void) const
762    {
763            return mManualCullMode;
764    }
765    //-----------------------------------------------------------------------
766    void Pass::setFog(bool overrideScene, FogMode mode, const ColourValue& colour, Real density, Real start, Real end)
767    {
768            mFogOverride = overrideScene;
769            if (overrideScene)
770            {
771                    mFogMode = mode;
772                    mFogColour = colour;
773                    mFogStart = start;
774                    mFogEnd = end;
775                    mFogDensity = density;
776            }
777    }
778    //-----------------------------------------------------------------------
779    bool Pass::getFogOverride(void) const
780    {
781            return mFogOverride;
782    }
783    //-----------------------------------------------------------------------
784    FogMode Pass::getFogMode(void) const
785    {
786            return mFogMode;
787    }
788    //-----------------------------------------------------------------------
789    const ColourValue& Pass::getFogColour(void) const
790    {
791            return mFogColour;
792    }
793    //-----------------------------------------------------------------------
794    Real Pass::getFogStart(void) const
795    {
796            return mFogStart;
797    }
798    //-----------------------------------------------------------------------
799    Real Pass::getFogEnd(void) const
800    {
801            return mFogEnd;
802    }
803    //-----------------------------------------------------------------------
804    Real Pass::getFogDensity(void) const
805    {
806            return mFogDensity;
807    }
808    //-----------------------------------------------------------------------
809    void Pass::setDepthBias(ushort bias)
810    {
811        assert(bias <= 16 && "Depth bias must be between 0 and 16");
812        mDepthBias = bias;
813    }
814    //-----------------------------------------------------------------------
815    ushort Pass::getDepthBias(void) const
816    {
817        return mDepthBias;
818    }
819    //-----------------------------------------------------------------------
820        Pass* Pass::_split(unsigned short numUnits)
821        {
822                if (mVertexProgramUsage || mFragmentProgramUsage)
823                {
824                        OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Programmable passes cannot be "
825                                "automatically split, define a fallback technique instead.",
826                                "Pass:_split");
827                }
828
829                if (mTextureUnitStates.size() > numUnits)
830                {
831                        size_t start = mTextureUnitStates.size() - numUnits;
832                       
833                        Pass* newPass = mParent->createPass();
834
835                        TextureUnitStates::iterator istart, i, iend;
836                        iend = mTextureUnitStates.end();
837                        i = istart = mTextureUnitStates.begin() + start;
838                        // Set the new pass to fallback using scene blend
839                        newPass->setSceneBlending(
840                                (*i)->getColourBlendFallbackSrc(), (*i)->getColourBlendFallbackDest());
841                        // Fixup the texture unit 0   of new pass   blending method   to replace
842                        // all colour and alpha   with texture without adjustment, because we
843                        // assume it's detail texture.
844                        (*i)->setColourOperationEx(LBX_SOURCE1,   LBS_TEXTURE, LBS_CURRENT);
845                        (*i)->setAlphaOperation(LBX_SOURCE1, LBS_TEXTURE, LBS_CURRENT);
846
847                        // Add all the other texture unit states
848                        for (; i != iend; ++i)
849                        {
850                                // detach from parent first
851                                (*i)->_notifyParent(0);
852                                newPass->addTextureUnitState(*i);
853                        }
854                        // Now remove texture units from this Pass, we don't need to delete since they've
855                        // been transferred
856                        mTextureUnitStates.erase(istart, iend);
857                        _dirtyHash();
858                        return newPass;
859                }
860                return NULL;
861        }
862        //-----------------------------------------------------------------------------
863        void Pass::_notifyIndex(unsigned short index)
864        {
865                if (mIndex != index)
866                {
867                        mIndex = index;
868                        _dirtyHash();
869                }
870        }
871    //-----------------------------------------------------------------------
872        void Pass::_load(void)
873        {
874                // We assume the Technique only calls this when the material is being
875                // loaded
876
877                // Load each TextureUnitState
878                TextureUnitStates::iterator i, iend;
879                iend = mTextureUnitStates.end();
880                for (i = mTextureUnitStates.begin(); i != iend; ++i)
881                {
882                        (*i)->_load();
883                }
884
885                // Load programs
886                if (mVertexProgramUsage)
887                {
888                        // Load vertex program
889            mVertexProgramUsage->_load();
890        }
891        if (mShadowCasterVertexProgramUsage)
892        {
893            // Load vertex program
894            mShadowCasterVertexProgramUsage->_load();
895        }
896        if (mShadowReceiverVertexProgramUsage)
897        {
898            // Load vertex program
899            mShadowReceiverVertexProgramUsage->_load();
900        }
901
902        if (mFragmentProgramUsage)
903        {
904                        // Load fragment program
905            mFragmentProgramUsage->_load();
906                }
907                if (mShadowReceiverFragmentProgramUsage)
908                {
909                        // Load Fragment program
910                        mShadowReceiverFragmentProgramUsage->_load();
911                }
912
913        // Recalculate hash
914        _dirtyHash();
915               
916        }
917    //-----------------------------------------------------------------------
918        void Pass::_unload(void)
919        {
920                // Unload each TextureUnitState
921                TextureUnitStates::iterator i, iend;
922                iend = mTextureUnitStates.end();
923                for (i = mTextureUnitStates.begin(); i != iend; ++i)
924                {
925                        (*i)->_unload();
926                }
927
928                // Unload programs
929                if (mVertexProgramUsage)
930                {
931                        // TODO
932                }
933        if (mFragmentProgramUsage)
934        {
935            // TODO
936        }
937        }
938    //-----------------------------------------------------------------------
939        void Pass::setVertexProgram(const String& name, bool resetParams)
940        {
941        // Turn off vertex program if name blank
942        if (name.empty())
943        {
944            if (mVertexProgramUsage) delete mVertexProgramUsage;
945            mVertexProgramUsage = NULL;
946        }
947        else
948        {
949            if (!mVertexProgramUsage)
950            {
951                mVertexProgramUsage = new GpuProgramUsage(GPT_VERTEX_PROGRAM);
952            }
953                    mVertexProgramUsage->setProgramName(name, resetParams);
954        }
955        // Needs recompilation
956        mParent->_notifyNeedsRecompile();
957        }
958    //-----------------------------------------------------------------------
959        void Pass::setVertexProgramParameters(GpuProgramParametersSharedPtr params)
960        {
961                if (!mVertexProgramUsage)
962        {
963            OGRE_EXCEPT (Exception::ERR_INVALIDPARAMS,
964                "This pass does not have a vertex program assigned!",
965                "Pass::setVertexProgramParameters");
966        }
967                mVertexProgramUsage->setParameters(params);
968        }
969    //-----------------------------------------------------------------------
970        void Pass::setFragmentProgram(const String& name, bool resetParams)
971        {
972        // Turn off fragment program if name blank
973        if (name.empty())
974        {
975            if (mFragmentProgramUsage) delete mFragmentProgramUsage;
976            mFragmentProgramUsage = NULL;
977        }
978        else
979        {
980            if (!mFragmentProgramUsage)
981            {
982                mFragmentProgramUsage = new GpuProgramUsage(GPT_FRAGMENT_PROGRAM);
983            }
984                    mFragmentProgramUsage->setProgramName(name, resetParams);
985        }
986        // Needs recompilation
987        mParent->_notifyNeedsRecompile();
988        }
989    //-----------------------------------------------------------------------
990        void Pass::setFragmentProgramParameters(GpuProgramParametersSharedPtr params)
991        {
992                if (!mFragmentProgramUsage)
993        {
994            OGRE_EXCEPT (Exception::ERR_INVALIDPARAMS,
995                "This pass does not have a fragment program assigned!",
996                "Pass::setFragmentProgramParameters");
997        }
998                mFragmentProgramUsage->setParameters(params);
999        }
1000        //-----------------------------------------------------------------------
1001        const String& Pass::getVertexProgramName(void) const
1002        {
1003        if (!mVertexProgramUsage)
1004            return StringUtil::BLANK;
1005        else
1006                    return mVertexProgramUsage->getProgramName();
1007        }
1008        //-----------------------------------------------------------------------
1009        GpuProgramParametersSharedPtr Pass::getVertexProgramParameters(void) const
1010        {
1011                if (!mVertexProgramUsage)
1012        {
1013            OGRE_EXCEPT (Exception::ERR_INVALIDPARAMS,
1014                "This pass does not have a vertex program assigned!",
1015                "Pass::getVertexProgramParameters");
1016        }
1017                return mVertexProgramUsage->getParameters();
1018        }
1019        //-----------------------------------------------------------------------
1020        const GpuProgramPtr& Pass::getVertexProgram(void) const
1021        {
1022                return mVertexProgramUsage->getProgram();
1023        }
1024        //-----------------------------------------------------------------------
1025        const String& Pass::getFragmentProgramName(void) const
1026        {
1027        if (!mFragmentProgramUsage)
1028            return StringUtil::BLANK;
1029        else
1030                return mFragmentProgramUsage->getProgramName();
1031        }
1032        //-----------------------------------------------------------------------
1033        GpuProgramParametersSharedPtr Pass::getFragmentProgramParameters(void) const
1034        {
1035                return mFragmentProgramUsage->getParameters();
1036        }
1037        //-----------------------------------------------------------------------
1038        const GpuProgramPtr& Pass::getFragmentProgram(void) const
1039        {
1040                return mFragmentProgramUsage->getProgram();
1041        }
1042        //-----------------------------------------------------------------------
1043    bool Pass::isLoaded(void) const
1044    {
1045        return mParent->isLoaded();
1046    }
1047        //-----------------------------------------------------------------------
1048    uint32 Pass::getHash(void) const
1049    {
1050        return mHash;
1051    }
1052        //-----------------------------------------------------------------------
1053    void Pass::_recalculateHash(void)
1054    {
1055        /* Hash format is 32-bit, divided as follows (high to low bits)
1056           bits   purpose
1057            4     Pass index (i.e. max 16 passes!)
1058           14     Hashed texture name from unit 0
1059           14     Hashed texture name from unit 1
1060
1061           Note that at the moment we don't sort on the 3rd texture unit plus
1062           on the assumption that these are less frequently used; sorting on
1063           the first 2 gives us the most benefit for now.
1064       */
1065        _StringHash H;
1066        mHash = (mIndex << 28);
1067        size_t c = getNumTextureUnitStates();
1068
1069        if (c && !mTextureUnitStates[0]->isBlank())
1070            mHash += (H(mTextureUnitStates[0]->getTextureName()) % (1 << 14)) << 14;
1071        if (c > 1 && !mTextureUnitStates[1]->isBlank())
1072            mHash += (H(mTextureUnitStates[1]->getTextureName()) % (1 << 14));
1073    }
1074    //-----------------------------------------------------------------------
1075        void Pass::_dirtyHash(void)
1076        {
1077                // Mark this hash as for follow up
1078                msDirtyHashList.insert(this);
1079        }
1080    //-----------------------------------------------------------------------
1081    void Pass::_notifyNeedsRecompile(void)
1082    {
1083        mParent->_notifyNeedsRecompile();
1084    }
1085    //-----------------------------------------------------------------------
1086    void Pass::setTextureFiltering(TextureFilterOptions filterType)
1087    {
1088        TextureUnitStates::iterator i, iend;
1089        iend = mTextureUnitStates.end();
1090        for (i = mTextureUnitStates.begin(); i != iend; ++i)
1091        {
1092            (*i)->setTextureFiltering(filterType);
1093        }
1094    }
1095    // --------------------------------------------------------------------
1096    void Pass::setTextureAnisotropy(unsigned int maxAniso)
1097    {
1098        TextureUnitStates::iterator i, iend;
1099        iend = mTextureUnitStates.end();
1100        for (i = mTextureUnitStates.begin(); i != iend; ++i)
1101        {
1102            (*i)->setTextureAnisotropy(maxAniso);
1103        }
1104    }
1105    //-----------------------------------------------------------------------
1106    void Pass::_updateAutoParamsNoLights(const AutoParamDataSource& source) const
1107    {
1108        if (hasVertexProgram())
1109        {
1110            // Update vertex program auto params
1111            mVertexProgramUsage->getParameters()->_updateAutoParamsNoLights(source);
1112        }
1113
1114        if (hasFragmentProgram())
1115        {
1116            // Update fragment program auto params
1117            mFragmentProgramUsage->getParameters()->_updateAutoParamsNoLights(source);
1118        }
1119    }
1120    //-----------------------------------------------------------------------
1121    void Pass::_updateAutoParamsLightsOnly(const AutoParamDataSource& source) const
1122    {
1123        if (hasVertexProgram())
1124        {
1125            // Update vertex program auto params
1126            mVertexProgramUsage->getParameters()->_updateAutoParamsLightsOnly(source);
1127        }
1128
1129        if (hasFragmentProgram())
1130        {
1131            // Update fragment program auto params
1132            mFragmentProgramUsage->getParameters()->_updateAutoParamsLightsOnly(source);
1133        }
1134    }
1135    //-----------------------------------------------------------------------
1136    void Pass::processPendingPassUpdates(void)
1137    {
1138        // Delete items in the graveyard
1139        PassSet::iterator i, iend;
1140        iend = msPassGraveyard.end();
1141        for (i = msPassGraveyard.begin(); i != iend; ++i)
1142        {
1143            delete *i;
1144        }
1145        msPassGraveyard.clear();
1146
1147        // The dirty ones will have been removed from the groups above using the old hash now
1148        iend = msDirtyHashList.end();
1149        for (i = msDirtyHashList.begin(); i != iend; ++i)
1150        {
1151            Pass* p = *i;
1152            p->_recalculateHash();
1153        }
1154        // Clear the dirty list
1155        msDirtyHashList.clear();
1156    }
1157    //-----------------------------------------------------------------------
1158    void Pass::queueForDeletion(void)
1159    {
1160        mQueuedForDeletion = true;
1161
1162        removeAllTextureUnitStates();
1163        if (mVertexProgramUsage)
1164        {
1165            delete mVertexProgramUsage;
1166            mVertexProgramUsage = 0;
1167        }
1168        if (mShadowCasterVertexProgramUsage)
1169        {
1170            delete mShadowCasterVertexProgramUsage;
1171            mShadowCasterVertexProgramUsage = 0;
1172        }
1173        if (mShadowReceiverVertexProgramUsage)
1174        {
1175            delete mShadowReceiverVertexProgramUsage;
1176            mShadowReceiverVertexProgramUsage = 0;
1177        }
1178        if (mFragmentProgramUsage)
1179        {
1180            delete mFragmentProgramUsage;
1181            mFragmentProgramUsage = 0;
1182        }
1183                if (mShadowReceiverFragmentProgramUsage)
1184                {
1185                        delete mShadowReceiverFragmentProgramUsage;
1186                        mShadowReceiverFragmentProgramUsage = 0;
1187                }
1188        // remove from dirty list, if there
1189        msDirtyHashList.erase(this);
1190
1191        msPassGraveyard.insert(this);
1192    }
1193    //-----------------------------------------------------------------------
1194    bool Pass::isAmbientOnly(void) const
1195    {
1196        // treat as ambient if lighting is off, or colour write is off,
1197        // or all non-ambient (& emissive) colours are black
1198        // NB a vertex program could override this, but passes using vertex
1199        // programs are expected to indicate they are ambient only by
1200        // setting the state so it matches one of the conditions above, even
1201        // though this state is not used in rendering.
1202        return (!mLightingEnabled || !mColourWrite ||
1203            (mDiffuse == ColourValue::Black &&
1204             mSpecular == ColourValue::Black));
1205    }
1206    //-----------------------------------------------------------------------
1207    void Pass::setShadowCasterVertexProgram(const String& name)
1208    {
1209        // Turn off vertex program if name blank
1210        if (name.empty())
1211        {
1212            if (mShadowCasterVertexProgramUsage) delete mShadowCasterVertexProgramUsage;
1213            mShadowCasterVertexProgramUsage = NULL;
1214        }
1215        else
1216        {
1217            if (!mShadowCasterVertexProgramUsage)
1218            {
1219                mShadowCasterVertexProgramUsage = new GpuProgramUsage(GPT_VERTEX_PROGRAM);
1220            }
1221            mShadowCasterVertexProgramUsage->setProgramName(name);
1222        }
1223        // Needs recompilation
1224        mParent->_notifyNeedsRecompile();
1225    }
1226    //-----------------------------------------------------------------------
1227    void Pass::setShadowCasterVertexProgramParameters(GpuProgramParametersSharedPtr params)
1228    {
1229        if (!mShadowCasterVertexProgramUsage)
1230        {
1231            OGRE_EXCEPT (Exception::ERR_INVALIDPARAMS,
1232                "This pass does not have a shadow caster vertex program assigned!",
1233                "Pass::setShadowCasterVertexProgramParameters");
1234        }
1235        mShadowCasterVertexProgramUsage->setParameters(params);
1236    }
1237    //-----------------------------------------------------------------------
1238    const String& Pass::getShadowCasterVertexProgramName(void) const
1239    {
1240        if (!mShadowCasterVertexProgramUsage)
1241            return StringUtil::BLANK;
1242        else
1243            return mShadowCasterVertexProgramUsage->getProgramName();
1244    }
1245    //-----------------------------------------------------------------------
1246    GpuProgramParametersSharedPtr Pass::getShadowCasterVertexProgramParameters(void) const
1247    {
1248        if (!mShadowCasterVertexProgramUsage)
1249        {
1250            OGRE_EXCEPT (Exception::ERR_INVALIDPARAMS,
1251                "This pass does not have a shadow caster vertex program assigned!",
1252                "Pass::getShadowCasterVertexProgramParameters");
1253        }
1254        return mShadowCasterVertexProgramUsage->getParameters();
1255    }
1256    //-----------------------------------------------------------------------
1257    const GpuProgramPtr& Pass::getShadowCasterVertexProgram(void) const
1258    {
1259        return mShadowCasterVertexProgramUsage->getProgram();
1260    }
1261    //-----------------------------------------------------------------------
1262    void Pass::setShadowReceiverVertexProgram(const String& name)
1263    {
1264        // Turn off vertex program if name blank
1265        if (name.empty())
1266        {
1267            if (mShadowReceiverVertexProgramUsage) delete mShadowReceiverVertexProgramUsage;
1268            mShadowReceiverVertexProgramUsage = NULL;
1269        }
1270        else
1271        {
1272            if (!mShadowReceiverVertexProgramUsage)
1273            {
1274                mShadowReceiverVertexProgramUsage = new GpuProgramUsage(GPT_VERTEX_PROGRAM);
1275            }
1276            mShadowReceiverVertexProgramUsage->setProgramName(name);
1277        }
1278        // Needs recompilation
1279        mParent->_notifyNeedsRecompile();
1280    }
1281    //-----------------------------------------------------------------------
1282    void Pass::setShadowReceiverVertexProgramParameters(GpuProgramParametersSharedPtr params)
1283    {
1284        if (!mShadowReceiverVertexProgramUsage)
1285        {
1286            OGRE_EXCEPT (Exception::ERR_INVALIDPARAMS,
1287                "This pass does not have a shadow receiver vertex program assigned!",
1288                "Pass::setShadowReceiverVertexProgramParameters");
1289        }
1290        mShadowReceiverVertexProgramUsage->setParameters(params);
1291    }
1292    //-----------------------------------------------------------------------
1293    const String& Pass::getShadowReceiverVertexProgramName(void) const
1294    {
1295        if (!mShadowReceiverVertexProgramUsage)
1296            return StringUtil::BLANK;
1297        else
1298            return mShadowReceiverVertexProgramUsage->getProgramName();
1299    }
1300    //-----------------------------------------------------------------------
1301    GpuProgramParametersSharedPtr Pass::getShadowReceiverVertexProgramParameters(void) const
1302    {
1303        if (!mShadowReceiverVertexProgramUsage)
1304        {
1305            OGRE_EXCEPT (Exception::ERR_INVALIDPARAMS,
1306                "This pass does not have a shadow receiver vertex program assigned!",
1307                "Pass::getShadowReceiverVertexProgramParameters");
1308        }
1309        return mShadowReceiverVertexProgramUsage->getParameters();
1310    }
1311    //-----------------------------------------------------------------------
1312    const GpuProgramPtr& Pass::getShadowReceiverVertexProgram(void) const
1313    {
1314        return mShadowReceiverVertexProgramUsage->getProgram();
1315    }
1316        //-----------------------------------------------------------------------
1317        void Pass::setShadowReceiverFragmentProgram(const String& name)
1318        {
1319                // Turn off Fragment program if name blank
1320                if (name.empty())
1321                {
1322                        if (mShadowReceiverFragmentProgramUsage) delete mShadowReceiverFragmentProgramUsage;
1323                        mShadowReceiverFragmentProgramUsage = NULL;
1324                }
1325                else
1326                {
1327                        if (!mShadowReceiverFragmentProgramUsage)
1328                        {
1329                                mShadowReceiverFragmentProgramUsage = new GpuProgramUsage(GPT_FRAGMENT_PROGRAM);
1330                        }
1331                        mShadowReceiverFragmentProgramUsage->setProgramName(name);
1332                }
1333                // Needs recompilation
1334                mParent->_notifyNeedsRecompile();
1335        }
1336        //-----------------------------------------------------------------------
1337        void Pass::setShadowReceiverFragmentProgramParameters(GpuProgramParametersSharedPtr params)
1338        {
1339                if (!mShadowReceiverFragmentProgramUsage)
1340                {
1341                        OGRE_EXCEPT (Exception::ERR_INVALIDPARAMS,
1342                                "This pass does not have a shadow receiver fragment program assigned!",
1343                                "Pass::setShadowReceiverFragmentProgramParameters");
1344                }
1345                mShadowReceiverFragmentProgramUsage->setParameters(params);
1346        }
1347        //-----------------------------------------------------------------------
1348        const String& Pass::getShadowReceiverFragmentProgramName(void) const
1349        {
1350                if (!mShadowReceiverFragmentProgramUsage)
1351                        return StringUtil::BLANK;
1352                else
1353                        return mShadowReceiverFragmentProgramUsage->getProgramName();
1354        }
1355        //-----------------------------------------------------------------------
1356        GpuProgramParametersSharedPtr Pass::getShadowReceiverFragmentProgramParameters(void) const
1357        {
1358                if (!mShadowReceiverFragmentProgramUsage)
1359                {
1360                        OGRE_EXCEPT (Exception::ERR_INVALIDPARAMS,
1361                                "This pass does not have a shadow receiver fragment program assigned!",
1362                                "Pass::getShadowReceiverFragmentProgramParameters");
1363                }
1364                return mShadowReceiverFragmentProgramUsage->getParameters();
1365        }
1366        //-----------------------------------------------------------------------
1367        const GpuProgramPtr& Pass::getShadowReceiverFragmentProgram(void) const
1368        {
1369                return mShadowReceiverFragmentProgramUsage->getProgram();
1370        }
1371    //-----------------------------------------------------------------------
1372        const String& Pass::getResourceGroup(void) const
1373        {
1374                return mParent->getResourceGroup();
1375        }
1376
1377    //-----------------------------------------------------------------------
1378    bool Pass::applyTextureAliases(const AliasTextureNamePairList& aliasList, const bool apply) const
1379    {
1380        // iterate through each texture unit state and apply the texture alias if it applies
1381        TextureUnitStates::const_iterator i, iend;
1382        iend = mTextureUnitStates.end();
1383        bool testResult = false;
1384
1385        for (i = mTextureUnitStates.begin(); i != iend; ++i)
1386        {
1387            if ((*i)->applyTextureAliases(aliasList, apply))
1388                testResult = true;
1389        }
1390
1391        return testResult;
1392
1393    }
1394
1395
1396}
Note: See TracBrowser for help on using the repository browser.