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

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