source: OGRE/trunk/ogrenew/OgreMain/src/OgreTextureUnitState.cpp @ 692

Revision 692, 38.6 KB checked in by mattausch, 18 years ago (diff)

adding ogre 1.2 and dependencies

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