Logo Search packages:      
Sourcecode: ogre version File versions

OgrePass.cpp

/*
-----------------------------------------------------------------------------
This source file is part of OGRE
    (Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org

Copyright (c) 2000-2006 Torus Knot Software Ltd
Also see acknowledgements in Readme.html

This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.

This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA, or go to
http://www.gnu.org/copyleft/lesser.txt.

You may alternatively use this source under the terms of a specific version of
the OGRE Unrestricted License provided you have obtained such a license from
Torus Knot Software Ltd.
-----------------------------------------------------------------------------
*/
#include "OgreStableHeaders.h"

#include "OgrePass.h"
#include "OgreTechnique.h"
#include "OgreException.h"
#include "OgreGpuProgramUsage.h"
#include "OgreTextureUnitState.h"
#include "OgreStringConverter.h"

namespace Ogre {

      /** Default pass hash function.
      @remarks
            Tries to minimise the number of texture changes.
      */
00044       struct MinTextureStateChangeHashFunc : public Pass::HashFunc
      {
            uint32 operator()(const Pass* p) const
            {

                  _StringHash H;
                  uint32 hash = p->getIndex() << 28;
                  size_t c = p->getNumTextureUnitStates();

                  const TextureUnitState* t0 = 0;
                  const TextureUnitState* t1 = 0;
                  if (c)
                        t0 = p->getTextureUnitState(0);
                  if (c > 1)
                        t1 = p->getTextureUnitState(1);

                  if (t0 && !t0->getTextureName().empty())
                        hash += (static_cast<uint32>(H(t0->getTextureName())) 
                              % (1 << 14)) << 14;
                  if (t1 && !t1->getTextureName().empty())
                        hash += (static_cast<uint32>(H(t1->getTextureName()))
                              % (1 << 14));

                  return hash;
            }
      };
      MinTextureStateChangeHashFunc sMinTextureStateChangeHashFunc;
      /** Alternate pass hash function.
      @remarks
            Tries to minimise the number of GPU program changes.
      */
00075       struct MinGpuProgramChangeHashFunc : public Pass::HashFunc
      {
            uint32 operator()(const Pass* p) const
            {

                  _StringHash H;
                  uint32 hash = p->getIndex() << 28;
                  if (p->hasVertexProgram())
                        hash += (static_cast<uint32>(H(p->getVertexProgramName()))
                              % (1 << 14)) << 14;
                  if (p->hasFragmentProgram())
                        hash += (static_cast<uint32>(H(p->getFragmentProgramName()))
                              % (1 << 14));

                  return hash;
            }
      };
      MinGpuProgramChangeHashFunc sMinGpuProgramChangeHashFunc;
    //-----------------------------------------------------------------------------
      Pass::PassSet Pass::msDirtyHashList;
    Pass::PassSet Pass::msPassGraveyard;
      OGRE_STATIC_MUTEX_INSTANCE(Pass::msDirtyHashListMutex)
      OGRE_STATIC_MUTEX_INSTANCE(Pass::msPassGraveyardMutex)

      Pass::HashFunc* Pass::msHashFunc = &sMinTextureStateChangeHashFunc;
      //-----------------------------------------------------------------------------
00101       void Pass::setHashFunction(BuiltinHashFunction builtin)
      {
            switch(builtin)
            {
            case MIN_TEXTURE_CHANGE:
                  msHashFunc = &sMinTextureStateChangeHashFunc;
                  break;
            case MIN_GPU_PROGRAM_CHANGE:
                  msHashFunc = &sMinGpuProgramChangeHashFunc;
                  break;
            }
      }
    //-----------------------------------------------------------------------------
00114       Pass::Pass(Technique* parent, unsigned short index)
        : mParent(parent)
            , mIndex(index)
            , mHash(0)
            , mAmbient(ColourValue::White)
            , mDiffuse(ColourValue::White)
            , mSpecular(ColourValue::Black)
            , mEmissive(ColourValue::Black)
            , mShininess(0)
            , mTracking(TVC_NONE)
            , mSourceBlendFactor(SBF_ONE)
            , mDestBlendFactor(SBF_ZERO)
            , mDepthCheck(true)
            , mDepthWrite(true)
            , mDepthFunc(CMPF_LESS_EQUAL)
            , mDepthBiasConstant(0.0f)
            , mDepthBiasSlopeScale(0.0f)
            , mColourWrite(true)
            , mAlphaRejectFunc(CMPF_ALWAYS_PASS)
            , mAlphaRejectVal(0)
            , mCullMode(CULL_CLOCKWISE)
            , mManualCullMode(MANUAL_CULL_BACK)
            , mLightingEnabled(true)
            , mMaxSimultaneousLights(OGRE_MAX_SIMULTANEOUS_LIGHTS)
            , mStartLight(0)
            , mIteratePerLight(false)
            , mLightsPerIteration(1)
            , mRunOnlyForOneLightType(true)
            , mOnlyLightType(Light::LT_POINT)
            , mShadeOptions(SO_GOURAUD)
            , mPolygonMode(PM_SOLID)
            , mFogOverride(false)
            , mFogMode(FOG_NONE)
            , mFogColour(ColourValue::White)
            , mFogStart(0.0)
            , mFogEnd(1.0)
            , mFogDensity(0.001)
            , mVertexProgramUsage(0)
            , mShadowCasterVertexProgramUsage(0)
            , mShadowReceiverVertexProgramUsage(0)
            , mFragmentProgramUsage(0)
            , mShadowReceiverFragmentProgramUsage(0)
            , mQueuedForDeletion(false)
            , mPassIterationCount(1)
            , mPointSize(1.0f)
            , mPointMinSize(0.0f)
            , mPointMaxSize(0.0f)
            , mPointSpritesEnabled(false)
            , mPointAttenuationEnabled(false)
            , mContentTypeLookupBuilt(false)
    {
            mPointAttenuationCoeffs[0] = 1.0f;
            mPointAttenuationCoeffs[1] = mPointAttenuationCoeffs[2] = 0.0f;

        // default name to index
        mName = StringConverter::toString(mIndex);

        _dirtyHash();
   }

