MyGUI  3.2.1
MyGUI_Canvas.cpp
Go to the documentation of this file.
00001 /*
00002  * This source file is part of MyGUI. For the latest info, see http://mygui.info/
00003  * Distributed under the MIT License
00004  * (See accompanying file COPYING.MIT or copy at http://opensource.org/licenses/MIT)
00005  */
00006 
00007 #include "MyGUI_Precompiled.h"
00008 #include "MyGUI_Canvas.h"
00009 #include "MyGUI_ResourceManager.h"
00010 #include "MyGUI_Gui.h"
00011 #include "MyGUI_RenderManager.h"
00012 #include "MyGUI_Bitwise.h"
00013 
00014 namespace MyGUI
00015 {
00016 
00017     Canvas::Canvas() :
00018         mTexture( nullptr ),
00019         mTexResizeMode( TRM_PT_CONST_SIZE ),
00020         mTexData( 0 ),
00021         mTexManaged( true ),
00022         mFrameAdvise( false ),
00023         mInvalidateData(false)
00024     {
00025         mGenTexName = utility::toString((size_t)this, "_Canvas");
00026     }
00027 
00028     void Canvas::createTexture( TextureResizeMode _resizeMode, TextureUsage _usage, PixelFormat _format )
00029     {
00030         int width = std::max(1, getWidth());
00031         int height = std::max(1, getHeight());
00032 
00033         createTexture( width, height, _resizeMode, _usage, _format );
00034     }
00035 
00036     void Canvas::createTexture( const IntSize& _size, TextureResizeMode _resizeMode, TextureUsage _usage, PixelFormat _format )
00037     {
00038         int width = std::max(1, _size.width);
00039         int height = std::max(1, _size.height);
00040 
00041         createTexture( width, height, _resizeMode, _usage, _format );
00042     }
00043 
00044     void Canvas::createExactTexture( int _width, int _height, TextureUsage _usage, PixelFormat _format )
00045     {
00046         int width = std::max(1, _width);
00047         int height = std::max(1, _height);
00048 
00049         destroyTexture();
00050 
00051         mTexture = RenderManager::getInstance().createTexture(mGenTexName);
00052         mTexture->setInvalidateListener(this);
00053         mTexture->createManual( width, height, _usage, _format );
00054 
00055         mTexManaged = true;
00056 
00057         _setTextureName( mGenTexName );
00058         correctUV();
00059         requestUpdateCanvas( this, Event( true, true, mInvalidateData ) );
00060     }
00061 
00062     void Canvas::resize( const IntSize& _size )
00063     {
00064         if ( _size.width <= 0 || _size.height <= 0 || ! mTexManaged )
00065             return;
00066 
00067         mReqTexSize = _size;
00068 
00069         frameAdvise( true );
00070     }
00071 
00072     void Canvas::createTexture( int _width, int _height, TextureResizeMode _resizeMode, TextureUsage _usage, PixelFormat _format )
00073     {
00074         mTexResizeMode = _resizeMode;
00075 
00076         int width = std::max(1, _width);
00077         int height = std::max(1, _height);
00078 
00079         if (_resizeMode == TRM_PT_CONST_SIZE)
00080         {
00081             mReqTexSize = IntSize(width, height);
00082         }
00083         else
00084         {
00085             mReqTexSize = IntSize(std::max(1, getWidth()), std::max(1, getHeight()));
00086         }
00087 
00088         bool create = checkCreate( width, height );
00089 
00090         width = Bitwise::firstPO2From(width);
00091         height = Bitwise::firstPO2From(height);
00092 
00093         if ( create )
00094             createExactTexture( width, height, _usage, _format );
00095     }
00096 
00097     void Canvas::setSize( const IntSize& _size )
00098     {
00099         resize( _size );
00100 
00101         Base::setSize( _size );
00102     }
00103 
00104     void Canvas::setCoord( const IntCoord& _coord )
00105     {
00106         resize( _coord.size() );
00107 
00108         Base::setCoord( _coord );
00109     }
00110 
00111     void Canvas::updateTexture()
00112     {
00113         mInvalidateData = true;
00114         frameAdvise( true );
00115     }
00116 
00117     bool Canvas::checkCreate( int _width, int _height ) const
00118     {
00119         if ( mTexture == nullptr )
00120             return true;
00121 
00122         if ( mTexture->getWidth() >= _width && mTexture->getHeight() >= _height )
00123             return false;
00124 
00125         return true;
00126     }
00127 
00128     void Canvas::validate( int& _width, int& _height, TextureUsage& _usage, PixelFormat& _format ) const
00129     {
00130         _width = std::max(1, _width);
00131         _height = std::max(1, _height);
00132 
00133         _width = Bitwise::firstPO2From(_width);
00134         _height = Bitwise::firstPO2From(_height);
00135 
00136         // restore usage and format
00137         if ( mTexture != nullptr )
00138         {
00139             if ( _usage == getDefaultTextureUsage() )
00140                 _usage = mTexture->getUsage();
00141 
00142             if ( _format == getDefaultTextureFormat() )
00143                 _format = mTexture->getFormat();
00144         }
00145     }
00146 
00147     void Canvas::destroyTexture()
00148     {
00149         _destroyTexture( true );
00150     }
00151 
00152     void Canvas::shutdownOverride()
00153     {
00154         _destroyTexture(false);
00155         frameAdvise(false);
00156     }
00157 
00158     void Canvas::initialiseOverride()
00159     {
00160     }
00161 
00162     void Canvas::_destroyTexture( bool _sendEvent )
00163     {
00164         if ( mTexture != nullptr )
00165         {
00166             if ( _sendEvent )
00167             {
00168                 eventPreTextureChanges( this );
00169             }
00170 
00171             RenderManager::getInstance().destroyTexture( mTexture );
00172             mTexture = nullptr;
00173         }
00174 
00175     }
00176 
00177     void Canvas::correctUV()
00178     {
00179         if ( mTexResizeMode == TRM_PT_VIEW_REQUESTED )
00180         {
00181             _setUVSet(
00182                 FloatRect(
00183                     0,
00184                     0,
00185                     (float) mReqTexSize.width  / (float) getTextureRealWidth(),
00186                     (float) mReqTexSize.height / (float) getTextureRealHeight()));
00187         }
00188 
00189         if ( mTexResizeMode == TRM_PT_CONST_SIZE || mTexResizeMode == TRM_PT_VIEW_ALL )
00190         {
00191             _setUVSet( FloatRect( 0, 0, 1, 1 ) );
00192         }
00193     }
00194 
00195     void* Canvas::lock(TextureUsage _usage)
00196     {
00197         void* data = mTexture->lock(_usage);
00198 
00199         mTexData = reinterpret_cast< uint8* >( data );
00200 
00201         return data;
00202     }
00203 
00204     void Canvas::unlock()
00205     {
00206         mTexture->unlock();
00207     }
00208 
00209     bool Canvas::isTextureSrcSize() const
00210     {
00211         return getTextureSrcSize() == getTextureRealSize();
00212     }
00213 
00214     void Canvas::frameAdvise( bool _advise )
00215     {
00216         if ( _advise )
00217         {
00218             if ( ! mFrameAdvise )
00219             {
00220                 MyGUI::Gui::getInstance().eventFrameStart += MyGUI::newDelegate( this, &Canvas::frameEntered );
00221                 mFrameAdvise = true;
00222             }
00223         }
00224         else
00225         {
00226             if ( mFrameAdvise )
00227             {
00228                 MyGUI::Gui::getInstance().eventFrameStart -= MyGUI::newDelegate( this, &Canvas::frameEntered );
00229                 mFrameAdvise = false;
00230             }
00231         }
00232     }
00233 
00234     void Canvas::frameEntered( float _time )
00235     {
00236         int width = mReqTexSize.width;
00237         int height = mReqTexSize.height;
00238         TextureUsage usage = getDefaultTextureUsage();
00239         PixelFormat format = getDefaultTextureFormat();
00240 
00241         validate( width, height, usage, format );
00242 
00243         bool create = checkCreate( width, height );
00244 
00245         if ( mTexResizeMode == TRM_PT_CONST_SIZE )
00246             create = false;
00247 
00248         if ( create )
00249         {
00250             createExactTexture( width, height, usage, format );
00251             correctUV();
00252         }
00253         else // I thought order is important
00254         {
00255             correctUV();
00256             requestUpdateCanvas( this, Event( false, true, mInvalidateData ) );
00257         }
00258 
00259         mInvalidateData = false;
00260         frameAdvise( false );
00261     }
00262 
00263     void Canvas::textureInvalidate(ITexture* _texture)
00264     {
00265         updateTexture();
00266     }
00267 
00268     void Canvas::_setUVSet(const FloatRect& _rect)
00269     {
00270         if (nullptr != getSubWidgetMain())
00271             getSubWidgetMain()->_setUVSet(_rect);
00272     }
00273 
00274     bool Canvas::isLocked() const
00275     {
00276         return mTexture->isLocked();
00277     }
00278 
00279     int Canvas::getTextureRealWidth() const
00280     {
00281         return (int) mTexture->getWidth();
00282     }
00283 
00284     int Canvas::getTextureRealHeight() const
00285     {
00286         return (int) mTexture->getHeight();
00287     }
00288 
00289     IntSize Canvas::getTextureRealSize() const
00290     {
00291         return IntSize( getTextureRealWidth(), getTextureRealHeight() );
00292     }
00293 
00294     int Canvas::getTextureSrcWidth() const
00295     {
00296         return mReqTexSize.width;
00297     }
00298 
00299     int Canvas::getTextureSrcHeight() const
00300     {
00301         return mReqTexSize.height;
00302     }
00303 
00304     IntSize Canvas::getTextureSrcSize() const
00305     {
00306         return mReqTexSize;
00307     }
00308 
00309     PixelFormat Canvas::getTextureFormat() const
00310     {
00311         return mTexture->getFormat();
00312     }
00313 
00314     const std::string& Canvas::getTextureName() const
00315     {
00316         return mTexture->getName();
00317     }
00318 
00319     void Canvas::setSize(int _width, int _height)
00320     {
00321         setSize(IntSize(_width, _height));
00322     }
00323 
00324     void Canvas::setCoord(int _left, int _top, int _width, int _height)
00325     {
00326         setCoord(IntCoord(_left, _top, _width, _height));
00327     }
00328 
00329     Canvas::TextureResizeMode Canvas::getResizeMode() const
00330     {
00331         return mTexResizeMode;
00332     }
00333 
00334     void Canvas::setResizeMode(TextureResizeMode _value)
00335     {
00336         mTexResizeMode = _value;
00337     }
00338 
00339     bool Canvas::isTextureCreated() const
00340     {
00341         return mTexture != nullptr;
00342     }
00343 
00344     bool Canvas::isTextureManaged() const
00345     {
00346         return mTexManaged;
00347     }
00348 
00349     ITexture* Canvas::getTexture() const
00350     {
00351         return mTexture;
00352     }
00353 
00354     void Canvas::setTextureManaged(bool _value)
00355     {
00356         mTexManaged = _value;
00357     }
00358 
00359     TextureUsage Canvas::getDefaultTextureUsage()
00360     {
00361         return TextureUsage::Stream | TextureUsage::Write;
00362     }
00363 
00364     PixelFormat Canvas::getDefaultTextureFormat()
00365     {
00366         return PixelFormat::R8G8B8A8;
00367     }
00368 
00369 } // namespace MyGUI