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