    //-----------------------------------------------------------------------------
00175       Pass::Pass(Technique *parent, unsigned short index, const Pass& oth)
        :mParent(parent), mIndex(index), mQueuedForDeletion(false), mPassIterationCount(1)
    {
        *this = oth;
        mParent = parent;
        mIndex = index;
        mQueuedForDeletion = false;
        _dirtyHash();
    }
    //-----------------------------------------------------------------------------
    Pass::~Pass()
    {

    }
    //-----------------------------------------------------------------------------
00190     Pass& Pass::operator=(const Pass& oth)
    {
        mName = oth.mName;
        mHash = oth.mHash;
          mAmbient = oth.mAmbient;
        mDiffuse = oth.mDiffuse;
          mSpecular = oth.mSpecular;
        mEmissive = oth.mEmissive;
          mShininess = oth.mShininess;
        mTracking = oth.mTracking;

        // Copy fog parameters
        mFogOverride = oth.mFogOverride;
        mFogMode = oth.mFogMode;
        mFogColour = oth.mFogColour;
        mFogStart = oth.mFogStart;
        mFogEnd = oth.mFogEnd;
        mFogDensity = oth.mFogDensity;

          // Default blending (overwrite)
          mSourceBlendFactor = oth.mSourceBlendFactor;
          mDestBlendFactor = oth.mDestBlendFactor;

          mDepthCheck = oth.mDepthCheck;
          mDepthWrite = oth.mDepthWrite;
            mAlphaRejectFunc = oth.mAlphaRejectFunc;
            mAlphaRejectVal = oth.mAlphaRejectVal;
        mColourWrite = oth.mColourWrite;
          mDepthFunc = oth.mDepthFunc;
        mDepthBiasConstant = oth.mDepthBiasConstant;
            mDepthBiasSlopeScale = oth.mDepthBiasSlopeScale;
          mCullMode = oth.mCullMode;
          mManualCullMode = oth.mManualCullMode;
          mLightingEnabled = oth.mLightingEnabled;
        mMaxSimultaneousLights = oth.mMaxSimultaneousLights;
            mStartLight = oth.mStartLight;
            mIteratePerLight = oth.mIteratePerLight;
            mLightsPerIteration = oth.mLightsPerIteration;
        mRunOnlyForOneLightType = oth.mRunOnlyForOneLightType;
        mOnlyLightType = oth.mOnlyLightType;
          mShadeOptions = oth.mShadeOptions;
            mPolygonMode = oth.mPolygonMode;
        mPassIterationCount = oth.mPassIterationCount;
            mPointSize = oth.mPointSize;
            mPointMinSize = oth.mPointMinSize;
            mPointMaxSize = oth.mPointMaxSize;
            mPointSpritesEnabled = oth.mPointSpritesEnabled;
            mPointAttenuationEnabled = oth.mPointAttenuationEnabled;
            memcpy(mPointAttenuationCoeffs, oth.mPointAttenuationCoeffs, sizeof(Real)*3);
            mShadowContentTypeLookup = oth.mShadowContentTypeLookup;
            mContentTypeLookupBuilt = oth.mContentTypeLookupBuilt;


            if (oth.mVertexProgramUsage)
            {
                  mVertexProgramUsage = new GpuProgramUsage(*(oth.mVertexProgramUsage));
            }
            else
            {
                mVertexProgramUsage = NULL;
            }
        if (oth.mShadowCasterVertexProgramUsage)
        {
            mShadowCasterVertexProgramUsage = new GpuProgramUsage(*(oth.mShadowCasterVertexProgramUsage));
        }
        else
        {
            mShadowCasterVertexProgramUsage = NULL;
        }
        if (oth.mShadowReceiverVertexProgramUsage)
        {
            mShadowReceiverVertexProgramUsage = new GpuProgramUsage(*(oth.mShadowReceiverVertexProgramUsage));
        }
        else
        {
            mShadowReceiverVertexProgramUsage = NULL;
        }
            if (oth.mFragmentProgramUsage)
            {
                mFragmentProgramUsage = new GpuProgramUsage(*(oth.mFragmentProgramUsage));
        }
        else
        {
                mFragmentProgramUsage = NULL;
        }
            if (oth.mShadowReceiverFragmentProgramUsage)
            {
                  mShadowReceiverFragmentProgramUsage = new GpuProgramUsage(*(oth.mShadowReceiverFragmentProgramUsage));
            }
            else
            {
                  mShadowReceiverFragmentProgramUsage = NULL;
            }

            TextureUnitStates::const_iterator i, iend;

        // Clear texture units but doesn't notify need recompilation in the case
        // we are cloning, The parent material will take care of this.
        iend = mTextureUnitStates.end();
        for (i = mTextureUnitStates.begin(); i != iend; ++i)
        {
            delete *i;
        }

        mTextureUnitStates.clear();

            // Copy texture units
            iend = oth.mTextureUnitStates.end();
            for (i = oth.mTextureUnitStates.begin(); i != iend; ++i)
            {
                  TextureUnitState* t = new TextureUnitState(this, *(*i));
                  mTextureUnitStates.push_back(t);
            }

        _dirtyHash();

            return *this;
    }
    //-----------------------------------------------------------------------
    void Pass::setName(const String& name)
    {
        mName = name;
    }
    //-----------------------------------------------------------------------
00314     void Pass::setPointSize(Real ps)
    {
          mPointSize = ps;
    }
    //-----------------------------------------------------------------------
00319       void Pass::setPointSpritesEnabled(bool enabled)
      {
            mPointSpritesEnabled = enabled;
      }
    //-----------------------------------------------------------------------
00324       bool Pass::getPointSpritesEnabled(void) const
      {
            return mPointSpritesEnabled;
      }
    //-----------------------------------------------------------------------
00329       void Pass::setPointAttenuation(bool enabled,
            Real constant, Real linear, Real quadratic)
      {
            mPointAttenuationEnabled = enabled;
            mPointAttenuationCoeffs[0] = constant;
            mPointAttenuationCoeffs[1] = linear;
            mPointAttenuationCoeffs[2] = quadratic;
      }
    //-----------------------------------------------------------------------
00338       bool Pass::isPointAttenuationEnabled(void) const
      {
            return mPointAttenuationEnabled;
      }
    //-----------------------------------------------------------------------
00343       Real Pass::getPointAttenuationConstant(void) const
      {
            return mPointAttenuationCoeffs[0];
      }
    //-----------------------------------------------------------------------
00348       Real Pass::getPointAttenuationLinear(void) const
      {
            return mPointAttenuationCoeffs[1];
      }
    //-----------------------------------------------------------------------
00353       Real Pass::getPointAttenuationQuadratic(void) const
      {
            return mPointAttenuationCoeffs[2];
      }
    //-----------------------------------------------------------------------
00358       void Pass::setPointMinSize(Real min)
      {
            mPointMinSize = min;
      }
    //-----------------------------------------------------------------------
00363       Real Pass::getPointMinSize(void) const
      {
            return mPointMinSize;
      }
    //-----------------------------------------------------------------------
00368       void Pass::setPointMaxSize(Real max)
      {
            mPointMaxSize = max;
      }
    //-----------------------------------------------------------------------
00373       Real Pass::getPointMaxSize(void) const
      {
            return mPointMaxSize;
      }
    //-----------------------------------------------------------------------
00378     void Pass::setAmbient(Real red, Real green, Real blue)
    {
          mAmbient.r = red;
          mAmbient.g = green;
          mAmbient.b = blue;

    }
    //-----------------------------------------------------------------------
00386     void Pass::setAmbient(const ColourValue& ambient)
    {
          mAmbient = ambient;
    }
    //-----------------------------------------------------------------------
00391     void Pass::setDiffuse(Real red, Real green, Real blue, Real alpha)
    {
          mDiffuse.r = red;
          mDiffuse.g = green;
          mDiffuse.b = blue;
            mDiffuse.a = alpha;
    }
    //-----------------------------------------------------------------------
00399     void Pass::setDiffuse(const ColourValue& diffuse)
    {
          mDiffuse = diffuse;
    }
    //-----------------------------------------------------------------------
00404     void Pass::setSpecular(Real red, Real green, Real blue, Real alpha)
    {
          mSpecular.r = red;
          mSpecular.g = green;
          mSpecular.b = blue;
            mSpecular.a = alpha;
    }
    //-----------------------------------------------------------------------
00412     void Pass::setSpecular(const ColourValue& specular)
    {
          mSpecular = specular;
    }
    //-----------------------------------------------------------------------
00417     void Pass::setShininess(Real val)
    {
          mShininess = val;
    }
    //-----------------------------------------------------------------------
00422     void Pass::setSelfIllumination(Real red, Real green, Real blue)
    {
          mEmissive.r = red;
          mEmissive.g = green;
          mEmissive.b = blue;

    }
    //-----------------------------------------------------------------------
00430     void Pass::setSelfIllumination(const ColourValue& selfIllum)
    {
          mEmissive = selfIllum;
    }
    //-----------------------------------------------------------------------
00435     void Pass::setVertexColourTracking(TrackVertexColourType tracking)
    {
        mTracking = tracking;
    }
    //-----------------------------------------------------------------------
00440     Real Pass::getPointSize(void) const
    {
          return mPointSize;
    }
    //-----------------------------------------------------------------------
00445     const ColourValue& Pass::getAmbient(void) const
    {
          return mAmbient;
    }
    //-----------------------------------------------------------------------
00450     const ColourValue& Pass::getDiffuse(void) const
    {
          return mDiffuse;
    }
    //-----------------------------------------------------------------------
00455     const ColourValue& Pass::getSpecular(void) const
    {
          return mSpecular;
    }
    //-----------------------------------------------------------------------
00460     const ColourValue& Pass::getSelfIllumination(void) const
    {
          return mEmissive;
    }
    //-----------------------------------------------------------------------
00465     Real Pass::getShininess(void) const
    {
          return mShininess;
    }
    //-----------------------------------------------------------------------
00470     TrackVertexColourType Pass::getVertexColourTracking(void) const
    {
        return mTracking;
    }
    //-----------------------------------------------------------------------
00475     TextureUnitState* Pass::createTextureUnitState(void)
    {
        TextureUnitState *t = new TextureUnitState(this);
        addTextureUnitState(t);
            mContentTypeLookupBuilt = false;
          return t;
    }
    //-----------------------------------------------------------------------
00483     TextureUnitState* Pass::createTextureUnitState(
        const String& textureName, unsigned short texCoordSet)
    {
        TextureUnitState *t = new TextureUnitState(this);
          t->setTextureName(textureName);
          t->setTextureCoordSet(texCoordSet);
        addTextureUnitState(t);
            mContentTypeLookupBuilt = false;
          return t;
    }
    //-----------------------------------------------------------------------
00494       void Pass::addTextureUnitState(TextureUnitState* state)
      {
        assert(state && "state is 0 in Pass::addTextureUnitState()");
        if (state)
        {
            // only attach TUS to pass if TUS does not belong to another pass
            if ((state->getParent() == 0) || (state->getParent() == this))
            {
                    mTextureUnitStates.push_back(state);
                        // Notify state
                        state->_notifyParent(this);
                // if texture unit state name is empty then give it a default name based on its index
                if (state->getName().empty())
                {
                    // its the last entry in the container so its index is size - 1
                    size_t idx = mTextureUnitStates.size() - 1;
                    state->setName( StringConverter::toString(idx) );
                    /** since the name was never set and a default one has been made, clear the alias name
                     so that when the texture unit name is set by the user, the alias name will be set to
                     that name
                    */
                    state->setTextureNameAlias(StringUtil::BLANK);
                }
                // Needs recompilation
                mParent->_notifyNeedsRecompile();
                _dirtyHash();
            }
            else
            {
                      OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "TextureUnitState already attached to another pass",
                            "Pass:addTextureUnitState");

            }
                  mContentTypeLookupBuilt = false;
        }
      }
    //-----------------------------------------------------------------------
