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