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 "OgreTextureUnitState.h" 00028 #include "OgrePass.h" 00029 #include "OgreMaterialManager.h" 00030 #include "OgreControllerManager.h" 00031 #include "OgreLogManager.h" 00032 #include "OgreException.h" 00033 #include "OgreTextureManager.h" 00034 00035 namespace Ogre { 00036 00037 //----------------------------------------------------------------------- 00038 TextureUnitState::TextureUnitState(Pass* parent) 00039 : mParent(parent) 00040 { 00041 mIsBlank = true; 00042 colourBlendMode.blendType = LBT_COLOUR; 00043 setColourOperation(LBO_MODULATE); 00044 setTextureAddressingMode(TAM_WRAP); 00045 00046 alphaBlendMode.operation = LBX_MODULATE; 00047 alphaBlendMode.blendType = LBT_ALPHA; 00048 alphaBlendMode.source1 = LBS_TEXTURE; 00049 alphaBlendMode.source2 = LBS_CURRENT; 00050 00051 //default filtering 00052 mMinFilter = FO_LINEAR; 00053 mMagFilter = FO_LINEAR; 00054 mMipFilter = FO_POINT; 00055 mMaxAniso = MaterialManager::getSingleton().getDefaultAnisotropy(); 00056 mIsDefaultAniso = true; 00057 mIsDefaultFiltering = true; 00058 00059 mUMod = mVMod = 0; 00060 mUScale = mVScale = 1; 00061 mRotate = 0; 00062 mTexModMatrix = Matrix4::IDENTITY; 00063 mRecalcTexMatrix = false; 00064 mAlphaRejectFunc = CMPF_ALWAYS_PASS; 00065 mAlphaRejectVal = 0; 00066 00067 mNumFrames = 0; 00068 mAnimDuration = 0; 00069 mAnimController = 0; 00070 mCubic = false; 00071 mTextureType = TEX_TYPE_2D; 00072 mTextureCoordSetIndex = 0; 00073 00074 mFrames[0] = StringUtil::BLANK; 00075 mCurrentFrame = 0; 00076 00077 mParent->_dirtyHash(); 00078 00079 } 00080 00081 //----------------------------------------------------------------------- 00082 TextureUnitState::TextureUnitState(Pass* parent, const TextureUnitState& oth ) 00083 { 00084 mParent = parent; 00085 *this = oth; 00086 } 00087 00088 //----------------------------------------------------------------------- 00089 TextureUnitState::TextureUnitState( Pass* parent, const String& texName, unsigned int texCoordSet) 00090 :mParent(parent) 00091 { 00092 mIsBlank = true; 00093 colourBlendMode.blendType = LBT_COLOUR; 00094 setColourOperation(LBO_MODULATE); 00095 setTextureAddressingMode(TAM_WRAP); 00096 00097 alphaBlendMode.operation = LBX_MODULATE; 00098 alphaBlendMode.blendType = LBT_ALPHA; 00099 alphaBlendMode.source1 = LBS_TEXTURE; 00100 alphaBlendMode.source2 = LBS_CURRENT; 00101 00102 //default filtering && anisotropy 00103 mMinFilter = FO_LINEAR; 00104 mMagFilter = FO_LINEAR; 00105 mMipFilter = FO_POINT; 00106 mMaxAniso = MaterialManager::getSingleton().getDefaultAnisotropy(); 00107 mIsDefaultAniso = true; 00108 mIsDefaultFiltering = true; 00109 00110 mUMod = mVMod = 0; 00111 mUScale = mVScale = 1; 00112 mRotate = 0; 00113 mAnimDuration = 0; 00114 mAnimController = 0; 00115 mTexModMatrix = Matrix4::IDENTITY; 00116 mRecalcTexMatrix = false; 00117 mAlphaRejectFunc = CMPF_ALWAYS_PASS; 00118 mAlphaRejectVal = 0; 00119 00120 mCubic = false; 00121 mTextureType = TEX_TYPE_2D; 00122 mTextureCoordSetIndex = 0; 00123 00124 setTextureName(texName); 00125 setTextureCoordSet(texCoordSet); 00126 00127 mParent->_dirtyHash(); 00128 00129 } 00130 //----------------------------------------------------------------------- 00131 TextureUnitState::~TextureUnitState() 00132 { 00133 // Destroy controllers 00134 if (mAnimController) 00135 { 00136 ControllerManager::getSingleton().destroyController(mAnimController); 00137 } 00138 // Destroy effect controllers 00139 for (EffectMap::iterator i = mEffects.begin(); i != mEffects.end(); ++i) 00140 { 00141 if (i->second.controller) 00142 { 00143 ControllerManager::getSingleton().destroyController(i->second.controller); 00144 } 00145 00146 } 00147 // Don't unload textures. may be used elsewhere 00148 00149 } 00150 //----------------------------------------------------------------------- 00151 TextureUnitState & TextureUnitState::operator = ( 00152 const TextureUnitState &oth ) 00153 { 00154 // copy basic members (int's, real's) 00155 memcpy( this, &oth, (uchar *)(&oth.mFrames[0]) - (uchar *)(&oth) ); 00156 00157 // copy complex members 00158 for( ushort i = 0; i<mNumFrames; i++ ) 00159 mFrames[i] = oth.mFrames[i]; 00160 00161 mEffects = oth.mEffects; 00162 00163 mParent->_dirtyHash(); 00164 00165 return *this; 00166 } 00167 //----------------------------------------------------------------------- 00168 const String& TextureUnitState::getTextureName(void) const 00169 { 00170 // Return name of current frame 00171 return mFrames[mCurrentFrame]; 00172 } 00173 //----------------------------------------------------------------------- 00174 void TextureUnitState::setTextureName( const String& name, TextureType texType) 00175 { 00176 if (texType == TEX_TYPE_CUBE_MAP) 00177 { 00178 // delegate to cubic texture implementation 00179 setCubicTextureName(name, true); 00180 } 00181 else 00182 { 00183 mFrames[0] = name; 00184 mNumFrames = 1; 00185 mCurrentFrame = 0; 00186 mCubic = false; 00187 mTextureType = texType; 00188 00189 if (name == "") 00190 { 00191 mIsBlank = true; 00192 return; 00193 } 00194 00195 // Load immediately ? 00196 if (isLoaded()) 00197 { 00198 _load(); // reload 00199 // Tell parent to recalculate hash 00200 mParent->_dirtyHash(); 00201 } 00202 } 00203 00204 } 00205 //----------------------------------------------------------------------- 00206 void TextureUnitState::setCubicTextureName( const String& name, bool forUVW) 00207 { 00208 if (forUVW) 00209 { 00210 setCubicTextureName(&name, forUVW); 00211 } 00212 else 00213 { 00214 String ext; 00215 String suffixes[6] = {"_fr", "_bk", "_lf", "_rt", "_up", "_dn"}; 00216 String baseName; 00217 String fullNames[6]; 00218 00219 00220 size_t pos = name.find_last_of("."); 00221 baseName = name.substr(0, pos); 00222 ext = name.substr(pos); 00223 00224 for (int i = 0; i < 6; ++i) 00225 { 00226 fullNames[i] = baseName + suffixes[i] + ext; 00227 } 00228 00229 setCubicTextureName(fullNames, forUVW); 00230 } 00231 } 00232 //----------------------------------------------------------------------- 00233 void TextureUnitState::setCubicTextureName(const String* const names, bool forUVW) 00234 { 00235 mNumFrames = forUVW ? 1 : 6; 00236 mCurrentFrame = 0; 00237 mCubic = true; 00238 mTextureType = forUVW ? TEX_TYPE_CUBE_MAP : TEX_TYPE_2D; 00239 00240 for (unsigned int i = 0; i < mNumFrames; ++i) 00241 { 00242 mFrames[i] = names[i]; 00243 } 00244 // Tell parent we need recompiling, will cause reload too 00245 mParent->_notifyNeedsRecompile(); 00246 } 00247 //----------------------------------------------------------------------- 00248 bool TextureUnitState::isCubic(void) const 00249 { 00250 return mCubic; 00251 } 00252 //----------------------------------------------------------------------- 00253 bool TextureUnitState::is3D(void) const 00254 { 00255 return mTextureType == TEX_TYPE_CUBE_MAP; 00256 } 00257 //----------------------------------------------------------------------- 00258 TextureType TextureUnitState::getTextureType(void) const 00259 { 00260 return mTextureType; 00261 00262 } 00263 //----------------------------------------------------------------------- 00264 void TextureUnitState::setAnimatedTextureName( const String& name, unsigned int numFrames, Real duration) 00265 { 00266 String ext; 00267 String baseName; 00268 00269 size_t pos = name.find_last_of("."); 00270 baseName = name.substr(0, pos); 00271 ext = name.substr(pos); 00272 00273 if (numFrames > MAX_FRAMES) 00274 { 00275 char cmsg[128]; 00276 sprintf(cmsg, "Maximum number of frames is %d.", MAX_FRAMES); 00277 Except(Exception::ERR_INVALIDPARAMS, cmsg, "TextureUnitState::setAnimatedTextureName"); 00278 } 00279 mNumFrames = numFrames; 00280 mAnimDuration = duration; 00281 mCurrentFrame = 0; 00282 mCubic = false; 00283 00284 for (unsigned int i = 0; i < mNumFrames; ++i) 00285 { 00286 char suffix[5]; 00287 sprintf(suffix, "_%d", i); 00288 00289 mFrames[i] = baseName + suffix + ext; 00290 } 00291 00292 // Load immediately if Material loaded 00293 if (isLoaded()) 00294 { 00295 _load(); 00296 // Tell parent to recalculate hash 00297 mParent->_dirtyHash(); 00298 } 00299 00300 } 00301 //----------------------------------------------------------------------- 00302 void TextureUnitState::setAnimatedTextureName(const String* const names, unsigned int numFrames, Real duration) 00303 { 00304 if (numFrames > MAX_FRAMES) 00305 { 00306 char cmsg[128]; 00307 sprintf(cmsg, "Maximum number of frames is %d.", MAX_FRAMES); 00308 Except(Exception::ERR_INVALIDPARAMS, cmsg, "TextureUnitState::setAnimatedTextureName"); 00309 } 00310 mNumFrames = numFrames; 00311 mAnimDuration = duration; 00312 mCurrentFrame = 0; 00313 mCubic = false; 00314 00315 for (unsigned int i = 0; i < mNumFrames; ++i) 00316 { 00317 mFrames[i] = names[i]; 00318 } 00319 00320 // Load immediately if Material loaded 00321 if (isLoaded()) 00322 { 00323 _load(); 00324 // Tell parent to recalculate hash 00325 mParent->_dirtyHash(); 00326 } 00327 } 00328 //----------------------------------------------------------------------- 00329 std::pair< uint, uint > TextureUnitState::getTextureDimensions( unsigned int frame ) const 00330 { 00331 Texture *tex = (Texture *)TextureManager::getSingleton().getByName( mFrames[ frame ] ); 00332 if (!tex) 00333 Except( Exception::ERR_ITEM_NOT_FOUND, "Could not find texture " + mFrames[ frame ], 00334 "TextureUnitState::getTextureDimensions" ); 00335 return std::pair< uint, uint >( tex->getWidth(), tex->getHeight() ); 00336 } 00337 //----------------------------------------------------------------------- 00338 void TextureUnitState::setCurrentFrame(unsigned int frameNumber) 00339 { 00340 assert(frameNumber < mNumFrames); 00341 mCurrentFrame = frameNumber; 00342 // this will affect the hash 00343 mParent->_dirtyHash(); 00344 00345 } 00346 //----------------------------------------------------------------------- 00347 unsigned int TextureUnitState::getCurrentFrame(void) const 00348 { 00349 return mCurrentFrame; 00350 } 00351 //----------------------------------------------------------------------- 00352 unsigned int TextureUnitState::getNumFrames(void) const 00353 { 00354 return mNumFrames; 00355 } 00356 //----------------------------------------------------------------------- 00357 const String& TextureUnitState::getFrameTextureName(unsigned int frameNumber) const 00358 { 00359 assert(frameNumber < mNumFrames); 00360 return mFrames[frameNumber]; 00361 } 00362 //----------------------------------------------------------------------- 00363 unsigned int TextureUnitState::getTextureCoordSet(void) const 00364 { 00365 return mTextureCoordSetIndex; 00366 } 00367 //----------------------------------------------------------------------- 00368 void TextureUnitState::setTextureCoordSet(unsigned int set) 00369 { 00370 mTextureCoordSetIndex = set; 00371 } 00372 //----------------------------------------------------------------------- 00373 void TextureUnitState::setColourOperationEx(LayerBlendOperationEx op, 00374 LayerBlendSource source1, 00375 LayerBlendSource source2, 00376 const ColourValue& arg1, 00377 const ColourValue& arg2, 00378 Real manualBlend) 00379 { 00380 colourBlendMode.operation = op; 00381 colourBlendMode.source1 = source1; 00382 colourBlendMode.source2 = source2; 00383 colourBlendMode.colourArg1 = arg1; 00384 colourBlendMode.colourArg2 = arg2; 00385 colourBlendMode.factor = manualBlend; 00386 } 00387 //----------------------------------------------------------------------- 00388 void TextureUnitState::setColourOperation(LayerBlendOperation op) 00389 { 00390 // Set up the multitexture and multipass blending operations 00391 switch (op) 00392 { 00393 case LBO_REPLACE: 00394 setColourOperationEx(LBX_SOURCE1, LBS_TEXTURE, LBS_CURRENT); 00395 setColourOpMultipassFallback(SBF_ONE, SBF_ZERO); 00396 break; 00397 case LBO_ADD: 00398 setColourOperationEx(LBX_ADD, LBS_TEXTURE, LBS_CURRENT); 00399 setColourOpMultipassFallback(SBF_ONE, SBF_ONE); 00400 break; 00401 case LBO_MODULATE: 00402 setColourOperationEx(LBX_MODULATE, LBS_TEXTURE, LBS_CURRENT); 00403 setColourOpMultipassFallback(SBF_DEST_COLOUR, SBF_ZERO); 00404 break; 00405 case LBO_ALPHA_BLEND: 00406 setColourOperationEx(LBX_BLEND_TEXTURE_ALPHA, LBS_TEXTURE, LBS_CURRENT); 00407 setColourOpMultipassFallback(SBF_SOURCE_ALPHA, SBF_ONE_MINUS_SOURCE_ALPHA); 00408 break; 00409 } 00410 00411 00412 } 00413 //----------------------------------------------------------------------- 00414 void TextureUnitState::setColourOpMultipassFallback(SceneBlendFactor sourceFactor, SceneBlendFactor destFactor) 00415 { 00416 colourBlendFallbackSrc = sourceFactor; 00417 colourBlendFallbackDest = destFactor; 00418 } 00419 //----------------------------------------------------------------------- 00420 void TextureUnitState::setAlphaOperation(LayerBlendOperationEx op, 00421 LayerBlendSource source1, 00422 LayerBlendSource source2, 00423 Real arg1, 00424 Real arg2, 00425 Real manualBlend) 00426 { 00427 alphaBlendMode.operation = op; 00428 alphaBlendMode.source1 = source1; 00429 alphaBlendMode.source2 = source2; 00430 alphaBlendMode.alphaArg1 = arg1; 00431 alphaBlendMode.alphaArg2 = arg2; 00432 alphaBlendMode.factor = manualBlend; 00433 } 00434 //----------------------------------------------------------------------- 00435 void TextureUnitState::addEffect(TextureEffect& effect) 00436 { 00437 // Ensure controller pointer is null 00438 effect.controller = 0; 00439 00440 if (effect.type == ET_ENVIRONMENT_MAP || effect.type == ET_SCROLL || effect.type == ET_ROTATE 00441 || effect.type == ET_PROJECTIVE_TEXTURE) 00442 { 00443 // Replace - must be unique 00444 // Search for existing effect of this type 00445 EffectMap::iterator i = mEffects.find(effect.type); 00446 if (i != mEffects.end()) 00447 { 00448 mEffects.erase(i); 00449 } 00450 } 00451 00452 if (isLoaded()) 00453 { 00454 // Create controller 00455 createEffectController(effect); 00456 } 00457 00458 // Record new effect 00459 mEffects.insert(EffectMap::value_type(effect.type, effect)); 00460 00461 } 00462 //----------------------------------------------------------------------- 00463 void TextureUnitState::removeAllEffects(void) 00464 { 00465 // Iterate over effects to remove controllers 00466 EffectMap::iterator i, iend; 00467 iend = mEffects.end(); 00468 for (i = mEffects.begin(); i != iend; ++i) 00469 { 00470 if (i->second.controller) 00471 { 00472 ControllerManager::getSingleton().destroyController(i->second.controller); 00473 } 00474 } 00475 00476 mEffects.clear(); 00477 } 00478 00479 //----------------------------------------------------------------------- 00480 bool TextureUnitState::isBlank(void) const 00481 { 00482 return mIsBlank; 00483 } 00484 00485 //----------------------------------------------------------------------- 00486 SceneBlendFactor TextureUnitState::getColourBlendFallbackSrc(void) const 00487 { 00488 return colourBlendFallbackSrc; 00489 } 00490 //----------------------------------------------------------------------- 00491 SceneBlendFactor TextureUnitState::getColourBlendFallbackDest(void) const 00492 { 00493 return colourBlendFallbackDest; 00494 } 00495 //----------------------------------------------------------------------- 00496 const LayerBlendModeEx& TextureUnitState::getColourBlendMode(void) const 00497 { 00498 return colourBlendMode; 00499 } 00500 //----------------------------------------------------------------------- 00501 const LayerBlendModeEx& TextureUnitState::getAlphaBlendMode(void) const 00502 { 00503 return alphaBlendMode; 00504 } 00505 //----------------------------------------------------------------------- 00506 TextureUnitState::TextureAddressingMode TextureUnitState::getTextureAddressingMode(void) const 00507 { 00508 return mAddressMode; 00509 } 00510 //----------------------------------------------------------------------- 00511 void TextureUnitState::setTextureAddressingMode(TextureUnitState::TextureAddressingMode tam) 00512 { 00513 mAddressMode = tam; 00514 } 00515 //----------------------------------------------------------------------- 00516 void TextureUnitState::setEnvironmentMap(bool enable, EnvMapType envMapType) 00517 { 00518 if (enable) 00519 { 00520 TextureEffect eff; 00521 eff.type = ET_ENVIRONMENT_MAP; 00522 00523 eff.subtype = envMapType; 00524 addEffect(eff); 00525 } 00526 else 00527 { 00528 removeEffect(ET_ENVIRONMENT_MAP); 00529 } 00530 } 00531 //----------------------------------------------------------------------- 00532 void TextureUnitState::removeEffect(TextureEffectType type) 00533 { 00534 // Get range of items matching this effect 00535 std::pair< EffectMap::iterator, EffectMap::iterator > remPair = 00536 mEffects.equal_range( type ); 00537 // Remove controllers 00538 for (EffectMap::iterator i = remPair.first; i != remPair.second; ++i) 00539 { 00540 if (i->second.controller) 00541 { 00542 ControllerManager::getSingleton().destroyController(i->second.controller); 00543 } 00544 } 00545 // Erase 00546 mEffects.erase( remPair.first, remPair.second ); 00547 } 00548 //----------------------------------------------------------------------- 00549 void TextureUnitState::setBlank(void) 00550 { 00551 mIsBlank = true; 00552 } 00553 //----------------------------------------------------------------------- 00554 void TextureUnitState::setTextureTransform(const Matrix4& xform) 00555 { 00556 mTexModMatrix = xform; 00557 mRecalcTexMatrix = false; 00558 } 00559 //----------------------------------------------------------------------- 00560 void TextureUnitState::setTextureScroll(Real u, Real v) 00561 { 00562 mUMod = u; 00563 mVMod = v; 00564 mRecalcTexMatrix = true; 00565 } 00566 //----------------------------------------------------------------------- 00567 void TextureUnitState::setTextureScale(Real uScale, Real vScale) 00568 { 00569 mUScale = uScale; 00570 mVScale = vScale; 00571 mRecalcTexMatrix = true; 00572 } 00573 //----------------------------------------------------------------------- 00574 void TextureUnitState::setTextureRotate(const Radian& angle) 00575 { 00576 mRotate = angle; 00577 mRecalcTexMatrix = true; 00578 } 00579 //----------------------------------------------------------------------- 00580 const Matrix4& TextureUnitState::getTextureTransform() 00581 { 00582 if (mRecalcTexMatrix) 00583 recalcTextureMatrix(); 00584 return mTexModMatrix; 00585 00586 } 00587 //----------------------------------------------------------------------- 00588 void TextureUnitState::recalcTextureMatrix() 00589 { 00590 // Assumption: 2D texture coords 00591 Matrix3 xform, rot; 00592 00593 xform = Matrix3::IDENTITY; 00594 if (mUScale || mVScale) 00595 { 00596 // Offset to center of texture 00597 xform[0][0] = 1/mUScale; 00598 xform[1][1] = 1/mVScale; 00599 // Skip matrix concat since first matrix update 00600 xform[0][2] = (-0.5 * xform[0][0]) + 0.5; 00601 xform[1][2] = (-0.5 * xform[1][1]) + 0.5; 00602 00603 } 00604 00605 if (mUMod || mVMod) 00606 { 00607 Matrix3 xlate = Matrix3::IDENTITY; 00608 00609 xlate[0][2] = mUMod; 00610 xlate[1][2] = mVMod; 00611 00612 xform = xlate * xform; 00613 } 00614 00615 if (mRotate != Radian(0)) 00616 { 00617 rot = Matrix3::IDENTITY; 00618 Radian theta ( mRotate ); 00619 Real cosTheta = Math::Cos(theta); 00620 Real sinTheta = Math::Sin(theta); 00621 00622 rot[0][0] = cosTheta; 00623 rot[0][1] = -sinTheta; 00624 rot[1][0] = sinTheta; 00625 rot[1][1] = cosTheta; 00626 // Offset center of rotation to center of texture 00627 rot[0][2] = 0.5 + ( (-0.5 * cosTheta) - (-0.5 * sinTheta) ); 00628 rot[1][2] = 0.5 + ( (-0.5 * sinTheta) + (-0.5 * cosTheta) ); 00629 00630 00631 xform = rot * xform; 00632 } 00633 00634 mTexModMatrix = xform; 00635 00636 } 00637 //----------------------------------------------------------------------- 00638 void TextureUnitState::setTextureUScroll(Real value) 00639 { 00640 mUMod = value; 00641 mRecalcTexMatrix = true; 00642 } 00643 //----------------------------------------------------------------------- 00644 void TextureUnitState::setTextureVScroll(Real value) 00645 { 00646 mVMod = value; 00647 mRecalcTexMatrix = true; 00648 } 00649 //----------------------------------------------------------------------- 00650 void TextureUnitState::setTextureUScale(Real value) 00651 { 00652 mUScale = value; 00653 mRecalcTexMatrix = true; 00654 } 00655 //----------------------------------------------------------------------- 00656 void TextureUnitState::setTextureVScale(Real value) 00657 { 00658 mVScale = value; 00659 mRecalcTexMatrix = true; 00660 } 00661 //----------------------------------------------------------------------- 00662 void TextureUnitState::setAlphaRejectSettings(CompareFunction func, unsigned char value) 00663 { 00664 mAlphaRejectFunc = func; 00665 mAlphaRejectVal = value; 00666 } 00667 //----------------------------------------------------------------------- 00668 CompareFunction TextureUnitState::getAlphaRejectFunction(void) const 00669 { 00670 return mAlphaRejectFunc; 00671 } 00672 //----------------------------------------------------------------------- 00673 unsigned char TextureUnitState::getAlphaRejectValue(void) const 00674 { 00675 return mAlphaRejectVal; 00676 } 00677 //----------------------------------------------------------------------- 00678 void TextureUnitState::setScrollAnimation(Real uSpeed, Real vSpeed) 00679 { 00680 // Remove existing effect 00681 removeEffect(ET_SCROLL); 00682 // Create new effect 00683 TextureEffect eff; 00684 eff.type = ET_SCROLL; 00685 eff.arg1 = uSpeed; 00686 eff.arg2 = vSpeed; 00687 addEffect(eff); 00688 } 00689 //----------------------------------------------------------------------- 00690 void TextureUnitState::setRotateAnimation(Real speed) 00691 { 00692 // Remove existing effect 00693 removeEffect(ET_ROTATE); 00694 // Create new effect 00695 TextureEffect eff; 00696 eff.type = ET_ROTATE; 00697 eff.arg1 = speed; 00698 addEffect(eff); 00699 } 00700 //----------------------------------------------------------------------- 00701 void TextureUnitState::setTransformAnimation(TextureTransformType ttype, 00702 WaveformType waveType, Real base, Real frequency, Real phase, Real amplitude) 00703 { 00704 // Remove existing effect 00705 removeEffect(ET_TRANSFORM); 00706 // Create new effect 00707 TextureEffect eff; 00708 eff.type = ET_TRANSFORM; 00709 eff.subtype = ttype; 00710 eff.waveType = waveType; 00711 eff.base = base; 00712 eff.frequency = frequency; 00713 eff.phase = phase; 00714 eff.amplitude = amplitude; 00715 addEffect(eff); 00716 } 00717 //----------------------------------------------------------------------- 00718 void TextureUnitState::_load(void) 00719 { 00720 // Load textures 00721 for (unsigned int i = 0; i < mNumFrames; ++i) 00722 { 00723 if (mFrames[i] != "") 00724 { 00725 // Ensure texture is loaded, default MipMaps and priority 00726 try { 00727 00728 TextureManager::getSingleton().load(mFrames[i], mTextureType); 00729 mIsBlank = false; 00730 } 00731 catch (...) { 00732 String msg; 00733 msg = msg + "Error loading texture " + mFrames[i] + ". Texture layer will be blank."; 00734 LogManager::getSingleton().logMessage(msg); 00735 mIsBlank = true; 00736 } 00737 } 00738 } 00739 // Animation controller 00740 if (mAnimDuration != 0) 00741 { 00742 createAnimController(); 00743 } 00744 // Effect controllers 00745 for (EffectMap::iterator it = mEffects.begin(); it != mEffects.end(); ++it) 00746 { 00747 createEffectController(it->second); 00748 } 00749 00750 } 00751 //----------------------------------------------------------------------- 00752 void TextureUnitState::createAnimController(void) 00753 { 00754 mAnimController = ControllerManager::getSingleton().createTextureAnimator(this, mAnimDuration); 00755 00756 } 00757 //----------------------------------------------------------------------- 00758 void TextureUnitState::createEffectController(TextureEffect& effect) 00759 { 00760 effect.controller = 0; 00761 ControllerManager& cMgr = ControllerManager::getSingleton(); 00762 switch (effect.type) 00763 { 00764 case ET_SCROLL: 00765 effect.controller = cMgr.createTextureScroller(this, effect.arg1, effect.arg2); 00766 break; 00767 case ET_ROTATE: 00768 effect.controller = cMgr.createTextureRotater(this, effect.arg1); 00769 break; 00770 case ET_TRANSFORM: 00771 effect.controller = cMgr.createTextureWaveTransformer(this, (TextureUnitState::TextureTransformType)effect.subtype, effect.waveType, effect.base, 00772 effect.frequency, effect.phase, effect.amplitude); 00773 break; 00774 case ET_ENVIRONMENT_MAP: 00775 break; 00776 default: 00777 break; 00778 } 00779 } 00780 //----------------------------------------------------------------------- 00781 Real TextureUnitState::getTextureUScroll(void) const 00782 { 00783 return mUMod; 00784 } 00785 00786 //----------------------------------------------------------------------- 00787 Real TextureUnitState::getTextureVScroll(void) const 00788 { 00789 return mVMod; 00790 } 00791 00792 //----------------------------------------------------------------------- 00793 Real TextureUnitState::getTextureUScale(void) const 00794 { 00795 return mUScale; 00796 } 00797 00798 //----------------------------------------------------------------------- 00799 Real TextureUnitState::getTextureVScale(void) const 00800 { 00801 return mVScale; 00802 } 00803 00804 //----------------------------------------------------------------------- 00805 const Radian& TextureUnitState::getTextureRotate(void) const 00806 { 00807 return mRotate; 00808 } 00809 00810 //----------------------------------------------------------------------- 00811 Real TextureUnitState::getAnimationDuration(void) const 00812 { 00813 return mAnimDuration; 00814 } 00815 00816 //----------------------------------------------------------------------- 00817 std::multimap<TextureUnitState::TextureEffectType, TextureUnitState::TextureEffect> TextureUnitState::getEffects(void) const 00818 { 00819 return mEffects; 00820 } 00821 00822 //----------------------------------------------------------------------- 00823 void TextureUnitState::setTextureFiltering(TextureFilterOptions filterType) 00824 { 00825 switch (filterType) 00826 { 00827 case TFO_NONE: 00828 setTextureFiltering(FO_POINT, FO_POINT, FO_NONE); 00829 break; 00830 case TFO_BILINEAR: 00831 setTextureFiltering(FO_LINEAR, FO_LINEAR, FO_POINT); 00832 break; 00833 case TFO_TRILINEAR: 00834 setTextureFiltering(FO_LINEAR, FO_LINEAR, FO_LINEAR); 00835 break; 00836 case TFO_ANISOTROPIC: 00837 setTextureFiltering(FO_ANISOTROPIC, FO_ANISOTROPIC, FO_LINEAR); 00838 break; 00839 } 00840 mIsDefaultFiltering = false; 00841 } 00842 //----------------------------------------------------------------------- 00843 void TextureUnitState::setTextureFiltering(FilterType ft, FilterOptions fo) 00844 { 00845 switch (ft) 00846 { 00847 case FT_MIN: 00848 mMinFilter = fo; 00849 break; 00850 case FT_MAG: 00851 mMagFilter = fo; 00852 break; 00853 case FT_MIP: 00854 mMipFilter = fo; 00855 break; 00856 } 00857 mIsDefaultFiltering = false; 00858 } 00859 //----------------------------------------------------------------------- 00860 void TextureUnitState::setTextureFiltering(FilterOptions minFilter, 00861 FilterOptions magFilter, FilterOptions mipFilter) 00862 { 00863 mMinFilter = minFilter; 00864 mMagFilter = magFilter; 00865 mMipFilter = mipFilter; 00866 mIsDefaultFiltering = false; 00867 } 00868 //----------------------------------------------------------------------- 00869 FilterOptions TextureUnitState::getTextureFiltering(FilterType ft) const 00870 { 00871 00872 switch (ft) 00873 { 00874 case FT_MIN: 00875 return mIsDefaultFiltering ? 00876 MaterialManager::getSingleton().getDefaultTextureFiltering(FT_MIN) : mMinFilter; 00877 case FT_MAG: 00878 return mIsDefaultFiltering ? 00879 MaterialManager::getSingleton().getDefaultTextureFiltering(FT_MAG) : mMagFilter; 00880 case FT_MIP: 00881 return mIsDefaultFiltering ? 00882 MaterialManager::getSingleton().getDefaultTextureFiltering(FT_MIP) : mMipFilter; 00883 } 00884 // to keep compiler happy 00885 return mMinFilter; 00886 } 00887 00888 //----------------------------------------------------------------------- 00889 void TextureUnitState::setTextureAnisotropy(unsigned int maxAniso) 00890 { 00891 mMaxAniso = maxAniso; 00892 mIsDefaultAniso = false; 00893 } 00894 //----------------------------------------------------------------------- 00895 unsigned int TextureUnitState::getTextureAnisotropy() const 00896 { 00897 return mIsDefaultAniso? MaterialManager::getSingleton().getDefaultAnisotropy() : mMaxAniso; 00898 } 00899 00900 //----------------------------------------------------------------------- 00901 void TextureUnitState::_unload(void) 00902 { 00903 // TODO 00904 } 00905 //----------------------------------------------------------------------------- 00906 bool TextureUnitState::isLoaded(void) 00907 { 00908 return mParent->isLoaded(); 00909 } 00910 //----------------------------------------------------------------------- 00911 void TextureUnitState::_notifyNeedsRecompile(void) 00912 { 00913 mParent->_notifyNeedsRecompile(); 00914 } 00915 //----------------------------------------------------------------------- 00916 bool TextureUnitState::hasViewRelativeTextureCoordinateGeneration(void) 00917 { 00918 // Right now this only returns true for reflection maps 00919 00920 EffectMap::const_iterator i, iend; 00921 iend = mEffects.end(); 00922 00923 for(i = mEffects.find(ET_ENVIRONMENT_MAP); i != iend; ++i) 00924 { 00925 if (i->second.subtype == ENV_REFLECTION) 00926 return true; 00927 } 00928 for(i = mEffects.find(ET_PROJECTIVE_TEXTURE); i != iend; ++i) 00929 { 00930 return true; 00931 } 00932 00933 return false; 00934 } 00935 //----------------------------------------------------------------------- 00936 void TextureUnitState::setProjectiveTexturing(bool enable, 00937 const Frustum* projectionSettings) 00938 { 00939 if (enable) 00940 { 00941 TextureEffect eff; 00942 eff.type = ET_PROJECTIVE_TEXTURE; 00943 eff.frustum = projectionSettings; 00944 addEffect(eff); 00945 } 00946 else 00947 { 00948 removeEffect(ET_PROJECTIVE_TEXTURE); 00949 } 00950 00951 } 00952 00953 }
Copyright © 2002-2003 by The OGRE Team
Last modified Sun Nov 28 19:48:50 2004