00531     TextureUnitState* Pass::getTextureUnitState(unsigned short index)
    {
        assert (index < mTextureUnitStates.size() && "Index out of bounds");
          return mTextureUnitStates[index];
    }
    //-----------------------------------------------------------------------------
00537     TextureUnitState* Pass::getTextureUnitState(const String& name)
    {
        TextureUnitStates::iterator i    = mTextureUnitStates.begin();
        TextureUnitStates::iterator iend = mTextureUnitStates.end();
        TextureUnitState* foundTUS = 0;

        // iterate through TUS Container to find a match
        while (i != iend)
        {
            if ( (*i)->getName() == name )
            {
                foundTUS = (*i);
                break;
            }

            ++i;
        }

        return foundTUS;
    }
      //-----------------------------------------------------------------------
00558       const TextureUnitState* Pass::getTextureUnitState(unsigned short index) const
      {
            assert (index < mTextureUnitStates.size() && "Index out of bounds");
            return mTextureUnitStates[index];
      }
      //-----------------------------------------------------------------------------
00564       const TextureUnitState* Pass::getTextureUnitState(const String& name) const
      {
            TextureUnitStates::const_iterator i    = mTextureUnitStates.begin();
            TextureUnitStates::const_iterator iend = mTextureUnitStates.end();
            const TextureUnitState* foundTUS = 0;

            // iterate through TUS Container to find a match
            while (i != iend)
            {
                  if ( (*i)->getName() == name )
                  {
                        foundTUS = (*i);
                        break;
                  }

                  ++i;
            }

            return foundTUS;
      }

    //-----------------------------------------------------------------------
