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

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