1 /* 2 ----------------------------------------------------------------------------- 3 This source file is part of OGRE 4 (Object-oriented Graphics Rendering Engine) 5 For the latest info, see http://www.ogre3d.org 6 7 Copyright (c) 2000-2014 Torus Knot Software Ltd 8 9 Permission is hereby granted, free of charge, to any person obtaining a copy 10 of this software and associated documentation files (the "Software"), to deal 11 in the Software without restriction, including without limitation the rights 12 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 copies of the Software, and to permit persons to whom the Software is 14 furnished to do so, subject to the following conditions: 15 16 The above copyright notice and this permission notice shall be included in 17 all copies or substantial portions of the Software. 18 19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 THE SOFTWARE. 26 ----------------------------------------------------------------------------- 27 */ 28 #include "OgreStableHeaders.h" 29 30 #include "OgreGpuProgramUsage.h" 31 #include "OgreTextureUnitState.h" 32 33 namespace Ogre { 34 35 /** Default pass hash function. 36 @remarks 37 Tries to minimise the number of texture changes. 38 */ 39 struct MinTextureStateChangeHashFunc : public Pass::HashFunc 40 { operator ()Ogre::MinTextureStateChangeHashFunc41 uint32 operator()(const Pass* p) const 42 { 43 OGRE_LOCK_MUTEX(p->mTexUnitChangeMutex); 44 uint32 hash = 0; 45 ushort c = p->getNumTextureUnitStates(); 46 47 for (ushort i = 0; i < c; ++i) 48 { 49 const TextureUnitState* tus = 0; 50 tus = p->getTextureUnitState(i); 51 hash = FastHash(tus->getTextureName().c_str(), tus->getTextureName().size(), hash); 52 } 53 54 return hash; 55 } 56 }; 57 MinTextureStateChangeHashFunc sMinTextureStateChangeHashFunc; 58 /** Alternate pass hash function. 59 @remarks 60 Tries to minimise the number of GPU program changes. 61 */ 62 struct MinGpuProgramChangeHashFunc : public Pass::HashFunc 63 { operator ()Ogre::MinGpuProgramChangeHashFunc64 uint32 operator()(const Pass* p) const 65 { 66 OGRE_LOCK_MUTEX(p->mGpuProgramChangeMutex); 67 uint32 hash = 0; 68 69 for(int i = 0; i < GPT_COUNT; i++) 70 { 71 const String& name = p->getGpuProgramName(GpuProgramType(i)); 72 if(!name.empty()) { 73 hash = FastHash(name.c_str(), name.size(), hash); 74 } 75 } 76 77 return hash; 78 } 79 }; 80 MinGpuProgramChangeHashFunc sMinGpuProgramChangeHashFunc; 81 //----------------------------------------------------------------------------- 82 Pass::PassSet Pass::msDirtyHashList; 83 Pass::PassSet Pass::msPassGraveyard; 84 OGRE_STATIC_MUTEX_INSTANCE(Pass::msDirtyHashListMutex); 85 OGRE_STATIC_MUTEX_INSTANCE(Pass::msPassGraveyardMutex); 86 87 Pass::HashFunc* Pass::msHashFunc = &sMinGpuProgramChangeHashFunc; 88 //----------------------------------------------------------------------------- getBuiltinHashFunction(BuiltinHashFunction builtin)89 Pass::HashFunc* Pass::getBuiltinHashFunction(BuiltinHashFunction builtin) 90 { 91 Pass::HashFunc* hashFunc = NULL; 92 93 switch(builtin) 94 { 95 case MIN_TEXTURE_CHANGE: 96 hashFunc = &sMinTextureStateChangeHashFunc; 97 break; 98 case MIN_GPU_PROGRAM_CHANGE: 99 hashFunc = &sMinGpuProgramChangeHashFunc; 100 break; 101 } 102 103 return hashFunc; 104 } 105 //----------------------------------------------------------------------------- setHashFunction(BuiltinHashFunction builtin)106 void Pass::setHashFunction(BuiltinHashFunction builtin) 107 { 108 switch(builtin) 109 { 110 case MIN_TEXTURE_CHANGE: 111 msHashFunc = &sMinTextureStateChangeHashFunc; 112 break; 113 case MIN_GPU_PROGRAM_CHANGE: 114 msHashFunc = &sMinGpuProgramChangeHashFunc; 115 break; 116 } 117 } 118 //----------------------------------------------------------------------------- Pass(Technique * parent,unsigned short index)119 Pass::Pass(Technique* parent, unsigned short index) 120 : mParent(parent) 121 , mHash(0) 122 , mIndex(index) 123 , mAmbient(ColourValue::White) 124 , mDiffuse(ColourValue::White) 125 , mSpecular(ColourValue::Black) 126 , mEmissive(ColourValue::Black) 127 , mShininess(0) 128 , mTracking(TVC_NONE) 129 , mHashDirtyQueued(false) 130 , mDepthCheck(true) 131 , mDepthWrite(true) 132 , mAlphaToCoverageEnabled(false) 133 , mTransparentSorting(true) 134 , mTransparentSortingForced(false) 135 , mLightingEnabled(true) 136 , mIteratePerLight(false) 137 , mRunOnlyForOneLightType(false) 138 , mNormaliseNormals(false) 139 , mPolygonModeOverrideable(true) 140 , mFogOverride(false) 141 , mQueuedForDeletion(false) 142 , mLightScissoring(false) 143 , mLightClipPlanes(false) 144 , mPointSpritesEnabled(false) 145 , mPointAttenuationEnabled(false) 146 , mContentTypeLookupBuilt(false) 147 , mAlphaRejectVal(0) 148 , mDepthFunc(CMPF_LESS_EQUAL) 149 , mDepthBiasConstant(0.0f) 150 , mDepthBiasSlopeScale(0.0f) 151 , mDepthBiasPerIteration(0.0f) 152 , mAlphaRejectFunc(CMPF_ALWAYS_PASS) 153 , mCullMode(CULL_CLOCKWISE) 154 , mManualCullMode(MANUAL_CULL_BACK) 155 , mMaxSimultaneousLights(OGRE_MAX_SIMULTANEOUS_LIGHTS) 156 , mStartLight(0) 157 , mLightsPerIteration(1) 158 , mOnlyLightType(Light::LT_POINT) 159 , mLightMask(0xFFFFFFFF) 160 , mShadeOptions(SO_GOURAUD) 161 , mPolygonMode(PM_SOLID) 162 , mFogMode(FOG_NONE) 163 , mFogColour(ColourValue::White) 164 , mFogStart(0.0) 165 , mFogEnd(1.0) 166 , mFogDensity(0.001) 167 , mPassIterationCount(1) 168 , mLineWidth(1.0f) 169 , mPointSize(1.0f) 170 , mPointMinSize(0.0f) 171 , mPointMaxSize(0.0f) 172 , mIlluminationStage(IS_UNKNOWN) 173 { 174 mPointAttenuationCoeffs[0] = 1.0f; 175 mPointAttenuationCoeffs[1] = mPointAttenuationCoeffs[2] = 0.0f; 176 177 // init the hash inline 178 _recalculateHash(); 179 } 180 181 //----------------------------------------------------------------------------- Pass(Technique * parent,unsigned short index,const Pass & oth)182 Pass::Pass(Technique *parent, unsigned short index, const Pass& oth) 183 : mParent(parent), mIndex(index), mQueuedForDeletion(false), mPassIterationCount(1) 184 { 185 *this = oth; 186 mParent = parent; 187 mIndex = index; 188 mQueuedForDeletion = false; 189 190 // init the hash inline 191 _recalculateHash(); 192 } 193 Pass::~Pass() = default; // ensure unique_ptr destructors are in cpp 194 //----------------------------------------------------------------------------- operator =(const Pass & oth)195 Pass& Pass::operator=(const Pass& oth) 196 { 197 mName = oth.mName; 198 mHash = oth.mHash; 199 mAmbient = oth.mAmbient; 200 mDiffuse = oth.mDiffuse; 201 mSpecular = oth.mSpecular; 202 mEmissive = oth.mEmissive; 203 mShininess = oth.mShininess; 204 mTracking = oth.mTracking; 205 206 // Copy fog parameters 207 mFogOverride = oth.mFogOverride; 208 mFogMode = oth.mFogMode; 209 mFogColour = oth.mFogColour; 210 mFogStart = oth.mFogStart; 211 mFogEnd = oth.mFogEnd; 212 mFogDensity = oth.mFogDensity; 213 214 // Default blending (overwrite) 215 mBlendState = oth.mBlendState; 216 217 mDepthCheck = oth.mDepthCheck; 218 mDepthWrite = oth.mDepthWrite; 219 mAlphaRejectFunc = oth.mAlphaRejectFunc; 220 mAlphaRejectVal = oth.mAlphaRejectVal; 221 mAlphaToCoverageEnabled = oth.mAlphaToCoverageEnabled; 222 mTransparentSorting = oth.mTransparentSorting; 223 mTransparentSortingForced = oth.mTransparentSortingForced; 224 mDepthFunc = oth.mDepthFunc; 225 mDepthBiasConstant = oth.mDepthBiasConstant; 226 mDepthBiasSlopeScale = oth.mDepthBiasSlopeScale; 227 mDepthBiasPerIteration = oth.mDepthBiasPerIteration; 228 mCullMode = oth.mCullMode; 229 mManualCullMode = oth.mManualCullMode; 230 mLightingEnabled = oth.mLightingEnabled; 231 mMaxSimultaneousLights = oth.mMaxSimultaneousLights; 232 mStartLight = oth.mStartLight; 233 mIteratePerLight = oth.mIteratePerLight; 234 mLightsPerIteration = oth.mLightsPerIteration; 235 mRunOnlyForOneLightType = oth.mRunOnlyForOneLightType; 236 mNormaliseNormals = oth.mNormaliseNormals; 237 mOnlyLightType = oth.mOnlyLightType; 238 mShadeOptions = oth.mShadeOptions; 239 mPolygonMode = oth.mPolygonMode; 240 mPolygonModeOverrideable = oth.mPolygonModeOverrideable; 241 mPassIterationCount = oth.mPassIterationCount; 242 mLineWidth = oth.mLineWidth; 243 mPointSize = oth.mPointSize; 244 mPointMinSize = oth.mPointMinSize; 245 mPointMaxSize = oth.mPointMaxSize; 246 mPointSpritesEnabled = oth.mPointSpritesEnabled; 247 mPointAttenuationEnabled = oth.mPointAttenuationEnabled; 248 memcpy(mPointAttenuationCoeffs, oth.mPointAttenuationCoeffs, sizeof(Real)*3); 249 mShadowContentTypeLookup = oth.mShadowContentTypeLookup; 250 mContentTypeLookupBuilt = oth.mContentTypeLookupBuilt; 251 mLightScissoring = oth.mLightScissoring; 252 mLightClipPlanes = oth.mLightClipPlanes; 253 mIlluminationStage = oth.mIlluminationStage; 254 mLightMask = oth.mLightMask; 255 256 for(int i = 0; i < GPT_COUNT; i++) 257 { 258 auto& programUsage = mProgramUsage[i]; 259 auto& othUsage = oth.mProgramUsage[i]; 260 othUsage ? programUsage.reset(new GpuProgramUsage(*othUsage, this)) : programUsage.reset(); 261 } 262 263 mShadowCasterVertexProgramUsage.reset(); 264 if (oth.mShadowCasterVertexProgramUsage) 265 { 266 mShadowCasterVertexProgramUsage.reset(new GpuProgramUsage(*(oth.mShadowCasterVertexProgramUsage), this)); 267 } 268 269 mShadowCasterFragmentProgramUsage.reset(); 270 if (oth.mShadowCasterFragmentProgramUsage) 271 { 272 mShadowCasterFragmentProgramUsage.reset(new GpuProgramUsage(*(oth.mShadowCasterFragmentProgramUsage), this)); 273 } 274 275 mShadowReceiverVertexProgramUsage.reset(); 276 if (oth.mShadowReceiverVertexProgramUsage) 277 { 278 mShadowReceiverVertexProgramUsage.reset(new GpuProgramUsage(*(oth.mShadowReceiverVertexProgramUsage), this)); 279 } 280 281 mShadowReceiverFragmentProgramUsage.reset(); 282 if (oth.mShadowReceiverFragmentProgramUsage) 283 { 284 mShadowReceiverFragmentProgramUsage.reset(new GpuProgramUsage(*(oth.mShadowReceiverFragmentProgramUsage), this)); 285 } 286 287 TextureUnitStates::const_iterator i, iend; 288 289 // Clear texture units but doesn't notify need recompilation in the case 290 // we are cloning, The parent material will take care of this. 291 iend = mTextureUnitStates.end(); 292 for (i = mTextureUnitStates.begin(); i != iend; ++i) 293 { 294 OGRE_DELETE *i; 295 } 296 297 mTextureUnitStates.clear(); 298 299 // Copy texture units 300 iend = oth.mTextureUnitStates.end(); 301 for (i = oth.mTextureUnitStates.begin(); i != iend; ++i) 302 { 303 TextureUnitState* t = OGRE_NEW TextureUnitState(this, *(*i)); 304 mTextureUnitStates.push_back(t); 305 } 306 307 _dirtyHash(); 308 309 return *this; 310 } 311 //----------------------------------------------------------------------------- calculateSize(void) const312 size_t Pass::calculateSize(void) const 313 { 314 size_t memSize = 0; 315 316 // Tally up TU states 317 TextureUnitStates::const_iterator i, iend; 318 iend = mTextureUnitStates.end(); 319 for (i = mTextureUnitStates.begin(); i != iend; ++i) 320 { 321 memSize += (*i)->calculateSize(); 322 } 323 for(const auto& u : mProgramUsage) 324 memSize += u ? u->calculateSize() : 0; 325 326 if(mShadowCasterVertexProgramUsage) 327 memSize += mShadowCasterVertexProgramUsage->calculateSize(); 328 if(mShadowCasterFragmentProgramUsage) 329 memSize += mShadowCasterFragmentProgramUsage->calculateSize(); 330 if(mShadowReceiverVertexProgramUsage) 331 memSize += mShadowReceiverVertexProgramUsage->calculateSize(); 332 if(mShadowReceiverFragmentProgramUsage) 333 memSize += mShadowReceiverFragmentProgramUsage->calculateSize(); 334 return memSize; 335 } 336 //----------------------------------------------------------------------- setName(const String & name)337 void Pass::setName(const String& name) 338 { 339 mName = name; 340 } 341 //----------------------------------------------------------------------- setPointSize(Real ps)342 void Pass::setPointSize(Real ps) 343 { 344 mPointSize = ps; 345 } 346 //----------------------------------------------------------------------- setPointSpritesEnabled(bool enabled)347 void Pass::setPointSpritesEnabled(bool enabled) 348 { 349 mPointSpritesEnabled = enabled; 350 } 351 //----------------------------------------------------------------------- getPointSpritesEnabled(void) const352 bool Pass::getPointSpritesEnabled(void) const 353 { 354 return mPointSpritesEnabled; 355 } 356 //----------------------------------------------------------------------- setPointAttenuation(bool enabled,Real constant,Real linear,Real quadratic)357 void Pass::setPointAttenuation(bool enabled, 358 Real constant, Real linear, Real quadratic) 359 { 360 mPointAttenuationEnabled = enabled; 361 mPointAttenuationCoeffs[0] = constant; 362 mPointAttenuationCoeffs[1] = linear; 363 mPointAttenuationCoeffs[2] = quadratic; 364 } 365 //----------------------------------------------------------------------- isPointAttenuationEnabled(void) const366 bool Pass::isPointAttenuationEnabled(void) const 367 { 368 return mPointAttenuationEnabled; 369 } 370 //----------------------------------------------------------------------- getPointAttenuationConstant(void) const371 Real Pass::getPointAttenuationConstant(void) const 372 { 373 return mPointAttenuationCoeffs[0]; 374 } 375 //----------------------------------------------------------------------- getPointAttenuationLinear(void) const376 Real Pass::getPointAttenuationLinear(void) const 377 { 378 return mPointAttenuationCoeffs[1]; 379 } 380 //----------------------------------------------------------------------- getPointAttenuationQuadratic(void) const381 Real Pass::getPointAttenuationQuadratic(void) const 382 { 383 return mPointAttenuationCoeffs[2]; 384 } 385 //----------------------------------------------------------------------- setPointMinSize(Real min)386 void Pass::setPointMinSize(Real min) 387 { 388 mPointMinSize = min; 389 } 390 //----------------------------------------------------------------------- getPointMinSize(void) const391 Real Pass::getPointMinSize(void) const 392 { 393 return mPointMinSize; 394 } 395 //----------------------------------------------------------------------- setPointMaxSize(Real max)396 void Pass::setPointMaxSize(Real max) 397 { 398 mPointMaxSize = max; 399 } 400 //----------------------------------------------------------------------- getPointMaxSize(void) const401 Real Pass::getPointMaxSize(void) const 402 { 403 return mPointMaxSize; 404 } 405 //----------------------------------------------------------------------- setAmbient(float red,float green,float blue)406 void Pass::setAmbient(float red, float green, float blue) 407 { 408 mAmbient.r = red; 409 mAmbient.g = green; 410 mAmbient.b = blue; 411 412 } 413 //----------------------------------------------------------------------- setAmbient(const ColourValue & ambient)414 void Pass::setAmbient(const ColourValue& ambient) 415 { 416 mAmbient = ambient; 417 } 418 //----------------------------------------------------------------------- setDiffuse(float red,float green,float blue,float alpha)419 void Pass::setDiffuse(float red, float green, float blue, float alpha) 420 { 421 mDiffuse.r = red; 422 mDiffuse.g = green; 423 mDiffuse.b = blue; 424 mDiffuse.a = alpha; 425 } 426 //----------------------------------------------------------------------- setDiffuse(const ColourValue & diffuse)427 void Pass::setDiffuse(const ColourValue& diffuse) 428 { 429 mDiffuse = diffuse; 430 } 431 //----------------------------------------------------------------------- setSpecular(float red,float green,float blue,float alpha)432 void Pass::setSpecular(float red, float green, float blue, float alpha) 433 { 434 mSpecular.r = red; 435 mSpecular.g = green; 436 mSpecular.b = blue; 437 mSpecular.a = alpha; 438 } 439 //----------------------------------------------------------------------- setSpecular(const ColourValue & specular)440 void Pass::setSpecular(const ColourValue& specular) 441 { 442 mSpecular = specular; 443 } 444 //----------------------------------------------------------------------- setShininess(Real val)445 void Pass::setShininess(Real val) 446 { 447 mShininess = val; 448 } 449 //----------------------------------------------------------------------- setSelfIllumination(float red,float green,float blue)450 void Pass::setSelfIllumination(float red, float green, float blue) 451 { 452 mEmissive.r = red; 453 mEmissive.g = green; 454 mEmissive.b = blue; 455 456 } 457 //----------------------------------------------------------------------- setSelfIllumination(const ColourValue & selfIllum)458 void Pass::setSelfIllumination(const ColourValue& selfIllum) 459 { 460 mEmissive = selfIllum; 461 } 462 //----------------------------------------------------------------------- setVertexColourTracking(TrackVertexColourType tracking)463 void Pass::setVertexColourTracking(TrackVertexColourType tracking) 464 { 465 mTracking = tracking; 466 } 467 //----------------------------------------------------------------------- getPointSize(void) const468 Real Pass::getPointSize(void) const 469 { 470 return mPointSize; 471 } 472 //----------------------------------------------------------------------- getAmbient(void) const473 const ColourValue& Pass::getAmbient(void) const 474 { 475 return mAmbient; 476 } 477 //----------------------------------------------------------------------- getDiffuse(void) const478 const ColourValue& Pass::getDiffuse(void) const 479 { 480 return mDiffuse; 481 } 482 //----------------------------------------------------------------------- getSpecular(void) const483 const ColourValue& Pass::getSpecular(void) const 484 { 485 return mSpecular; 486 } 487 //----------------------------------------------------------------------- getSelfIllumination(void) const488 const ColourValue& Pass::getSelfIllumination(void) const 489 { 490 return mEmissive; 491 } 492 //----------------------------------------------------------------------- getShininess(void) const493 Real Pass::getShininess(void) const 494 { 495 return mShininess; 496 } 497 //----------------------------------------------------------------------- getVertexColourTracking(void) const498 TrackVertexColourType Pass::getVertexColourTracking(void) const 499 { 500 return mTracking; 501 } 502 //----------------------------------------------------------------------- createTextureUnitState(void)503 TextureUnitState* Pass::createTextureUnitState(void) 504 { 505 TextureUnitState *t = OGRE_NEW TextureUnitState(this); 506 addTextureUnitState(t); 507 mContentTypeLookupBuilt = false; 508 return t; 509 } 510 //----------------------------------------------------------------------- createTextureUnitState(const String & textureName,unsigned short texCoordSet)511 TextureUnitState* Pass::createTextureUnitState( 512 const String& textureName, unsigned short texCoordSet) 513 { 514 TextureUnitState *t = OGRE_NEW TextureUnitState(this); 515 t->setTextureName(textureName); 516 t->setTextureCoordSet(texCoordSet); 517 addTextureUnitState(t); 518 mContentTypeLookupBuilt = false; 519 return t; 520 } 521 //----------------------------------------------------------------------- addTextureUnitState(TextureUnitState * state)522 void Pass::addTextureUnitState(TextureUnitState* state) 523 { 524 OGRE_LOCK_MUTEX(mTexUnitChangeMutex); 525 526 assert(state && "state is 0 in Pass::addTextureUnitState()"); 527 if (state) 528 { 529 // only attach TUS to pass if TUS does not belong to another pass 530 if ((state->getParent() == 0) || (state->getParent() == this)) 531 { 532 mTextureUnitStates.push_back(state); 533 // Notify state 534 state->_notifyParent(this); 535 // if texture unit state name is empty then give it a default name based on its index 536 if (state->getName().empty()) 537 { 538 // its the last entry in the container so its index is size - 1 539 size_t idx = mTextureUnitStates.size() - 1; 540 541 // allow 8 digit hex number. there should never be that many texture units. 542 // This sprintf replaced a call to StringConverter::toString for performance reasons 543 state->setName( StringUtil::format("%lx", static_cast<long>(idx))); 544 545 /** since the name was never set and a default one has been made, clear the alias name 546 so that when the texture unit name is set by the user, the alias name will be set to 547 that name 548 */ 549 state->setTextureNameAlias(BLANKSTRING); 550 } 551 // Needs recompilation 552 mParent->_notifyNeedsRecompile(); 553 _dirtyHash(); 554 } 555 else 556 { 557 OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "TextureUnitState already attached to another pass", 558 "Pass:addTextureUnitState"); 559 560 } 561 mContentTypeLookupBuilt = false; 562 } 563 } 564 //----------------------------------------------------------------------- getTextureUnitState(unsigned short index) const565 TextureUnitState* Pass::getTextureUnitState(unsigned short index) const 566 { 567 OGRE_LOCK_MUTEX(mTexUnitChangeMutex); 568 assert (index < mTextureUnitStates.size() && "Index out of bounds"); 569 return mTextureUnitStates[index]; 570 } 571 //----------------------------------------------------------------------------- getTextureUnitState(const String & name) const572 TextureUnitState* Pass::getTextureUnitState(const String& name) const 573 { 574 OGRE_LOCK_MUTEX(mTexUnitChangeMutex); 575 TextureUnitStates::const_iterator i = mTextureUnitStates.begin(); 576 TextureUnitStates::const_iterator iend = mTextureUnitStates.end(); 577 TextureUnitState* foundTUS = 0; 578 579 // iterate through TUS Container to find a match 580 while (i != iend) 581 { 582 if ( (*i)->getName() == name ) 583 { 584 foundTUS = (*i); 585 break; 586 } 587 588 ++i; 589 } 590 591 return foundTUS; 592 } 593 594 //----------------------------------------------------------------------- getTextureUnitStateIndex(const TextureUnitState * state) const595 unsigned short Pass::getTextureUnitStateIndex(const TextureUnitState* state) const 596 { 597 OGRE_LOCK_MUTEX(mTexUnitChangeMutex); 598 assert(state && "state is 0 in Pass::getTextureUnitStateIndex()"); 599 600 // only find index for state attached to this pass 601 if (state->getParent() == this) 602 { 603 TextureUnitStates::const_iterator i = 604 std::find(mTextureUnitStates.begin(), mTextureUnitStates.end(), state); 605 assert(i != mTextureUnitStates.end() && "state is supposed to attached to this pass"); 606 return static_cast<unsigned short>(std::distance(mTextureUnitStates.begin(), i)); 607 } 608 else 609 { 610 OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "TextureUnitState is not attached to this pass", 611 "Pass:getTextureUnitStateIndex"); 612 } 613 } 614 615 //----------------------------------------------------------------------- 616 Pass::TextureUnitStateIterator getTextureUnitStateIterator(void)617 Pass::getTextureUnitStateIterator(void) 618 { 619 return TextureUnitStateIterator(mTextureUnitStates.begin(), mTextureUnitStates.end()); 620 } 621 //----------------------------------------------------------------------- 622 Pass::ConstTextureUnitStateIterator getTextureUnitStateIterator(void) const623 Pass::getTextureUnitStateIterator(void) const 624 { 625 return ConstTextureUnitStateIterator(mTextureUnitStates.begin(), mTextureUnitStates.end()); 626 } 627 //----------------------------------------------------------------------- removeTextureUnitState(unsigned short index)628 void Pass::removeTextureUnitState(unsigned short index) 629 { 630 OGRE_LOCK_MUTEX(mTexUnitChangeMutex); 631 assert (index < mTextureUnitStates.size() && "Index out of bounds"); 632 633 TextureUnitStates::iterator i = mTextureUnitStates.begin() + index; 634 OGRE_DELETE *i; 635 mTextureUnitStates.erase(i); 636 if (!mQueuedForDeletion) 637 { 638 // Needs recompilation 639 mParent->_notifyNeedsRecompile(); 640 } 641 _dirtyHash(); 642 mContentTypeLookupBuilt = false; 643 } 644 //----------------------------------------------------------------------- removeAllTextureUnitStates(void)645 void Pass::removeAllTextureUnitStates(void) 646 { 647 OGRE_LOCK_MUTEX(mTexUnitChangeMutex); 648 TextureUnitStates::iterator i, iend; 649 iend = mTextureUnitStates.end(); 650 for (i = mTextureUnitStates.begin(); i != iend; ++i) 651 { 652 OGRE_DELETE *i; 653 } 654 mTextureUnitStates.clear(); 655 if (!mQueuedForDeletion) 656 { 657 // Needs recompilation 658 mParent->_notifyNeedsRecompile(); 659 } 660 _dirtyHash(); 661 mContentTypeLookupBuilt = false; 662 } 663 //----------------------------------------------------------------------- _getBlendFlags(SceneBlendType type,SceneBlendFactor & source,SceneBlendFactor & dest)664 void Pass::_getBlendFlags(SceneBlendType type, SceneBlendFactor& source, SceneBlendFactor& dest) 665 { 666 switch ( type ) 667 { 668 case SBT_TRANSPARENT_ALPHA: 669 source = SBF_SOURCE_ALPHA; 670 dest = SBF_ONE_MINUS_SOURCE_ALPHA; 671 return; 672 case SBT_TRANSPARENT_COLOUR: 673 source = SBF_SOURCE_COLOUR; 674 dest = SBF_ONE_MINUS_SOURCE_COLOUR; 675 return; 676 case SBT_MODULATE: 677 source = SBF_DEST_COLOUR; 678 dest = SBF_ZERO; 679 return; 680 case SBT_ADD: 681 source = SBF_ONE; 682 dest = SBF_ONE; 683 return; 684 case SBT_REPLACE: 685 source = SBF_ONE; 686 dest = SBF_ZERO; 687 return; 688 } 689 690 // Default to SBT_REPLACE 691 692 source = SBF_ONE; 693 dest = SBF_ZERO; 694 } 695 //----------------------------------------------------------------------- setSceneBlending(SceneBlendType sbt)696 void Pass::setSceneBlending(SceneBlendType sbt) 697 { 698 // Convert type into blend factors 699 700 SceneBlendFactor source; 701 SceneBlendFactor dest; 702 _getBlendFlags(sbt, source, dest); 703 704 // Set blend factors 705 706 setSceneBlending(source, dest); 707 } 708 //----------------------------------------------------------------------- setSeparateSceneBlending(const SceneBlendType sbt,const SceneBlendType sbta)709 void Pass::setSeparateSceneBlending( const SceneBlendType sbt, const SceneBlendType sbta ) 710 { 711 // Convert types into blend factors 712 713 SceneBlendFactor source; 714 SceneBlendFactor dest; 715 _getBlendFlags(sbt, source, dest); 716 717 SceneBlendFactor sourceAlpha; 718 SceneBlendFactor destAlpha; 719 _getBlendFlags(sbta, sourceAlpha, destAlpha); 720 721 // Set blend factors 722 723 setSeparateSceneBlending(source, dest, sourceAlpha, destAlpha); 724 } 725 726 //----------------------------------------------------------------------- setSceneBlending(SceneBlendFactor sourceFactor,SceneBlendFactor destFactor)727 void Pass::setSceneBlending(SceneBlendFactor sourceFactor, SceneBlendFactor destFactor) 728 { 729 mBlendState.sourceFactor = sourceFactor; 730 mBlendState.sourceFactorAlpha = sourceFactor; 731 mBlendState.destFactor = destFactor; 732 mBlendState.destFactorAlpha = destFactor; 733 } 734 //----------------------------------------------------------------------- setSeparateSceneBlending(const SceneBlendFactor sourceFactor,const SceneBlendFactor destFactor,const SceneBlendFactor sourceFactorAlpha,const SceneBlendFactor destFactorAlpha)735 void Pass::setSeparateSceneBlending( const SceneBlendFactor sourceFactor, const SceneBlendFactor destFactor, const SceneBlendFactor sourceFactorAlpha, const SceneBlendFactor destFactorAlpha ) 736 { 737 mBlendState.sourceFactor = sourceFactor; 738 mBlendState.destFactor = destFactor; 739 mBlendState.sourceFactorAlpha = sourceFactorAlpha; 740 mBlendState.destFactorAlpha = destFactorAlpha; 741 } 742 //----------------------------------------------------------------------- getSourceBlendFactor(void) const743 SceneBlendFactor Pass::getSourceBlendFactor(void) const 744 { 745 return mBlendState.sourceFactor; 746 } 747 //----------------------------------------------------------------------- getDestBlendFactor(void) const748 SceneBlendFactor Pass::getDestBlendFactor(void) const 749 { 750 return mBlendState.destFactor; 751 } 752 //----------------------------------------------------------------------- getSourceBlendFactorAlpha(void) const753 SceneBlendFactor Pass::getSourceBlendFactorAlpha(void) const 754 { 755 return mBlendState.sourceFactorAlpha ; 756 } 757 //----------------------------------------------------------------------- getDestBlendFactorAlpha(void) const758 SceneBlendFactor Pass::getDestBlendFactorAlpha(void) const 759 { 760 return mBlendState.destFactorAlpha; 761 } 762 //----------------------------------------------------------------------- hasSeparateSceneBlending() const763 bool Pass::hasSeparateSceneBlending() const 764 { 765 return true; 766 } 767 //----------------------------------------------------------------------- setSceneBlendingOperation(SceneBlendOperation op)768 void Pass::setSceneBlendingOperation(SceneBlendOperation op) 769 { 770 mBlendState.operation = op; 771 mBlendState.alphaOperation = op; 772 } 773 //----------------------------------------------------------------------- setSeparateSceneBlendingOperation(SceneBlendOperation op,SceneBlendOperation alphaOp)774 void Pass::setSeparateSceneBlendingOperation(SceneBlendOperation op, SceneBlendOperation alphaOp) 775 { 776 mBlendState.operation = op; 777 mBlendState.alphaOperation = alphaOp; 778 } 779 //----------------------------------------------------------------------- getSceneBlendingOperation() const780 SceneBlendOperation Pass::getSceneBlendingOperation() const 781 { 782 return mBlendState.operation; 783 } 784 //----------------------------------------------------------------------- getSceneBlendingOperationAlpha() const785 SceneBlendOperation Pass::getSceneBlendingOperationAlpha() const 786 { 787 return mBlendState.alphaOperation; 788 } 789 //----------------------------------------------------------------------- hasSeparateSceneBlendingOperations() const790 bool Pass::hasSeparateSceneBlendingOperations() const 791 { 792 return true; 793 } 794 //----------------------------------------------------------------------- isTransparent(void) const795 bool Pass::isTransparent(void) const 796 { 797 // Transparent if any of the destination colour is taken into account 798 if (mBlendState.destFactor == SBF_ZERO && 799 mBlendState.sourceFactor != SBF_DEST_COLOUR && 800 mBlendState.sourceFactor != SBF_ONE_MINUS_DEST_COLOUR && 801 mBlendState.sourceFactor != SBF_DEST_ALPHA && 802 mBlendState.sourceFactor != SBF_ONE_MINUS_DEST_ALPHA) 803 { 804 return false; 805 } 806 else 807 { 808 return true; 809 } 810 } 811 //----------------------------------------------------------------------- setDepthCheckEnabled(bool enabled)812 void Pass::setDepthCheckEnabled(bool enabled) 813 { 814 mDepthCheck = enabled; 815 } 816 //----------------------------------------------------------------------- getDepthCheckEnabled(void) const817 bool Pass::getDepthCheckEnabled(void) const 818 { 819 return mDepthCheck; 820 } 821 //----------------------------------------------------------------------- setDepthWriteEnabled(bool enabled)822 void Pass::setDepthWriteEnabled(bool enabled) 823 { 824 mDepthWrite = enabled; 825 } 826 //----------------------------------------------------------------------- getDepthWriteEnabled(void) const827 bool Pass::getDepthWriteEnabled(void) const 828 { 829 return mDepthWrite; 830 } 831 //----------------------------------------------------------------------- setDepthFunction(CompareFunction func)832 void Pass::setDepthFunction( CompareFunction func) 833 { 834 mDepthFunc = func; 835 } 836 //----------------------------------------------------------------------- getDepthFunction(void) const837 CompareFunction Pass::getDepthFunction(void) const 838 { 839 return mDepthFunc; 840 } 841 //----------------------------------------------------------------------- setAlphaRejectSettings(CompareFunction func,unsigned char value,bool alphaToCoverage)842 void Pass::setAlphaRejectSettings(CompareFunction func, unsigned char value, bool alphaToCoverage) 843 { 844 mAlphaRejectFunc = func; 845 mAlphaRejectVal = value; 846 mAlphaToCoverageEnabled = alphaToCoverage; 847 } 848 //----------------------------------------------------------------------- setAlphaRejectFunction(CompareFunction func)849 void Pass::setAlphaRejectFunction(CompareFunction func) 850 { 851 mAlphaRejectFunc = func; 852 } 853 //----------------------------------------------------------------------- setAlphaRejectValue(unsigned char val)854 void Pass::setAlphaRejectValue(unsigned char val) 855 { 856 mAlphaRejectVal = val; 857 } 858 //--------------------------------------------------------------------- setAlphaToCoverageEnabled(bool enabled)859 void Pass::setAlphaToCoverageEnabled(bool enabled) 860 { 861 mAlphaToCoverageEnabled = enabled; 862 } 863 //----------------------------------------------------------------------- setTransparentSortingEnabled(bool enabled)864 void Pass::setTransparentSortingEnabled(bool enabled) 865 { 866 mTransparentSorting = enabled; 867 } 868 //----------------------------------------------------------------------- getTransparentSortingEnabled(void) const869 bool Pass::getTransparentSortingEnabled(void) const 870 { 871 return mTransparentSorting; 872 } 873 //----------------------------------------------------------------------- setTransparentSortingForced(bool enabled)874 void Pass::setTransparentSortingForced(bool enabled) 875 { 876 mTransparentSortingForced = enabled; 877 } 878 //----------------------------------------------------------------------- getTransparentSortingForced(void) const879 bool Pass::getTransparentSortingForced(void) const 880 { 881 return mTransparentSortingForced; 882 } 883 //----------------------------------------------------------------------- setColourWriteEnabled(bool enabled)884 void Pass::setColourWriteEnabled(bool enabled) 885 { 886 mBlendState.writeR = enabled; 887 mBlendState.writeG = enabled; 888 mBlendState.writeB = enabled; 889 mBlendState.writeA = enabled; 890 } 891 //----------------------------------------------------------------------- getColourWriteEnabled() const892 bool Pass::getColourWriteEnabled() const 893 { 894 return mBlendState.writeR || mBlendState.writeG || mBlendState.writeB || 895 mBlendState.writeA; 896 } 897 //----------------------------------------------------------------------- 898 setColourWriteEnabled(bool red,bool green,bool blue,bool alpha)899 void Pass::setColourWriteEnabled(bool red, bool green, bool blue, bool alpha) 900 { 901 mBlendState.writeR = red; 902 mBlendState.writeG = green; 903 mBlendState.writeB = blue; 904 mBlendState.writeA = alpha; 905 } 906 //----------------------------------------------------------------------- getColourWriteEnabled(bool & red,bool & green,bool & blue,bool & alpha) const907 void Pass::getColourWriteEnabled(bool& red, bool& green, bool& blue, bool& alpha) const 908 { 909 red = mBlendState.writeR; 910 green = mBlendState.writeG; 911 blue = mBlendState.writeB; 912 alpha = mBlendState.writeA; 913 } 914 //----------------------------------------------------------------------- setCullingMode(CullingMode mode)915 void Pass::setCullingMode( CullingMode mode) 916 { 917 mCullMode = mode; 918 } 919 //----------------------------------------------------------------------- getCullingMode(void) const920 CullingMode Pass::getCullingMode(void) const 921 { 922 return mCullMode; 923 } 924 //----------------------------------------------------------------------- setLightingEnabled(bool enabled)925 void Pass::setLightingEnabled(bool enabled) 926 { 927 mLightingEnabled = enabled; 928 } 929 //----------------------------------------------------------------------- getLightingEnabled(void) const930 bool Pass::getLightingEnabled(void) const 931 { 932 return mLightingEnabled; 933 } 934 //----------------------------------------------------------------------- setMaxSimultaneousLights(unsigned short maxLights)935 void Pass::setMaxSimultaneousLights(unsigned short maxLights) 936 { 937 mMaxSimultaneousLights = maxLights; 938 } 939 //----------------------------------------------------------------------- getMaxSimultaneousLights(void) const940 unsigned short Pass::getMaxSimultaneousLights(void) const 941 { 942 return mMaxSimultaneousLights; 943 } 944 //----------------------------------------------------------------------- setStartLight(unsigned short startLight)945 void Pass::setStartLight(unsigned short startLight) 946 { 947 mStartLight = startLight; 948 } 949 //----------------------------------------------------------------------- getStartLight(void) const950 unsigned short Pass::getStartLight(void) const 951 { 952 return mStartLight; 953 } 954 //----------------------------------------------------------------------- setLightMask(uint32 mask)955 void Pass::setLightMask(uint32 mask) 956 { 957 mLightMask = mask; 958 } 959 //----------------------------------------------------------------------- getLightMask() const960 uint32 Pass::getLightMask() const 961 { 962 return mLightMask; 963 } 964 //----------------------------------------------------------------------- setLightCountPerIteration(unsigned short c)965 void Pass::setLightCountPerIteration(unsigned short c) 966 { 967 mLightsPerIteration = c; 968 } 969 //----------------------------------------------------------------------- getLightCountPerIteration(void) const970 unsigned short Pass::getLightCountPerIteration(void) const 971 { 972 return mLightsPerIteration; 973 } 974 //----------------------------------------------------------------------- setIteratePerLight(bool enabled,bool onlyForOneLightType,Light::LightTypes lightType)975 void Pass::setIteratePerLight(bool enabled, 976 bool onlyForOneLightType, Light::LightTypes lightType) 977 { 978 mIteratePerLight = enabled; 979 mRunOnlyForOneLightType = onlyForOneLightType; 980 mOnlyLightType = lightType; 981 } 982 //----------------------------------------------------------------------- setShadingMode(ShadeOptions mode)983 void Pass::setShadingMode(ShadeOptions mode) 984 { 985 mShadeOptions = mode; 986 } 987 //----------------------------------------------------------------------- getShadingMode(void) const988 ShadeOptions Pass::getShadingMode(void) const 989 { 990 return mShadeOptions; 991 } 992 //----------------------------------------------------------------------- setPolygonMode(PolygonMode mode)993 void Pass::setPolygonMode(PolygonMode mode) 994 { 995 mPolygonMode = mode; 996 } 997 //----------------------------------------------------------------------- getPolygonMode(void) const998 PolygonMode Pass::getPolygonMode(void) const 999 { 1000 return mPolygonMode; 1001 } 1002 //----------------------------------------------------------------------- setManualCullingMode(ManualCullingMode mode)1003 void Pass::setManualCullingMode(ManualCullingMode mode) 1004 { 1005 mManualCullMode = mode; 1006 } 1007 //----------------------------------------------------------------------- getManualCullingMode(void) const1008 ManualCullingMode Pass::getManualCullingMode(void) const 1009 { 1010 return mManualCullMode; 1011 } 1012 //----------------------------------------------------------------------- setFog(bool overrideScene,FogMode mode,const ColourValue & colour,Real density,Real start,Real end)1013 void Pass::setFog(bool overrideScene, FogMode mode, const ColourValue& colour, Real density, Real start, Real end) 1014 { 1015 mFogOverride = overrideScene; 1016 if (overrideScene) 1017 { 1018 mFogMode = mode; 1019 mFogColour = colour; 1020 mFogStart = start; 1021 mFogEnd = end; 1022 mFogDensity = density; 1023 } 1024 } 1025 //----------------------------------------------------------------------- getFogOverride(void) const1026 bool Pass::getFogOverride(void) const 1027 { 1028 return mFogOverride; 1029 } 1030 //----------------------------------------------------------------------- getFogMode(void) const1031 FogMode Pass::getFogMode(void) const 1032 { 1033 return mFogMode; 1034 } 1035 //----------------------------------------------------------------------- getFogColour(void) const1036 const ColourValue& Pass::getFogColour(void) const 1037 { 1038 return mFogColour; 1039 } 1040 //----------------------------------------------------------------------- getFogStart(void) const1041 Real Pass::getFogStart(void) const 1042 { 1043 return mFogStart; 1044 } 1045 //----------------------------------------------------------------------- getFogEnd(void) const1046 Real Pass::getFogEnd(void) const 1047 { 1048 return mFogEnd; 1049 } 1050 //----------------------------------------------------------------------- getFogDensity(void) const1051 Real Pass::getFogDensity(void) const 1052 { 1053 return mFogDensity; 1054 } 1055 //----------------------------------------------------------------------- setDepthBias(float constantBias,float slopeScaleBias)1056 void Pass::setDepthBias(float constantBias, float slopeScaleBias) 1057 { 1058 mDepthBiasConstant = constantBias; 1059 mDepthBiasSlopeScale = slopeScaleBias; 1060 } 1061 //----------------------------------------------------------------------- getDepthBiasConstant(void) const1062 float Pass::getDepthBiasConstant(void) const 1063 { 1064 return mDepthBiasConstant; 1065 } 1066 //----------------------------------------------------------------------- getDepthBiasSlopeScale(void) const1067 float Pass::getDepthBiasSlopeScale(void) const 1068 { 1069 return mDepthBiasSlopeScale; 1070 } 1071 //--------------------------------------------------------------------- setIterationDepthBias(float biasPerIteration)1072 void Pass::setIterationDepthBias(float biasPerIteration) 1073 { 1074 mDepthBiasPerIteration = biasPerIteration; 1075 } 1076 //--------------------------------------------------------------------- getIterationDepthBias() const1077 float Pass::getIterationDepthBias() const 1078 { 1079 return mDepthBiasPerIteration; 1080 } 1081 //----------------------------------------------------------------------- _split(unsigned short numUnits)1082 Pass* Pass::_split(unsigned short numUnits) 1083 { 1084 if (isProgrammable()) 1085 { 1086 OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Programmable passes cannot be " 1087 "automatically split, define a fallback technique instead.", 1088 "Pass:_split"); 1089 } 1090 1091 if (mTextureUnitStates.size() > numUnits) 1092 { 1093 size_t start = mTextureUnitStates.size() - numUnits; 1094 1095 Pass* newPass = mParent->createPass(); 1096 1097 TextureUnitStates::iterator istart, i, iend; 1098 iend = mTextureUnitStates.end(); 1099 i = istart = mTextureUnitStates.begin() + start; 1100 // Set the new pass to fallback using scene blend 1101 newPass->setSceneBlending( 1102 (*i)->getColourBlendFallbackSrc(), (*i)->getColourBlendFallbackDest()); 1103 // Fixup the texture unit 0 of new pass blending method to replace 1104 // all colour and alpha with texture without adjustment, because we 1105 // assume it's detail texture. 1106 (*i)->setColourOperationEx(LBX_SOURCE1, LBS_TEXTURE, LBS_CURRENT); 1107 (*i)->setAlphaOperation(LBX_SOURCE1, LBS_TEXTURE, LBS_CURRENT); 1108 1109 // Add all the other texture unit states 1110 for (; i != iend; ++i) 1111 { 1112 // detach from parent first 1113 (*i)->_notifyParent(0); 1114 newPass->addTextureUnitState(*i); 1115 } 1116 // Now remove texture units from this Pass, we don't need to delete since they've 1117 // been transferred 1118 mTextureUnitStates.erase(istart, iend); 1119 _dirtyHash(); 1120 mContentTypeLookupBuilt = false; 1121 return newPass; 1122 } 1123 return NULL; 1124 } 1125 //----------------------------------------------------------------------------- _notifyIndex(unsigned short index)1126 void Pass::_notifyIndex(unsigned short index) 1127 { 1128 if (mIndex != index) 1129 { 1130 mIndex = index; 1131 _dirtyHash(); 1132 } 1133 } 1134 //----------------------------------------------------------------------- _prepare(void)1135 void Pass::_prepare(void) 1136 { 1137 // We assume the Technique only calls this when the material is being 1138 // prepared 1139 1140 // prepare each TextureUnitState 1141 TextureUnitStates::iterator i, iend; 1142 iend = mTextureUnitStates.end(); 1143 for (i = mTextureUnitStates.begin(); i != iend; ++i) 1144 { 1145 (*i)->_prepare(); 1146 } 1147 1148 } 1149 //----------------------------------------------------------------------- _unprepare(void)1150 void Pass::_unprepare(void) 1151 { 1152 // unprepare each TextureUnitState 1153 TextureUnitStates::iterator i, iend; 1154 iend = mTextureUnitStates.end(); 1155 for (i = mTextureUnitStates.begin(); i != iend; ++i) 1156 { 1157 (*i)->_unprepare(); 1158 } 1159 1160 } 1161 //----------------------------------------------------------------------- _load(void)1162 void Pass::_load(void) 1163 { 1164 // We assume the Technique only calls this when the material is being 1165 // loaded 1166 1167 // Load each TextureUnitState 1168 TextureUnitStates::iterator i, iend; 1169 iend = mTextureUnitStates.end(); 1170 for (i = mTextureUnitStates.begin(); i != iend; ++i) 1171 { 1172 (*i)->_load(); 1173 } 1174 1175 // Load programs 1176 for (const auto& u : mProgramUsage) 1177 if(u) u->_load(); 1178 1179 if (mShadowCasterVertexProgramUsage) 1180 { 1181 // Load vertex program 1182 mShadowCasterVertexProgramUsage->_load(); 1183 } 1184 if (mShadowCasterFragmentProgramUsage) 1185 { 1186 // Load fragment program 1187 mShadowCasterFragmentProgramUsage->_load(); 1188 } 1189 if (mShadowReceiverVertexProgramUsage) 1190 { 1191 // Load vertex program 1192 mShadowReceiverVertexProgramUsage->_load(); 1193 } 1194 1195 if (mShadowReceiverFragmentProgramUsage) 1196 { 1197 // Load Fragment program 1198 mShadowReceiverFragmentProgramUsage->_load(); 1199 } 1200 1201 if (mHashDirtyQueued) 1202 { 1203 _dirtyHash(); 1204 } 1205 1206 } 1207 //----------------------------------------------------------------------- _unload(void)1208 void Pass::_unload(void) 1209 { 1210 // Unload each TextureUnitState 1211 TextureUnitStates::iterator i, iend; 1212 iend = mTextureUnitStates.end(); 1213 for (i = mTextureUnitStates.begin(); i != iend; ++i) 1214 { 1215 (*i)->_unload(); 1216 } 1217 1218 // TODO Unload programs 1219 } 1220 //----------------------------------------------------------------------- setVertexProgram(const String & name,bool resetParams)1221 void Pass::setVertexProgram(const String& name, bool resetParams) 1222 { 1223 setGpuProgram(GPT_VERTEX_PROGRAM, name, resetParams); 1224 } 1225 //----------------------------------------------------------------------- setGpuProgramParameters(GpuProgramType type,const GpuProgramParametersSharedPtr & params)1226 void Pass::setGpuProgramParameters(GpuProgramType type, const GpuProgramParametersSharedPtr& params) 1227 { 1228 OGRE_LOCK_MUTEX(mGpuProgramChangeMutex); 1229 1230 const auto& programUsage = getProgramUsage(type); 1231 if (!programUsage) 1232 { 1233 OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, 1234 "This pass does not have this program type assigned!"); 1235 } 1236 programUsage->setParameters(params); 1237 } setVertexProgramParameters(GpuProgramParametersSharedPtr params)1238 void Pass::setVertexProgramParameters(GpuProgramParametersSharedPtr params) 1239 { 1240 setGpuProgramParameters(GPT_VERTEX_PROGRAM, params); 1241 } 1242 //----------------------------------------------------------------------- setGpuProgram(GpuProgramType type,const GpuProgramPtr & program,bool resetParams)1243 void Pass::setGpuProgram(GpuProgramType type, const GpuProgramPtr& program, bool resetParams) 1244 { 1245 OGRE_LOCK_MUTEX(mGpuProgramChangeMutex); 1246 1247 std::unique_ptr<GpuProgramUsage>& programUsage = getProgramUsage(type); 1248 1249 // Turn off fragment program if name blank 1250 if (!program) 1251 { 1252 programUsage.reset(); 1253 } 1254 else 1255 { 1256 if (!programUsage) 1257 { 1258 programUsage.reset(new GpuProgramUsage(type, this)); 1259 } 1260 programUsage->setProgram(program, resetParams); 1261 } 1262 // Needs recompilation 1263 mParent->_notifyNeedsRecompile(); 1264 1265 if( Pass::getHashFunction() == Pass::getBuiltinHashFunction( Pass::MIN_GPU_PROGRAM_CHANGE ) ) 1266 { 1267 _dirtyHash(); 1268 } 1269 } 1270 setGpuProgram(GpuProgramType type,const String & name,bool resetParams)1271 void Pass::setGpuProgram(GpuProgramType type, const String& name, bool resetParams) 1272 { 1273 if (getGpuProgramName(type) == name) 1274 return; 1275 1276 GpuProgramPtr program; 1277 if (!name.empty()) 1278 program = GpuProgramUsage::_getProgramByName(name, getResourceGroup(), type); 1279 1280 setGpuProgram(type, program, resetParams); 1281 } 1282 setFragmentProgram(const String & name,bool resetParams)1283 void Pass::setFragmentProgram(const String& name, bool resetParams) 1284 { 1285 setGpuProgram(GPT_FRAGMENT_PROGRAM, name, resetParams); 1286 } 1287 //----------------------------------------------------------------------- setFragmentProgramParameters(GpuProgramParametersSharedPtr params)1288 void Pass::setFragmentProgramParameters(GpuProgramParametersSharedPtr params) 1289 { 1290 setGpuProgramParameters(GPT_FRAGMENT_PROGRAM, params); 1291 } 1292 //----------------------------------------------------------------------- setGeometryProgram(const String & name,bool resetParams)1293 void Pass::setGeometryProgram(const String& name, bool resetParams) 1294 { 1295 setGpuProgram(GPT_GEOMETRY_PROGRAM, name, resetParams); 1296 } 1297 //----------------------------------------------------------------------- setGeometryProgramParameters(GpuProgramParametersSharedPtr params)1298 void Pass::setGeometryProgramParameters(GpuProgramParametersSharedPtr params) 1299 { 1300 setGpuProgramParameters(GPT_GEOMETRY_PROGRAM, params); 1301 } 1302 //----------------------------------------------------------------------- setTessellationHullProgram(const String & name,bool resetParams)1303 void Pass::setTessellationHullProgram(const String& name, bool resetParams) 1304 { 1305 setGpuProgram(GPT_HULL_PROGRAM, name, resetParams); 1306 } 1307 //----------------------------------------------------------------------- setTessellationHullProgramParameters(GpuProgramParametersSharedPtr params)1308 void Pass::setTessellationHullProgramParameters(GpuProgramParametersSharedPtr params) 1309 { 1310 setGpuProgramParameters(GPT_HULL_PROGRAM, params); 1311 } 1312 //----------------------------------------------------------------------- setTessellationDomainProgram(const String & name,bool resetParams)1313 void Pass::setTessellationDomainProgram(const String& name, bool resetParams) 1314 { 1315 setGpuProgram(GPT_DOMAIN_PROGRAM, name, resetParams); 1316 } 1317 //----------------------------------------------------------------------- setTessellationDomainProgramParameters(GpuProgramParametersSharedPtr params)1318 void Pass::setTessellationDomainProgramParameters(GpuProgramParametersSharedPtr params) 1319 { 1320 setGpuProgramParameters(GPT_DOMAIN_PROGRAM, params); 1321 } 1322 //----------------------------------------------------------------------- setComputeProgram(const String & name,bool resetParams)1323 void Pass::setComputeProgram(const String& name, bool resetParams) 1324 { 1325 setGpuProgram(GPT_COMPUTE_PROGRAM, name, resetParams); 1326 } 1327 //----------------------------------------------------------------------- setComputeProgramParameters(GpuProgramParametersSharedPtr params)1328 void Pass::setComputeProgramParameters(GpuProgramParametersSharedPtr params) 1329 { 1330 setGpuProgramParameters(GPT_COMPUTE_PROGRAM, params); 1331 } 1332 //----------------------------------------------------------------------- getGpuProgramParameters(GpuProgramType type) const1333 const GpuProgramParametersSharedPtr& Pass::getGpuProgramParameters(GpuProgramType type) const 1334 { 1335 OGRE_LOCK_MUTEX(mGpuProgramChangeMutex); 1336 const auto& programUsage = getProgramUsage(type); 1337 if (!programUsage) 1338 { 1339 OGRE_EXCEPT (Exception::ERR_INVALIDPARAMS, 1340 "This pass does not have this program type assigned!"); 1341 } 1342 return programUsage->getParameters(); 1343 } 1344 getVertexProgramParameters(void) const1345 GpuProgramParametersSharedPtr Pass::getVertexProgramParameters(void) const 1346 { 1347 return getGpuProgramParameters(GPT_VERTEX_PROGRAM); 1348 } 1349 getProgramUsage(GpuProgramType programType)1350 std::unique_ptr<GpuProgramUsage>& Pass::getProgramUsage(GpuProgramType programType) { 1351 return mProgramUsage[programType]; 1352 } 1353 getProgramUsage(GpuProgramType programType) const1354 const std::unique_ptr<GpuProgramUsage>& Pass::getProgramUsage(GpuProgramType programType) const 1355 { 1356 return mProgramUsage[programType]; 1357 } 1358 hasGpuProgram(GpuProgramType programType) const1359 bool Pass::hasGpuProgram(GpuProgramType programType) const { 1360 return getProgramUsage(programType) != NULL; 1361 } getGpuProgram(GpuProgramType programType) const1362 const GpuProgramPtr& Pass::getGpuProgram(GpuProgramType programType) const 1363 { 1364 OGRE_LOCK_MUTEX(mGpuProgramChangeMutex); 1365 OgreAssert(mProgramUsage[programType], "check whether program is available using hasGpuProgram()"); 1366 return mProgramUsage[programType]->getProgram(); 1367 } 1368 //----------------------------------------------------------------------- getVertexProgram(void) const1369 const GpuProgramPtr& Pass::getVertexProgram(void) const 1370 { 1371 return getGpuProgram(GPT_VERTEX_PROGRAM); 1372 } 1373 //----------------------------------------------------------------------- getGpuProgramName(GpuProgramType type) const1374 const String& Pass::getGpuProgramName(GpuProgramType type) const 1375 { 1376 OGRE_LOCK_MUTEX(mGpuProgramChangeMutex); 1377 1378 const std::unique_ptr<GpuProgramUsage>& programUsage = getProgramUsage(type); 1379 if (!programUsage) 1380 return BLANKSTRING; 1381 else 1382 return programUsage->getProgramName(); 1383 } 1384 //----------------------------------------------------------------------- getFragmentProgramParameters(void) const1385 GpuProgramParametersSharedPtr Pass::getFragmentProgramParameters(void) const 1386 { 1387 return getGpuProgramParameters(GPT_FRAGMENT_PROGRAM); 1388 } 1389 //----------------------------------------------------------------------- getFragmentProgram(void) const1390 const GpuProgramPtr& Pass::getFragmentProgram(void) const 1391 { 1392 return getGpuProgram(GPT_FRAGMENT_PROGRAM); 1393 } 1394 //----------------------------------------------------------------------- getGeometryProgramParameters(void) const1395 GpuProgramParametersSharedPtr Pass::getGeometryProgramParameters(void) const 1396 { 1397 return getGpuProgramParameters(GPT_GEOMETRY_PROGRAM); 1398 } 1399 //----------------------------------------------------------------------- getGeometryProgram(void) const1400 const GpuProgramPtr& Pass::getGeometryProgram(void) const 1401 { 1402 return getGpuProgram(GPT_GEOMETRY_PROGRAM); 1403 } 1404 //----------------------------------------------------------------------- getTessellationHullProgramParameters(void) const1405 GpuProgramParametersSharedPtr Pass::getTessellationHullProgramParameters(void) const 1406 { 1407 return getGpuProgramParameters(GPT_HULL_PROGRAM); 1408 } 1409 //----------------------------------------------------------------------- getTessellationHullProgram(void) const1410 const GpuProgramPtr& Pass::getTessellationHullProgram(void) const 1411 { 1412 return getGpuProgram(GPT_HULL_PROGRAM); 1413 } 1414 //----------------------------------------------------------------------- getTessellationDomainProgramParameters(void) const1415 GpuProgramParametersSharedPtr Pass::getTessellationDomainProgramParameters(void) const 1416 { 1417 return getGpuProgramParameters(GPT_DOMAIN_PROGRAM); 1418 } 1419 //----------------------------------------------------------------------- getTessellationDomainProgram(void) const1420 const GpuProgramPtr& Pass::getTessellationDomainProgram(void) const 1421 { 1422 return getGpuProgram(GPT_DOMAIN_PROGRAM); 1423 } 1424 //----------------------------------------------------------------------- getComputeProgramParameters(void) const1425 GpuProgramParametersSharedPtr Pass::getComputeProgramParameters(void) const 1426 { 1427 return getGpuProgramParameters(GPT_COMPUTE_PROGRAM); 1428 } 1429 //----------------------------------------------------------------------- getComputeProgram(void) const1430 const GpuProgramPtr& Pass::getComputeProgram(void) const 1431 { 1432 return getGpuProgram(GPT_COMPUTE_PROGRAM); 1433 } 1434 //----------------------------------------------------------------------- isLoaded(void) const1435 bool Pass::isLoaded(void) const 1436 { 1437 return mParent->isLoaded(); 1438 } 1439 //----------------------------------------------------------------------- _recalculateHash(void)1440 void Pass::_recalculateHash(void) 1441 { 1442 /* Hash format is 32-bit, divided as follows (high to low bits) 1443 bits purpose 1444 4 Pass index (i.e. max 16 passes!) 1445 28 Pass contents 1446 */ 1447 mHash = (*msHashFunc)(this); 1448 1449 // overwrite the 4 upper bits with pass index 1450 mHash = (uint32(mIndex) << 28) | (mHash >> 4); 1451 } 1452 //----------------------------------------------------------------------- _dirtyHash(void)1453 void Pass::_dirtyHash(void) 1454 { 1455 Material* mat = mParent->getParent(); 1456 if (mat->isLoading() || mat->isLoaded()) 1457 { 1458 OGRE_LOCK_MUTEX(msDirtyHashListMutex); 1459 // Mark this hash as for follow up 1460 msDirtyHashList.insert(this); 1461 mHashDirtyQueued = false; 1462 } 1463 else 1464 { 1465 mHashDirtyQueued = true; 1466 } 1467 } 1468 //--------------------------------------------------------------------- clearDirtyHashList(void)1469 void Pass::clearDirtyHashList(void) 1470 { 1471 OGRE_LOCK_MUTEX(msDirtyHashListMutex); 1472 msDirtyHashList.clear(); 1473 } 1474 //----------------------------------------------------------------------- _notifyNeedsRecompile(void)1475 void Pass::_notifyNeedsRecompile(void) 1476 { 1477 mParent->_notifyNeedsRecompile(); 1478 } 1479 //----------------------------------------------------------------------- setTextureFiltering(TextureFilterOptions filterType)1480 void Pass::setTextureFiltering(TextureFilterOptions filterType) 1481 { 1482 OGRE_LOCK_MUTEX(mTexUnitChangeMutex); 1483 1484 TextureUnitStates::iterator i, iend; 1485 iend = mTextureUnitStates.end(); 1486 for (i = mTextureUnitStates.begin(); i != iend; ++i) 1487 { 1488 (*i)->setTextureFiltering(filterType); 1489 } 1490 } 1491 // -------------------------------------------------------------------- setTextureAnisotropy(unsigned int maxAniso)1492 void Pass::setTextureAnisotropy(unsigned int maxAniso) 1493 { 1494 OGRE_LOCK_MUTEX(mTexUnitChangeMutex); 1495 TextureUnitStates::iterator i, iend; 1496 iend = mTextureUnitStates.end(); 1497 for (i = mTextureUnitStates.begin(); i != iend; ++i) 1498 { 1499 (*i)->setTextureAnisotropy(maxAniso); 1500 } 1501 } 1502 //----------------------------------------------------------------------- _updateAutoParams(const AutoParamDataSource * source,uint16 mask) const1503 void Pass::_updateAutoParams(const AutoParamDataSource* source, uint16 mask) const 1504 { 1505 for(int i = 0; i < GPT_COUNT; i++) 1506 { 1507 const auto& programUsage = getProgramUsage(GpuProgramType(i)); 1508 if (programUsage) 1509 { 1510 // Update program auto params 1511 programUsage->getParameters()->_updateAutoParams(source, mask); 1512 } 1513 } 1514 } 1515 //----------------------------------------------------------------------- processPendingPassUpdates(void)1516 void Pass::processPendingPassUpdates(void) 1517 { 1518 { 1519 OGRE_LOCK_MUTEX(msPassGraveyardMutex); 1520 // Delete items in the graveyard 1521 PassSet::iterator i, iend; 1522 iend = msPassGraveyard.end(); 1523 for (i = msPassGraveyard.begin(); i != iend; ++i) 1524 { 1525 OGRE_DELETE *i; 1526 } 1527 msPassGraveyard.clear(); 1528 } 1529 PassSet tempDirtyHashList; 1530 { 1531 OGRE_LOCK_MUTEX(msDirtyHashListMutex); 1532 // The dirty ones will have been removed from the groups above using the old hash now 1533 tempDirtyHashList.swap(msDirtyHashList); 1534 } 1535 PassSet::iterator i, iend; 1536 iend = tempDirtyHashList.end(); 1537 for (i = tempDirtyHashList.begin(); i != iend; ++i) 1538 { 1539 Pass* p = *i; 1540 p->_recalculateHash(); 1541 } 1542 } 1543 //----------------------------------------------------------------------- queueForDeletion(void)1544 void Pass::queueForDeletion(void) 1545 { 1546 mQueuedForDeletion = true; 1547 1548 removeAllTextureUnitStates(); 1549 for (auto& u : mProgramUsage) 1550 u.reset(); 1551 1552 mShadowCasterVertexProgramUsage.reset(); 1553 mShadowCasterFragmentProgramUsage.reset(); 1554 mShadowReceiverVertexProgramUsage.reset(); 1555 mShadowReceiverFragmentProgramUsage.reset(); 1556 1557 // remove from dirty list, if there 1558 { 1559 OGRE_LOCK_MUTEX(msDirtyHashListMutex); 1560 msDirtyHashList.erase(this); 1561 } 1562 { 1563 OGRE_LOCK_MUTEX(msPassGraveyardMutex); 1564 msPassGraveyard.insert(this); 1565 } 1566 } 1567 //----------------------------------------------------------------------- isAmbientOnly(void) const1568 bool Pass::isAmbientOnly(void) const 1569 { 1570 // treat as ambient if lighting is off, or colour write is off, 1571 // or all non-ambient (& emissive) colours are black 1572 // NB a vertex program could override this, but passes using vertex 1573 // programs are expected to indicate they are ambient only by 1574 // setting the state so it matches one of the conditions above, even 1575 // though this state is not used in rendering. 1576 return (!mLightingEnabled || !getColourWriteEnabled() || 1577 (mDiffuse == ColourValue::Black && 1578 mSpecular == ColourValue::Black)); 1579 } 1580 //----------------------------------------------------------------------- setShadowCasterVertexProgram(const String & name)1581 void Pass::setShadowCasterVertexProgram(const String& name) 1582 { 1583 // Turn off vertex program if name blank 1584 if (name.empty()) 1585 { 1586 mShadowCasterVertexProgramUsage.reset(); 1587 } 1588 else 1589 { 1590 if (!mShadowCasterVertexProgramUsage) 1591 { 1592 mShadowCasterVertexProgramUsage.reset(new GpuProgramUsage(GPT_VERTEX_PROGRAM, this)); 1593 } 1594 mShadowCasterVertexProgramUsage->setProgramName(name); 1595 } 1596 // Needs recompilation 1597 mParent->_notifyNeedsRecompile(); 1598 } 1599 //----------------------------------------------------------------------- setShadowCasterVertexProgramParameters(GpuProgramParametersSharedPtr params)1600 void Pass::setShadowCasterVertexProgramParameters(GpuProgramParametersSharedPtr params) 1601 { 1602 if (!mShadowCasterVertexProgramUsage) 1603 { 1604 OGRE_EXCEPT (Exception::ERR_INVALIDPARAMS, 1605 "This pass does not have a shadow caster vertex program assigned!", 1606 "Pass::setShadowCasterVertexProgramParameters"); 1607 } 1608 mShadowCasterVertexProgramUsage->setParameters(params); 1609 } 1610 //----------------------------------------------------------------------- getShadowCasterVertexProgramName(void) const1611 const String& Pass::getShadowCasterVertexProgramName(void) const 1612 { 1613 if (!mShadowCasterVertexProgramUsage) 1614 return BLANKSTRING; 1615 else 1616 return mShadowCasterVertexProgramUsage->getProgramName(); 1617 } 1618 //----------------------------------------------------------------------- getShadowCasterVertexProgramParameters(void) const1619 GpuProgramParametersSharedPtr Pass::getShadowCasterVertexProgramParameters(void) const 1620 { 1621 if (!mShadowCasterVertexProgramUsage) 1622 { 1623 OGRE_EXCEPT (Exception::ERR_INVALIDPARAMS, 1624 "This pass does not have a shadow caster vertex program assigned!", 1625 "Pass::getShadowCasterVertexProgramParameters"); 1626 } 1627 return mShadowCasterVertexProgramUsage->getParameters(); 1628 } 1629 //----------------------------------------------------------------------- getShadowCasterVertexProgram(void) const1630 const GpuProgramPtr& Pass::getShadowCasterVertexProgram(void) const 1631 { 1632 return mShadowCasterVertexProgramUsage->getProgram(); 1633 } 1634 //----------------------------------------------------------------------- setShadowCasterFragmentProgram(const String & name)1635 void Pass::setShadowCasterFragmentProgram(const String& name) 1636 { 1637 // Turn off fragment program if name blank 1638 if (name.empty()) 1639 { 1640 mShadowCasterFragmentProgramUsage.reset(); 1641 } 1642 else 1643 { 1644 if (!mShadowCasterFragmentProgramUsage) 1645 { 1646 mShadowCasterFragmentProgramUsage.reset(new GpuProgramUsage(GPT_FRAGMENT_PROGRAM, this)); 1647 } 1648 mShadowCasterFragmentProgramUsage->setProgramName(name); 1649 } 1650 // Needs recompilation 1651 mParent->_notifyNeedsRecompile(); 1652 } 1653 //----------------------------------------------------------------------- setShadowCasterFragmentProgramParameters(GpuProgramParametersSharedPtr params)1654 void Pass::setShadowCasterFragmentProgramParameters(GpuProgramParametersSharedPtr params) 1655 { 1656 if (!mShadowCasterFragmentProgramUsage && 1657 !Root::getSingletonPtr()->getRenderSystem()->getCapabilities()->hasCapability( 1658 RSC_FIXED_FUNCTION)) 1659 { 1660 OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, 1661 "This pass does not have a shadow caster fragment program assigned!", 1662 "Pass::setShadowCasterFragmentProgramParameters"); 1663 } 1664 mShadowCasterFragmentProgramUsage->setParameters(params); 1665 } 1666 //----------------------------------------------------------------------- getShadowCasterFragmentProgramName(void) const1667 const String& Pass::getShadowCasterFragmentProgramName(void) const 1668 { 1669 if (!mShadowCasterFragmentProgramUsage) 1670 return BLANKSTRING; 1671 else 1672 return mShadowCasterFragmentProgramUsage->getProgramName(); 1673 } 1674 //----------------------------------------------------------------------- getShadowCasterFragmentProgramParameters(void) const1675 GpuProgramParametersSharedPtr Pass::getShadowCasterFragmentProgramParameters(void) const 1676 { 1677 1678 if (!mShadowCasterFragmentProgramUsage && 1679 !Root::getSingletonPtr()->getRenderSystem()->getCapabilities()->hasCapability( 1680 RSC_FIXED_FUNCTION)) 1681 { 1682 OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, 1683 "This pass does not have a shadow caster fragment program assigned!", 1684 "Pass::getShadowCasterFragmentProgramParameters"); 1685 } 1686 1687 return mShadowCasterFragmentProgramUsage->getParameters(); 1688 } 1689 //----------------------------------------------------------------------- getShadowCasterFragmentProgram(void) const1690 const GpuProgramPtr& Pass::getShadowCasterFragmentProgram(void) const 1691 { 1692 return mShadowCasterFragmentProgramUsage->getProgram(); 1693 } 1694 //----------------------------------------------------------------------- setShadowReceiverVertexProgram(const String & name)1695 void Pass::setShadowReceiverVertexProgram(const String& name) 1696 { 1697 // Turn off vertex program if name blank 1698 if (name.empty()) 1699 { 1700 mShadowReceiverVertexProgramUsage.reset(); 1701 } 1702 else 1703 { 1704 if (!mShadowReceiverVertexProgramUsage) 1705 { 1706 mShadowReceiverVertexProgramUsage.reset(new GpuProgramUsage(GPT_VERTEX_PROGRAM, this)); 1707 } 1708 mShadowReceiverVertexProgramUsage->setProgramName(name); 1709 } 1710 // Needs recompilation 1711 mParent->_notifyNeedsRecompile(); 1712 } 1713 //----------------------------------------------------------------------- setShadowReceiverVertexProgramParameters(GpuProgramParametersSharedPtr params)1714 void Pass::setShadowReceiverVertexProgramParameters(GpuProgramParametersSharedPtr params) 1715 { 1716 if (!mShadowReceiverVertexProgramUsage) 1717 { 1718 OGRE_EXCEPT (Exception::ERR_INVALIDPARAMS, 1719 "This pass does not have a shadow receiver vertex program assigned!", 1720 "Pass::setShadowReceiverVertexProgramParameters"); 1721 } 1722 mShadowReceiverVertexProgramUsage->setParameters(params); 1723 } 1724 //----------------------------------------------------------------------- getShadowReceiverVertexProgramName(void) const1725 const String& Pass::getShadowReceiverVertexProgramName(void) const 1726 { 1727 if (!mShadowReceiverVertexProgramUsage) 1728 return BLANKSTRING; 1729 else 1730 return mShadowReceiverVertexProgramUsage->getProgramName(); 1731 } 1732 //----------------------------------------------------------------------- getShadowReceiverVertexProgramParameters(void) const1733 GpuProgramParametersSharedPtr Pass::getShadowReceiverVertexProgramParameters(void) const 1734 { 1735 if (!mShadowReceiverVertexProgramUsage) 1736 { 1737 OGRE_EXCEPT (Exception::ERR_INVALIDPARAMS, 1738 "This pass does not have a shadow receiver vertex program assigned!", 1739 "Pass::getShadowReceiverVertexProgramParameters"); 1740 } 1741 return mShadowReceiverVertexProgramUsage->getParameters(); 1742 } 1743 //----------------------------------------------------------------------- getShadowReceiverVertexProgram(void) const1744 const GpuProgramPtr& Pass::getShadowReceiverVertexProgram(void) const 1745 { 1746 return mShadowReceiverVertexProgramUsage->getProgram(); 1747 } 1748 //----------------------------------------------------------------------- setShadowReceiverFragmentProgram(const String & name)1749 void Pass::setShadowReceiverFragmentProgram(const String& name) 1750 { 1751 // Turn off Fragment program if name blank 1752 if (name.empty()) 1753 { 1754 mShadowReceiverFragmentProgramUsage.reset(); 1755 } 1756 else 1757 { 1758 if (!mShadowReceiverFragmentProgramUsage) 1759 { 1760 mShadowReceiverFragmentProgramUsage.reset(new GpuProgramUsage(GPT_FRAGMENT_PROGRAM, this)); 1761 } 1762 mShadowReceiverFragmentProgramUsage->setProgramName(name); 1763 } 1764 // Needs recompilation 1765 mParent->_notifyNeedsRecompile(); 1766 } 1767 //----------------------------------------------------------------------- setShadowReceiverFragmentProgramParameters(GpuProgramParametersSharedPtr params)1768 void Pass::setShadowReceiverFragmentProgramParameters(GpuProgramParametersSharedPtr params) 1769 { 1770 if (!mShadowReceiverFragmentProgramUsage) 1771 { 1772 OGRE_EXCEPT (Exception::ERR_INVALIDPARAMS, 1773 "This pass does not have a shadow receiver fragment program assigned!", 1774 "Pass::setShadowReceiverFragmentProgramParameters"); 1775 } 1776 mShadowReceiverFragmentProgramUsage->setParameters(params); 1777 } 1778 //----------------------------------------------------------------------- getShadowReceiverFragmentProgramName(void) const1779 const String& Pass::getShadowReceiverFragmentProgramName(void) const 1780 { 1781 if (!mShadowReceiverFragmentProgramUsage) 1782 return BLANKSTRING; 1783 else 1784 return mShadowReceiverFragmentProgramUsage->getProgramName(); 1785 } 1786 //----------------------------------------------------------------------- getShadowReceiverFragmentProgramParameters(void) const1787 GpuProgramParametersSharedPtr Pass::getShadowReceiverFragmentProgramParameters(void) const 1788 { 1789 if (!mShadowReceiverFragmentProgramUsage) 1790 { 1791 OGRE_EXCEPT (Exception::ERR_INVALIDPARAMS, 1792 "This pass does not have a shadow receiver fragment program assigned!", 1793 "Pass::getShadowReceiverFragmentProgramParameters"); 1794 } 1795 return mShadowReceiverFragmentProgramUsage->getParameters(); 1796 } 1797 //----------------------------------------------------------------------- getShadowReceiverFragmentProgram(void) const1798 const GpuProgramPtr& Pass::getShadowReceiverFragmentProgram(void) const 1799 { 1800 return mShadowReceiverFragmentProgramUsage->getProgram(); 1801 } 1802 //----------------------------------------------------------------------- getResourceGroup(void) const1803 const String& Pass::getResourceGroup(void) const 1804 { 1805 return mParent->getResourceGroup(); 1806 } 1807 1808 //----------------------------------------------------------------------- applyTextureAliases(const AliasTextureNamePairList & aliasList,const bool apply) const1809 bool Pass::applyTextureAliases(const AliasTextureNamePairList& aliasList, const bool apply) const 1810 { 1811 // iterate through each texture unit state and apply the texture alias if it applies 1812 TextureUnitStates::const_iterator i, iend; 1813 iend = mTextureUnitStates.end(); 1814 bool testResult = false; 1815 1816 for (i = mTextureUnitStates.begin(); i != iend; ++i) 1817 { 1818 if ((*i)->applyTextureAliases(aliasList, apply)) 1819 testResult = true; 1820 } 1821 1822 return testResult; 1823 1824 } 1825 //----------------------------------------------------------------------- _getTextureUnitWithContentTypeIndex(TextureUnitState::ContentType contentType,unsigned short index) const1826 unsigned short Pass::_getTextureUnitWithContentTypeIndex( 1827 TextureUnitState::ContentType contentType, unsigned short index) const 1828 { 1829 if (!mContentTypeLookupBuilt) 1830 { 1831 mShadowContentTypeLookup.clear(); 1832 for (unsigned short i = 0; i < mTextureUnitStates.size(); ++i) 1833 { 1834 if (mTextureUnitStates[i]->getContentType() == TextureUnitState::CONTENT_SHADOW) 1835 { 1836 mShadowContentTypeLookup.push_back(i); 1837 } 1838 } 1839 mContentTypeLookupBuilt = true; 1840 } 1841 1842 switch(contentType) 1843 { 1844 case TextureUnitState::CONTENT_SHADOW: 1845 if (index < mShadowContentTypeLookup.size()) 1846 { 1847 return mShadowContentTypeLookup[index]; 1848 } 1849 break; 1850 default: 1851 // Simple iteration 1852 for (unsigned short i = 0; i < mTextureUnitStates.size(); ++i) 1853 { 1854 if (mTextureUnitStates[i]->getContentType() == TextureUnitState::CONTENT_SHADOW) 1855 { 1856 if (index == 0) 1857 { 1858 return i; 1859 } 1860 else 1861 { 1862 --index; 1863 } 1864 } 1865 } 1866 break; 1867 } 1868 1869 // not found - return out of range 1870 return static_cast<unsigned short>(mTextureUnitStates.size() + 1); 1871 1872 } 1873 } 1874