00586     unsigned short Pass::getTextureUnitStateIndex(const TextureUnitState* state) const
    {
        assert(state && "state is 0 in Pass::getTextureUnitStateIndex()");

        // only find index for state attached to this pass
        if (state->getParent() == this)
        {
            TextureUnitStates::const_iterator i =
                std::find(mTextureUnitStates.begin(), mTextureUnitStates.end(), state);
            assert(i != mTextureUnitStates.end() && "state is supposed to attached to this pass");
            return static_cast<unsigned short>(std::distance(mTextureUnitStates.begin(), i));
        }
        else
        {
                  OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "TextureUnitState is not attached to this pass",
                        "Pass:getTextureUnitStateIndex");
        }
    }

    //-----------------------------------------------------------------------
    Pass::TextureUnitStateIterator
00607         Pass::getTextureUnitStateIterator(void)
    {
        return TextureUnitStateIterator(mTextureUnitStates.begin(), mTextureUnitStates.end());
    }
      //-----------------------------------------------------------------------
      Pass::ConstTextureUnitStateIterator
00613             Pass::getTextureUnitStateIterator(void) const
      {
            return ConstTextureUnitStateIterator(mTextureUnitStates.begin(), mTextureUnitStates.end());
      }
    //-----------------------------------------------------------------------
00618     void Pass::removeTextureUnitState(unsigned short index)
    {
        assert (index < mTextureUnitStates.size() && "Index out of bounds");

        TextureUnitStates::iterator i = mTextureUnitStates.begin() + index;
        delete *i;
          mTextureUnitStates.erase(i);
        if (!mQueuedForDeletion)
        {
            // Needs recompilation
            mParent->_notifyNeedsRecompile();
        }
        _dirtyHash();
            mContentTypeLookupBuilt = false;
    }
    //-----------------------------------------------------------------------
00634     void Pass::removeAllTextureUnitStates(void)
    {
        TextureUnitStates::iterator i, iend;
        iend = mTextureUnitStates.end();
        for (i = mTextureUnitStates.begin(); i != iend; ++i)
        {
            delete *i;
        }
        mTextureUnitStates.clear();
        if (!mQueuedForDeletion)
        {
            // Needs recompilation
            mParent->_notifyNeedsRecompile();
        }
        _dirtyHash();
            mContentTypeLookupBuilt = false;
    }
    //-----------------------------------------------------------------------
00652     void Pass::setSceneBlending(SceneBlendType sbt)
    {
          // Turn predefined type into blending factors
          switch (sbt)
          {
          case SBT_TRANSPARENT_ALPHA:
                setSceneBlending(SBF_SOURCE_ALPHA, SBF_ONE_MINUS_SOURCE_ALPHA);
                break;
          case SBT_TRANSPARENT_COLOUR:
                setSceneBlending(SBF_SOURCE_COLOUR, SBF_ONE_MINUS_SOURCE_COLOUR);
                break;
            case SBT_MODULATE:
                  setSceneBlending(SBF_DEST_COLOUR, SBF_ZERO);
                  break;
          case SBT_ADD:
                setSceneBlending(SBF_ONE, SBF_ONE);
                break;
        case SBT_REPLACE:
            setSceneBlending(SBF_ONE, SBF_ZERO);
            break;
          // TODO: more
          }

    }
    //-----------------------------------------------------------------------
00677     void Pass::setSceneBlending(SceneBlendFactor sourceFactor, SceneBlendFactor destFactor)
    {
          mSourceBlendFactor = sourceFactor;
          mDestBlendFactor = destFactor;
    }
    //-----------------------------------------------------------------------
00683     SceneBlendFactor Pass::getSourceBlendFactor(void) const
    {
          return mSourceBlendFactor;
    }
    //-----------------------------------------------------------------------
00688     SceneBlendFactor Pass::getDestBlendFactor(void) const
    {
          return mDestBlendFactor;
    }
    //-----------------------------------------------------------------------
00693     bool Pass::isTransparent(void) const
    {
            // Transparent if any of the destination colour is taken into account
            if (mDestBlendFactor == SBF_ZERO &&
                  mSourceBlendFactor != SBF_DEST_COLOUR &&
                  mSourceBlendFactor != SBF_ONE_MINUS_DEST_COLOUR &&
                  mSourceBlendFactor != SBF_DEST_ALPHA &&
                  mSourceBlendFactor != SBF_ONE_MINUS_DEST_ALPHA)
            {
                return false;
            }
          else
            {
                return true;
            }
    }
    //-----------------------------------------------------------------------
00710     void Pass::setDepthCheckEnabled(bool enabled)
    {
          mDepthCheck = enabled;
    }
    //-----------------------------------------------------------------------
00715     bool Pass::getDepthCheckEnabled(void) const
    {
          return mDepthCheck;
    }
    //-----------------------------------------------------------------------
00720     void Pass::setDepthWriteEnabled(bool enabled)
    {
          mDepthWrite = enabled;
    }
    //-----------------------------------------------------------------------
00725     bool Pass::getDepthWriteEnabled(void) const
    {
          return mDepthWrite;
    }
    //-----------------------------------------------------------------------
00730     void Pass::setDepthFunction( CompareFunction func)
    {
          mDepthFunc = func;
    }
    //-----------------------------------------------------------------------
00735     CompareFunction Pass::getDepthFunction(void) const
    {
          return mDepthFunc;
    }
      //-----------------------------------------------------------------------
00740       void Pass::setAlphaRejectSettings(CompareFunction func, unsigned char value)
      {
            mAlphaRejectFunc = func;
            mAlphaRejectVal = value;
      }
      //-----------------------------------------------------------------------
00746       void Pass::setAlphaRejectFunction(CompareFunction func)
      {
            mAlphaRejectFunc = func;
      }
      //-----------------------------------------------------------------------
00751       void Pass::setAlphaRejectValue(unsigned char val)
      {
            mAlphaRejectVal = val;
      }
    //-----------------------------------------------------------------------
00756       void Pass::setColourWriteEnabled(bool enabled)
      {
            mColourWrite = enabled;
      }
    //-----------------------------------------------------------------------
00761       bool Pass::getColourWriteEnabled(void) const
      {
            return mColourWrite;
      }
    //-----------------------------------------------------------------------
00766     void Pass::setCullingMode( CullingMode mode)
    {
          mCullMode = mode;
    }
    //-----------------------------------------------------------------------
