source: OGRE/trunk/ogre_changes/Ogre1.2/OgreMain/src/OgreTextureUnitState.cpp @ 948

Revision 948, 38.8 KB checked in by szirmay, 18 years ago (diff)
Line 
1/*
2-----------------------------------------------------------------------------
3This source file is part of OGRE
4    (Object-oriented Graphics Rendering Engine)
5For the latest info, see http://ogre.sourceforge.net/
6
7Copyright (c) 2000-2005 The OGRE Team
8Also see acknowledgements in Readme.html
9
10This program is free software; you can redistribute it and/or modify it under
11the terms of the GNU Lesser General Public License as published by the Free Software
12Foundation; either version 2 of the License, or (at your option) any later
13version.
14
15This program is distributed in the hope that it will be useful, but WITHOUT
16ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
18
19You should have received a copy of the GNU Lesser General Public License along with
20this program; if not, write to the Free Software Foundation, Inc., 59 Temple
21Place - Suite 330, Boston, MA 02111-1307, USA, or go to
22http://www.gnu.org/copyleft/lesser.txt.
23-----------------------------------------------------------------------------
24*/
25#include "OgreStableHeaders.h"
26
27#include "OgreTextureUnitState.h"
28#include "OgrePass.h"
29#include "OgreMaterialManager.h"
30#include "OgreControllerManager.h"
31#include "OgreLogManager.h"
32#include "OgreException.h"
33#include "OgreTextureManager.h"
34
35namespace Ogre {
36
37    //-----------------------------------------------------------------------
38    TextureUnitState::TextureUnitState(Pass* parent)
39        : mParent(parent)
40    {
41        mIsBlank = true;
42                mIsAlpha = false;
43        colourBlendMode.blendType = LBT_COLOUR;
44        setColourOperation(LBO_MODULATE);
45        setTextureAddressingMode(TAM_WRAP);
46        mBorderColour = ColourValue::Black;
47
48        alphaBlendMode.operation = LBX_MODULATE;
49        alphaBlendMode.blendType = LBT_ALPHA;
50        alphaBlendMode.source1 = LBS_TEXTURE;
51        alphaBlendMode.source2 = LBS_CURRENT;
52               
53                //default filtering
54                mMinFilter = FO_LINEAR;
55                mMagFilter = FO_LINEAR;
56                mMipFilter = FO_POINT;
57                mMaxAniso = MaterialManager::getSingleton().getDefaultAnisotropy();
58        mIsDefaultAniso = true;
59        mIsDefaultFiltering = true;
60
61                mUMod = mVMod = 0;
62        mUScale = mVScale = 1;
63        mRotate = 0;
64        mTexModMatrix = Matrix4::IDENTITY;
65        mRecalcTexMatrix = false;
66
67        mAnimDuration = 0;
68        mAnimController = 0;
69        mCubic = false;
70        mTextureType = TEX_TYPE_2D;
71                mTextureSrcMipmaps = -1;
72        mTextureCoordSetIndex = 0;
73
74        mCurrentFrame = 0;
75
76        mParent->_dirtyHash();
77
78                #ifdef GAMETOOLS_ILLUMINATION_MODULE
79                        isVT = false;
80                #endif
81
82    }
83
84    //-----------------------------------------------------------------------
85    TextureUnitState::TextureUnitState(Pass* parent, const TextureUnitState& oth )
86    {
87        mParent = parent;
88        mAnimController = 0;
89        *this = oth;           
90    }
91
92    //-----------------------------------------------------------------------
93    TextureUnitState::TextureUnitState( Pass* parent, const String& texName, unsigned int texCoordSet)
94        :mParent(parent)
95    {
96        mIsBlank = true;
97                mIsAlpha = false;
98        colourBlendMode.blendType = LBT_COLOUR;
99        setColourOperation(LBO_MODULATE);
100        setTextureAddressingMode(TAM_WRAP);
101        mBorderColour = ColourValue::Black;
102
103        alphaBlendMode.operation = LBX_MODULATE;
104        alphaBlendMode.blendType = LBT_ALPHA;
105        alphaBlendMode.source1 = LBS_TEXTURE;
106        alphaBlendMode.source2 = LBS_CURRENT;
107
108                //default filtering && anisotropy
109                mMinFilter = FO_LINEAR;
110                mMagFilter = FO_LINEAR;
111                mMipFilter = FO_POINT;
112                mMaxAniso = MaterialManager::getSingleton().getDefaultAnisotropy();
113        mIsDefaultAniso = true;
114        mIsDefaultFiltering = true;
115
116                mUMod = mVMod = 0;
117        mUScale = mVScale = 1;
118        mRotate = 0;
119        mAnimDuration = 0;
120        mAnimController = 0;
121        mTexModMatrix = Matrix4::IDENTITY;
122        mRecalcTexMatrix = false;
123
124        mCubic = false;
125        mTextureType = TEX_TYPE_2D;
126        mTextureCoordSetIndex = 0;
127
128        setTextureName(texName);
129        setTextureCoordSet(texCoordSet);
130
131        mParent->_dirtyHash();
132
133                #ifdef GAMETOOLS_ILLUMINATION_MODULE
134                        isVT = false;
135                #endif
136
137    }
138    //-----------------------------------------------------------------------
139    TextureUnitState::~TextureUnitState()
140    {
141        // Unload ensure all controllers destroyed
142        _unload();
143    }
144    //-----------------------------------------------------------------------
145    TextureUnitState & TextureUnitState::operator = (
146        const TextureUnitState &oth )
147    {
148        assert(mAnimController == 0);
149        assert(mEffects.empty());
150
151        // copy basic members (int's, real's)
152        memcpy( this, &oth, (uchar *)(&oth.mFrames) - (uchar *)(&oth) );
153        // copy complex members
154        mFrames  = oth.mFrames;
155        mName    = oth.mName;
156        mEffects = oth.mEffects;
157
158        mTextureNameAlias = oth.mTextureNameAlias;
159
160        // Can't sharing controllers with other TUS, reset to null to avoid potential bug.
161        for (EffectMap::iterator j = mEffects.begin(); j != mEffects.end(); ++j)
162        {
163            j->second.controller = 0;
164        }
165
166        // Load immediately if Material loaded
167        if (isLoaded())
168        {
169            _load();
170            // Tell parent to recalculate hash
171            mParent->_dirtyHash();
172        }
173
174                #ifdef GAMETOOLS_ILLUMINATION_MODULE
175                        isVT = oth.isVT;
176                #endif
177
178        return *this;
179    }
180    //-----------------------------------------------------------------------
181    const String& TextureUnitState::getTextureName(void) const
182    {
183        // Return name of current frame
184        if (mCurrentFrame < mFrames.size())
185            return mFrames[mCurrentFrame];
186        else
187            return StringUtil::BLANK;
188    }
189    //-----------------------------------------------------------------------
190    void TextureUnitState::setTextureName( const String& name, TextureType texType, int mipmaps, bool alpha)
191    {
192        if (texType == TEX_TYPE_CUBE_MAP)
193        {
194            // delegate to cubic texture implementation
195            setCubicTextureName(name, true);
196        }
197        else
198        {
199            mFrames.resize(1);
200            mFrames[0] = name;
201            mCurrentFrame = 0;
202            mCubic = false;
203            mTextureType = texType;
204                        mTextureSrcMipmaps = mipmaps;
205            if (alpha)
206                mIsAlpha = alpha;
207            if (name == "")
208            {
209                mIsBlank = true;
210                return;
211            }
212           
213            // Load immediately ?
214            if (isLoaded())
215            {
216                _load(); // reload
217                // Tell parent to recalculate hash
218                mParent->_dirtyHash();
219            }
220        }
221
222    }
223    //-----------------------------------------------------------------------
224    void TextureUnitState::setCubicTextureName( const String& name, bool forUVW)
225    {
226        if (forUVW)
227        {
228            setCubicTextureName(&name, forUVW);
229        }
230        else
231        {
232            String ext;
233            String suffixes[6] = {"_fr", "_bk", "_lf", "_rt", "_up", "_dn"};
234            String baseName;
235            String fullNames[6];
236
237
238            size_t pos = name.find_last_of(".");
239            baseName = name.substr(0, pos);
240            ext = name.substr(pos);
241
242            for (int i = 0; i < 6; ++i)
243            {
244                fullNames[i] = baseName + suffixes[i] + ext;
245            }
246
247            setCubicTextureName(fullNames, forUVW);
248        }
249    }
250    //-----------------------------------------------------------------------
251    void TextureUnitState::setCubicTextureName(const String* const names, bool forUVW)
252    {
253        mFrames.resize(forUVW ? 1 : 6);
254        mCurrentFrame = 0;
255        mCubic = true;
256        mTextureType = forUVW ? TEX_TYPE_CUBE_MAP : TEX_TYPE_2D;
257
258        for (unsigned int i = 0; i < mFrames.size(); ++i)
259        {
260            mFrames[i] = names[i];
261        }
262        // Tell parent we need recompiling, will cause reload too
263        mParent->_notifyNeedsRecompile();
264    }
265    //-----------------------------------------------------------------------
266    bool TextureUnitState::isCubic(void) const
267    {
268        return mCubic;
269    }
270    //-----------------------------------------------------------------------
271    bool TextureUnitState::is3D(void) const
272    {
273        return mTextureType == TEX_TYPE_CUBE_MAP;
274    }
275    //-----------------------------------------------------------------------
276    TextureType TextureUnitState::getTextureType(void) const
277    {
278        return mTextureType;
279
280    }
281
282    //-----------------------------------------------------------------------
283    void TextureUnitState::setFrameTextureName(const String& name, unsigned int frameNumber)
284    {
285        if (frameNumber < mFrames.size())
286        {
287            mFrames[frameNumber] = name;
288
289            if (isLoaded())
290            {
291                _load(); // reload
292                // Tell parent to recalculate hash
293                mParent->_dirtyHash();
294            }
295        }
296        else // raise exception for frameNumber out of bounds
297        {
298            OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "frameNumber paramter value exceeds number of stored frames.",
299                "TextureUnitState::setFrameTextureName");
300        }
301    }
302
303    //-----------------------------------------------------------------------
304    void TextureUnitState::addFrameTextureName(const String& name)
305    {
306        mFrames.push_back(name);
307
308        // Load immediately if Material loaded
309        if (isLoaded())
310        {
311            _load();
312            // Tell parent to recalculate hash
313            mParent->_dirtyHash();
314        }
315    }
316
317    //-----------------------------------------------------------------------
318    void TextureUnitState::deleteFrameTextureName(const size_t frameNumber)
319    {
320        if (frameNumber < mFrames.size())
321        {
322            mFrames.erase(mFrames.begin() + frameNumber);
323
324            if (mFrames.empty())
325                mIsBlank = true;
326
327            if (isLoaded())
328            {
329                _load();
330                // Tell parent to recalculate hash
331                mParent->_dirtyHash();
332            }
333        }
334        else
335        {
336            OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "frameNumber paramter value exceeds number of stored frames.",
337                "TextureUnitState::deleteFrameTextureName");
338        }
339    }
340
341    //-----------------------------------------------------------------------
342    void TextureUnitState::setAnimatedTextureName( const String& name, unsigned int numFrames, Real duration)
343    {
344        String ext;
345        String baseName;
346
347        size_t pos = name.find_last_of(".");
348        baseName = name.substr(0, pos);
349        ext = name.substr(pos);
350
351        mFrames.resize(numFrames);
352        mAnimDuration = duration;
353        mCurrentFrame = 0;
354        mCubic = false;
355
356        for (unsigned int i = 0; i < mFrames.size(); ++i)
357        {
358                        StringUtil::StrStreamType str;
359            str << baseName << "_" << i << ext;
360            mFrames[i] = str.str();
361        }
362
363        // Load immediately if Material loaded
364        if (isLoaded())
365        {
366            _load();
367            // Tell parent to recalculate hash
368            mParent->_dirtyHash();
369        }
370
371    }
372    //-----------------------------------------------------------------------
373    void TextureUnitState::setAnimatedTextureName(const String* const names, unsigned int numFrames, Real duration)
374    {
375        mFrames.resize(numFrames);
376        mAnimDuration = duration;
377        mCurrentFrame = 0;
378        mCubic = false;
379
380        for (unsigned int i = 0; i < mFrames.size(); ++i)
381        {
382            mFrames[i] = names[i];
383        }
384
385        // Load immediately if Material loaded
386        if (isLoaded())
387        {
388            _load();
389            // Tell parent to recalculate hash
390            mParent->_dirtyHash();
391        }
392    }
393    //-----------------------------------------------------------------------
394    std::pair< uint, uint > TextureUnitState::getTextureDimensions( unsigned int frame ) const
395    {
396        if (frame < mFrames.size())
397        {
398            TexturePtr tex = TextureManager::getSingleton().getByName( mFrames[ frame ] );
399
400                    if (tex.isNull())
401                            OGRE_EXCEPT( Exception::ERR_ITEM_NOT_FOUND, "Could not find texture " + mFrames[ frame ],
402                                    "TextureUnitState::getTextureDimensions" );
403            return std::pair< uint, uint >( tex->getWidth(), tex->getHeight() );
404        }
405        else // frame exceeds the number of frames stored
406        {
407                    OGRE_EXCEPT( Exception::ERR_ITEM_NOT_FOUND, "frame number exceeded number of stored frames" ,
408                            "TextureUnitState::getTextureDimensions" );
409        }
410
411    }
412    //-----------------------------------------------------------------------
413    void TextureUnitState::setCurrentFrame(unsigned int frameNumber)
414    {
415        if (frameNumber < mFrames.size())
416        {
417            mCurrentFrame = frameNumber;
418            // this will affect the hash
419            mParent->_dirtyHash();
420        }
421        else
422        {
423            OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "frameNumber paramter value exceeds number of stored frames.",
424                "TextureUnitState::setCurrentFrame");
425        }
426
427    }
428    //-----------------------------------------------------------------------
429    unsigned int TextureUnitState::getCurrentFrame(void) const
430    {
431        return mCurrentFrame;
432    }
433    //-----------------------------------------------------------------------
434    unsigned int TextureUnitState::getNumFrames(void) const
435    {
436        return (unsigned int)mFrames.size();
437    }
438    //-----------------------------------------------------------------------
439    const String& TextureUnitState::getFrameTextureName(unsigned int frameNumber) const
440    {
441        if (frameNumber >= mFrames.size())
442        {
443            OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "frameNumber paramter value exceeds number of stored frames.",
444                "TextureUnitState::getFrameTextureName");
445        }
446
447        return mFrames[frameNumber];
448    }
449    //-----------------------------------------------------------------------
450    unsigned int TextureUnitState::getTextureCoordSet(void) const
451    {
452        return mTextureCoordSetIndex;
453    }
454    //-----------------------------------------------------------------------
455    void TextureUnitState::setTextureCoordSet(unsigned int set)
456    {
457        mTextureCoordSetIndex = set;
458    }
459    //-----------------------------------------------------------------------
460    void TextureUnitState::setColourOperationEx(LayerBlendOperationEx op,
461        LayerBlendSource source1,
462        LayerBlendSource source2,
463        const ColourValue& arg1,
464        const ColourValue& arg2,
465        Real manualBlend)
466    {
467        colourBlendMode.operation = op;
468        colourBlendMode.source1 = source1;
469        colourBlendMode.source2 = source2;
470        colourBlendMode.colourArg1 = arg1;
471        colourBlendMode.colourArg2 = arg2;
472        colourBlendMode.factor = manualBlend;
473    }
474    //-----------------------------------------------------------------------
475    void TextureUnitState::setColourOperation(LayerBlendOperation op)
476    {
477        // Set up the multitexture and multipass blending operations
478        switch (op)
479        {
480        case LBO_REPLACE:
481            setColourOperationEx(LBX_SOURCE1, LBS_TEXTURE, LBS_CURRENT);
482            setColourOpMultipassFallback(SBF_ONE, SBF_ZERO);
483            break;
484        case LBO_ADD:
485            setColourOperationEx(LBX_ADD, LBS_TEXTURE, LBS_CURRENT);
486            setColourOpMultipassFallback(SBF_ONE, SBF_ONE);
487            break;
488        case LBO_MODULATE:
489            setColourOperationEx(LBX_MODULATE, LBS_TEXTURE, LBS_CURRENT);
490            setColourOpMultipassFallback(SBF_DEST_COLOUR, SBF_ZERO);
491            break;
492        case LBO_ALPHA_BLEND:
493            setColourOperationEx(LBX_BLEND_TEXTURE_ALPHA, LBS_TEXTURE, LBS_CURRENT);
494            setColourOpMultipassFallback(SBF_SOURCE_ALPHA, SBF_ONE_MINUS_SOURCE_ALPHA);
495            break;
496        }
497
498
499    }
500    //-----------------------------------------------------------------------
501    void TextureUnitState::setColourOpMultipassFallback(SceneBlendFactor sourceFactor, SceneBlendFactor destFactor)
502    {
503        colourBlendFallbackSrc = sourceFactor;
504        colourBlendFallbackDest = destFactor;
505    }
506    //-----------------------------------------------------------------------
507    void TextureUnitState::setAlphaOperation(LayerBlendOperationEx op,
508        LayerBlendSource source1,
509        LayerBlendSource source2,
510        Real arg1,
511        Real arg2,
512        Real manualBlend)
513    {
514        alphaBlendMode.operation = op;
515        alphaBlendMode.source1 = source1;
516        alphaBlendMode.source2 = source2;
517        alphaBlendMode.alphaArg1 = arg1;
518        alphaBlendMode.alphaArg2 = arg2;
519        alphaBlendMode.factor = manualBlend;
520    }
521    //-----------------------------------------------------------------------
522    void TextureUnitState::addEffect(TextureEffect& effect)
523    {
524        // Ensure controller pointer is null
525        effect.controller = 0;
526
527        if (effect.type == ET_ENVIRONMENT_MAP
528                        || effect.type == ET_UVSCROLL
529                        || effect.type == ET_USCROLL
530                        || effect.type == ET_VSCROLL
531                        || effect.type == ET_ROTATE
532            || effect.type == ET_PROJECTIVE_TEXTURE)
533        {
534            // Replace - must be unique
535            // Search for existing effect of this type
536            EffectMap::iterator i = mEffects.find(effect.type);
537            if (i != mEffects.end())
538            {
539                // Destroy old effect controller if exist
540                if (i->second.controller)
541                {
542                    ControllerManager::getSingleton().destroyController(i->second.controller);
543                }
544
545                mEffects.erase(i);
546            }
547        }
548
549        if (isLoaded())
550        {
551            // Create controller
552            createEffectController(effect);
553        }
554
555        // Record new effect
556        mEffects.insert(EffectMap::value_type(effect.type, effect));
557
558    }
559    //-----------------------------------------------------------------------
560    void TextureUnitState::removeAllEffects(void)
561    {
562        // Iterate over effects to remove controllers
563        EffectMap::iterator i, iend;
564        iend = mEffects.end();
565        for (i = mEffects.begin(); i != iend; ++i)
566        {
567            if (i->second.controller)
568            {
569                ControllerManager::getSingleton().destroyController(i->second.controller);
570            }
571        }
572
573        mEffects.clear();
574    }
575
576    //-----------------------------------------------------------------------
577    bool TextureUnitState::isBlank(void) const
578    {
579        return mIsBlank;
580    }
581
582    //-----------------------------------------------------------------------
583    SceneBlendFactor TextureUnitState::getColourBlendFallbackSrc(void) const
584    {
585        return colourBlendFallbackSrc;
586    }
587    //-----------------------------------------------------------------------
588    SceneBlendFactor TextureUnitState::getColourBlendFallbackDest(void) const
589    {
590        return colourBlendFallbackDest;
591    }
592    //-----------------------------------------------------------------------
593    const LayerBlendModeEx& TextureUnitState::getColourBlendMode(void) const
594    {
595        return colourBlendMode;
596    }
597    //-----------------------------------------------------------------------
598    const LayerBlendModeEx& TextureUnitState::getAlphaBlendMode(void) const
599    {
600        return alphaBlendMode;
601    }
602    //-----------------------------------------------------------------------
603    const TextureUnitState::UVWAddressingMode&
604        TextureUnitState::getTextureAddressingMode(void) const
605    {
606        return mAddressMode;
607    }
608    //-----------------------------------------------------------------------
609    void TextureUnitState::setTextureAddressingMode(
610                TextureUnitState::TextureAddressingMode tam)
611    {
612        mAddressMode.u = tam;
613        mAddressMode.v = tam;
614        mAddressMode.w = tam;
615    }
616    //-----------------------------------------------------------------------
617    void TextureUnitState::setTextureAddressingMode(
618                TextureUnitState::TextureAddressingMode u,
619                TextureUnitState::TextureAddressingMode v,
620                TextureUnitState::TextureAddressingMode w)
621    {
622        mAddressMode.u = u;
623        mAddressMode.v = v;
624        mAddressMode.w = w;
625    }
626    //-----------------------------------------------------------------------
627    void TextureUnitState::setTextureAddressingMode(
628                const TextureUnitState::UVWAddressingMode& uvw)
629    {
630        mAddressMode = uvw;
631    }
632    //-----------------------------------------------------------------------
633    void TextureUnitState::setTextureBorderColour(const ColourValue& colour)
634    {
635        mBorderColour = colour;
636    }
637    //-----------------------------------------------------------------------
638    const ColourValue& TextureUnitState::getTextureBorderColour(void) const
639    {
640        return mBorderColour;
641    }
642    //-----------------------------------------------------------------------
643    void TextureUnitState::setEnvironmentMap(bool enable, EnvMapType envMapType)
644    {
645        if (enable)
646        {
647            TextureEffect eff;
648            eff.type = ET_ENVIRONMENT_MAP;
649
650            eff.subtype = envMapType;
651            addEffect(eff);
652        }
653        else
654        {
655            removeEffect(ET_ENVIRONMENT_MAP);
656        }
657    }
658    //-----------------------------------------------------------------------
659    void TextureUnitState::removeEffect(TextureEffectType type)
660    {
661        // Get range of items matching this effect
662        std::pair< EffectMap::iterator, EffectMap::iterator > remPair =
663            mEffects.equal_range( type );
664        // Remove controllers
665        for (EffectMap::iterator i = remPair.first; i != remPair.second; ++i)
666        {
667            if (i->second.controller)
668            {
669                ControllerManager::getSingleton().destroyController(i->second.controller);
670            }
671        }
672        // Erase         
673        mEffects.erase( remPair.first, remPair.second );
674    }
675    //-----------------------------------------------------------------------
676    void TextureUnitState::setBlank(void)
677    {
678        mIsBlank = true;
679    }
680    //-----------------------------------------------------------------------
681    void TextureUnitState::setTextureTransform(const Matrix4& xform)
682    {
683        mTexModMatrix = xform;
684        mRecalcTexMatrix = false;
685    }
686    //-----------------------------------------------------------------------
687    void TextureUnitState::setTextureScroll(Real u, Real v)
688    {
689        mUMod = u;
690        mVMod = v;
691        mRecalcTexMatrix = true;
692    }
693    //-----------------------------------------------------------------------
694    void TextureUnitState::setTextureScale(Real uScale, Real vScale)
695    {
696        mUScale = uScale;
697        mVScale = vScale;
698        mRecalcTexMatrix = true;
699    }
700    //-----------------------------------------------------------------------
701    void TextureUnitState::setTextureRotate(const Radian& angle)
702    {
703        mRotate = angle;
704        mRecalcTexMatrix = true;
705    }
706    //-----------------------------------------------------------------------
707    const Matrix4& TextureUnitState::getTextureTransform() const
708    {
709        if (mRecalcTexMatrix)
710            recalcTextureMatrix();
711        return mTexModMatrix;
712
713    }
714    //-----------------------------------------------------------------------
715    void TextureUnitState::recalcTextureMatrix() const
716    {
717        // Assumption: 2D texture coords
718        Matrix4 xform;
719
720        xform = Matrix4::IDENTITY;
721        if (mUScale != 1 || mVScale != 1)
722        {
723            // Offset to center of texture
724            xform[0][0] = 1/mUScale;
725            xform[1][1] = 1/mVScale;
726            // Skip matrix concat since first matrix update
727            xform[0][3] = (-0.5 * xform[0][0]) + 0.5;
728            xform[1][3] = (-0.5 * xform[1][1]) + 0.5;
729        }
730
731        if (mUMod || mVMod)
732        {
733            Matrix4 xlate = Matrix4::IDENTITY;
734
735            xlate[0][3] = mUMod;
736            xlate[1][3] = mVMod;
737
738            xform = xlate * xform;
739        }
740
741        if (mRotate != Radian(0))
742        {
743            Matrix4 rot = Matrix4::IDENTITY;
744            Radian theta ( mRotate );
745            Real cosTheta = Math::Cos(theta);
746            Real sinTheta = Math::Sin(theta);
747
748            rot[0][0] = cosTheta;
749            rot[0][1] = -sinTheta;
750            rot[1][0] = sinTheta;
751            rot[1][1] = cosTheta;
752            // Offset center of rotation to center of texture
753            rot[0][3] = 0.5 + ( (-0.5 * cosTheta) - (-0.5 * sinTheta) );
754            rot[1][3] = 0.5 + ( (-0.5 * sinTheta) + (-0.5 * cosTheta) );
755
756            xform = rot * xform;
757        }
758
759        mTexModMatrix = xform;
760
761    }
762    //-----------------------------------------------------------------------
763    void TextureUnitState::setTextureUScroll(Real value)
764    {
765        mUMod = value;
766        mRecalcTexMatrix = true;
767    }
768    //-----------------------------------------------------------------------
769    void TextureUnitState::setTextureVScroll(Real value)
770    {
771        mVMod = value;
772        mRecalcTexMatrix = true;
773    }
774    //-----------------------------------------------------------------------
775    void TextureUnitState::setTextureUScale(Real value)
776    {
777        mUScale = value;
778        mRecalcTexMatrix = true;
779    }
780    //-----------------------------------------------------------------------
781    void TextureUnitState::setTextureVScale(Real value)
782    {
783        mVScale = value;
784        mRecalcTexMatrix = true;
785    }
786    //-----------------------------------------------------------------------
787    void TextureUnitState::setScrollAnimation(Real uSpeed, Real vSpeed)
788    {
789        // Remove existing effects
790        removeEffect(ET_UVSCROLL);
791        removeEffect(ET_USCROLL);
792        removeEffect(ET_VSCROLL);
793        // Create new effect
794        TextureEffect eff;
795        if(uSpeed == vSpeed)
796        {
797                eff.type = ET_UVSCROLL;
798                eff.arg1 = uSpeed;
799                addEffect(eff);
800        }
801        else
802        {
803                if(uSpeed)
804                {
805                        eff.type = ET_USCROLL;
806        eff.arg1 = uSpeed;
807        addEffect(eff);
808    }
809                if(vSpeed)
810                {
811                        eff.type = ET_VSCROLL;
812                        eff.arg1 = vSpeed;
813                        addEffect(eff);
814                }
815        }
816    }
817    //-----------------------------------------------------------------------
818    void TextureUnitState::setRotateAnimation(Real speed)
819    {
820        // Remove existing effect
821        removeEffect(ET_ROTATE);
822        // Create new effect
823        TextureEffect eff;
824        eff.type = ET_ROTATE;
825        eff.arg1 = speed;
826        addEffect(eff);
827    }
828    //-----------------------------------------------------------------------
829    void TextureUnitState::setTransformAnimation(TextureTransformType ttype,
830        WaveformType waveType, Real base, Real frequency, Real phase, Real amplitude)
831    {
832        // Remove existing effect
833        removeEffect(ET_TRANSFORM);
834        // Create new effect
835        TextureEffect eff;
836        eff.type = ET_TRANSFORM;
837        eff.subtype = ttype;
838        eff.waveType = waveType;
839        eff.base = base;
840        eff.frequency = frequency;
841        eff.phase = phase;
842        eff.amplitude = amplitude;
843        addEffect(eff);
844    }
845    //-----------------------------------------------------------------------
846    void TextureUnitState::_load(void)
847    {
848        // Unload first
849        _unload();
850
851        // Load textures
852        for (unsigned int i = 0; i < mFrames.size(); ++i)
853        {
854            if (mFrames[i] != "")
855            {
856                // Ensure texture is loaded, specified number of mipmaps and priority
857                try {
858
859                    TextureManager::getSingleton().load(mFrames[i],
860                                                mParent->getResourceGroup(), mTextureType, mTextureSrcMipmaps, 1.0f, mIsAlpha);
861                    mIsBlank = false;
862                }
863                catch (Exception &e) {
864                    String msg;
865                    msg = msg + "Error loading texture " + mFrames[i]  +
866                                        ". Texture layer will be blank. Loading the texture failed with the following exception: "+e.getFullDescription();
867                    LogManager::getSingleton().logMessage(msg);
868                    mIsBlank = true;
869                }
870            }
871        }
872        // Animation controller
873        if (mAnimDuration != 0)
874        {
875            createAnimController();
876        }
877        // Effect controllers
878        for (EffectMap::iterator it = mEffects.begin(); it != mEffects.end(); ++it)
879        {
880            createEffectController(it->second);
881        }
882
883    }
884    //-----------------------------------------------------------------------
885    void TextureUnitState::createAnimController(void)
886    {
887        assert(mAnimController == 0);
888        mAnimController = ControllerManager::getSingleton().createTextureAnimator(this, mAnimDuration);
889
890    }
891    //-----------------------------------------------------------------------
892    void TextureUnitState::createEffectController(TextureEffect& effect)
893    {
894        assert(effect.controller == 0);
895        ControllerManager& cMgr = ControllerManager::getSingleton();
896        switch (effect.type)
897        {
898        case ET_UVSCROLL:
899            effect.controller = cMgr.createTextureUVScroller(this, effect.arg1);
900            break;
901        case ET_USCROLL:
902            effect.controller = cMgr.createTextureUScroller(this, effect.arg1);
903            break;
904        case ET_VSCROLL:
905            effect.controller = cMgr.createTextureVScroller(this, effect.arg1);
906            break;
907        case ET_ROTATE:
908            effect.controller = cMgr.createTextureRotater(this, effect.arg1);
909            break;
910        case ET_TRANSFORM:
911            effect.controller = cMgr.createTextureWaveTransformer(this, (TextureUnitState::TextureTransformType)effect.subtype, effect.waveType, effect.base,
912                effect.frequency, effect.phase, effect.amplitude);
913            break;
914        case ET_ENVIRONMENT_MAP:
915            break;
916        default:
917            break;
918        }
919    }
920    //-----------------------------------------------------------------------
921        Real TextureUnitState::getTextureUScroll(void) const
922    {
923                return mUMod;
924    }
925
926        //-----------------------------------------------------------------------
927        Real TextureUnitState::getTextureVScroll(void) const
928    {
929                return mVMod;
930    }
931
932        //-----------------------------------------------------------------------
933        Real TextureUnitState::getTextureUScale(void) const
934    {
935                return mUScale;
936    }
937
938        //-----------------------------------------------------------------------
939        Real TextureUnitState::getTextureVScale(void) const
940    {
941                return mVScale;
942    }
943
944        //-----------------------------------------------------------------------
945        const Radian& TextureUnitState::getTextureRotate(void) const
946    {
947                return mRotate;
948    }
949       
950        //-----------------------------------------------------------------------
951        Real TextureUnitState::getAnimationDuration(void) const
952        {
953                return mAnimDuration;
954        }
955
956        //-----------------------------------------------------------------------
957        const TextureUnitState::EffectMap& TextureUnitState::getEffects(void) const
958        {
959                return mEffects;
960        }
961
962        //-----------------------------------------------------------------------
963        void TextureUnitState::setTextureFiltering(TextureFilterOptions filterType)
964        {
965        switch (filterType)
966        {
967        case TFO_NONE:
968            setTextureFiltering(FO_POINT, FO_POINT, FO_NONE);
969            break;
970        case TFO_BILINEAR:
971            setTextureFiltering(FO_LINEAR, FO_LINEAR, FO_POINT);
972            break;
973        case TFO_TRILINEAR:
974            setTextureFiltering(FO_LINEAR, FO_LINEAR, FO_LINEAR);
975            break;
976        case TFO_ANISOTROPIC:
977            setTextureFiltering(FO_ANISOTROPIC, FO_ANISOTROPIC, FO_LINEAR);
978            break;
979        }
980        mIsDefaultFiltering = false;
981        }
982        //-----------------------------------------------------------------------
983    void TextureUnitState::setTextureFiltering(FilterType ft, FilterOptions fo)
984    {
985        switch (ft)
986        {
987        case FT_MIN:
988            mMinFilter = fo;
989            break;
990        case FT_MAG:
991            mMagFilter = fo;
992            break;
993        case FT_MIP:
994            mMipFilter = fo;
995            break;
996        }
997        mIsDefaultFiltering = false;
998    }
999        //-----------------------------------------------------------------------
1000    void TextureUnitState::setTextureFiltering(FilterOptions minFilter,
1001        FilterOptions magFilter, FilterOptions mipFilter)
1002    {
1003        mMinFilter = minFilter;
1004        mMagFilter = magFilter;
1005        mMipFilter = mipFilter;
1006        mIsDefaultFiltering = false;
1007    }
1008        //-----------------------------------------------------------------------
1009        FilterOptions TextureUnitState::getTextureFiltering(FilterType ft) const
1010        {
1011
1012        switch (ft)
1013        {
1014        case FT_MIN:
1015            return mIsDefaultFiltering ?
1016                MaterialManager::getSingleton().getDefaultTextureFiltering(FT_MIN) : mMinFilter;
1017        case FT_MAG:
1018            return mIsDefaultFiltering ?
1019                MaterialManager::getSingleton().getDefaultTextureFiltering(FT_MAG) : mMagFilter;
1020        case FT_MIP:
1021            return mIsDefaultFiltering ?
1022                MaterialManager::getSingleton().getDefaultTextureFiltering(FT_MIP) : mMipFilter;
1023        }
1024                // to keep compiler happy
1025                return mMinFilter;
1026        }
1027
1028        //-----------------------------------------------------------------------
1029        void TextureUnitState::setTextureAnisotropy(unsigned int maxAniso)
1030        {
1031                mMaxAniso = maxAniso;
1032        mIsDefaultAniso = false;
1033        }
1034        //-----------------------------------------------------------------------
1035        unsigned int TextureUnitState::getTextureAnisotropy() const
1036        {
1037        return mIsDefaultAniso? MaterialManager::getSingleton().getDefaultAnisotropy() : mMaxAniso;
1038        }
1039
1040        //-----------------------------------------------------------------------
1041    void TextureUnitState::_unload(void)
1042    {
1043        // Destroy animation controller
1044        if (mAnimController)
1045        {
1046            ControllerManager::getSingleton().destroyController(mAnimController);
1047            mAnimController = 0;
1048        }
1049
1050        // Destroy effect controllers
1051        for (EffectMap::iterator i = mEffects.begin(); i != mEffects.end(); ++i)
1052        {
1053            if (i->second.controller)
1054            {
1055                ControllerManager::getSingleton().destroyController(i->second.controller);
1056                i->second.controller = 0;
1057            }
1058        }
1059
1060        // Don't unload textures. may be used elsewhere
1061    }
1062    //-----------------------------------------------------------------------------
1063    bool TextureUnitState::isLoaded(void)
1064    {
1065        return mParent->isLoaded();
1066    }
1067    //-----------------------------------------------------------------------
1068    void TextureUnitState::_notifyNeedsRecompile(void)
1069    {
1070        mParent->_notifyNeedsRecompile();
1071    }
1072    //-----------------------------------------------------------------------
1073    bool TextureUnitState::hasViewRelativeTextureCoordinateGeneration(void)
1074    {
1075        // Right now this only returns true for reflection maps
1076
1077        EffectMap::const_iterator i, iend;
1078        iend = mEffects.end();
1079       
1080        for(i = mEffects.find(ET_ENVIRONMENT_MAP); i != iend; ++i)
1081        {
1082            if (i->second.subtype == ENV_REFLECTION)
1083                return true;
1084        }
1085        for(i = mEffects.find(ET_PROJECTIVE_TEXTURE); i != iend; ++i)
1086        {
1087            return true;
1088        }
1089
1090        return false;
1091    }
1092    //-----------------------------------------------------------------------
1093    void TextureUnitState::setProjectiveTexturing(bool enable,
1094        const Frustum* projectionSettings)
1095    {
1096        if (enable)
1097        {
1098            TextureEffect eff;
1099            eff.type = ET_PROJECTIVE_TEXTURE;
1100            eff.frustum = projectionSettings;
1101            addEffect(eff);
1102        }
1103        else
1104        {
1105            removeEffect(ET_PROJECTIVE_TEXTURE);
1106        }
1107
1108    }
1109    //-----------------------------------------------------------------------
1110    void TextureUnitState::setName(const String& name)
1111    {
1112        mName = name;
1113                if (mTextureNameAlias.empty())
1114                        mTextureNameAlias = mName;
1115    }
1116
1117    //-----------------------------------------------------------------------
1118    void TextureUnitState::setTextureNameAlias(const String& name)
1119    {
1120        mTextureNameAlias = name;
1121    }
1122
1123    //-----------------------------------------------------------------------
1124    bool TextureUnitState::applyTextureAliases(const AliasTextureNamePairList& aliasList, const bool apply)
1125    {
1126        bool testResult = false;
1127        // if TUS has an alias see if its in the alias container
1128        if (!mTextureNameAlias.empty())
1129        {
1130            AliasTextureNamePairList::const_iterator aliasEntry =
1131                aliasList.find(mTextureNameAlias);
1132
1133            if (aliasEntry != aliasList.end())
1134            {
1135                // match was found so change the texture name in mFrames
1136                testResult = true;
1137
1138                if (apply)
1139                {
1140                    // currently assumes animated frames are sequentially numbered
1141                    // cubic, 1d, 2d, and 3d textures are determined from current TUS state
1142                   
1143                    // if cubic or 3D
1144                    if (mCubic)
1145                    {
1146                        setCubicTextureName(aliasEntry->second, mTextureType == TEX_TYPE_CUBE_MAP);
1147                    }
1148                    else
1149                    {
1150                        // if more than one frame then assume animated frames
1151                        if (mFrames.size() > 1)
1152                            setAnimatedTextureName(aliasEntry->second, mFrames.size(), mAnimDuration);
1153                        else
1154                            setTextureName(aliasEntry->second, mTextureType, mTextureSrcMipmaps);
1155                    }
1156                }
1157               
1158            }
1159        }
1160
1161        return testResult;
1162    }
1163        //-----------------------------------------------------------------------------
1164        void TextureUnitState::_notifyParent(Pass* parent)
1165        {
1166                mParent = parent;
1167        }
1168
1169}
Note: See TracBrowser for help on using the repository browser.