Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/OgreMain/src/OgreTextureUnitState.cpp @ 1

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