00771     CullingMode Pass::getCullingMode(void) const
    {
          return mCullMode;
    }
    //-----------------------------------------------------------------------
00776     void Pass::setLightingEnabled(bool enabled)
    {
          mLightingEnabled = enabled;
    }
    //-----------------------------------------------------------------------
00781     bool Pass::getLightingEnabled(void) const
    {
          return mLightingEnabled;
    }
    //-----------------------------------------------------------------------
00786     void Pass::setMaxSimultaneousLights(unsigned short maxLights)
    {
        mMaxSimultaneousLights = maxLights;
    }
    //-----------------------------------------------------------------------
00791     unsigned short Pass::getMaxSimultaneousLights(void) const
    {
        return mMaxSimultaneousLights;
    }
      //-----------------------------------------------------------------------
00796       void Pass::setStartLight(unsigned short startLight)
      {
            mStartLight = startLight;
      }
      //-----------------------------------------------------------------------
00801       unsigned short Pass::getStartLight(void) const
      {
            return mStartLight;
      }
      //-----------------------------------------------------------------------
00806       void Pass::setLightCountPerIteration(unsigned short c)
      {
            mLightsPerIteration = c;
      }
      //-----------------------------------------------------------------------
00811       unsigned short Pass::getLightCountPerIteration(void) const
      {
            return mLightsPerIteration;
      }
    //-----------------------------------------------------------------------
00816     void Pass::setIteratePerLight(bool enabled,
            bool onlyForOneLightType, Light::LightTypes lightType)
    {
        mIteratePerLight = enabled;
        mRunOnlyForOneLightType = onlyForOneLightType;
        mOnlyLightType = lightType;
    }
    //-----------------------------------------------------------------------
00824     void Pass::setShadingMode(ShadeOptions mode)
    {
          mShadeOptions = mode;
    }
    //-----------------------------------------------------------------------
00829     ShadeOptions Pass::getShadingMode(void) const
    {
          return mShadeOptions;
    }
      //-----------------------------------------------------------------------
00834       void Pass::setPolygonMode(PolygonMode mode)
      {
            mPolygonMode = mode;
      }
      //-----------------------------------------------------------------------
00839       PolygonMode Pass::getPolygonMode(void) const
      {
            return mPolygonMode;
      }
    //-----------------------------------------------------------------------
00844     void Pass::setManualCullingMode(ManualCullingMode mode)
    {
          mManualCullMode = mode;
    }
    //-----------------------------------------------------------------------
00849     ManualCullingMode Pass::getManualCullingMode(void) const
    {
          return mManualCullMode;
    }
    //-----------------------------------------------------------------------
00854     void Pass::setFog(bool overrideScene, FogMode mode, const ColourValue& colour, Real density, Real start, Real end)
    {
          mFogOverride = overrideScene;
          if (overrideScene)
          {
                mFogMode = mode;
                mFogColour = colour;
                mFogStart = start;
                mFogEnd = end;
                mFogDensity = density;
          }
    }
    //-----------------------------------------------------------------------
00867     bool Pass::getFogOverride(void) const
    {
          return mFogOverride;
    }
    //-----------------------------------------------------------------------
00872     FogMode Pass::getFogMode(void) const
    {
          return mFogMode;
    }
    //-----------------------------------------------------------------------
00877     const ColourValue& Pass::getFogColour(void) const
    {
          return mFogColour;
    }
    //-----------------------------------------------------------------------
00882     Real Pass::getFogStart(void) const
    {
          return mFogStart;
    }
    //-----------------------------------------------------------------------
00887     Real Pass::getFogEnd(void) const
    {
          return mFogEnd;
    }
    //-----------------------------------------------------------------------
00892     Real Pass::getFogDensity(void) const
    {
          return mFogDensity;
    }
    //-----------------------------------------------------------------------
00897     void Pass::setDepthBias(float constantBias, float slopeScaleBias)
    {
       mDepthBiasConstant = constantBias;
         mDepthBiasSlopeScale = slopeScaleBias;
    }
    //-----------------------------------------------------------------------
00903     float Pass::getDepthBiasConstant(void) const
    {
        return mDepthBiasConstant;
    }
      //-----------------------------------------------------------------------
00908       float Pass::getDepthBiasSlopeScale(void) const
      {
            return mDepthBiasSlopeScale;
      }
    //-----------------------------------------------------------------------
00913       Pass* Pass::_split(unsigned short numUnits)
      {
            if (mVertexProgramUsage || mFragmentProgramUsage)
            {
                  OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Programmable passes cannot be "
                        "automatically split, define a fallback technique instead.",
                        "Pass:_split");
            }

            if (mTextureUnitStates.size() > numUnits)
            {
                  size_t start = mTextureUnitStates.size() - numUnits;

                  Pass* newPass = mParent->createPass();

                  TextureUnitStates::iterator istart, i, iend;
                  iend = mTextureUnitStates.end();
                  i = istart = mTextureUnitStates.begin() + start;
                  // Set the new pass to fallback using scene blend
                  newPass->setSceneBlending(
                        (*i)->getColourBlendFallbackSrc(), (*i)->getColourBlendFallbackDest());
                  // Fixup the texture unit 0   of new pass   blending method   to replace
                  // all colour and alpha   with texture without adjustment, because we
                  // assume it's detail texture.
                  (*i)->setColourOperationEx(LBX_SOURCE1,   LBS_TEXTURE, LBS_CURRENT);
                  (*i)->setAlphaOperation(LBX_SOURCE1, LBS_TEXTURE, LBS_CURRENT);

                  // Add all the other texture unit states
                  for (; i != iend; ++i)
                  {
                        // detach from parent first
                        (*i)->_notifyParent(0);
                        newPass->addTextureUnitState(*i);
                  }
                  // Now remove texture units from this Pass, we don't need to delete since they've
                  // been transferred
                  mTextureUnitStates.erase(istart, iend);
                  _dirtyHash();
                  mContentTypeLookupBuilt = false;
                  return newPass;
            }
            return NULL;
      }
      //-----------------------------------------------------------------------------
00957       void Pass::_notifyIndex(unsigned short index)
      {
            if (mIndex != index)
            {
                  mIndex = index;
                  _dirtyHash();
            }
      }
    //-----------------------------------------------------------------------
