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

# OgreTechnique.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://www.ogre3d.org/
    00006
    00007 Copyright © 2000-2002 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 "OgreTechnique.h"
    00028 #include "OgreMaterial.h"
    00029 #include "OgrePass.h"
    00030 #include "OgreRoot.h"
    00031 #include "OgreRenderSystem.h"
    00032 #include "OgreRenderSystemCapabilities.h"
    00033 #include "OgreGpuProgramManager.h"
    00034
    00035
    00036 namespace Ogre {
    00037     //-----------------------------------------------------------------------------
    00038     Technique::Technique(Material* parent)
    00039         : mParent(parent), mIsSupported(false), mLodIndex(0)
    00040     {
    00041         // See above, defaults to unsupported until examined
    00042     }
    00043     //-----------------------------------------------------------------------------
    00044     Technique::Technique(Material* parent, const Technique& oth)
    00045         : mParent(parent), mLodIndex(0)
    00046     {
    00047         // Copy using operator=
    00048         *this = oth;
    00049     }
    00050     //-----------------------------------------------------------------------------
    00051     Technique::~Technique()
    00052     {
    00053         removeAllPasses();
    00054         clearIlluminationPasses();
    00055     }
    00056     //-----------------------------------------------------------------------------
    00057     bool Technique::isSupported(void) const
    00058     {
    00059         return mIsSupported;
    00060     }
    00061     //-----------------------------------------------------------------------------
    00062     void Technique::_compile(bool autoManageTextureUnits)
    00063     {
    00064         // assume not supported
    00065         mIsSupported = false;
    00066         // Go through each pass, checking requirements
    00067         Passes::iterator i, iend;
    00068         iend = mPasses.end();
    00069         for (i = mPasses.begin(); i != iend; ++i)
    00070         {
    00071             Pass* currPass = *i;
    00072             // Check texture unit requirements
    00073             size_t numTexUnitsRequested = currPass->getNumTextureUnitStates();
    00074             const RenderSystemCapabilities* caps =
    00075                 Root::getSingleton().getRenderSystem()->getCapabilities();
    00076             unsigned short numTexUnits = caps->getNumTextureUnits();
    00077
    00078             if (currPass->hasFragmentProgram())
    00079             {
    00080                 // Check texture units
    00081                 if (numTexUnitsRequested > numTexUnits)
    00082                 {
    00083                     // Can't do this one, and can't split a fragment pass
    00084                     return;
    00085                 }
    00086                 // Check fragment program version
    00087                 if (!currPass->getFragmentProgram()->isSupported())
    00088                 {
    00089                     // Can't do this one
    00090                     return;
    00091                 }
    00092             }
    00093             else
    00094             {
    00095                 // Check a few fixed-function options in texture layers
    00096                 Pass::TextureUnitStateIterator texi = currPass->getTextureUnitStateIterator();
    00097                 while (texi.hasMoreElements())
    00098                 {
    00099                     TextureUnitState* tex = texi.getNext();
    00100                     // Any Cube textures? NB we make the assumption that any
    00101                     // card capable of running fragment programs can support
    00102                     // cubic textures, which has to be true, surely?
    00103                     if (tex->is3D() && !caps->hasCapability(RSC_CUBEMAPPING))
    00104                     {
    00105                         // Fail
    00106                         return;
    00107                     }
    00108                     // Any Dot3 blending?
    00109                     if (tex->getColourBlendMode().operation == LBX_DOTPRODUCT &&
    00110                             !caps->hasCapability(RSC_DOT3))
    00111                     {
    00112                         // Fail
    00113                         return;
    00114                     }
    00115                 }
    00116
    00117                 // We're ok on operations, now we need to check # texture units
    00118                 // Keep splitting this pass so long as units requested > gpu units
    00119                 while (numTexUnitsRequested > numTexUnits)
    00120                 {
    00121                     // chop this pass into many passes
    00122                     currPass = currPass->_split(numTexUnits);
    00123                     numTexUnitsRequested = currPass->getNumTextureUnitStates();
    00124                 }
    00125             }
    00126
    00127             if (currPass->hasVertexProgram())
    00128             {
    00129                 // Check vertex program version
    00130                 if (!currPass->getVertexProgram()->isSupported() )
    00131                 {
    00132                     // Can't do this one
    00133                     return;
    00134                 }
    00135             }
    00136
    00137         }
    00138         // If we got this far, we're ok
    00139         mIsSupported = true;
    00140
    00141         // Now compile for categorised illumination, incase we need it
    00142         _compileIlluminationPasses();
    00143
    00144     }
    00145     //-----------------------------------------------------------------------------
    00146     Pass* Technique::createPass(void)
    00147     {
    00148         Pass* newPass = new Pass(this, static_cast<unsigned short>(mPasses.size()));
    00149         mPasses.push_back(newPass);
    00150         return newPass;
    00151     }
    00152     //-----------------------------------------------------------------------------
    00153     Pass* Technique::getPass(unsigned short index)
    00154     {
    00155         assert(index < mPasses.size() && "Index out of bounds");
    00156         return mPasses[index];
    00157     }
    00158     //-----------------------------------------------------------------------------
    00159     unsigned short Technique::getNumPasses(void) const
    00160     {
    00161         return static_cast<unsigned short>(mPasses.size());
    00162     }
    00163     //-----------------------------------------------------------------------------
    00164     void Technique::removePass(unsigned short index)
    00165     {
    00166         assert(index < mPasses.size() && "Index out of bounds");
    00167         Passes::iterator i = mPasses.begin() + index;
    00168         (*i)->queueForDeletion();
    00169         mPasses.erase(i);
    00170     }
    00171     //-----------------------------------------------------------------------------
    00172     void Technique::removeAllPasses(void)
    00173     {
    00174         Passes::iterator i, iend;
    00175         iend = mPasses.end();
    00176         for (i = mPasses.begin(); i != iend; ++i)
    00177         {
    00178             (*i)->queueForDeletion();
    00179         }
    00180         mPasses.clear();
    00181     }
    00182     //-----------------------------------------------------------------------------
    00183     const Technique::PassIterator Technique::getPassIterator(void)
    00184     {
    00185         return PassIterator(mPasses.begin(), mPasses.end());
    00186     }
    00187     //-----------------------------------------------------------------------------
    00188     Technique& Technique::operator=(const Technique& rhs)
    00189     {
    00190         this->mIsSupported = rhs.mIsSupported;
    00191         this->mLodIndex = rhs.mLodIndex;
    00192         // copy passes
    00193         removeAllPasses();
    00194         Passes::const_iterator i, iend;
    00195         iend = rhs.mPasses.end();
    00196         for (i = rhs.mPasses.begin(); i != iend; ++i)
    00197         {
    00198             Pass* p = new Pass(this, (*i)->getIndex(), *(*i));
    00199             mPasses.push_back(p);
    00200         }
    00201         // recompile illumination passes
    00202         _compileIlluminationPasses();
    00203         return *this;
    00204     }
    00205     //-----------------------------------------------------------------------------
    00206     bool Technique::isTransparent(void) const
    00207     {
    00208         if (mPasses.empty())
    00209         {
    00210             return false;
    00211         }
    00212         else
    00213         {
    00214             // Base decision on the transparency of the first pass
    00215             return mPasses[0]->isTransparent();
    00216         }
    00217     }
    00218     //-----------------------------------------------------------------------------
    00219     bool Technique::isDepthWriteEnabled(void) const
    00220     {
    00221         if (mPasses.empty())
    00222         {
    00223             return false;
    00224         }
    00225         else
    00226         {
    00227             // Base decision on the depth settings of the first pass
    00228             return mPasses[0]->getDepthWriteEnabled();
    00229         }
    00230     }
    00231     //-----------------------------------------------------------------------------
    00232     bool Technique::isDepthCheckEnabled(void) const
    00233     {
    00234         if (mPasses.empty())
    00235         {
    00236             return false;
    00237         }
    00238         else
    00239         {
    00240             // Base decision on the depth settings of the first pass
    00241             return mPasses[0]->getDepthCheckEnabled();
    00242         }
    00243     }
    00244     //-----------------------------------------------------------------------------
    00245     void Technique::_load(void)
    00246     {
    00247         assert (mIsSupported && "This technique is not supported");
    00248         // Load each pass
    00249         Passes::iterator i, iend;
    00250         iend = mPasses.end();
    00251         for (i = mPasses.begin(); i != iend; ++i)
    00252         {
    00253             (*i)->_load();
    00254         }
    00255     }
    00256     //-----------------------------------------------------------------------------
    00257     void Technique::_unload(void)
    00258     {
    00259         // Unload each pass
    00260         Passes::iterator i, iend;
    00261         iend = mPasses.end();
    00262         for (i = mPasses.begin(); i != iend; ++i)
    00263         {
    00264             (*i)->_unload();
    00265         }
    00266     }
    00267     //-----------------------------------------------------------------------------
    00268     bool Technique::isLoaded(void) const
    00269     {
    00270         return mParent->isLoaded();
    00271     }
    00272     //-----------------------------------------------------------------------
    00273     void Technique::setAmbient(Real red, Real green, Real blue)
    00274     {
    00275         Passes::iterator i, iend;
    00276         iend = mPasses.end();
    00277         for (i = mPasses.begin(); i != iend; ++i)
    00278         {
    00279             (*i)->setAmbient(red, green, blue);
    00280         }
    00281
    00282     }
    00283     //-----------------------------------------------------------------------
    00284     void Technique::setAmbient(const ColourValue& ambient)
    00285     {
    00286         setAmbient(ambient.r, ambient.g, ambient.b);
    00287     }
    00288     //-----------------------------------------------------------------------
    00289     void Technique::setDiffuse(Real red, Real green, Real blue, Real alpha)
    00290     {
    00291         Passes::iterator i, iend;
    00292         iend = mPasses.end();
    00293         for (i = mPasses.begin(); i != iend; ++i)
    00294         {
    00295             (*i)->setDiffuse(red, green, blue, alpha);
    00296         }
    00297     }
    00298     //-----------------------------------------------------------------------
    00299     void Technique::setDiffuse(const ColourValue& diffuse)
    00300     {
    00301         setDiffuse(diffuse.r, diffuse.g, diffuse.b, diffuse.a);
    00302     }
    00303     //-----------------------------------------------------------------------
    00304     void Technique::setSpecular(Real red, Real green, Real blue, Real alpha)
    00305     {
    00306         Passes::iterator i, iend;
    00307         iend = mPasses.end();
    00308         for (i = mPasses.begin(); i != iend; ++i)
    00309         {
    00310             (*i)->setSpecular(red, green, blue, alpha);
    00311         }
    00312     }
    00313     //-----------------------------------------------------------------------
    00314     void Technique::setSpecular(const ColourValue& specular)
    00315     {
    00316         setSpecular(specular.r, specular.g, specular.b, specular.a);
    00317     }
    00318     //-----------------------------------------------------------------------
    00319     void Technique::setShininess(Real val)
    00320     {
    00321         Passes::iterator i, iend;
    00322         iend = mPasses.end();
    00323         for (i = mPasses.begin(); i != iend; ++i)
    00324         {
    00325             (*i)->setShininess(val);
    00326         }
    00327     }
    00328     //-----------------------------------------------------------------------
    00329     void Technique::setSelfIllumination(Real red, Real green, Real blue)
    00330     {
    00331         Passes::iterator i, iend;
    00332         iend = mPasses.end();
    00333         for (i = mPasses.begin(); i != iend; ++i)
    00334         {
    00335             (*i)->setSelfIllumination(red, green, blue);
    00336         }
    00337     }
    00338     //-----------------------------------------------------------------------
    00339     void Technique::setSelfIllumination(const ColourValue& selfIllum)
    00340     {
    00341         setSelfIllumination(selfIllum.r, selfIllum.g, selfIllum.b);
    00342     }
    00343     //-----------------------------------------------------------------------
    00344     void Technique::setDepthCheckEnabled(bool enabled)
    00345     {
    00346         Passes::iterator i, iend;
    00347         iend = mPasses.end();
    00348         for (i = mPasses.begin(); i != iend; ++i)
    00349         {
    00350             (*i)->setDepthCheckEnabled(enabled);
    00351         }
    00352     }
    00353     //-----------------------------------------------------------------------
    00354     void Technique::setDepthWriteEnabled(bool enabled)
    00355     {
    00356         Passes::iterator i, iend;
    00357         iend = mPasses.end();
    00358         for (i = mPasses.begin(); i != iend; ++i)
    00359         {
    00360             (*i)->setDepthWriteEnabled(enabled);
    00361         }
    00362     }
    00363     //-----------------------------------------------------------------------
    00364     void Technique::setDepthFunction( CompareFunction func )
    00365     {
    00366         Passes::iterator i, iend;
    00367         iend = mPasses.end();
    00368         for (i = mPasses.begin(); i != iend; ++i)
    00369         {
    00370             (*i)->setDepthFunction(func);
    00371         }
    00372     }
    00373     //-----------------------------------------------------------------------
    00374     void Technique::setColourWriteEnabled(bool enabled)
    00375     {
    00376         Passes::iterator i, iend;
    00377         iend = mPasses.end();
    00378         for (i = mPasses.begin(); i != iend; ++i)
    00379         {
    00380             (*i)->setColourWriteEnabled(enabled);
    00381         }
    00382     }
    00383     //-----------------------------------------------------------------------
    00384     void Technique::setCullingMode( CullingMode mode )
    00385     {
    00386         Passes::iterator i, iend;
    00387         iend = mPasses.end();
    00388         for (i = mPasses.begin(); i != iend; ++i)
    00389         {
    00390             (*i)->setCullingMode(mode);
    00391         }
    00392     }
    00393     //-----------------------------------------------------------------------
    00394     void Technique::setManualCullingMode( ManualCullingMode mode )
    00395     {
    00396         Passes::iterator i, iend;
    00397         iend = mPasses.end();
    00398         for (i = mPasses.begin(); i != iend; ++i)
    00399         {
    00400             (*i)->setManualCullingMode(mode);
    00401         }
    00402     }
    00403     //-----------------------------------------------------------------------
    00404     void Technique::setLightingEnabled(bool enabled)
    00405     {
    00406         Passes::iterator i, iend;
    00407         iend = mPasses.end();
    00408         for (i = mPasses.begin(); i != iend; ++i)
    00409         {
    00410             (*i)->setLightingEnabled(enabled);
    00411         }
    00412     }
    00413     //-----------------------------------------------------------------------
    00414     void Technique::setShadingMode( ShadeOptions mode )
    00415     {
    00416         Passes::iterator i, iend;
    00417         iend = mPasses.end();
    00418         for (i = mPasses.begin(); i != iend; ++i)
    00419         {
    00420             (*i)->setShadingMode(mode);
    00421         }
    00422     }
    00423     //-----------------------------------------------------------------------
    00424     void Technique::setFog(bool overrideScene, FogMode mode, const ColourValue& colour,
    00425         Real expDensity, Real linearStart, Real linearEnd)
    00426     {
    00427         Passes::iterator i, iend;
    00428         iend = mPasses.end();
    00429         for (i = mPasses.begin(); i != iend; ++i)
    00430         {
    00431             (*i)->setFog(overrideScene, mode, colour, expDensity, linearStart, linearEnd);
    00432         }
    00433     }
    00434     //-----------------------------------------------------------------------
    00435     void Technique::setDepthBias(ushort bias)
    00436     {
    00437         Passes::iterator i, iend;
    00438         iend = mPasses.end();
    00439         for (i = mPasses.begin(); i != iend; ++i)
    00440         {
    00441             (*i)->setDepthBias(bias);
    00442         }
    00443     }
    00444     //-----------------------------------------------------------------------
    00445     void Technique::setTextureFiltering(TextureFilterOptions filterType)
    00446     {
    00447         Passes::iterator i, iend;
    00448         iend = mPasses.end();
    00449         for (i = mPasses.begin(); i != iend; ++i)
    00450         {
    00451             (*i)->setTextureFiltering(filterType);
    00452         }
    00453     }
    00454     // --------------------------------------------------------------------
    00455     void Technique::setTextureAnisotropy(unsigned int maxAniso)
    00456     {
    00457         Passes::iterator i, iend;
    00458         iend = mPasses.end();
    00459         for (i = mPasses.begin(); i != iend; ++i)
    00460         {
    00461             (*i)->setTextureAnisotropy(maxAniso);
    00462         }
    00463     }
    00464     // --------------------------------------------------------------------
    00465     void Technique::setSceneBlending( const SceneBlendType sbt )
    00466     {
    00467         Passes::iterator i, iend;
    00468         iend = mPasses.end();
    00469         for (i = mPasses.begin(); i != iend; ++i)
    00470         {
    00471             (*i)->setSceneBlending(sbt);
    00472         }
    00473     }
    00474     // --------------------------------------------------------------------
    00475     void Technique::setSceneBlending( const SceneBlendFactor sourceFactor,
    00476         const SceneBlendFactor destFactor)
    00477     {
    00478         Passes::iterator i, iend;
    00479         iend = mPasses.end();
    00480         for (i = mPasses.begin(); i != iend; ++i)
    00481         {
    00482             (*i)->setSceneBlending(sourceFactor, destFactor);
    00483         }
    00484     }
    00485
    00486     //-----------------------------------------------------------------------
    00487     void Technique::_notifyNeedsRecompile(void)
    00488     {
    00489         mParent->_notifyNeedsRecompile();
    00490     }
    00491     //-----------------------------------------------------------------------
    00492     void Technique::setLodIndex(unsigned short index)
    00493     {
    00494         mLodIndex = index;
    00495         _notifyNeedsRecompile();
    00496     }
    00497     //-----------------------------------------------------------------------
    00498     void Technique::_compileIlluminationPasses(void)
    00499     {
    00500         clearIlluminationPasses();
    00501
    00502         if (isTransparent())
    00503         {
    00504             // Don't need to split transparents since they are rendered separately
    00505             return;
    00506         }
    00507
    00508         Passes::iterator i, iend;
    00509         iend = mPasses.end();
    00510         i = mPasses.begin();
    00511
    00512         IlluminationStage iStage = IS_AMBIENT;
    00513
    00514         bool haveAmbient = false;
    00515         while (i != iend)
    00516         {
    00517             IlluminationPass* iPass;
    00518             Pass* p = *i;
    00519             switch(iStage)
    00520             {
    00521             case IS_AMBIENT:
    00522                 // Keep looking for ambient only
    00523                 if (p->isAmbientOnly())
    00524                 {
    00525                     // Add this pass wholesale
    00526                     iPass = new IlluminationPass();
    00527                     iPass->destroyOnShutdown = false;
    00528                     iPass->originalPass = iPass->pass = p;
    00529                     iPass->stage = iStage;
    00530                     mIlluminationPasses.push_back(iPass);
    00531                     haveAmbient = true;
    00532                     // progress to next pass
    00533                     ++i;
    00534                 }
    00535                 else
    00536                 {
    00537                     // Split off any ambient part
    00538                     if (p->getAmbient() != ColourValue::Black ||
    00539                         p->getSelfIllumination() != ColourValue::Black)
    00540                     {
    00541                         // Copy existing pass
    00542                         Pass* newPass = new Pass(this, p->getIndex());
    00543                         *newPass = *p;
    00544                         // Remove any texture units
    00545                         newPass->removeAllTextureUnitStates();
    00546                         // Remove any fragment program
    00547                         if (newPass->hasFragmentProgram())
    00548                             newPass->setFragmentProgram("");
    00549                         // We have to leave vertex program alone (if any) and
    00550                         // just trust that the author is using light bindings, which
    00551                         // we will ensure there are none in the ambient pass
    00552                         newPass->setDiffuse(ColourValue::Black);
    00553                         newPass->setSpecular(ColourValue::Black);
    00554
    00555                         // If ambient & emissive are zero, then no colour write
    00556                         if (newPass->getAmbient() == ColourValue::Black &&
    00557                             newPass->getSelfIllumination() == ColourValue::Black)
    00558                         {
    00559                             newPass->setColourWriteEnabled(false);
    00560                         }
    00561
    00562                         iPass = new IlluminationPass();
    00563                         iPass->destroyOnShutdown = true;
    00564                         iPass->originalPass = p;
    00565                         iPass->pass = newPass;
    00566                         iPass->stage = iStage;
    00567
    00568                         mIlluminationPasses.push_back(iPass);
    00569                         haveAmbient = true;
    00570
    00571                     }
    00572
    00573                     if (!haveAmbient)
    00574                     {
    00575                         // Make up a new basic pass
    00576                         Pass* newPass = new Pass(this, p->getIndex());
    00577                         newPass->setAmbient(ColourValue::Black);
    00578                         newPass->setDiffuse(ColourValue::Black);
    00579                         iPass = new IlluminationPass();
    00580                         iPass->destroyOnShutdown = true;
    00581                         iPass->originalPass = p;
    00582                         iPass->pass = newPass;
    00583                         iPass->stage = iStage;
    00584                         mIlluminationPasses.push_back(iPass);
    00585                         haveAmbient = true;
    00586                     }
    00587                     // This means we're done with ambients, progress to per-light
    00588                     iStage = IS_PER_LIGHT;
    00589                 }
    00590                 break;
    00591             case IS_PER_LIGHT:
    00592                 if (p->getRunOncePerLight())
    00593                 {
    00594                     // If this is per-light already, use it directly
    00595                     iPass = new IlluminationPass();
    00596                     iPass->destroyOnShutdown = false;
    00597                     iPass->originalPass = iPass->pass = p;
    00598                     iPass->stage = iStage;
    00599                     mIlluminationPasses.push_back(iPass);
    00600                     // progress to next pass
    00601                     ++i;
    00602                 }
    00603                 else
    00604                 {
    00605                     // Split off per-light details (can only be done for one)
    00606                     if (p->getLightingEnabled() &&
    00607                         (p->getDiffuse() != ColourValue::Black ||
    00608                         p->getSpecular() != ColourValue::Black))
    00609                     {
    00610                         // Copy existing pass
    00611                         Pass* newPass = new Pass(this, p->getIndex());
    00612                         *newPass = *p;
    00613                         // remove texture units
    00614                         newPass->removeAllTextureUnitStates();
    00615                         // remove fragment programs
    00616                         if (newPass->hasFragmentProgram())
    00617                             newPass->setFragmentProgram("");
    00618                         // Cannot remove vertex program, have to assume that
    00619                         // it will process diffuse lights, ambient will be turned off
    00620                         newPass->setAmbient(ColourValue::Black);
    00621                         newPass->setSelfIllumination(ColourValue::Black);
    00622                         // must be additive
    00623                         newPass->setSceneBlending(SBF_ONE, SBF_ONE);
    00624
    00625                         iPass = new IlluminationPass();
    00626                         iPass->destroyOnShutdown = true;
    00627                         iPass->originalPass = p;
    00628                         iPass->pass = newPass;
    00629                         iPass->stage = iStage;
    00630
    00631                         mIlluminationPasses.push_back(iPass);
    00632
    00633                     }
    00634                     // This means the end of per-light passes
    00635                     iStage = IS_DECAL;
    00636                 }
    00637                 break;
    00638             case IS_DECAL:
    00639                 // We just want a 'lighting off' pass to finish off
    00640                 // and only if there are texture units
    00641                 if (p->getNumTextureUnitStates() > 0)
    00642                 {
    00643                     if (!p->getLightingEnabled())
    00644                     {
    00645                         // we assume this pass already combines as required with the scene
    00646                         iPass = new IlluminationPass();
    00647                         iPass->destroyOnShutdown = false;
    00648                         iPass->originalPass = iPass->pass = p;
    00649                         iPass->stage = iStage;
    00650                         mIlluminationPasses.push_back(iPass);
    00651                     }
    00652                     else
    00653                     {
    00654                         // Copy the pass and tweak away the lighting parts
    00655                         Pass* newPass = new Pass(this, p->getIndex());
    00656                         *newPass = *p;
    00657                         newPass->setAmbient(ColourValue::Black);
    00658                         newPass->setDiffuse(ColourValue::Black);
    00659                         newPass->setSpecular(ColourValue::Black);
    00660                         newPass->setSelfIllumination(ColourValue::Black);
    00661                         newPass->setLightingEnabled(false);
    00662                         // modulate
    00663                         newPass->setSceneBlending(SBF_DEST_COLOUR, SBF_ZERO);
    00664
    00665                         // NB there is nothing we can do about vertex & fragment
    00666                         // programs here, so people will just have to make their
    00667                         // programs friendly-like if they want to use this technique
    00668                         iPass = new IlluminationPass();
    00669                         iPass->destroyOnShutdown = true;
    00670                         iPass->originalPass = p;
    00671                         iPass->pass = newPass;
    00672                         iPass->stage = iStage;
    00673                         mIlluminationPasses.push_back(iPass);
    00674
    00675                     }
    00676                 }
    00677                 ++i; // always increment on decal, since nothing more to do with this pass
    00678
    00679                 break;
    00680             }
    00681         }
    00682
    00683     }
    00684     //-----------------------------------------------------------------------
    00685     void Technique::clearIlluminationPasses(void)
    00686     {
    00687         IlluminationPassList::iterator i, iend;
    00688         iend = mIlluminationPasses.end();
    00689         for (i = mIlluminationPasses.begin(); i != iend; ++i)
    00690         {
    00691             if ((*i)->destroyOnShutdown)
    00692             {
    00693                 (*i)->pass->queueForDeletion();
    00694             }
    00695             delete *i;
    00696         }
    00697         mIlluminationPasses.clear();
    00698     }
    00699     //-----------------------------------------------------------------------
    00700     const Technique::IlluminationPassIterator
    00701     Technique::getIlluminationPassIterator(void)
    00702     {
    00703         return IlluminationPassIterator(mIlluminationPasses.begin(),
    00704             mIlluminationPasses.end());
    00705     }
    00706
    00707
    00708 }

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