Cinder

  • Main Page
  • Related Pages
  • Namespaces
  • Classes
  • Files
  • Examples
  • File List
  • File Members

include/cinder/gl/Texture.h

Go to the documentation of this file.
00001 /*
00002  Copyright (c) 2010, The Barbarian Group
00003  All rights reserved.
00004 
00005  Redistribution and use in source and binary forms, with or without modification, are permitted provided that
00006  the following conditions are met:
00007 
00008     * Redistributions of source code must retain the above copyright notice, this list of conditions and
00009     the following disclaimer.
00010     * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
00011     the following disclaimer in the documentation and/or other materials provided with the distribution.
00012 
00013  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
00014  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
00015  PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
00016  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
00017  TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00018  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00019  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00020  POSSIBILITY OF SUCH DAMAGE.
00021 */
00022 
00023 #pragma once
00024 
00025 #include "cinder/Cinder.h"
00026 #include "cinder/gl/gl.h"
00027 #include "cinder/Surface.h"
00028 #include "cinder/Rect.h"
00029 #include "cinder/Stream.h"
00030 
00031 #include <vector>
00032 #include <utility>
00033 
00034 namespace cinder { namespace gl {
00035 
00038 class Texture {
00039   public:
00040     struct Format;
00041     
00043     Texture() {}
00045     Texture( int aWidth, int aHeight, Format format = Format() );
00047     Texture( const unsigned char *data, int dataFormat, int aWidth, int aHeight, Format format = Format() );
00049     Texture( const Surface8u &surface, Format format = Format() );
00051     Texture( const Surface32f &surface, Format format = Format() );
00053     Texture( const Channel8u &channel, Format format = Format() );
00055     Texture( const Channel32f &channel, Format format = Format() );
00057     Texture( ImageSourceRef imageSource, Format format = Format() );
00059     Texture( GLenum aTarget, GLuint aTextureID, int aWidth, int aHeight, bool aDoNotDispose );
00060 
00062     void            setDoNotDispose( bool aDoNotDispose = true ) { mObj->mDoNotDispose = aDoNotDispose; }
00064     void            setDeallocator( void(*aDeallocatorFunc)( void * ), void *aDeallocatorRefcon );
00066     void            setWrap( GLenum wrapS, GLenum wrapT ) { setWrapS( wrapS ); setWrapT( wrapT ); }
00069     void            setWrapS( GLenum wrapS );
00072     void            setWrapT( GLenum wrapT );
00075     void            setMinFilter( GLenum minFilter );   
00078     void            setMagFilter( GLenum magFilter );
00079 
00081     void            setCleanTexCoords( float maxU, float maxV );
00082 
00084     void            update( const Surface &surface );
00086     void            update( const Surface32f &surface );
00089     void            update( const Surface &surface, const Area &area );
00091     void            update( const Channel32f &channel );
00093     void            update( const Channel8u &channel, const Area &area );
00094     
00096     GLint           getWidth() const;
00098     GLint           getHeight() const;
00100     GLint           getCleanWidth() const;
00102     GLint           getCleanHeight() const;
00104     Vec2i           getSize() const { return Vec2i( getWidth(), getHeight() ); }    
00106     float           getAspectRatio() const { return getWidth() / (float)getHeight(); }
00108     Area            getBounds() const { return Area( 0, 0, getWidth(), getHeight() ); }
00110     Area            getCleanBounds() const { return Area( 0, 0, getCleanWidth(), getCleanHeight() ); }
00112     bool            hasAlpha() const;
00114     float           getLeft() const;
00115     float           getRight() const;   
00116     float           getTop() const;     
00117     float           getBottom() const;  
00119     float           getMaxU() const;
00120     float           getMaxV() const;
00122     Rectf           getAreaTexCoords( const Area &area ) const;
00124     GLint           getInternalFormat() const;
00126     GLuint          getId() const { return mObj->mTextureID; }
00128     GLenum          getTarget() const { return mObj->mTarget; }
00130     bool            isFlipped() const { return mObj->mFlipped; }
00132     void            setFlipped( bool aFlipped = true ) { mObj->mFlipped = aFlipped; }
00133 
00136     void            enableAndBind() const;
00138     void            disable() const;
00140     void            bind( GLuint textureUnit = 0 ) const;
00142     void            unbind( GLuint textureUnit = 0 ) const;
00143 
00145     static Texture  loadDds( IStreamRef ddsStream, Format format );
00146 
00148     static void     SurfaceChannelOrderToDataFormatAndType( const SurfaceChannelOrder &sco, GLint *dataFormat, GLenum *type );
00150     static bool     dataFormatHasAlpha( GLint dataFormat );
00152     static bool     dataFormatHasColor( GLint dataFormat );
00153 
00155     Texture         weakClone() const;
00156 
00157 #if ! defined( CINDER_GLES )    
00158 
00159     operator    ImageSourceRef() const;
00160 #endif
00161     
00162     struct Format {
00164         Format();
00165         
00167         void    setTarget( GLenum target ) { mTarget = target; }
00169 #ifndef CINDER_GLES
00170         void    setTargetRect() { mTarget = GL_TEXTURE_RECTANGLE_ARB; }
00171 #endif      
00172 
00174         void    enableMipmapping( bool enableMipmapping = true ) { mMipmapping = enableMipmapping; }
00175 
00177         void    setInternalFormat( GLint internalFormat ) { mInternalFormat = internalFormat; }
00179         void    setAutoInternalFormat() { mInternalFormat = -1; }       
00180         
00182         void    setWrap( GLenum wrapS, GLenum wrapT ) { setWrapS( wrapS ); setWrapT( wrapT ); }
00185         void    setWrapS( GLenum wrapS ) { mWrapS = wrapS; }
00188         void    setWrapT( GLenum wrapT ) { mWrapT = wrapT; }
00191         void    setMinFilter( GLenum minFilter ) { mMinFilter = minFilter; }
00194         void    setMagFilter( GLenum magFilter ) { mMagFilter = magFilter; }
00195                 
00197         GLenum  getTarget() const { return mTarget; }
00199         bool    hasMipmapping() const { return mMipmapping; }
00200 
00202         GLint   getInternalFormat() const { return mInternalFormat; }
00204         bool    isAutoInternalFormat() const { return mInternalFormat == -1; }
00205         
00207         GLenum  getWrapS() const { return mWrapS; }
00209         GLenum  getWrapT() const { return mWrapT; }
00211         GLenum  getMinFilter() const { return mMinFilter; }
00213         GLenum  getMagFilter() const { return mMagFilter; }
00214         
00215       protected:
00216         GLenum          mTarget;
00217         GLenum          mWrapS, mWrapT;
00218         GLenum          mMinFilter, mMagFilter;
00219         bool            mMipmapping;
00220         GLint           mInternalFormat;
00221         
00222         friend class Texture;
00223     };
00224 
00225  protected:
00226     void    init( const unsigned char *data, int unpackRowLength, GLenum dataFormat, GLenum type, const Format &format );   
00227     void    init( const float *data, GLint dataFormat, const Format &format );
00228     void    init( ImageSourceRef imageSource, const Format &format );   
00229             
00230     struct Obj {
00231         Obj() : mWidth( -1 ), mHeight( -1 ), mCleanWidth( -1 ), mCleanHeight( -1 ), mInternalFormat( -1 ), mTextureID( 0 ), mFlipped( false ), mDeallocatorFunc( 0 ) {}
00232         Obj( int aWidth, int aHeight ) : mInternalFormat( -1 ), mWidth( aWidth ), mHeight( aHeight ), mCleanWidth( aWidth ), mCleanHeight( aHeight ), mFlipped( false ), mTextureID( 0 ), mDeallocatorFunc( 0 )  {}
00233         ~Obj();
00234 
00235         mutable GLint   mWidth, mHeight, mCleanWidth, mCleanHeight;
00236         float           mMaxU, mMaxV;
00237         mutable GLint   mInternalFormat;
00238         GLenum          mTarget;
00239         GLuint          mTextureID;
00240         bool            mDoNotDispose;
00241         bool            mFlipped;   
00242         void            (*mDeallocatorFunc)(void *refcon);
00243         void            *mDeallocatorRefcon;            
00244     };
00245     std::shared_ptr<Obj>        mObj;
00246 
00247   public:
00249 
00250     typedef std::shared_ptr<Obj> Texture::*unspecified_bool_type;
00251     operator unspecified_bool_type() const { return ( mObj.get() == 0 ) ? 0 : &Texture::mObj; }
00252     void reset() { mObj.reset(); }
00254 };
00255 
00256 class TextureCache {
00257  public:
00258     TextureCache() {}
00259     TextureCache( const Surface8u &prototypeSurface, const Texture::Format &format );
00260     
00261     gl::Texture     cache( const Surface8u &data );
00262     
00263   protected:
00264     struct Obj {
00265         Obj( const Surface8u &prototypeSurface, const Texture::Format &format );
00266 
00267         void        markTextureAsFree( int id );
00268 
00269         int             mWidth, mHeight;
00270         Texture::Format mFormat;
00271         
00272         int                                         mNextId;
00273         std::vector<std::pair<int,gl::Texture> >    mTextures;
00274         
00275         static void TextureCacheDeallocator( void *aDeallocatorRefcon );
00276     };
00277  
00278     std::shared_ptr<Obj>        mObj;
00279 
00280   public:
00282 
00283     typedef std::shared_ptr<Obj> TextureCache::*unspecified_bool_type;
00284     operator unspecified_bool_type() const { return ( mObj.get() == 0 ) ? 0 : &TextureCache::mObj; }
00285     void reset() { mObj.reset(); }
00287 };
00288 
00289 
00290 class SurfaceConstraintsGLTexture : public SurfaceConstraints {
00291  public:
00292     virtual SurfaceChannelOrder getChannelOrder( bool alpha ) const { return ( alpha ) ? SurfaceChannelOrder::BGRA : SurfaceChannelOrder::BGR; }
00293     virtual int32_t             getRowBytes( int requestedWidth, const SurfaceChannelOrder &sco, int elementSize ) const { return requestedWidth * elementSize * sco.getPixelInc(); }
00294 };
00295 
00296 class TextureDataExc : public std::exception {
00297 public: 
00298     TextureDataExc( const std::string &log ) throw();
00299     virtual const char* what() const throw()
00300     {
00301         return mMessage;
00302     }
00303 
00304 private:
00305     char    mMessage[16001];
00306     GLint   mShaderType;
00307 };
00308 
00309 
00310 } } // namespace cinder::gl