00966       void Pass::_load(void)
      {
            // We assume the Technique only calls this when the material is being
            // loaded

            // Load each TextureUnitState
            TextureUnitStates::iterator i, iend;
            iend = mTextureUnitStates.end();
            for (i = mTextureUnitStates.begin(); i != iend; ++i)
            {
                  (*i)->_load();
            }

            // Load programs
            if (mVertexProgramUsage)
            {
                  // Load vertex program
            mVertexProgramUsage->_load();
        }
        if (mShadowCasterVertexProgramUsage)
        {
            // Load vertex program
            mShadowCasterVertexProgramUsage->_load();
        }
        if (mShadowReceiverVertexProgramUsage)
        {
            // Load vertex program
            mShadowReceiverVertexProgramUsage->_load();
        }

        if (mFragmentProgramUsage)
        {
                  // Load fragment program
            mFragmentProgramUsage->_load();
            }
            if (mShadowReceiverFragmentProgramUsage)
            {
                  // Load Fragment program
                  mShadowReceiverFragmentProgramUsage->_load();
            }

      }
    //-----------------------------------------------------------------------
01009       void Pass::_unload(void)
      {
            // Unload each TextureUnitState
            TextureUnitStates::iterator i, iend;
            iend = mTextureUnitStates.end();
            for (i = mTextureUnitStates.begin(); i != iend; ++i)
            {
                  (*i)->_unload();
            }

            // Unload programs
            if (mVertexProgramUsage)
            {
                  // TODO
            }
        if (mFragmentProgramUsage)
        {
            // TODO
        }
      }
    //-----------------------------------------------------------------------
01030       void Pass::setVertexProgram(const String& name, bool resetParams)
      {
        // Turn off vertex program if name blank
        if (name.empty())
        {
            if (mVertexProgramUsage) delete mVertexProgramUsage;
            mVertexProgramUsage = NULL;
        }
        else
        {
            if (!mVertexProgramUsage)
            {
                mVertexProgramUsage = new GpuProgramUsage(GPT_VERTEX_PROGRAM);
            }
                mVertexProgramUsage->setProgramName(name, resetParams);
        }
        // Needs recompilation
        mParent->_notifyNeedsRecompile();
      }
    //-----------------------------------------------------------------------
01050       void Pass::setVertexProgramParameters(GpuProgramParametersSharedPtr params)
      {
            if (!mVertexProgramUsage)
        {
            OGRE_EXCEPT (Exception::ERR_INVALIDPARAMS,
                "This pass does not have a vertex program assigned!",
                "Pass::setVertexProgramParameters");
        }
            mVertexProgramUsage->setParameters(params);
      }
    //-----------------------------------------------------------------------
01061       void Pass::setFragmentProgram(const String& name, bool resetParams)
      {
        // Turn off fragment program if name blank
        if (name.empty())
        {
            if (mFragmentProgramUsage) delete mFragmentProgramUsage;
            mFragmentProgramUsage = NULL;
        }
        else
        {
            if (!mFragmentProgramUsage)
            {
                mFragmentProgramUsage = new GpuProgramUsage(GPT_FRAGMENT_PROGRAM);
            }
                mFragmentProgramUsage->setProgramName(name, resetParams);
        }
        // Needs recompilation
        mParent->_notifyNeedsRecompile();
      }
    //-----------------------------------------------------------------------
01081       void Pass::setFragmentProgramParameters(GpuProgramParametersSharedPtr params)
      {
            if (!mFragmentProgramUsage)
        {
            OGRE_EXCEPT (Exception::ERR_INVALIDPARAMS,
                "This pass does not have a fragment program assigned!",
                "Pass::setFragmentProgramParameters");
        }
            mFragmentProgramUsage->setParameters(params);
      }
      //-----------------------------------------------------------------------
01092       const String& Pass::getVertexProgramName(void) const
      {
        if (!mVertexProgramUsage)
            return StringUtil::BLANK;
        else
                return mVertexProgramUsage->getProgramName();
      }
      //-----------------------------------------------------------------------
01100       GpuProgramParametersSharedPtr Pass::getVertexProgramParameters(void) const
      {
            if (!mVertexProgramUsage)
        {
            OGRE_EXCEPT (Exception::ERR_INVALIDPARAMS,
                "This pass does not have a vertex program assigned!",
                "Pass::getVertexProgramParameters");
        }
            return mVertexProgramUsage->getParameters();
      }
      //-----------------------------------------------------------------------
01111       const GpuProgramPtr& Pass::getVertexProgram(void) const
      {
            return mVertexProgramUsage->getProgram();
      }
      //-----------------------------------------------------------------------
01116       const String& Pass::getFragmentProgramName(void) const
      {
        if (!mFragmentProgramUsage)
            return StringUtil::BLANK;
        else
            return mFragmentProgramUsage->getProgramName();
      }
      //-----------------------------------------------------------------------
01124       GpuProgramParametersSharedPtr Pass::getFragmentProgramParameters(void) const
      {
            return mFragmentProgramUsage->getParameters();
      }
      //-----------------------------------------------------------------------
01129       const GpuProgramPtr& Pass::getFragmentProgram(void) const
      {
            return mFragmentProgramUsage->getProgram();
      }
      //-----------------------------------------------------------------------
    bool Pass::isLoaded(void) const
    {
        return mParent->isLoaded();
    }
      //-----------------------------------------------------------------------
01139     void Pass::_recalculateHash(void)
    {
        /* Hash format is 32-bit, divided as follows (high to low bits)
           bits   purpose
            4     Pass index (i.e. max 16 passes!)
           14     Hashed texture name from unit 0
           14     Hashed texture name from unit 1

           Note that at the moment we don't sort on the 3rd texture unit plus
           on the assumption that these are less frequently used; sorting on
           the first 2 gives us the most benefit for now.
       */
        mHash = (*msHashFunc)(this);
    }
    //-----------------------------------------------------------------------
01154       void Pass::_dirtyHash(void)
      {
            OGRE_LOCK_MUTEX(msDirtyHashListMutex)
            // Mark this hash as for follow up
            msDirtyHashList.insert(this);
      }
      //---------------------------------------------------------------------
01161       void Pass::clearDirtyHashList(void) 
      { 
            OGRE_LOCK_MUTEX(msDirtyHashListMutex)
            msDirtyHashList.clear(); 
      }
    //-----------------------------------------------------------------------
01167     void Pass::_notifyNeedsRecompile(void)
    {
        mParent->_notifyNeedsRecompile();
    }
    //-----------------------------------------------------------------------
01172     void Pass::setTextureFiltering(TextureFilterOptions filterType)
    {
        TextureUnitStates::iterator i, iend;
        iend = mTextureUnitStates.end();
        for (i = mTextureUnitStates.begin(); i != iend; ++i)
        {
            (*i)->setTextureFiltering(filterType);
        }
    }
    // --------------------------------------------------------------------
