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