MyGUI 3.0.1
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     {
00040         mGenTexName = utility::toString( this, "_Canvas" );
00041     }
00042 
00043     void Canvas::_initialise(WidgetStyle _style, const IntCoord& _coord, Align _align, ResourceSkin* _info, Widget* _parent, ICroppedRectangle * _croppedParent, IWidgetCreator * _creator, const std::string& _name)
00044     {
00045         Base::_initialise(_style, _coord, _align, _info, _parent, _croppedParent, _creator, _name);
00046     }
00047 
00048     Canvas::~Canvas()
00049     {
00050         _destroyTexture( false );
00051     }
00052 
00053     void Canvas::createTexture( TextureResizeMode _resizeMode, TextureUsage _usage, PixelFormat _format )
00054     {
00055         createTexture( getSize(), _resizeMode, _usage, _format );
00056     }
00057 
00058     void Canvas::createTexture( const IntSize& _size, TextureResizeMode _resizeMode, TextureUsage _usage, PixelFormat _format )
00059     {
00060         if ( _size.width <= 0 || _size.height <= 0 )
00061         {
00062             MYGUI_ASSERT( 0, "At least one of dimensions isn't positive!" );
00063             return;
00064         }
00065 
00066         createTexture( _size.width, _size.height, _resizeMode, _usage, _format );
00067     }
00068 
00069     void Canvas::createExactTexture( int _width, int _height, TextureUsage _usage, PixelFormat _format )
00070     {
00071         MYGUI_ASSERT( _width >= 0 && _height >= 0, "negative size" );
00072 
00073         destroyTexture();
00074 
00075         mTexture = RenderManager::getInstance().createTexture(mGenTexName);
00076         mTexture->setInvalidateListener(this);
00077         mTexture->createManual( _width, _height, _usage, _format );
00078 
00079         mTexManaged = true;
00080 
00081         _setTextureName( mGenTexName );
00082         correctUV();
00083         requestUpdateCanvas( this, Event( true, true, false ) );
00084     }
00085 
00086     void Canvas::resize( const IntSize& _size )
00087     {
00088         if ( _size.width <= 0 || _size.height <= 0 || ! mTexManaged )
00089             return;
00090 
00091         mReqTexSize = _size;
00092 
00093         frameAdvise( true );
00094     }
00095 
00096     void Canvas::createTexture( int _width, int _height, TextureResizeMode _resizeMode, TextureUsage _usage, PixelFormat _format )
00097     {
00098         MYGUI_ASSERT( _width >= 0 && _height >= 0, "negative size" );
00099 
00100         if ( mReqTexSize.empty() )
00101             mReqTexSize = IntSize( _width, _height );
00102 
00103         mTexResizeMode = _resizeMode;
00104 
00105         bool create = checkCreate( _width, _height );
00106 
00107         _width = Bitwise::firstPO2From(_width);
00108         _height = Bitwise::firstPO2From(_height);
00109 
00110         if ( create )
00111             createExactTexture( _width, _height, _usage, _format );
00112     }
00113 
00114     void Canvas::setSize( const IntSize& _size )
00115     {
00116         resize( _size );
00117 
00118         Base::setSize( _size );
00119     }
00120 
00121     void Canvas::setCoord( const IntCoord& _coord )
00122     {
00123         resize( _coord.size() );
00124 
00125         Base::setCoord( _coord );
00126     }
00127 
00128     void Canvas::updateTexture()
00129     {
00130         requestUpdateCanvas( this, Event( false, false, true ) );
00131     }
00132 
00133     bool Canvas::checkCreate( int _width, int _height ) const
00134     {
00135         if ( mTexture == nullptr )
00136             return true;
00137 
00138         if ( mTexture->getWidth() >= _width && mTexture->getHeight() >= _height )
00139             return false;
00140 
00141         return true;
00142     }
00143 
00144     void Canvas::validate( int& _width, int& _height, TextureUsage& _usage, PixelFormat& _format ) const
00145     {
00146         _width = Bitwise::firstPO2From(_width);
00147         _height = Bitwise::firstPO2From(_height);
00148 
00149         // restore usage and format
00150         if ( mTexture != nullptr )
00151         {
00152             if ( _usage == getDefaultTextureUsage() )
00153                 _usage = mTexture->getUsage();
00154 
00155             if ( _format == getDefaultTextureFormat() )
00156                 _format = mTexture->getFormat();
00157         }
00158     }
00159 
00160     void Canvas::destroyTexture()
00161     {
00162         _destroyTexture( true );
00163     }
00164 
00165     void Canvas::_destroyTexture( bool _sendEvent )
00166     {
00167         if ( mTexture != nullptr )
00168         {
00169             if ( _sendEvent )
00170             {
00171                 eventPreTextureChanges( this );
00172             }
00173 
00174             RenderManager::getInstance().destroyTexture( mTexture );
00175             mTexture = nullptr;
00176         }
00177 
00178     }
00179 
00180     void Canvas::correctUV()
00181     {
00182         if ( mTexResizeMode == TRM_PT_VIEW_REQUESTED )
00183         {
00184             _setUVSet( FloatRect( 0, 0,
00185                 (float) mReqTexSize.width  / (float) getTextureRealWidth(),
00186                 (float) mReqTexSize.height / (float) getTextureRealHeight()
00187                 ) );
00188         }
00189 
00190         if ( mTexResizeMode == TRM_PT_CONST_SIZE || mTexResizeMode == TRM_PT_VIEW_ALL )
00191         {
00192             _setUVSet( FloatRect( 0, 0, 1, 1 ) );
00193         }
00194     }
00195 
00196     void* Canvas::lock(TextureUsage _usage)
00197     {
00198         void* data = mTexture->lock(_usage);
00199 
00200         mTexData = reinterpret_cast< uint8* >( data );
00201 
00202         return data;
00203     }
00204 
00205     void Canvas::unlock()
00206     {
00207         mTexture->unlock();
00208     }
00209 
00210     void Canvas::baseChangeWidgetSkin( ResourceSkin* _info )
00211     {
00212         Base::baseChangeWidgetSkin( _info );
00213     }
00214 
00215     void Canvas::initialiseWidgetSkin( ResourceSkin* _info )
00216     {
00217     }
00218 
00219     void Canvas::shutdownWidgetSkin()
00220     {
00221     }
00222 
00223     bool Canvas::isTextureSrcSize() const
00224     {
00225         return getTextureSrcSize() == getTextureRealSize();
00226     }
00227 
00228     void Canvas::frameAdvise( bool _advise )
00229     {
00230         if ( _advise )
00231         {
00232             if ( ! mFrameAdvise )
00233             {
00234                 MyGUI::Gui::getInstance().eventFrameStart += MyGUI::newDelegate( this, &Canvas::frameEntered );
00235                 mFrameAdvise = true;
00236             }
00237         }
00238         else
00239         {
00240             if ( mFrameAdvise )
00241             {
00242                 MyGUI::Gui::getInstance().eventFrameStart -= MyGUI::newDelegate( this, &Canvas::frameEntered );
00243                 mFrameAdvise = false;
00244             }
00245         }
00246     }
00247 
00248     void Canvas::frameEntered( float _time )
00249     {
00250         int width = mReqTexSize.width;
00251         int height = mReqTexSize.height;
00252         TextureUsage usage = getDefaultTextureUsage();
00253         PixelFormat format = getDefaultTextureFormat();
00254 
00255         validate( width, height, usage, format );
00256 
00257         bool create = checkCreate( width, height );
00258 
00259         if ( mTexResizeMode == TRM_PT_CONST_SIZE )
00260             create = false;
00261 
00262         if ( create )
00263         {
00264             createExactTexture( width, height, usage, format );
00265             correctUV();
00266         }
00267         else // I thought order is important
00268         {
00269             correctUV();
00270             requestUpdateCanvas( this, Event( false, true, false ) );
00271         }
00272 
00273         frameAdvise( false );
00274     }
00275 
00276     void Canvas::textureInvalidate(ITexture* _texture)
00277     {
00278         updateTexture();
00279     }
00280 
00281 } // namespace MyGUI