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

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

added ogre dependencies and patched ogre sources

Line 
1/*
2-----------------------------------------------------------------------------
3This source file is part of OGRE
4    (Object-oriented Graphics Rendering Engine)
5For the latest info, see http://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 "OgreMaterialManager.h"
30#include "OgreException.h"
31#include "OgreGpuProgramUsage.h"
32#include "OgreTextureUnitState.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)
42    {
43        // Default to white ambient & diffuse, no specular / emissive
44            mAmbient = mDiffuse = ColourValue::White;
45            mSpecular = mEmissive = ColourValue::Black;
46            mShininess = 0;
47       mTracking = TVC_NONE;
48        mHash = 0;
49
50        // By default, don't override the scene's fog settings
51        mFogOverride = false;
52        mFogMode = FOG_NONE;
53        mFogColour = ColourValue::White;
54        mFogStart = 0.0;
55        mFogEnd = 1.0;
56        mFogDensity = 0.001;
57
58            // Default blending (overwrite)
59            mSourceBlendFactor = SBF_ONE;
60            mDestBlendFactor = SBF_ZERO;
61
62            mDepthCheck = true;
63            mDepthWrite = true;
64        mColourWrite = true;
65            mDepthFunc = CMPF_LESS_EQUAL;
66        mDepthBias = 0;
67                mAlphaRejectFunc = CMPF_ALWAYS_PASS;
68                mAlphaRejectVal = 0;
69            mCullMode = CULL_CLOCKWISE;
70            mManualCullMode = MANUAL_CULL_BACK;
71            mLightingEnabled = true;
72        mMaxSimultaneousLights = OGRE_MAX_SIMULTANEOUS_LIGHTS;
73                mRunOncePerLight = false;
74        mRunOnlyForOneLightType = true;
75        mOnlyLightType = Light::LT_POINT;
76            mShadeOptions = SO_GOURAUD;
77
78                mVertexProgramUsage = NULL;
79        mShadowCasterVertexProgramUsage = NULL;
80        mShadowReceiverVertexProgramUsage = NULL;
81                mFragmentProgramUsage = NULL;
82
83        mQueuedForDeletion = false;
84
85        _dirtyHash();
86   }
87       
88    //-----------------------------------------------------------------------------
89        Pass::Pass(Technique *parent, unsigned short index, const Pass& oth)
90        :mParent(parent), mIndex(index), mQueuedForDeletion(false)
91    {
92        *this = oth;
93        mParent = parent;
94        mIndex = index;
95        mQueuedForDeletion = false;
96        _dirtyHash();
97    }
98    //-----------------------------------------------------------------------------
99    Pass::~Pass()
100    {
101
102    }
103    //-----------------------------------------------------------------------------
104    Pass& Pass::operator=(const Pass& oth)
105    {
106            mAmbient = oth.mAmbient;
107        mDiffuse = oth.mDiffuse;
108            mSpecular = oth.mSpecular;
109        mEmissive = oth.mEmissive;
110            mShininess = oth.mShininess;
111       mTracking = oth.mTracking;
112
113        // Copy fog parameters
114        mFogOverride = oth.mFogOverride;
115        mFogMode = oth.mFogMode;
116        mFogColour = oth.mFogColour;
117        mFogStart = oth.mFogStart;
118        mFogEnd = oth.mFogEnd;
119        mFogDensity = oth.mFogDensity;
120
121            // Default blending (overwrite)
122            mSourceBlendFactor = oth.mSourceBlendFactor;
123            mDestBlendFactor = oth.mDestBlendFactor;
124
125            mDepthCheck = oth.mDepthCheck;
126            mDepthWrite = oth.mDepthWrite;
127                mAlphaRejectFunc = oth.mAlphaRejectFunc;
128                mAlphaRejectVal = oth.mAlphaRejectVal;
129        mColourWrite = oth.mColourWrite;
130            mDepthFunc = oth.mDepthFunc;
131        mDepthBias = oth.mDepthBias;
132            mCullMode = oth.mCullMode;
133            mManualCullMode = oth.mManualCullMode;
134            mLightingEnabled = oth.mLightingEnabled;
135        mMaxSimultaneousLights = oth.mMaxSimultaneousLights;
136                mRunOncePerLight = oth.mRunOncePerLight;
137        mRunOnlyForOneLightType = oth.mRunOnlyForOneLightType;
138        mOnlyLightType = oth.mOnlyLightType;
139            mShadeOptions = oth.mShadeOptions;
140
141                if (oth.mVertexProgramUsage)
142                {
143                        mVertexProgramUsage = new GpuProgramUsage(*(oth.mVertexProgramUsage));
144                }
145                else
146                {
147                    mVertexProgramUsage = NULL;
148                }
149        if (oth.mShadowCasterVertexProgramUsage)
150        {
151            mShadowCasterVertexProgramUsage = new GpuProgramUsage(*(oth.mShadowCasterVertexProgramUsage));
152        }
153        else
154        {
155            mShadowCasterVertexProgramUsage = NULL;
156        }
157        if (oth.mShadowReceiverVertexProgramUsage)
158        {
159            mShadowReceiverVertexProgramUsage = new GpuProgramUsage(*(oth.mShadowReceiverVertexProgramUsage));
160        }
161        else
162        {
163            mShadowReceiverVertexProgramUsage = NULL;
164        }
165                if (oth.mFragmentProgramUsage)
166                {
167                    mFragmentProgramUsage = new GpuProgramUsage(*(oth.mFragmentProgramUsage));
168        }
169        else
170        {
171                    mFragmentProgramUsage = NULL;
172        }
173
174                TextureUnitStates::const_iterator i, iend;
175
176        // Clear texture units but doesn't notify need recompilation in the case
177        // we are cloning, The parent material will take care of this.
178        iend = mTextureUnitStates.end();
179        for (i = mTextureUnitStates.begin(); i != iend; ++i)
180        {
181            delete *i;
182        }
183
184        mTextureUnitStates.clear();
185
186                // Copy texture units
187                iend = oth.mTextureUnitStates.end();
188                for (i = oth.mTextureUnitStates.begin(); i != iend; ++i)
189                {
190                        TextureUnitState* t = new TextureUnitState(this, *(*i));
191                        mTextureUnitStates.push_back(t);
192                }
193
194        _dirtyHash();
195
196                return *this;
197    }
198    //-----------------------------------------------------------------------
199    void Pass::setAmbient(Real red, Real green, Real blue)
200    {
201            mAmbient.r = red;
202            mAmbient.g = green;
203            mAmbient.b = blue;
204
205    }
206    //-----------------------------------------------------------------------
207    void Pass::setAmbient(const ColourValue& ambient)
208    {
209            mAmbient = ambient;
210    }
211    //-----------------------------------------------------------------------
212    void Pass::setDiffuse(Real red, Real green, Real blue, Real alpha)
213    {
214            mDiffuse.r = red;
215            mDiffuse.g = green;
216            mDiffuse.b = blue;
217                mDiffuse.a = alpha;
218    }
219    //-----------------------------------------------------------------------
220    void Pass::setDiffuse(const ColourValue& diffuse)
221    {
222            mDiffuse = diffuse;
223    }
224    //-----------------------------------------------------------------------
225    void Pass::setSpecular(Real red, Real green, Real blue, Real alpha)
226    {
227            mSpecular.r = red;
228            mSpecular.g = green;
229            mSpecular.b = blue;
230                mSpecular.a = alpha;
231    }
232    //-----------------------------------------------------------------------
233    void Pass::setSpecular(const ColourValue& specular)
234    {
235            mSpecular = specular;
236    }
237    //-----------------------------------------------------------------------
238    void Pass::setShininess(Real val)
239    {
240            mShininess = val;
241    }
242    //-----------------------------------------------------------------------
243    void Pass::setSelfIllumination(Real red, Real green, Real blue)
244    {
245            mEmissive.r = red;
246            mEmissive.g = green;
247            mEmissive.b = blue;
248
249    }
250    //-----------------------------------------------------------------------
251    void Pass::setSelfIllumination(const ColourValue& selfIllum)
252    {
253            mEmissive = selfIllum;
254    }
255    //-----------------------------------------------------------------------
256    void Pass::setVertexColourTracking(TrackVertexColourType tracking)
257    {
258        mTracking = tracking;
259    }
260    //-----------------------------------------------------------------------
261    const ColourValue& Pass::getAmbient(void) const
262    {
263            return mAmbient;
264    }
265    //-----------------------------------------------------------------------
266    const ColourValue& Pass::getDiffuse(void) const
267    {
268            return mDiffuse;
269    }
270    //-----------------------------------------------------------------------
271    const ColourValue& Pass::getSpecular(void) const
272    {
273            return mSpecular;
274    }
275    //-----------------------------------------------------------------------
276    const ColourValue& Pass::getSelfIllumination(void) const
277    {
278            return mEmissive;
279    }
280    //-----------------------------------------------------------------------
281    Real Pass::getShininess(void) const
282    {
283            return mShininess;
284    }
285    //-----------------------------------------------------------------------
286    TrackVertexColourType Pass::getVertexColourTracking(void) const
287    {
288        return mTracking;
289    }
290    //-----------------------------------------------------------------------
291    TextureUnitState* Pass::createTextureUnitState(void)
292    {
293        TextureUnitState *t = new TextureUnitState(this);
294        mTextureUnitStates.push_back(t);
295        // Needs recompilation
296        mParent->_notifyNeedsRecompile();
297        _dirtyHash();
298            return t;
299    }
300    //-----------------------------------------------------------------------
301    TextureUnitState* Pass::createTextureUnitState(
302        const String& textureName, unsigned short texCoordSet)
303    {
304        TextureUnitState *t = new TextureUnitState(this);
305            t->setTextureName(textureName);
306            t->setTextureCoordSet(texCoordSet);
307        mTextureUnitStates.push_back(t);
308        // Needs recompilation
309        mParent->_notifyNeedsRecompile();
310        _dirtyHash();
311            return t;
312    }
313    //-----------------------------------------------------------------------
314        void Pass::addTextureUnitState(TextureUnitState* state)
315        {
316                // Notify state
317                state->_notifyParent(this);
318                mTextureUnitStates.push_back(state);
319        // Needs recompilation
320        mParent->_notifyNeedsRecompile();
321        _dirtyHash();
322        }
323    //-----------------------------------------------------------------------
324    TextureUnitState* Pass::getTextureUnitState(unsigned short index)
325    {
326        assert (index < mTextureUnitStates.size() && "Index out of bounds");
327            return mTextureUnitStates[index];
328    }
329    //-----------------------------------------------------------------------
330    Pass::TextureUnitStateIterator
331        Pass::getTextureUnitStateIterator(void)
332    {
333        return TextureUnitStateIterator(mTextureUnitStates.begin(), mTextureUnitStates.end());
334    }
335    //-----------------------------------------------------------------------
336    void Pass::removeTextureUnitState(unsigned short index)
337    {
338        assert (index < mTextureUnitStates.size() && "Index out of bounds");
339
340        TextureUnitStates::iterator i = mTextureUnitStates.begin() + index;
341        delete *i;
342            mTextureUnitStates.erase(i);
343        if (!mQueuedForDeletion)
344        {
345            // Needs recompilation
346            mParent->_notifyNeedsRecompile();
347        }
348        _dirtyHash();
349    }
350    //-----------------------------------------------------------------------
351    void Pass::removeAllTextureUnitStates(void)
352    {
353        TextureUnitStates::iterator i, iend;
354        iend = mTextureUnitStates.end();
355        for (i = mTextureUnitStates.begin(); i != iend; ++i)
356        {
357            delete *i;
358        }
359        mTextureUnitStates.clear();
360        if (!mQueuedForDeletion)
361        {       
362            // Needs recompilation
363            mParent->_notifyNeedsRecompile();
364        }
365        _dirtyHash();
366    }
367    //-----------------------------------------------------------------------
368    void Pass::setSceneBlending(SceneBlendType sbt)
369    {
370            // Turn predefined type into blending factors
371            switch (sbt)
372            {
373            case SBT_TRANSPARENT_ALPHA:
374                    setSceneBlending(SBF_SOURCE_ALPHA, SBF_ONE_MINUS_SOURCE_ALPHA);
375                    break;
376            case SBT_TRANSPARENT_COLOUR:
377                    setSceneBlending(SBF_SOURCE_COLOUR, SBF_ONE_MINUS_SOURCE_COLOUR);
378                    break;
379                case SBT_MODULATE:
380                        setSceneBlending(SBF_DEST_COLOUR, SBF_ZERO);
381                        break;
382            case SBT_ADD:
383                    setSceneBlending(SBF_ONE, SBF_ONE);
384                    break;
385            // TODO: more
386            }
387
388    }
389    //-----------------------------------------------------------------------
390    void Pass::setSceneBlending(SceneBlendFactor sourceFactor, SceneBlendFactor destFactor)
391    {
392            mSourceBlendFactor = sourceFactor;
393            mDestBlendFactor = destFactor;
394    }
395    //-----------------------------------------------------------------------
396    SceneBlendFactor Pass::getSourceBlendFactor(void) const
397    {
398            return mSourceBlendFactor;
399    }
400    //-----------------------------------------------------------------------
401    SceneBlendFactor Pass::getDestBlendFactor(void) const
402    {
403            return mDestBlendFactor;
404    }
405    //-----------------------------------------------------------------------
406    bool Pass::isTransparent(void) const
407    {
408                // Transparent if any of the destination colour is taken into account
409                if (mDestBlendFactor == SBF_ZERO &&
410                        mSourceBlendFactor != SBF_DEST_COLOUR &&
411                        mSourceBlendFactor != SBF_ONE_MINUS_DEST_COLOUR &&
412                        mSourceBlendFactor != SBF_DEST_ALPHA &&
413                        mSourceBlendFactor != SBF_ONE_MINUS_DEST_ALPHA)
414                {
415                    return false;
416                }
417            else
418                {
419                    return true;
420                }
421    }
422    //-----------------------------------------------------------------------
423    void Pass::setDepthCheckEnabled(bool enabled)
424    {
425            mDepthCheck = enabled;
426    }
427    //-----------------------------------------------------------------------
428    bool Pass::getDepthCheckEnabled(void) const
429    {
430            return mDepthCheck;
431    }
432    //-----------------------------------------------------------------------
433    void Pass::setDepthWriteEnabled(bool enabled)
434    {
435            mDepthWrite = enabled;
436    }
437    //-----------------------------------------------------------------------
438    bool Pass::getDepthWriteEnabled(void) const
439    {
440            return mDepthWrite;
441    }
442    //-----------------------------------------------------------------------
443    void Pass::setDepthFunction( CompareFunction func)
444    {
445            mDepthFunc = func;
446    }
447    //-----------------------------------------------------------------------
448    CompareFunction Pass::getDepthFunction(void) const
449    {
450            return mDepthFunc;
451    }
452        //-----------------------------------------------------------------------
453        void Pass::setAlphaRejectSettings(CompareFunction func, unsigned char value)
454        {
455                mAlphaRejectFunc = func;
456                mAlphaRejectVal = value;
457        }
458        //-----------------------------------------------------------------------
459        void Pass::setAlphaRejectFunction(CompareFunction func)
460        {
461                mAlphaRejectFunc = func;
462        }
463        //-----------------------------------------------------------------------
464        void Pass::setAlphaRejectValue(unsigned char val)
465        {
466                mAlphaRejectVal = val;
467        }
468    //-----------------------------------------------------------------------
469        void Pass::setColourWriteEnabled(bool enabled)
470        {
471                mColourWrite = enabled;
472        }
473    //-----------------------------------------------------------------------
474        bool Pass::getColourWriteEnabled(void) const
475        {
476                return mColourWrite;
477        }
478    //-----------------------------------------------------------------------
479    void Pass::setCullingMode( CullingMode mode)
480    {
481            mCullMode = mode;
482    }
483    //-----------------------------------------------------------------------
484    CullingMode Pass::getCullingMode(void) const
485    {
486            return mCullMode;
487    }
488    //-----------------------------------------------------------------------
489    void Pass::setLightingEnabled(bool enabled)
490    {
491            mLightingEnabled = enabled;
492    }
493    //-----------------------------------------------------------------------
494    bool Pass::getLightingEnabled(void) const
495    {
496            return mLightingEnabled;
497    }
498    //-----------------------------------------------------------------------
499    void Pass::setMaxSimultaneousLights(unsigned short maxLights)
500    {
501        mMaxSimultaneousLights = maxLights;
502    }
503    //-----------------------------------------------------------------------
504    unsigned short Pass::getMaxSimultaneousLights(void) const
505    {
506        return mMaxSimultaneousLights;
507    }
508    //-----------------------------------------------------------------------
509    void Pass::setRunOncePerLight(bool enabled,
510            bool onlyForOneLightType, Light::LightTypes lightType)
511    {
512        mRunOncePerLight = enabled;
513        mRunOnlyForOneLightType = onlyForOneLightType;
514        mOnlyLightType = lightType;
515    }
516    //-----------------------------------------------------------------------
517    void Pass::setShadingMode(ShadeOptions mode)
518    {
519            mShadeOptions = mode;
520    }
521    //-----------------------------------------------------------------------
522    ShadeOptions Pass::getShadingMode(void) const
523    {
524            return mShadeOptions;
525    }
526    //-----------------------------------------------------------------------
527    void Pass::setManualCullingMode(ManualCullingMode mode)
528    {
529            mManualCullMode = mode;
530    }
531    //-----------------------------------------------------------------------
532    ManualCullingMode Pass::getManualCullingMode(void) const
533    {
534            return mManualCullMode;
535    }
536    //-----------------------------------------------------------------------
537    void Pass::setFog(bool overrideScene, FogMode mode, const ColourValue& colour, Real density, Real start, Real end)
538    {
539            mFogOverride = overrideScene;
540            if (overrideScene)
541            {
542                    mFogMode = mode;
543                    mFogColour = colour;
544                    mFogStart = start;
545                    mFogEnd = end;
546                    mFogDensity = density;
547            }
548    }
549    //-----------------------------------------------------------------------
550    bool Pass::getFogOverride(void) const
551    {
552            return mFogOverride;
553    }
554    //-----------------------------------------------------------------------
555    FogMode Pass::getFogMode(void) const
556    {
557            return mFogMode;
558    }
559    //-----------------------------------------------------------------------
560    const ColourValue& Pass::getFogColour(void) const
561    {
562            return mFogColour;
563    }
564    //-----------------------------------------------------------------------
565    Real Pass::getFogStart(void) const
566    {
567            return mFogStart;
568    }
569    //-----------------------------------------------------------------------
570    Real Pass::getFogEnd(void) const
571    {
572            return mFogEnd;
573    }
574    //-----------------------------------------------------------------------
575    Real Pass::getFogDensity(void) const
576    {
577            return mFogDensity;
578    }
579    //-----------------------------------------------------------------------
580    void Pass::setDepthBias(ushort bias)
581    {
582        assert(bias <= 16 && "Depth bias must be between 0 and 16");
583        mDepthBias = bias;
584    }
585    //-----------------------------------------------------------------------
586    ushort Pass::getDepthBias(void) const
587    {
588        return mDepthBias;
589    }
590    //-----------------------------------------------------------------------
591        Pass* Pass::_split(unsigned short numUnits)
592        {
593                if (mVertexProgramUsage || mFragmentProgramUsage)
594                {
595                        OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Programmable passes cannot be "
596                                "automatically split, define a fallback technique instead.",
597                                "Pass:_split");
598                }
599
600                if (mTextureUnitStates.size() > numUnits)
601                {
602                        size_t start = mTextureUnitStates.size() - numUnits;
603                       
604                        Pass* newPass = mParent->createPass();
605
606                        TextureUnitStates::iterator istart, i, iend;
607                        iend = mTextureUnitStates.end();
608                        i = istart = mTextureUnitStates.begin() + start;
609                        // Set the new pass to fallback using scene blend
610                        newPass->setSceneBlending(
611                                (*i)->getColourBlendFallbackSrc(), (*i)->getColourBlendFallbackDest());
612                        // Fixup the texture unit 0   of new pass   blending method   to replace
613                        // all colour and alpha   with texture without adjustment, because we
614                        // assume it's detail texture.
615                        (*i)->setColourOperationEx(LBX_SOURCE1,   LBS_TEXTURE, LBS_CURRENT);
616                        (*i)->setAlphaOperation(LBX_SOURCE1, LBS_TEXTURE, LBS_CURRENT);
617
618                        // Add all the other texture unit states
619                        for (; i != iend; ++i)
620                        {
621                                newPass->addTextureUnitState(*i);
622                        }
623                        // Now remove texture units from this Pass, we don't need to delete since they've
624                        // been transferred
625                        mTextureUnitStates.erase(istart, iend);
626                        _dirtyHash();
627                        return newPass;
628                }
629                return NULL;
630        }
631        //-----------------------------------------------------------------------------
632        void Pass::_notifyIndex(unsigned short index)
633        {
634                if (mIndex != index)
635                {
636                        mIndex = index;
637                        _dirtyHash();
638                }
639        }
640    //-----------------------------------------------------------------------
641        void Pass::_load(void)
642        {
643                // We assume the Technique only calls this when the material is being
644                // loaded
645
646                // Load each TextureUnitState
647                TextureUnitStates::iterator i, iend;
648                iend = mTextureUnitStates.end();
649                for (i = mTextureUnitStates.begin(); i != iend; ++i)
650                {
651                        (*i)->_load();
652                }
653
654                // Load programs
655                if (mVertexProgramUsage)
656                {
657                        // Load vertex program
658            mVertexProgramUsage->_load();
659        }
660        if (mShadowCasterVertexProgramUsage)
661        {
662            // Load vertex program
663            mShadowCasterVertexProgramUsage->_load();
664        }
665        if (mShadowReceiverVertexProgramUsage)
666        {
667            // Load vertex program
668            mShadowReceiverVertexProgramUsage->_load();
669        }
670
671        if (mFragmentProgramUsage)
672        {
673                        // Load fragment program
674            mFragmentProgramUsage->_load();
675                }
676
677        // Recalculate hash
678        _dirtyHash();
679               
680        }
681    //-----------------------------------------------------------------------
682        void Pass::_unload(void)
683        {
684                // Unload each TextureUnitState
685                TextureUnitStates::iterator i, iend;
686                iend = mTextureUnitStates.end();
687                for (i = mTextureUnitStates.begin(); i != iend; ++i)
688                {
689                        (*i)->_unload();
690                }
691
692                // Unload programs
693                if (mVertexProgramUsage)
694                {
695                        // TODO
696                }
697        if (mFragmentProgramUsage)
698        {
699            // TODO
700        }
701        }
702    //-----------------------------------------------------------------------
703        void Pass::setVertexProgram(const String& name, bool resetParams)
704        {
705        // Turn off vertex program if name blank
706        if (name.empty())
707        {
708            if (mVertexProgramUsage) delete mVertexProgramUsage;
709            mVertexProgramUsage = NULL;
710        }
711        else
712        {
713            if (!mVertexProgramUsage)
714            {
715                mVertexProgramUsage = new GpuProgramUsage(GPT_VERTEX_PROGRAM);
716            }
717                    mVertexProgramUsage->setProgramName(name, resetParams);
718        }
719        // Needs recompilation
720        mParent->_notifyNeedsRecompile();
721        }
722    //-----------------------------------------------------------------------
723        void Pass::setVertexProgramParameters(GpuProgramParametersSharedPtr params)
724        {
725                if (!mVertexProgramUsage)
726        {
727            OGRE_EXCEPT (Exception::ERR_INVALIDPARAMS,
728                "This pass does not have a vertex program assigned!",
729                "Pass::setVertexProgramParameters");
730        }
731                mVertexProgramUsage->setParameters(params);
732        }
733    //-----------------------------------------------------------------------
734        void Pass::setFragmentProgram(const String& name, bool resetParams)
735        {
736        // Turn off fragment program if name blank
737        if (name.empty())
738        {
739            if (mFragmentProgramUsage) delete mFragmentProgramUsage;
740            mFragmentProgramUsage = NULL;
741        }
742        else
743        {
744            if (!mFragmentProgramUsage)
745            {
746                mFragmentProgramUsage = new GpuProgramUsage(GPT_FRAGMENT_PROGRAM);
747            }
748                    mFragmentProgramUsage->setProgramName(name, resetParams);
749        }
750        // Needs recompilation
751        mParent->_notifyNeedsRecompile();
752        }
753    //-----------------------------------------------------------------------
754        void Pass::setFragmentProgramParameters(GpuProgramParametersSharedPtr params)
755        {
756                if (!mFragmentProgramUsage)
757        {
758            OGRE_EXCEPT (Exception::ERR_INVALIDPARAMS,
759                "This pass does not have a fragment program assigned!",
760                "Pass::setFragmentProgramParameters");
761        }
762                mFragmentProgramUsage->setParameters(params);
763        }
764        //-----------------------------------------------------------------------
765        const String& Pass::getVertexProgramName(void) const
766        {
767        if (!mVertexProgramUsage)
768            return StringUtil::BLANK;
769        else
770                    return mVertexProgramUsage->getProgramName();
771        }
772        //-----------------------------------------------------------------------
773        GpuProgramParametersSharedPtr Pass::getVertexProgramParameters(void)
774        {
775                if (!mVertexProgramUsage)
776        {
777            OGRE_EXCEPT (Exception::ERR_INVALIDPARAMS,
778                "This pass does not have a vertex program assigned!",
779                "Pass::getVertexProgramParameters");
780        }
781                return mVertexProgramUsage->getParameters();
782        }
783        //-----------------------------------------------------------------------
784        const GpuProgramPtr& Pass::getVertexProgram(void)
785        {
786                return mVertexProgramUsage->getProgram();
787        }
788        //-----------------------------------------------------------------------
789        const String& Pass::getFragmentProgramName(void) const
790        {
791                return mFragmentProgramUsage->getProgramName();
792        }
793        //-----------------------------------------------------------------------
794        GpuProgramParametersSharedPtr Pass::getFragmentProgramParameters(void)
795        {
796                return mFragmentProgramUsage->getParameters();
797        }
798        //-----------------------------------------------------------------------
799        const GpuProgramPtr& Pass::getFragmentProgram(void)
800        {
801                return mFragmentProgramUsage->getProgram();
802        }
803        //-----------------------------------------------------------------------
804    bool Pass::isLoaded(void) const
805    {
806        return mParent->isLoaded();
807    }
808        //-----------------------------------------------------------------------
809    unsigned long Pass::getHash(void) const
810    {
811        return mHash;
812    }
813        //-----------------------------------------------------------------------
814    void Pass::_recalculateHash(void)
815    {
816        /* Hash format is 32-bit, divided as follows (high to low bits)
817           bits   purpose
818            4     Pass index (i.e. max 16 passes!)
819           14     Hashed texture name from unit 0
820           14     Hashed texture name from unit 1
821
822           Note that at the moment we don't sort on the 3rd texture unit plus
823           on the assumption that these are less frequently used; sorting on
824           the first 2 gives us the most benefit for now.
825       */
826        _StringHash H;
827        mHash = (mIndex << 28);
828        size_t c = getNumTextureUnitStates();
829
830        if (c && !mTextureUnitStates[0]->isBlank())
831            mHash += (H(mTextureUnitStates[0]->getTextureName()) % (1 << 14)) << 14;
832        if (c > 1 && !mTextureUnitStates[1]->isBlank())
833            mHash += (H(mTextureUnitStates[1]->getTextureName()) % (1 << 14));
834    }
835    //-----------------------------------------------------------------------
836        void Pass::_dirtyHash(void)
837        {
838                // Mark this hash as for follow up
839                msDirtyHashList.insert(this);
840        }
841    //-----------------------------------------------------------------------
842    void Pass::_notifyNeedsRecompile(void)
843    {
844        mParent->_notifyNeedsRecompile();
845    }
846    //-----------------------------------------------------------------------
847    void Pass::setTextureFiltering(TextureFilterOptions filterType)
848    {
849        TextureUnitStates::iterator i, iend;
850        iend = mTextureUnitStates.end();
851        for (i = mTextureUnitStates.begin(); i != iend; ++i)
852        {
853            (*i)->setTextureFiltering(filterType);
854        }
855    }
856    // --------------------------------------------------------------------
857    void Pass::setTextureAnisotropy(unsigned int maxAniso)
858    {
859        TextureUnitStates::iterator i, iend;
860        iend = mTextureUnitStates.end();
861        for (i = mTextureUnitStates.begin(); i != iend; ++i)
862        {
863            (*i)->setTextureAnisotropy(maxAniso);
864        }
865    }
866    //-----------------------------------------------------------------------
867    void Pass::_updateAutoParamsNoLights(const AutoParamDataSource& source)
868    {
869        if (hasVertexProgram())
870        {
871            // Update vertex program auto params
872            mVertexProgramUsage->getParameters()->_updateAutoParamsNoLights(source);
873        }
874
875        if (hasFragmentProgram())
876        {
877            // Update fragment program auto params
878            mFragmentProgramUsage->getParameters()->_updateAutoParamsNoLights(source);
879        }
880    }
881    //-----------------------------------------------------------------------
882    void Pass::_updateAutoParamsLightsOnly(const AutoParamDataSource& source)
883    {
884        if (hasVertexProgram())
885        {
886            // Update vertex program auto params
887            mVertexProgramUsage->getParameters()->_updateAutoParamsLightsOnly(source);
888        }
889
890        if (hasFragmentProgram())
891        {
892            // Update fragment program auto params
893            mFragmentProgramUsage->getParameters()->_updateAutoParamsLightsOnly(source);
894        }
895    }
896    //-----------------------------------------------------------------------
897    void Pass::processPendingPassUpdates(void)
898    {
899        // Delete items in the graveyard
900        PassSet::iterator i, iend;
901        iend = msPassGraveyard.end();
902        for (i = msPassGraveyard.begin(); i != iend; ++i)
903        {
904            delete *i;
905        }
906        msPassGraveyard.clear();
907
908        // The dirty ones will have been removed from the groups above using the old hash now
909        iend = msDirtyHashList.end();
910        for (i = msDirtyHashList.begin(); i != iend; ++i)
911        {
912            Pass* p = *i;
913            p->_recalculateHash();
914        }
915        // Clear the dirty list
916        msDirtyHashList.clear();
917    }
918    //-----------------------------------------------------------------------
919    void Pass::queueForDeletion(void)
920    {
921        mQueuedForDeletion = true;
922
923        removeAllTextureUnitStates();
924        if (mVertexProgramUsage)
925        {
926            delete mVertexProgramUsage;
927            mVertexProgramUsage = 0;
928        }
929        if (mShadowCasterVertexProgramUsage)
930        {
931            delete mShadowCasterVertexProgramUsage;
932            mShadowCasterVertexProgramUsage = 0;
933        }
934        if (mShadowReceiverVertexProgramUsage)
935        {
936            delete mShadowReceiverVertexProgramUsage;
937            mShadowReceiverVertexProgramUsage = 0;
938        }
939        if (mFragmentProgramUsage)
940        {
941            delete mFragmentProgramUsage;
942            mFragmentProgramUsage = 0;
943        }
944        // remove from dirty list, if there
945        msDirtyHashList.erase(this);
946
947        msPassGraveyard.insert(this);
948    }
949    //-----------------------------------------------------------------------
950    bool Pass::isAmbientOnly(void) const
951    {
952        // treat as ambient if lighting is off, or colour write is off,
953        // or all non-ambient (& emissive) colours are black
954        // NB a vertex program could override this, but passes using vertex
955        // programs are expected to indicate they are ambient only by
956        // setting the state so it matches one of the conditions above, even
957        // though this state is not used in rendering.
958        return (!mLightingEnabled || !mColourWrite ||
959            (mDiffuse == ColourValue::Black &&
960             mSpecular == ColourValue::Black));
961    }
962    //-----------------------------------------------------------------------
963    void Pass::setShadowCasterVertexProgram(const String& name)
964    {
965        // Turn off vertex program if name blank
966        if (name.empty())
967        {
968            if (mShadowCasterVertexProgramUsage) delete mShadowCasterVertexProgramUsage;
969            mShadowCasterVertexProgramUsage = NULL;
970        }
971        else
972        {
973            if (!mShadowCasterVertexProgramUsage)
974            {
975                mShadowCasterVertexProgramUsage = new GpuProgramUsage(GPT_VERTEX_PROGRAM);
976            }
977            mShadowCasterVertexProgramUsage->setProgramName(name);
978        }
979        // Needs recompilation
980        mParent->_notifyNeedsRecompile();
981    }
982    //-----------------------------------------------------------------------
983    void Pass::setShadowCasterVertexProgramParameters(GpuProgramParametersSharedPtr params)
984    {
985        if (!mShadowCasterVertexProgramUsage)
986        {
987            OGRE_EXCEPT (Exception::ERR_INVALIDPARAMS,
988                "This pass does not have a shadow caster vertex program assigned!",
989                "Pass::setShadowCasterVertexProgramParameters");
990        }
991        mShadowCasterVertexProgramUsage->setParameters(params);
992    }
993    //-----------------------------------------------------------------------
994    const String& Pass::getShadowCasterVertexProgramName(void) const
995    {
996        if (!mShadowCasterVertexProgramUsage)
997            return StringUtil::BLANK;
998        else
999            return mShadowCasterVertexProgramUsage->getProgramName();
1000    }
1001    //-----------------------------------------------------------------------
1002    GpuProgramParametersSharedPtr Pass::getShadowCasterVertexProgramParameters(void)
1003    {
1004        if (!mShadowCasterVertexProgramUsage)
1005        {
1006            OGRE_EXCEPT (Exception::ERR_INVALIDPARAMS,
1007                "This pass does not have a shadow caster vertex program assigned!",
1008                "Pass::getShadowCasterVertexProgramParameters");
1009        }
1010        return mShadowCasterVertexProgramUsage->getParameters();
1011    }
1012    //-----------------------------------------------------------------------
1013    const GpuProgramPtr& Pass::getShadowCasterVertexProgram(void)
1014    {
1015        return mShadowCasterVertexProgramUsage->getProgram();
1016    }
1017    //-----------------------------------------------------------------------
1018    void Pass::setShadowReceiverVertexProgram(const String& name)
1019    {
1020        // Turn off vertex program if name blank
1021        if (name.empty())
1022        {
1023            if (mShadowReceiverVertexProgramUsage) delete mShadowReceiverVertexProgramUsage;
1024            mShadowReceiverVertexProgramUsage = NULL;
1025        }
1026        else
1027        {
1028            if (!mShadowReceiverVertexProgramUsage)
1029            {
1030                mShadowReceiverVertexProgramUsage = new GpuProgramUsage(GPT_VERTEX_PROGRAM);
1031            }
1032            mShadowReceiverVertexProgramUsage->setProgramName(name);
1033        }
1034        // Needs recompilation
1035        mParent->_notifyNeedsRecompile();
1036    }
1037    //-----------------------------------------------------------------------
1038    void Pass::setShadowReceiverVertexProgramParameters(GpuProgramParametersSharedPtr params)
1039    {
1040        if (!mShadowReceiverVertexProgramUsage)
1041        {
1042            OGRE_EXCEPT (Exception::ERR_INVALIDPARAMS,
1043                "This pass does not have a shadow receiver vertex program assigned!",
1044                "Pass::setShadowReceiverVertexProgramParameters");
1045        }
1046        mShadowReceiverVertexProgramUsage->setParameters(params);
1047    }
1048    //-----------------------------------------------------------------------
1049    const String& Pass::getShadowReceiverVertexProgramName(void) const
1050    {
1051        if (!mShadowReceiverVertexProgramUsage)
1052            return StringUtil::BLANK;
1053        else
1054            return mShadowReceiverVertexProgramUsage->getProgramName();
1055    }
1056    //-----------------------------------------------------------------------
1057    GpuProgramParametersSharedPtr Pass::getShadowReceiverVertexProgramParameters(void)
1058    {
1059        if (!mShadowReceiverVertexProgramUsage)
1060        {
1061            OGRE_EXCEPT (Exception::ERR_INVALIDPARAMS,
1062                "This pass does not have a shadow receiver vertex program assigned!",
1063                "Pass::getShadowReceiverVertexProgramParameters");
1064        }
1065        return mShadowReceiverVertexProgramUsage->getParameters();
1066    }
1067    //-----------------------------------------------------------------------
1068    const GpuProgramPtr& Pass::getShadowReceiverVertexProgram(void)
1069    {
1070        return mShadowReceiverVertexProgramUsage->getProgram();
1071    }
1072    //-----------------------------------------------------------------------
1073        const String& Pass::getResourceGroup(void) const
1074        {
1075                return mParent->getResourceGroup();
1076        }
1077
1078}
Note: See TracBrowser for help on using the repository browser.