01182     void Pass::setTextureAnisotropy(unsigned int maxAniso)
    {
        TextureUnitStates::iterator i, iend;
        iend = mTextureUnitStates.end();
        for (i = mTextureUnitStates.begin(); i != iend; ++i)
        {
            (*i)->setTextureAnisotropy(maxAniso);
        }
    }
    //-----------------------------------------------------------------------
01192     void Pass::_updateAutoParamsNoLights(const AutoParamDataSource& source) const
    {
        if (hasVertexProgram())
        {
            // Update vertex program auto params
            mVertexProgramUsage->getParameters()->_updateAutoParamsNoLights(source);
        }

        if (hasFragmentProgram())
        {
            // Update fragment program auto params
            mFragmentProgramUsage->getParameters()->_updateAutoParamsNoLights(source);
        }
    }
    //-----------------------------------------------------------------------
01207     void Pass::_updateAutoParamsLightsOnly(const AutoParamDataSource& source) const
    {
        if (hasVertexProgram())
        {
            // Update vertex program auto params
            mVertexProgramUsage->getParameters()->_updateAutoParamsLightsOnly(source);
        }

        if (hasFragmentProgram())
        {
            // Update fragment program auto params
            mFragmentProgramUsage->getParameters()->_updateAutoParamsLightsOnly(source);
        }
    }
    //-----------------------------------------------------------------------
01222     void Pass::processPendingPassUpdates(void)
    {
            {
                  OGRE_LOCK_MUTEX(msPassGraveyardMutex)
                  // Delete items in the graveyard
                  PassSet::iterator i, iend;
                  iend = msPassGraveyard.end();
                  for (i = msPassGraveyard.begin(); i != iend; ++i)
                  {
                        delete *i;
                  }
                  msPassGraveyard.clear();
            }

            {
                  OGRE_LOCK_MUTEX(msDirtyHashListMutex)
                  PassSet::iterator i, iend;
                  // The dirty ones will have been removed from the groups above using the old hash now
                  iend = msDirtyHashList.end();
                  for (i = msDirtyHashList.begin(); i != iend; ++i)
                  {
                        Pass* p = *i;
                        p->_recalculateHash();
                  }
                  // Clear the dirty list
                  msDirtyHashList.clear();
            }
    }
    //-----------------------------------------------------------------------
01251     void Pass::queueForDeletion(void)
    {
        mQueuedForDeletion = true;

        removeAllTextureUnitStates();
        if (mVertexProgramUsage)
        {
            delete mVertexProgramUsage;
            mVertexProgramUsage = 0;
        }
        if (mShadowCasterVertexProgramUsage)
        {
            delete mShadowCasterVertexProgramUsage;
            mShadowCasterVertexProgramUsage = 0;
        }
        if (mShadowReceiverVertexProgramUsage)
        {
            delete mShadowReceiverVertexProgramUsage;
            mShadowReceiverVertexProgramUsage = 0;
        }
        if (mFragmentProgramUsage)
        {
            delete mFragmentProgramUsage;
            mFragmentProgramUsage = 0;
        }
            if (mShadowReceiverFragmentProgramUsage)
            {
                  delete mShadowReceiverFragmentProgramUsage;
                  mShadowReceiverFragmentProgramUsage = 0;
            }
        // remove from dirty list, if there
            {
                  OGRE_LOCK_MUTEX(msDirtyHashListMutex)
                  msDirtyHashList.erase(this);
            }
            {
                  OGRE_LOCK_MUTEX(msPassGraveyardMutex)
                  msPassGraveyard.insert(this);
            }
    }
    //-----------------------------------------------------------------------
01292     bool Pass::isAmbientOnly(void) const
    {
        // treat as ambient if lighting is off, or colour write is off,
        // or all non-ambient (& emissive) colours are black
        // NB a vertex program could override this, but passes using vertex
        // programs are expected to indicate they are ambient only by
        // setting the state so it matches one of the conditions above, even
        // though this state is not used in rendering.
        return (!mLightingEnabled || !mColourWrite ||
            (mDiffuse == ColourValue::Black &&
             mSpecular == ColourValue::Black));
    }
    //-----------------------------------------------------------------------
01305     void Pass::setShadowCasterVertexProgram(const String& name)
    {
        // Turn off vertex program if name blank
        if (name.empty())
        {
            if (mShadowCasterVertexProgramUsage) delete mShadowCasterVertexProgramUsage;
            mShadowCasterVertexProgramUsage = NULL;
        }
        else
        {
            if (!mShadowCasterVertexProgramUsage)
            {
                mShadowCasterVertexProgramUsage = new GpuProgramUsage(GPT_VERTEX_PROGRAM);
            }
            mShadowCasterVertexProgramUsage->setProgramName(name);
        }
        // Needs recompilation
        mParent->_notifyNeedsRecompile();
    }
    //-----------------------------------------------------------------------
01325     void Pass::setShadowCasterVertexProgramParameters(GpuProgramParametersSharedPtr params)
    {
        if (!mShadowCasterVertexProgramUsage)
        {
            OGRE_EXCEPT (Exception::ERR_INVALIDPARAMS,
                "This pass does not have a shadow caster vertex program assigned!",
                "Pass::setShadowCasterVertexProgramParameters");
        }
        mShadowCasterVertexProgramUsage->setParameters(params);
    }
    //-----------------------------------------------------------------------
01336     const String& Pass::getShadowCasterVertexProgramName(void) const
    {
        if (!mShadowCasterVertexProgramUsage)
            return StringUtil::BLANK;
        else
            return mShadowCasterVertexProgramUsage->getProgramName();
    }
    //-----------------------------------------------------------------------
01344     GpuProgramParametersSharedPtr Pass::getShadowCasterVertexProgramParameters(void) const
    {
        if (!mShadowCasterVertexProgramUsage)
        {
            OGRE_EXCEPT (Exception::ERR_INVALIDPARAMS,
                "This pass does not have a shadow caster vertex program assigned!",
                "Pass::getShadowCasterVertexProgramParameters");
        }
        return mShadowCasterVertexProgramUsage->getParameters();
    }
    //-----------------------------------------------------------------------
01355     const GpuProgramPtr& Pass::getShadowCasterVertexProgram(void) const
    {
        return mShadowCasterVertexProgramUsage->getProgram();
    }
    //-----------------------------------------------------------------------
