MyGUI  3.0.3
MyGUI_Canvas.cpp
Go to the documentation of this file.
00001 
00007 /*
00008     This file is part of MyGUI.
00009 
00010     MyGUI is free software: you can redistribute it and/or modify
00011     it under the terms of the GNU Lesser General Public License as published by
00012     the Free Software Foundation, either version 3 of the License, or
00013     (at your option) any later version.
00014 
00015     MyGUI is distributed in the hope that it will be useful,
00016     but WITHOUT ANY WARRANTY; without even the implied warranty of
00017     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018     GNU Lesser General Public License for more details.
00019 
00020     You should have received a copy of the GNU Lesser General Public License
00021     along with MyGUI.  If not, see <http://www.gnu.org/licenses/>.
00022 */
00023 #include "MyGUI_Precompiled.h"
00024 #include "MyGUI_Canvas.h"
00025 #include "MyGUI_ResourceManager.h"
00026 #include "MyGUI_Gui.h"
00027 #include "MyGUI_RenderManager.h"
00028 #include "MyGUI_Bitwise.h"
00029 
00030 namespace MyGUI
00031 {
00032 
00033     Canvas::Canvas() :
00034         mTexture( nullptr ),
00035         mTexResizeMode( TRM_PT_CONST_SIZE ),
00036         mTexData( 0 ),
00037         mTexManaged( true ),
00038         mFrameAdvise( false ),
00039         mInvalidateData(false)
00040     {
00041         mGenTexName = utility::toString( this, "_Canvas" );
00042     }
00043 
00044     void Canvas::_initialise(WidgetStyle _style, const IntCoord& _coord, Align _align, ResourceSkin* _info, Widget* _parent, ICroppedRectangle * _croppedParent, IWidgetCreator * _creator, const std::string& _name)
00045     {
00046         Base::_initialise(_style, _coord, _align, _info, _parent, _croppedParent, _creator, _name);
00047     }
00048 
00049     Canvas::~Canvas()
00050     {
00051         _destroyTexture( false );
00052     }
00053 
00054     void Canvas::createTexture( TextureResizeMode _resizeMode, TextureUsage _usage, PixelFormat _format )
00055     {
00056         int width = std::max(1, getWidth());
00057         int height = std::max(1, getHeight());
00058 
00059         createTexture( width, height, _resizeMode, _usage, _format );
00060     }
00061 
00062     void Canvas::createTexture( const IntSize& _size, TextureResizeMode _resizeMode, TextureUsage _usage, PixelFormat _format )
00063     {
00064         int width = std::max(1, _size.width);
00065         int height = std::max(1, _size.height);
00066 
00067         createTexture( width, height, _resizeMode, _usage, _format );
00068     }
00069 
00070     void Canvas::createExactTexture( int _width, int _height, TextureUsage _usage, PixelFormat _format )
00071     {
00072         int width = std::max(1, _width);
00073         int height = std::max(1, _height);
00074 
00075         destroyTexture();
00076 
00077         mTexture = RenderManager::getInstance().createTexture(mGenTexName);
00078         mTexture->setInvalidateListener(this);
00079         mTexture->createManual( width, height, _usage, _format );
00080 
00081         mTexManaged = true;
00082 
00083         _setTextureName( mGenTexName );
00084         correctUV();
00085         requestUpdateCanvas( this, Event( true, true, mInvalidateData ) );
00086     }
00087 
00088     void Canvas::resize( const IntSize& _size )
00089     {
00090         if ( _size.width <= 0 || _size.height <= 0 || ! mTexManaged )
00091             return;
00092 
00093         mReqTexSize = _size;
00094 
00095         frameAdvise( true );
00096     }
00097 
00098     void Canvas::createTexture( int _width, int _height, TextureResizeMode _resizeMode, TextureUsage _usage, PixelFormat _format )
00099     {
00100         int width = std::max(1, _width);
00101         int height = std::max(1, _height);
00102 
00103         if ( mReqTexSize.empty() )
00104             mReqTexSize = IntSize( width, height );
00105 
00106         mTexResizeMode = _resizeMode;
00107 
00108         bool create = checkCreate( width, height );
00109 
00110         width = Bitwise::firstPO2From(width);
00111         height = Bitwise::firstPO2From(height);
00112 
00113         if ( create )
00114             createExactTexture( width, height, _usage, _format );
00115     }
00116 
00117     void Canvas::setSize( const IntSize& _size )
00118     {
00119         resize( _size );
00120 
00121         Base::setSize( _size );
00122     }
00123 
00124     void Canvas::setCoord( const IntCoord& _coord )
00125     {
00126         resize( _coord.size() );
00127 
00128         Base::setCoord( _coord );
00129     }
00130 
00131     void Canvas::updateTexture()
00132     {
00133         mInvalidateData = true;
00134         frameAdvise( true );
00135     }
00136 
00137     bool Canvas::checkCreate( int _width, int _height ) const
00138     {
00139         if ( mTexture == nullptr )
00140             return true;
00141 
00142         if ( mTexture->getWidth() >= _width && mTexture->getHeight() >= _height )
00143             return false;
00144 
00145         return true;
00146     }
00147 
00148     void Canvas::validate( int& _width, int& _height, TextureUsage& _usage, PixelFormat& _format ) const
00149     {
00150         _width = std::max(1, _width);
00151         _height = std::max(1, _height);
00152 
00153         _width = Bitwise::firstPO2From(_width);
00154         _height = Bitwise::firstPO2From(_height);
00155 
00156         // restore usage and format
00157         if ( mTexture != nullptr )
00158         {
00159             if ( _usage == getDefaultTextureUsage() )
00160                 _usage = mTexture->getUsage();
00161 
00162             if ( _format == getDefaultTextureFormat() )
00163                 _format = mTexture->getFormat();
00164         }
00165     }
00166 
00167     void Canvas::destroyTexture()
00168     {
00169         _destroyTexture( true );
00170     }
00171 
00172     void Canvas::_destroyTexture( bool _sendEvent )
00173     {
00174         if ( mTexture != nullptr )
00175         {
00176             if ( _sendEvent )
00177             {
00178                 eventPreTextureChanges( this );
00179             }
00180 
00181             RenderManager::getInstance().destroyTexture( mTexture );
00182             mTexture = nullptr;
00183         }
00184 
00185     }
00186 
00187     void Canvas::correctUV()
00188     {
00189         if ( mTexResizeMode == TRM_PT_VIEW_REQUESTED )
00190         {
00191             _setUVSet( FloatRect( 0, 0,
00192                 (float) mReqTexSize.width  / (float) getTextureRealWidth(),
00193                 (float) mReqTexSize.height / (float) getTextureRealHeight()
00194                 ) );
00195         }
00196 
00197         if ( mTexResizeMode == TRM_PT_CONST_SIZE || mTexResizeMode == TRM_PT_VIEW_ALL )
00198         {
00199             _setUVSet( FloatRect( 0, 0, 1, 1 ) );
00200         }
00201     }
00202 
00203     void* Canvas::lock(TextureUsage _usage)
00204     {
00205         void* data = mTexture->lock(_usage);
00206 
00207         mTexData = reinterpret_cast< uint8* >( data );
00208 
00209         return data;
00210     }
00211 
00212     void Canvas::unlock()
00213     {
00214         mTexture->unlock();
00215     }
00216 
00217     void Canvas::baseChangeWidgetSkin( ResourceSkin* _info )
00218     {
00219         Base::baseChangeWidgetSkin( _info );
00220     }
00221 
00222     void Canvas::initialiseWidgetSkin( ResourceSkin* _info )
00223     {
00224     }
00225 
00226     void Canvas::shutdownWidgetSkin()
00227     {
00228     }
00229 
00230     bool Canvas::isTextureSrcSize() const
00231     {
00232         return getTextureSrcSize() == getTextureRealSize();
00233     }
00234 
00235     void Canvas::frameAdvise( bool _advise )
00236     {
00237         if ( _advise )
00238         {
00239             if ( ! mFrameAdvise )
00240             {
00241                 MyGUI::Gui::getInstance().eventFrameStart += MyGUI::newDelegate( this, &Canvas::frameEntered );
00242                 mFrameAdvise = true;
00243             }
00244         }
00245         else
00246         {
00247             if ( mFrameAdvise )
00248             {
00249                 MyGUI::Gui::getInstance().eventFrameStart -= MyGUI::newDelegate( this, &Canvas::frameEntered );
00250                 mFrameAdvise = false;
00251             }
00252         }
00253     }
00254 
00255     void Canvas::frameEntered( float _time )
00256     {
00257         int width = mReqTexSize.width;
00258         int height = mReqTexSize.height;
00259         TextureUsage usage = getDefaultTextureUsage();
00260         PixelFormat format = getDefaultTextureFormat();
00261 
00262         validate( width, height, usage, format );
00263 
00264         bool create = checkCreate( width, height );
00265 
00266         if ( mTexResizeMode == TRM_PT_CONST_SIZE )
00267             create = false;
00268 
00269         if ( create )
00270         {
00271             createExactTexture( width, height, usage, format );
00272             correctUV();
00273         }
00274         else // I thought order is important
00275         {
00276             correctUV();
00277             requestUpdateCanvas( this, Event( false, true, mInvalidateData ) );
00278         }
00279 
00280         mInvalidateData = false;
00281         frameAdvise( false );
00282     }
00283 
00284     void Canvas::textureInvalidate(ITexture* _texture)
00285     {
00286         updateTexture();
00287     }
00288 
00289 } // namespace MyGUI