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

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