01360     void Pass::setShadowReceiverVertexProgram(const String& name)
    {
        // Turn off vertex program if name blank
        if (name.empty())
        {
            if (mShadowReceiverVertexProgramUsage) delete mShadowReceiverVertexProgramUsage;
            mShadowReceiverVertexProgramUsage = NULL;
        }
        else
        {
            if (!mShadowReceiverVertexProgramUsage)
            {
                mShadowReceiverVertexProgramUsage = new GpuProgramUsage(GPT_VERTEX_PROGRAM);
            }
            mShadowReceiverVertexProgramUsage->setProgramName(name);
        }
        // Needs recompilation
        mParent->_notifyNeedsRecompile();
    }
    //-----------------------------------------------------------------------
01380     void Pass::setShadowReceiverVertexProgramParameters(GpuProgramParametersSharedPtr params)
    {
        if (!mShadowReceiverVertexProgramUsage)
        {
            OGRE_EXCEPT (Exception::ERR_INVALIDPARAMS,
                "This pass does not have a shadow receiver vertex program assigned!",
                "Pass::setShadowReceiverVertexProgramParameters");
        }
        mShadowReceiverVertexProgramUsage->setParameters(params);
    }
    //-----------------------------------------------------------------------
01391     const String& Pass::getShadowReceiverVertexProgramName(void) const
    {
        if (!mShadowReceiverVertexProgramUsage)
            return StringUtil::BLANK;
        else
            return mShadowReceiverVertexProgramUsage->getProgramName();
    }
    //-----------------------------------------------------------------------
01399     GpuProgramParametersSharedPtr Pass::getShadowReceiverVertexProgramParameters(void) const
    {
        if (!mShadowReceiverVertexProgramUsage)
        {
            OGRE_EXCEPT (Exception::ERR_INVALIDPARAMS,
                "This pass does not have a shadow receiver vertex program assigned!",
                "Pass::getShadowReceiverVertexProgramParameters");
        }
        return mShadowReceiverVertexProgramUsage->getParameters();
    }
    //-----------------------------------------------------------------------
01410     const GpuProgramPtr& Pass::getShadowReceiverVertexProgram(void) const
    {
        return mShadowReceiverVertexProgramUsage->getProgram();
    }
      //-----------------------------------------------------------------------
01415       void Pass::setShadowReceiverFragmentProgram(const String& name)
      {
            // Turn off Fragment program if name blank
            if (name.empty())
            {
                  if (mShadowReceiverFragmentProgramUsage) delete mShadowReceiverFragmentProgramUsage;
                  mShadowReceiverFragmentProgramUsage = NULL;
            }
            else
            {
                  if (!mShadowReceiverFragmentProgramUsage)
                  {
                        mShadowReceiverFragmentProgramUsage = new GpuProgramUsage(GPT_FRAGMENT_PROGRAM);
                  }
                  mShadowReceiverFragmentProgramUsage->setProgramName(name);
            }
            // Needs recompilation
            mParent->_notifyNeedsRecompile();
      }
      //-----------------------------------------------------------------------
01435       void Pass::setShadowReceiverFragmentProgramParameters(GpuProgramParametersSharedPtr params)
      {
            if (!mShadowReceiverFragmentProgramUsage)
            {
                  OGRE_EXCEPT (Exception::ERR_INVALIDPARAMS,
                        "This pass does not have a shadow receiver fragment program assigned!",
                        "Pass::setShadowReceiverFragmentProgramParameters");
            }
            mShadowReceiverFragmentProgramUsage->setParameters(params);
      }
      //-----------------------------------------------------------------------
01446       const String& Pass::getShadowReceiverFragmentProgramName(void) const
      {
            if (!mShadowReceiverFragmentProgramUsage)
                  return StringUtil::BLANK;
            else
                  return mShadowReceiverFragmentProgramUsage->getProgramName();
      }
      //-----------------------------------------------------------------------
01454       GpuProgramParametersSharedPtr Pass::getShadowReceiverFragmentProgramParameters(void) const
      {
            if (!mShadowReceiverFragmentProgramUsage)
            {
                  OGRE_EXCEPT (Exception::ERR_INVALIDPARAMS,
                        "This pass does not have a shadow receiver fragment program assigned!",
                        "Pass::getShadowReceiverFragmentProgramParameters");
            }
            return mShadowReceiverFragmentProgramUsage->getParameters();
      }
      //-----------------------------------------------------------------------
01465       const GpuProgramPtr& Pass::getShadowReceiverFragmentProgram(void) const
      {
            return mShadowReceiverFragmentProgramUsage->getProgram();
      }
    //-----------------------------------------------------------------------
01470       const String& Pass::getResourceGroup(void) const
      {
            return mParent->getResourceGroup();
      }

    //-----------------------------------------------------------------------
01476     bool Pass::applyTextureAliases(const AliasTextureNamePairList& aliasList, const bool apply) const
    {
        // iterate through each texture unit state and apply the texture alias if it applies
        TextureUnitStates::const_iterator i, iend;
        iend = mTextureUnitStates.end();
        bool testResult = false;

        for (i = mTextureUnitStates.begin(); i != iend; ++i)
        {
            if ((*i)->applyTextureAliases(aliasList, apply))
                testResult = true;
        }

        return testResult;

    }
      //-----------------------------------------------------------------------
01493       unsigned short Pass::_getTextureUnitWithContentTypeIndex(
            TextureUnitState::ContentType contentType, unsigned short index) const
      {
            if (!mContentTypeLookupBuilt)
            {
                  mShadowContentTypeLookup.clear();
                  for (unsigned short i = 0; i < mTextureUnitStates.size(); ++i)
                  {
                        if (mTextureUnitStates[i]->getContentType() == TextureUnitState::CONTENT_SHADOW)
                        {
                              mShadowContentTypeLookup.push_back(i);
                        }
                  }
                  mContentTypeLookupBuilt = true;
            }

            switch(contentType)
            {
            case TextureUnitState::CONTENT_SHADOW:
                  if (index < mShadowContentTypeLookup.size())
                  {
                        return mShadowContentTypeLookup[index];
                  }
                  break;
            default:
                  // Simple iteration
                  for (unsigned short i = 0; i < mTextureUnitStates.size(); ++i)
                  {
                        if (mTextureUnitStates[i]->getContentType() == TextureUnitState::CONTENT_SHADOW)
                        {
                              if (index == 0)
                              {
                                    return i;
                              }
                              else
                              {
                                    --index;
                              }
                        }
                  }
                  break;
            }

            // not found - return out of range
            return static_cast<unsigned short>(mTextureUnitStates.size() + 1);

      }


}

Generated by  Doxygen 1.6.0   Back to index