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

Copyright © 2002-2003 by The OGRE Team
Last modified Fri May 14 23:22:32 2004