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