Cinder

  • Main Page
  • Related Pages
  • Namespaces
  • Classes
  • Files
  • 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 
00048 class Texture {
00049   public:
00050     struct Format;
00051     
00053     Texture() {}
00055     Texture( int aWidth, int aHeight, Format format = Format() );
00057     Texture( const unsigned char *data, int dataFormat, int aWidth, int aHeight, Format format = Format() );
00059     Texture( const Surface8u &surface, Format format = Format() );
00061     Texture( const Surface32f &surface, Format format = Format() );
00063     Texture( const Channel8u &channel, Format format = Format() );
00065     Texture( const Channel32f &channel, Format format = Format() );
00067     Texture( ImageSourceRef imageSource, Format format = Format() );
00069     Texture( GLenum aTarget, GLuint aTextureID, int aWidth, int aHeight, bool aDoNotDispose );
00070 
00072     void            setDoNotDispose( bool aDoNotDispose = true ) { mObj->mDoNotDispose = aDoNotDispose; }
00074     void            setDeallocator( void(*aDeallocatorFunc)( void * ), void *aDeallocatorRefcon );
00076     void            setWrap( GLenum wrapS, GLenum wrapT ) { setWrapS( wrapS ); setWrapT( wrapT ); }
00079     void            setWrapS( GLenum wrapS );
00082     void            setWrapT( GLenum wrapT );
00085     void            setMinFilter( GLenum minFilter );   
00088     void            setMagFilter( GLenum magFilter );
00089 
00091     void            setCleanTexCoords( float maxU, float maxV );
00092 
00094     void            update( const Surface &surface );
00097     void            update( const Surface &surface, const Area &area );
00099     void            update( const Channel8u &surface, const Area &area );
00100     
00102     GLint           getWidth() const;
00104     GLint           getHeight() const;
00106     Vec2i           getSize() const { return Vec2i( getWidth(), getHeight() ); }    
00108     float           getAspectRatio() const { return getWidth() / (float)getHeight(); }
00110     Area            getBounds() const { return Area( 0, 0, getWidth(), getHeight() ); }
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          getTextureId() 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 ), mInternalFormat( -1 ), mTextureID( 0 ), mFlipped( false ), mDeallocatorFunc( 0 ) {}
00232         Obj( int aWidth, int aHeight ) : mInternalFormat( -1 ), mWidth( aWidth ), mHeight( aHeight ), mFlipped( false ), mTextureID( 0 ), mDeallocatorFunc( 0 )  {}
00233         ~Obj();
00234 
00235         mutable GLint   mWidth, mHeight;
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     shared_ptr<Obj>     mObj;
00246 
00247   public:
00249 
00250     typedef shared_ptr<Obj> Texture::*unspecified_bool_type;
00251     operator unspecified_bool_type() { 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     shared_ptr<Obj>     mObj;
00279 
00280   public:
00282 
00283     TextureCache( const TextureCache &other ) { mObj = other.mObj; }    
00284     TextureCache& operator=( const TextureCache &other ) { mObj = other.mObj; return *this; }
00285     bool operator==( const TextureCache &other ) { return mObj == other.mObj; }
00286     typedef shared_ptr<Obj> TextureCache::*unspecified_bool_type;
00287     operator unspecified_bool_type() { return ( mObj.get() == 0 ) ? 0 : &TextureCache::mObj; }
00288     void reset() { mObj.reset(); }
00290 };
00291 
00292 
00293 class SurfaceConstraintsGLTexture : public SurfaceConstraints {
00294  public:
00295     virtual SurfaceChannelOrder getChannelOrder( bool alpha ) const { return ( alpha ) ? SurfaceChannelOrder::BGRA : SurfaceChannelOrder::BGR; }
00296     virtual int32_t             getRowBytes( int requestedWidth, const SurfaceChannelOrder &sco, int elementSize ) const { return requestedWidth * elementSize * sco.getPixelInc(); }
00297 };
00298 
00299 class TextureDataExc : public std::exception {
00300 public: 
00301     TextureDataExc( const std::string &log ) throw();
00302     virtual const char* what() const throw()
00303     {
00304         return mMessage;
00305     }
00306 
00307 private:
00308     char    mMessage[16001];
00309     GLint   mShaderType;
00310 };
00311 
00312 
00313 } } // namespace cinder::gl