Main Page Namespace List Class Hierarchy Alphabetical List Compound List File List Namespace Members Compound Members File Members Related Pages

# OgrePass.cpp

Go to the documentation of this file.

    00001 /*
    00002 -----------------------------------------------------------------------------
    00003 This source file is part of OGRE
    00004     (Object-oriented Graphics Rendering Engine)
    00005 For the latest info, see http://ogre.sourceforge.net/
    00006
    00007 Copyright © 2000-2003 The OGRE Team
    00008 Also see acknowledgements in Readme.html
    00009
    00010 This program is free software; you can redistribute it and/or modify it under
    00011 the terms of the GNU Lesser General Public License as published by the Free Software
    00012 Foundation; either version 2 of the License, or (at your option) any later
    00013 version.
    00014
    00015 This program is distributed in the hope that it will be useful, but WITHOUT
    00016 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    00017 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
    00018
    00019 You should have received a copy of the GNU Lesser General Public License along with
    00020 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
    00021 Place - Suite 330, Boston, MA 02111-1307, USA, or go to
    00022 http://www.gnu.org/copyleft/lesser.txt.
    00023 -----------------------------------------------------------------------------
    00024 */
    00025 #include "OgreStableHeaders.h"
    00026
    00027 #include "OgrePass.h"
    00028 #include "OgreTechnique.h"
    00029 #include "OgreMaterialManager.h"
    00030 #include "OgreException.h"
    00031 #include "OgreGpuProgramUsage.h"
    00032 #include "OgreTextureUnitState.h"
    00033
    00034 namespace Ogre {
    00035
    00036     //-----------------------------------------------------------------------------
    00037     Pass::PassSet Pass::msDirtyHashList;
    00038     Pass::PassSet Pass::msPassGraveyard;
    00039     //-----------------------------------------------------------------------------
    00040     Pass::Pass(Technique* parent, unsigned short index)
    00041         : mParent(parent), mIndex(index)
    00042     {
    00043         // Default to white ambient & diffuse, no specular / emissive
    00044         mAmbient = mDiffuse = ColourValue::White;
    00045         mSpecular = mEmissive = ColourValue::Black;
    00046         mShininess = 0;
    00047         mHash = 0;
    00048
    00049         // By default, don't override the scene's fog settings
    00050         mFogOverride = false;
    00051         mFogMode = FOG_NONE;
    00052         mFogColour = ColourValue::White;
    00053         mFogStart = 0.0;
    00054         mFogEnd = 1.0;
    00055         mFogDensity = 0.001;
    00056
    00057         // Default blending (overwrite)
    00058         mSourceBlendFactor = SBF_ONE;
    00059         mDestBlendFactor = SBF_ZERO;
    00060
    00061         mDepthCheck = true;
    00062         mDepthWrite = true;
    00063         mColourWrite = true;
    00064         mDepthFunc = CMPF_LESS_EQUAL;
    00065         mDepthBias = 0;
    00066         mCullMode = CULL_CLOCKWISE;
    00067         mManualCullMode = MANUAL_CULL_BACK;
    00068         mLightingEnabled = true;
    00069         mMaxSimultaneousLights = OGRE_MAX_SIMULTANEOUS_LIGHTS;
    00070         mRunOncePerLight = false;
    00071         mRunOnlyForOneLightType = true;
    00072         mOnlyLightType = Light::LT_POINT;
    00073         mShadeOptions = SO_GOURAUD;
    00074
    00075         mVertexProgramUsage = NULL;
    00076         mShadowCasterVertexProgramUsage = NULL;
    00077         mShadowReceiverVertexProgramUsage = NULL;
    00078         mFragmentProgramUsage = NULL;
    00079
    00080         mQueuedForDeletion = false;
    00081
    00082         _dirtyHash();
    00083    }
    00084
    00085     //-----------------------------------------------------------------------------
    00086     Pass::Pass(Technique *parent, unsigned short index, const Pass& oth)
    00087         :mParent(parent), mIndex(index)
    00088     {
    00089         *this = oth;
    00090         mParent = parent;
    00091         mIndex = index;
    00092         mQueuedForDeletion = false;
    00093         _dirtyHash();
    00094     }
    00095     //-----------------------------------------------------------------------------
    00096     Pass::~Pass()
    00097     {
    00098
    00099     }
    00100     //-----------------------------------------------------------------------------
    00101     Pass& Pass::operator=(const Pass& oth)
    00102     {
    00103         mAmbient = oth.mAmbient;
    00104         mDiffuse = oth.mDiffuse;
    00105         mSpecular = oth.mSpecular;
    00106         mEmissive = oth.mEmissive;
    00107         mShininess = oth.mShininess;
    00108
    00109         // Copy fog parameters
    00110         mFogOverride = oth.mFogOverride;
    00111         mFogMode = oth.mFogMode;
    00112         mFogColour = oth.mFogColour;
    00113         mFogStart = oth.mFogStart;
    00114         mFogEnd = oth.mFogEnd;
    00115         mFogDensity = oth.mFogDensity;
    00116
    00117         // Default blending (overwrite)
    00118         mSourceBlendFactor = oth.mSourceBlendFactor;
    00119         mDestBlendFactor = oth.mDestBlendFactor;
    00120
    00121         mDepthCheck = oth.mDepthCheck;
    00122         mDepthWrite = oth.mDepthWrite;
    00123         mColourWrite = oth.mColourWrite;
    00124         mDepthFunc = oth.mDepthFunc;
    00125         mDepthBias = oth.mDepthBias;
    00126         mCullMode = oth.mCullMode;
    00127         mManualCullMode = oth.mManualCullMode;
    00128         mLightingEnabled = oth.mLightingEnabled;
    00129         mMaxSimultaneousLights = oth.mMaxSimultaneousLights;
    00130         mRunOncePerLight = oth.mRunOncePerLight;
    00131         mRunOnlyForOneLightType = oth.mRunOnlyForOneLightType;
    00132         mOnlyLightType = oth.mOnlyLightType;
    00133         mShadeOptions = oth.mShadeOptions;
    00134
    00135         if (oth.mVertexProgramUsage)
    00136         {
    00137             mVertexProgramUsage = new GpuProgramUsage(*(oth.mVertexProgramUsage));
    00138         }
    00139         else
    00140         {
    00141             mVertexProgramUsage = NULL;
    00142         }
    00143         if (oth.mShadowCasterVertexProgramUsage)
    00144         {
    00145             mShadowCasterVertexProgramUsage = new GpuProgramUsage(*(oth.mShadowCasterVertexProgramUsage));
    00146         }
    00147         else
    00148         {
    00149             mShadowCasterVertexProgramUsage = NULL;
    00150         }
    00151         if (oth.mShadowReceiverVertexProgramUsage)
    00152         {
    00153             mShadowReceiverVertexProgramUsage = new GpuProgramUsage(*(oth.mShadowReceiverVertexProgramUsage));
    00154         }
    00155         else
    00156         {
    00157             mShadowReceiverVertexProgramUsage = NULL;
    00158         }
    00159         if (oth.mFragmentProgramUsage)
    00160         {
    00161             mFragmentProgramUsage = new GpuProgramUsage(*(oth.mFragmentProgramUsage));
    00162         }
    00163         else
    00164         {
    00165             mFragmentProgramUsage = NULL;
    00166         }
    00167
    00168         // Copy texture units
    00169         removeAllTextureUnitStates();
    00170         TextureUnitStates::const_iterator i, iend;
    00171         iend = oth.mTextureUnitStates.end();
    00172         for (i = oth.mTextureUnitStates.begin(); i != iend; ++i)
    00173         {
    00174             TextureUnitState* t = new TextureUnitState(this, *(*i));
    00175             mTextureUnitStates.push_back(t);
    00176         }
    00177
    00178         _dirtyHash();
    00179
    00180         return *this;
    00181     }
    00182     //-----------------------------------------------------------------------
    00183     void Pass::setAmbient(Real red, Real green, Real blue)
    00184     {
    00185         mAmbient.r = red;
    00186         mAmbient.g = green;
    00187         mAmbient.b = blue;
    00188
    00189     }
    00190     //-----------------------------------------------------------------------
    00191     void Pass::setAmbient(const ColourValue& ambient)
    00192     {
    00193         mAmbient = ambient;
    00194     }
    00195     //-----------------------------------------------------------------------
    00196     void Pass::setDiffuse(Real red, Real green, Real blue, Real alpha)
    00197     {
    00198         mDiffuse.r = red;
    00199         mDiffuse.g = green;
    00200         mDiffuse.b = blue;
    00201         mDiffuse.a = alpha;
    00202     }
    00203     //-----------------------------------------------------------------------
    00204     void Pass::setDiffuse(const ColourValue& diffuse)
    00205     {
    00206         mDiffuse = diffuse;
    00207     }
    00208     //-----------------------------------------------------------------------
    00209     void Pass::setSpecular(Real red, Real green, Real blue, Real alpha)
    00210     {
    00211         mSpecular.r = red;
    00212         mSpecular.g = green;
    00213         mSpecular.b = blue;
    00214         mSpecular.a = alpha;
    00215     }
    00216     //-----------------------------------------------------------------------
    00217     void Pass::setSpecular(const ColourValue& specular)
    00218     {
    00219         mSpecular = specular;
    00220     }
    00221     //-----------------------------------------------------------------------
    00222     void Pass::setShininess(Real val)
    00223     {
    00224         mShininess = val;
    00225     }
    00226     //-----------------------------------------------------------------------
    00227     void Pass::setSelfIllumination(Real red, Real green, Real blue)
    00228     {
    00229         mEmissive.r = red;
    00230         mEmissive.g = green;
    00231         mEmissive.b = blue;
    00232
    00233     }
    00234     //-----------------------------------------------------------------------
    00235     void Pass::setSelfIllumination(const ColourValue& selfIllum)
    00236     {
    00237         mEmissive = selfIllum;
    00238     }
    00239     //-----------------------------------------------------------------------
    00240     const ColourValue& Pass::getAmbient(void) const
    00241     {
    00242         return mAmbient;
    00243     }
    00244     //-----------------------------------------------------------------------
    00245     const ColourValue& Pass::getDiffuse(void) const
    00246     {
    00247         return mDiffuse;
    00248     }
    00249     //-----------------------------------------------------------------------
    00250     const ColourValue& Pass::getSpecular(void) const
    00251     {
    00252         return mSpecular;
    00253     }
    00254     //-----------------------------------------------------------------------
    00255     const ColourValue& Pass::getSelfIllumination(void) const
    00256     {
    00257         return mEmissive;
    00258     }
    00259     //-----------------------------------------------------------------------
    00260     Real Pass::getShininess(void) const
    00261     {
    00262         return mShininess;
    00263     }
    00264     //-----------------------------------------------------------------------
    00265     TextureUnitState* Pass::createTextureUnitState(void)
    00266     {
    00267         TextureUnitState *t = new TextureUnitState(this);
    00268         mTextureUnitStates.push_back(t);
    00269         // Needs recompilation
    00270         mParent->_notifyNeedsRecompile();
    00271         _dirtyHash();
    00272         return t;
    00273     }
    00274     //-----------------------------------------------------------------------
    00275     TextureUnitState* Pass::createTextureUnitState(
    00276         const String& textureName, unsigned short texCoordSet)
    00277     {
    00278         TextureUnitState *t = new TextureUnitState(this);
    00279         t->setTextureName(textureName);
    00280         t->setTextureCoordSet(texCoordSet);
    00281         mTextureUnitStates.push_back(t);
    00282         // Needs recompilation
    00283         mParent->_notifyNeedsRecompile();
    00284         _dirtyHash();
    00285         return t;
    00286     }
    00287     //-----------------------------------------------------------------------
    00288     void Pass::addTextureUnitState(TextureUnitState* state)
    00289     {
    00290         mTextureUnitStates.push_back(state);
    00291         // Needs recompilation
    00292         mParent->_notifyNeedsRecompile();
    00293         _dirtyHash();
    00294     }
    00295     //-----------------------------------------------------------------------
    00296     TextureUnitState* Pass::getTextureUnitState(unsigned short index)
    00297     {
    00298         assert (index < mTextureUnitStates.size() && "Index out of bounds");
    00299         return mTextureUnitStates[index];
    00300     }
    00301     //-----------------------------------------------------------------------
    00302     Pass::TextureUnitStateIterator
    00303         Pass::getTextureUnitStateIterator(void)
    00304     {
    00305         return TextureUnitStateIterator(mTextureUnitStates.begin(), mTextureUnitStates.end());
    00306     }
    00307     //-----------------------------------------------------------------------
    00308     void Pass::removeTextureUnitState(unsigned short index)
    00309     {
    00310         assert (index < mTextureUnitStates.size() && "Index out of bounds");
    00311
    00312         TextureUnitStates::iterator i = mTextureUnitStates.begin() + index;
    00313         delete *i;
    00314         mTextureUnitStates.erase(i);
    00315         if (!mQueuedForDeletion)
    00316         {
    00317             // Needs recompilation
    00318             mParent->_notifyNeedsRecompile();
    00319         }
    00320         _dirtyHash();
    00321     }
    00322     //-----------------------------------------------------------------------
    00323     void Pass::removeAllTextureUnitStates(void)
    00324     {
    00325         TextureUnitStates::iterator i, iend;
    00326         iend = mTextureUnitStates.end();
    00327         for (i = mTextureUnitStates.begin(); i != iend; ++i)
    00328         {
    00329             delete *i;
    00330         }
    00331         mTextureUnitStates.clear();
    00332         if (!mQueuedForDeletion)
    00333         {
    00334             // Needs recompilation
    00335             mParent->_notifyNeedsRecompile();
    00336         }
    00337         _dirtyHash();
    00338     }
    00339     //-----------------------------------------------------------------------
    00340     void Pass::setSceneBlending(SceneBlendType sbt)
    00341     {
    00342         // Turn predefined type into blending factors
    00343         switch (sbt)
    00344         {
    00345         case SBT_TRANSPARENT_ALPHA:
    00346             setSceneBlending(SBF_SOURCE_ALPHA, SBF_ONE_MINUS_SOURCE_ALPHA);
    00347             break;
    00348         case SBT_TRANSPARENT_COLOUR:
    00349             setSceneBlending(SBF_SOURCE_COLOUR, SBF_ONE_MINUS_SOURCE_COLOUR);
    00350             break;
    00351         case SBT_ADD:
    00352             setSceneBlending(SBF_ONE, SBF_ONE);
    00353             break;
    00354         // TODO: more
    00355         }
    00356
    00357     }
    00358     //-----------------------------------------------------------------------
    00359     void Pass::setSceneBlending(SceneBlendFactor sourceFactor, SceneBlendFactor destFactor)
    00360     {
    00361         mSourceBlendFactor = sourceFactor;
    00362         mDestBlendFactor = destFactor;
    00363     }
    00364     //-----------------------------------------------------------------------
    00365     SceneBlendFactor Pass::getSourceBlendFactor(void) const
    00366     {
    00367         return mSourceBlendFactor;
    00368     }
    00369     //-----------------------------------------------------------------------
    00370     SceneBlendFactor Pass::getDestBlendFactor(void) const
    00371     {
    00372         return mDestBlendFactor;
    00373     }
    00374     //-----------------------------------------------------------------------
    00375     bool Pass::isTransparent(void) const
    00376     {
    00377         // Transparent if any of the destination colour is taken into account
    00378         if (mDestBlendFactor != SBF_ZERO)
    00379             return true;
    00380         else
    00381             return false;
    00382     }
    00383     //-----------------------------------------------------------------------
    00384     void Pass::setDepthCheckEnabled(bool enabled)
    00385     {
    00386         mDepthCheck = enabled;
    00387     }
    00388     //-----------------------------------------------------------------------
    00389     bool Pass::getDepthCheckEnabled(void) const
    00390     {
    00391         return mDepthCheck;
    00392     }
    00393     //-----------------------------------------------------------------------
    00394     void Pass::setDepthWriteEnabled(bool enabled)
    00395     {
    00396         mDepthWrite = enabled;
    00397     }
    00398     //-----------------------------------------------------------------------
    00399     bool Pass::getDepthWriteEnabled(void) const
    00400     {
    00401         return mDepthWrite;
    00402     }
    00403     //-----------------------------------------------------------------------
    00404     void Pass::setDepthFunction( CompareFunction func)
    00405     {
    00406         mDepthFunc = func;
    00407     }
    00408     //-----------------------------------------------------------------------
    00409     CompareFunction Pass::getDepthFunction(void) const
    00410     {
    00411         return mDepthFunc;
    00412     }
    00413     //-----------------------------------------------------------------------
    00414     void Pass::setColourWriteEnabled(bool enabled)
    00415     {
    00416         mColourWrite = enabled;
    00417     }
    00418     //-----------------------------------------------------------------------
    00419     bool Pass::getColourWriteEnabled(void) const
    00420     {
    00421         return mColourWrite;
    00422     }
    00423     //-----------------------------------------------------------------------
    00424     void Pass::setCullingMode( CullingMode mode)
    00425     {
    00426         mCullMode = mode;
    00427     }
    00428     //-----------------------------------------------------------------------
    00429     CullingMode Pass::getCullingMode(void) const
    00430     {
    00431         return mCullMode;
    00432     }
    00433     //-----------------------------------------------------------------------
    00434     void Pass::setLightingEnabled(bool enabled)
    00435     {
    00436         mLightingEnabled = enabled;
    00437     }
    00438     //-----------------------------------------------------------------------
    00439     bool Pass::getLightingEnabled(void) const
    00440     {
    00441         return mLightingEnabled;
    00442     }
    00443     //-----------------------------------------------------------------------
    00444     void Pass::setMaxSimultaneousLights(unsigned short maxLights)
    00445     {
    00446         mMaxSimultaneousLights = maxLights;
    00447     }
    00448     //-----------------------------------------------------------------------
    00449     unsigned short Pass::getMaxSimultaneousLights(void) const
    00450     {
    00451         return mMaxSimultaneousLights;
    00452     }
    00453     //-----------------------------------------------------------------------
    00454     void Pass::setRunOncePerLight(bool enabled,
    00455             bool onlyForOneLightType, Light::LightTypes lightType)
    00456     {
    00457         mRunOncePerLight = enabled;
    00458         mRunOnlyForOneLightType = onlyForOneLightType;
    00459         mOnlyLightType = lightType;
    00460     }
    00461     //-----------------------------------------------------------------------
    00462     void Pass::setShadingMode(ShadeOptions mode)
    00463     {
    00464         mShadeOptions = mode;
    00465     }
    00466     //-----------------------------------------------------------------------
    00467     ShadeOptions Pass::getShadingMode(void) const
    00468     {
    00469         return mShadeOptions;
    00470     }
    00471     //-----------------------------------------------------------------------
    00472     void Pass::setManualCullingMode(ManualCullingMode mode)
    00473     {
    00474         mManualCullMode = mode;
    00475     }
    00476     //-----------------------------------------------------------------------
    00477     ManualCullingMode Pass::getManualCullingMode(void) const
    00478     {
    00479         return mManualCullMode;
    00480     }
    00481     //-----------------------------------------------------------------------
    00482     void Pass::setFog(bool overrideScene, FogMode mode, const ColourValue& colour, Real density, Real start, Real end)
    00483     {
    00484         mFogOverride = overrideScene;
    00485         if (overrideScene)
    00486         {
    00487             mFogMode = mode;
    00488             mFogColour = colour;
    00489             mFogStart = start;
    00490             mFogEnd = end;
    00491             mFogDensity = density;
    00492         }
    00493     }
    00494     //-----------------------------------------------------------------------
    00495     bool Pass::getFogOverride(void) const
    00496     {
    00497         return mFogOverride;
    00498     }
    00499     //-----------------------------------------------------------------------
    00500     FogMode Pass::getFogMode(void) const
    00501     {
    00502         return mFogMode;
    00503     }
    00504     //-----------------------------------------------------------------------
    00505     const ColourValue& Pass::getFogColour(void) const
    00506     {
    00507         return mFogColour;
    00508     }
    00509     //-----------------------------------------------------------------------
    00510     Real Pass::getFogStart(void) const
    00511     {
    00512         return mFogStart;
    00513     }
    00514     //-----------------------------------------------------------------------
    00515     Real Pass::getFogEnd(void) const
    00516     {
    00517         return mFogEnd;
    00518     }
    00519     //-----------------------------------------------------------------------
    00520     Real Pass::getFogDensity(void) const
    00521     {
    00522         return mFogDensity;
    00523     }
    00524     //-----------------------------------------------------------------------
    00525     void Pass::setDepthBias(ushort bias)
    00526     {
    00527         assert(bias <= 16 && "Depth bias must be between 0 and 16");
    00528         mDepthBias = bias;
    00529     }
    00530     //-----------------------------------------------------------------------
    00531     ushort Pass::getDepthBias(void) const
    00532     {
    00533         return mDepthBias;
    00534     }
    00535     //-----------------------------------------------------------------------
    00536     Pass* Pass::_split(unsigned short numUnits)
    00537     {
    00538         if (mFragmentProgramUsage)
    00539         {
    00540             Except(Exception::ERR_INVALIDPARAMS, "Passes with fragment programs cannot be "
    00541                 "automatically split, define a fallback technique instead.",
    00542                 "Pass:_split");
    00543         }
    00544
    00545         if (mTextureUnitStates.size() > numUnits)
    00546         {
    00547             size_t start = mTextureUnitStates.size() - numUnits;
    00548
    00549             Pass* newPass = mParent->createPass();
    00550
    00551             TextureUnitStates::iterator istart, i, iend;
    00552             iend = mTextureUnitStates.end();
    00553             i = istart = mTextureUnitStates.begin() + start;
    00554             // Set the new pass to fallback using scene blend
    00555             newPass->setSceneBlending(
    00556                 (*i)->getColourBlendFallbackSrc(), (*i)->getColourBlendFallbackDest());
    00557             // Add all the other passes
    00558             for (; i != iend; ++i)
    00559             {
    00560                 newPass->addTextureUnitState(*i);
    00561             }
    00562             // Now remove texture units from this Pass, we don't need to delete since they've
    00563             // been transferred
    00564             mTextureUnitStates.erase(istart, iend);
    00565             return newPass;
    00566         }
    00567         return NULL;
    00568     }
    00569     //-----------------------------------------------------------------------
    00570     void Pass::_load(void)
    00571     {
    00572         // We assume the Technique only calls this when the material is being
    00573         // loaded
    00574
    00575         // Load each TextureUnitState
    00576         TextureUnitStates::iterator i, iend;
    00577         iend = mTextureUnitStates.end();
    00578         for (i = mTextureUnitStates.begin(); i != iend; ++i)
    00579         {
    00580             (*i)->_load();
    00581         }
    00582
    00583         // Load programs
    00584         if (mVertexProgramUsage)
    00585         {
    00586             // Load vertex program
    00587             mVertexProgramUsage->_load();
    00588         }
    00589         if (mShadowCasterVertexProgramUsage)
    00590         {
    00591             // Load vertex program
    00592             mShadowCasterVertexProgramUsage->_load();
    00593         }
    00594         if (mShadowReceiverVertexProgramUsage)
    00595         {
    00596             // Load vertex program
    00597             mShadowReceiverVertexProgramUsage->_load();
    00598         }
    00599
    00600         if (mFragmentProgramUsage)
    00601         {
    00602             // Load fragment program
    00603             mFragmentProgramUsage->_load();
    00604         }
    00605
    00606         // Recalculate hash
    00607         _dirtyHash();
    00608
    00609     }
    00610     //-----------------------------------------------------------------------
    00611     void Pass::_unload(void)
    00612     {
    00613         // Unload each TextureUnitState
    00614         TextureUnitStates::iterator i, iend;
    00615         iend = mTextureUnitStates.end();
    00616         for (i = mTextureUnitStates.begin(); i != iend; ++i)
    00617         {
    00618             (*i)->_unload();
    00619         }
    00620
    00621         // Unload programs
    00622         if (mVertexProgramUsage)
    00623         {
    00624             // TODO
    00625         }
    00626         if (mFragmentProgramUsage)
    00627         {
    00628             // TODO
    00629         }
    00630     }
    00631     //-----------------------------------------------------------------------
    00632     void Pass::setVertexProgram(const String& name, bool resetParams)
    00633     {
    00634         // Turn off vertex program if name blank
    00635         if (name.empty())
    00636         {
    00637             if (mVertexProgramUsage) delete mVertexProgramUsage;
    00638             mVertexProgramUsage = NULL;
    00639         }
    00640         else
    00641         {
    00642             if (!mVertexProgramUsage)
    00643             {
    00644                 mVertexProgramUsage = new GpuProgramUsage(GPT_VERTEX_PROGRAM);
    00645             }
    00646             mVertexProgramUsage->setProgramName(name, resetParams);
    00647         }
    00648         // Needs recompilation
    00649         mParent->_notifyNeedsRecompile();
    00650     }
    00651     //-----------------------------------------------------------------------
    00652     void Pass::setVertexProgramParameters(GpuProgramParametersSharedPtr params)
    00653     {
    00654         if (!mVertexProgramUsage)
    00655         {
    00656             Except (Exception::ERR_INVALIDPARAMS,
    00657                 "This pass does not have a vertex program assigned!",
    00658                 "Pass::setVertexProgramParameters");
    00659         }
    00660         mVertexProgramUsage->setParameters(params);
    00661     }
    00662     //-----------------------------------------------------------------------
    00663     void Pass::setFragmentProgram(const String& name, bool resetParams)
    00664     {
    00665         // Turn off fragment program if name blank
    00666         if (name.empty())
    00667         {
    00668             if (mFragmentProgramUsage) delete mFragmentProgramUsage;
    00669             mFragmentProgramUsage = NULL;
    00670         }
    00671         else
    00672         {
    00673             if (!mFragmentProgramUsage)
    00674             {
    00675                 mFragmentProgramUsage = new GpuProgramUsage(GPT_FRAGMENT_PROGRAM);
    00676             }
    00677             mFragmentProgramUsage->setProgramName(name, resetParams);
    00678         }
    00679         // Needs recompilation
    00680         mParent->_notifyNeedsRecompile();
    00681     }
    00682     //-----------------------------------------------------------------------
    00683     void Pass::setFragmentProgramParameters(GpuProgramParametersSharedPtr params)
    00684     {
    00685         if (!mFragmentProgramUsage)
    00686         {
    00687             Except (Exception::ERR_INVALIDPARAMS,
    00688                 "This pass does not have a fragment program assigned!",
    00689                 "Pass::setFragmentProgramParameters");
    00690         }
    00691         mFragmentProgramUsage->setParameters(params);
    00692     }
    00693     //-----------------------------------------------------------------------
    00694     const String& Pass::getVertexProgramName(void) const
    00695     {
    00696         if (!mVertexProgramUsage)
    00697             return StringUtil::BLANK;
    00698         else
    00699             return mVertexProgramUsage->getProgramName();
    00700     }
    00701     //-----------------------------------------------------------------------
    00702     GpuProgramParametersSharedPtr Pass::getVertexProgramParameters(void)
    00703     {
    00704         if (!mVertexProgramUsage)
    00705         {
    00706             Except (Exception::ERR_INVALIDPARAMS,
    00707                 "This pass does not have a vertex program assigned!",
    00708                 "Pass::getVertexProgramParameters");
    00709         }
    00710         return mVertexProgramUsage->getParameters();
    00711     }
    00712     //-----------------------------------------------------------------------
    00713     GpuProgram* Pass::getVertexProgram(void)
    00714     {
    00715         return mVertexProgramUsage->getProgram();
    00716     }
    00717     //-----------------------------------------------------------------------
    00718     const String& Pass::getFragmentProgramName(void) const
    00719     {
    00720         return mFragmentProgramUsage->getProgramName();
    00721     }
    00722     //-----------------------------------------------------------------------
    00723     GpuProgramParametersSharedPtr Pass::getFragmentProgramParameters(void)
    00724     {
    00725         return mFragmentProgramUsage->getParameters();
    00726     }
    00727     //-----------------------------------------------------------------------
    00728     GpuProgram* Pass::getFragmentProgram(void)
    00729     {
    00730         return mFragmentProgramUsage->getProgram();
    00731     }
    00732     //-----------------------------------------------------------------------
    00733     bool Pass::isLoaded(void) const
    00734     {
    00735         return mParent->isLoaded();
    00736     }
    00737     //-----------------------------------------------------------------------
    00738     unsigned long Pass::getHash(void) const
    00739     {
    00740         return mHash;
    00741     }
    00742     //-----------------------------------------------------------------------
    00743     void Pass::_recalculateHash(void)
    00744     {
    00745         /* Hash format is 32-bit, divided as follows (high to low bits)
    00746            bits   purpose
    00747             4     Pass index (i.e. max 16 passes!)
    00748            14     Hashed texture name from unit 0
    00749            14     Hashed texture name from unit 1
    00750
    00751            Note that at the moment we don't sort on the 3rd texture unit plus
    00752            on the assumption that these are less frequently used; sorting on
    00753            the first 2 gives us the most benefit for now.
    00754        */
    00755         _StringHash H;
    00756         mHash = (mIndex << 28);
    00757         size_t c = getNumTextureUnitStates();
    00758
    00759         if (c && !mTextureUnitStates[0]->isBlank())
    00760             mHash += (H(mTextureUnitStates[0]->getTextureName()) % (1 << 14)) << 14;
    00761         if (c > 1 && !mTextureUnitStates[1]->isBlank())
    00762             mHash += (H(mTextureUnitStates[1]->getTextureName()) % (1 << 14));
    00763     }
    00764     //-----------------------------------------------------------------------
    00765     void Pass::_dirtyHash(void)
    00766     {
    00767         // Mark this hash as for follow up
    00768         msDirtyHashList.insert(this);
    00769     }
    00770     //-----------------------------------------------------------------------
    00771     void Pass::_notifyNeedsRecompile(void)
    00772     {
    00773         mParent->_notifyNeedsRecompile();
    00774     }
    00775     //-----------------------------------------------------------------------
    00776     void Pass::setTextureFiltering(TextureFilterOptions filterType)
    00777     {
    00778         TextureUnitStates::iterator i, iend;
    00779         iend = mTextureUnitStates.end();
    00780         for (i = mTextureUnitStates.begin(); i != iend; ++i)
    00781         {
    00782             (*i)->setTextureFiltering(filterType);
    00783         }
    00784     }
    00785     // --------------------------------------------------------------------
    00786     void Pass::setTextureAnisotropy(unsigned int maxAniso)
    00787     {
    00788         TextureUnitStates::iterator i, iend;
    00789         iend = mTextureUnitStates.end();
    00790         for (i = mTextureUnitStates.begin(); i != iend; ++i)
    00791         {
    00792             (*i)->setTextureAnisotropy(maxAniso);
    00793         }
    00794     }
    00795     //-----------------------------------------------------------------------
    00796     void Pass::_updateAutoParamsNoLights(const AutoParamDataSource& source)
    00797     {
    00798         if (hasVertexProgram())
    00799         {
    00800             // Update vertex program auto params
    00801             mVertexProgramUsage->getParameters()->_updateAutoParamsNoLights(source);
    00802         }
    00803
    00804         if (hasFragmentProgram())
    00805         {
    00806             // Update fragment program auto params
    00807             mFragmentProgramUsage->getParameters()->_updateAutoParamsNoLights(source);
    00808         }
    00809     }
    00810     //-----------------------------------------------------------------------
    00811     void Pass::_updateAutoParamsLightsOnly(const AutoParamDataSource& source)
    00812     {
    00813         if (hasVertexProgram())
    00814         {
    00815             // Update vertex program auto params
    00816             mVertexProgramUsage->getParameters()->_updateAutoParamsLightsOnly(source);
    00817         }
    00818
    00819         if (hasFragmentProgram())
    00820         {
    00821             // Update fragment program auto params
    00822             mFragmentProgramUsage->getParameters()->_updateAutoParamsLightsOnly(source);
    00823         }
    00824     }
    00825     //-----------------------------------------------------------------------
    00826     void Pass::processPendingPassUpdates(void)
    00827     {
    00828         // Delete items in the graveyard
    00829         PassSet::iterator i, iend;
    00830         iend = msPassGraveyard.end();
    00831         for (i = msPassGraveyard.begin(); i != iend; ++i)
    00832         {
    00833             delete *i;
    00834         }
    00835         msPassGraveyard.clear();
    00836
    00837         // The dirty ones will have been removed from the groups above using the old hash now
    00838         iend = msDirtyHashList.end();
    00839         for (i = msDirtyHashList.begin(); i != iend; ++i)
    00840         {
    00841             Pass* p = *i;
    00842             p->_recalculateHash();
    00843         }
    00844         // Clear the dirty list
    00845         msDirtyHashList.clear();
    00846     }
    00847     //-----------------------------------------------------------------------
    00848     void Pass::queueForDeletion(void)
    00849     {
    00850         mQueuedForDeletion = true;
    00851
    00852         removeAllTextureUnitStates();
    00853         if (mVertexProgramUsage)
    00854         {
    00855             delete mVertexProgramUsage;
    00856             mVertexProgramUsage = 0;
    00857         }
    00858         if (mShadowCasterVertexProgramUsage)
    00859         {
    00860             delete mShadowCasterVertexProgramUsage;
    00861             mShadowCasterVertexProgramUsage = 0;
    00862         }
    00863         if (mShadowReceiverVertexProgramUsage)
    00864         {
    00865             delete mShadowReceiverVertexProgramUsage;
    00866             mShadowReceiverVertexProgramUsage = 0;
    00867         }
    00868         if (mFragmentProgramUsage)
    00869         {
    00870             delete mFragmentProgramUsage;
    00871             mFragmentProgramUsage = 0;
    00872         }
    00873         // remove from dirty list, if there
    00874         msDirtyHashList.erase(this);
    00875
    00876         msPassGraveyard.insert(this);
    00877     }
    00878     //-----------------------------------------------------------------------
    00879     bool Pass::isAmbientOnly(void) const
    00880     {
    00881         // treat as ambient if lighting is off, or colour write is off,
    00882         // or all non-ambient (& emissive) colours are black
    00883         // NB a vertex program could override this, but passes using vertex
    00884         // programs are expected to indicate they are ambient only by
    00885         // setting the state so it matches one of the conditions above, even
    00886         // though this state is not used in rendering.
    00887         return (!mLightingEnabled || !mColourWrite ||
    00888             (mDiffuse == ColourValue::Black &&
    00889              mSpecular == ColourValue::Black));
    00890     }
    00891     //-----------------------------------------------------------------------
    00892     void Pass::setShadowCasterVertexProgram(const String& name)
    00893     {
    00894         // Turn off vertex program if name blank
    00895         if (name.empty())
    00896         {
    00897             if (mShadowCasterVertexProgramUsage) delete mShadowCasterVertexProgramUsage;
    00898             mShadowCasterVertexProgramUsage = NULL;
    00899         }
    00900         else
    00901         {
    00902             if (!mShadowCasterVertexProgramUsage)
    00903             {
    00904                 mShadowCasterVertexProgramUsage = new GpuProgramUsage(GPT_VERTEX_PROGRAM);
    00905             }
    00906             mShadowCasterVertexProgramUsage->setProgramName(name);
    00907         }
    00908         // Needs recompilation
    00909         mParent->_notifyNeedsRecompile();
    00910     }
    00911     //-----------------------------------------------------------------------
    00912     void Pass::setShadowCasterVertexProgramParameters(GpuProgramParametersSharedPtr params)
    00913     {
    00914         if (!mShadowCasterVertexProgramUsage)
    00915         {
    00916             Except (Exception::ERR_INVALIDPARAMS,
    00917                 "This pass does not have a shadow caster vertex program assigned!",
    00918                 "Pass::setShadowCasterVertexProgramParameters");
    00919         }
    00920         mShadowCasterVertexProgramUsage->setParameters(params);
    00921     }
    00922     //-----------------------------------------------------------------------
    00923     const String& Pass::getShadowCasterVertexProgramName(void) const
    00924     {
    00925         if (!mShadowCasterVertexProgramUsage)
    00926             return StringUtil::BLANK;
    00927         else
    00928             return mShadowCasterVertexProgramUsage->getProgramName();
    00929     }
    00930     //-----------------------------------------------------------------------
    00931     GpuProgramParametersSharedPtr Pass::getShadowCasterVertexProgramParameters(void)
    00932     {
    00933         if (!mShadowCasterVertexProgramUsage)
    00934         {
    00935             Except (Exception::ERR_INVALIDPARAMS,
    00936                 "This pass does not have a shadow caster vertex program assigned!",
    00937                 "Pass::getShadowCasterVertexProgramParameters");
    00938         }
    00939         return mShadowCasterVertexProgramUsage->getParameters();
    00940     }
    00941     //-----------------------------------------------------------------------
    00942     GpuProgram* Pass::getShadowCasterVertexProgram(void)
    00943     {
    00944         return mShadowCasterVertexProgramUsage->getProgram();
    00945     }
    00946     //-----------------------------------------------------------------------
    00947     void Pass::setShadowReceiverVertexProgram(const String& name)
    00948     {
    00949         // Turn off vertex program if name blank
    00950         if (name.empty())
    00951         {
    00952             if (mShadowReceiverVertexProgramUsage) delete mShadowReceiverVertexProgramUsage;
    00953             mShadowReceiverVertexProgramUsage = NULL;
    00954         }
    00955         else
    00956         {
    00957             if (!mShadowReceiverVertexProgramUsage)
    00958             {
    00959                 mShadowReceiverVertexProgramUsage = new GpuProgramUsage(GPT_VERTEX_PROGRAM);
    00960             }
    00961             mShadowReceiverVertexProgramUsage->setProgramName(name);
    00962         }
    00963         // Needs recompilation
    00964         mParent->_notifyNeedsRecompile();
    00965     }
    00966     //-----------------------------------------------------------------------
    00967     void Pass::setShadowReceiverVertexProgramParameters(GpuProgramParametersSharedPtr params)
    00968     {
    00969         if (!mShadowReceiverVertexProgramUsage)
    00970         {
    00971             Except (Exception::ERR_INVALIDPARAMS,
    00972                 "This pass does not have a shadow receiver vertex program assigned!",
    00973                 "Pass::setShadowReceiverVertexProgramParameters");
    00974         }
    00975         mShadowReceiverVertexProgramUsage->setParameters(params);
    00976     }
    00977     //-----------------------------------------------------------------------
    00978     const String& Pass::getShadowReceiverVertexProgramName(void) const
    00979     {
    00980         if (!mShadowReceiverVertexProgramUsage)
    00981             return StringUtil::BLANK;
    00982         else
    00983             return mShadowReceiverVertexProgramUsage->getProgramName();
    00984     }
    00985     //-----------------------------------------------------------------------
    00986     GpuProgramParametersSharedPtr Pass::getShadowReceiverVertexProgramParameters(void)
    00987     {
    00988         if (!mShadowReceiverVertexProgramUsage)
    00989         {
    00990             Except (Exception::ERR_INVALIDPARAMS,
    00991                 "This pass does not have a shadow receiver vertex program assigned!",
    00992                 "Pass::getShadowReceiverVertexProgramParameters");
    00993         }
    00994         return mShadowReceiverVertexProgramUsage->getParameters();
    00995     }
    00996     //-----------------------------------------------------------------------
    00997     GpuProgram* Pass::getShadowReceiverVertexProgram(void)
    00998     {
    00999         return mShadowReceiverVertexProgramUsage->getProgram();
    01000     }
    01001
    01002 }

Copyright © 2002-2003 by The OGRE Team
Last modified Sun Nov 28 19:48:38 2004