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 );
00087     void            update( const Surface &surface, const Area &area );
00089     void            update( const Channel8u &surface, const Area &area );
00090     
00092     GLint           getWidth() const;
00094     GLint           getHeight() const;
00096     GLint           getCleanWidth() const;
00098     GLint           getCleanHeight() const;
00100     Vec2i           getSize() const { return Vec2i( getWidth(), getHeight() ); }    
00102     float           getAspectRatio() const { return getWidth() / (float)getHeight(); }
00104     Area            getBounds() const { return Area( 0, 0, getWidth(), getHeight() ); }
00106     Area            getCleanBounds() const { return Area( 0, 0, getCleanWidth(), getCleanHeight() ); }
00108     bool            hasAlpha() const;
00110     float           getLeft() const;
00111     float           getRight() const;   
00112     float           getTop() const;     
00113     float           getBottom() const;  
00115     float           getMaxU() const;
00116     float           getMaxV() const;
00118     Rectf           getAreaTexCoords( const Area &area ) const;
00120     GLint           getInternalFormat() const;
00122     GLuint          getId() const { return mObj->mTextureID; }
00124     GLenum          getTarget() const { return mObj->mTarget; }
00126     bool            isFlipped() const { return mObj->mFlipped; }
00128     void            setFlipped( bool aFlipped = true ) { mObj->mFlipped = aFlipped; }
00129 
00132     void            enableAndBind() const;
00134     void            disable() const;
00136     void            bind( GLuint textureUnit = 0 ) const;
00138     void            unbind( GLuint textureUnit = 0 ) const;
00139 
00141     static Texture  loadDds( IStreamRef ddsStream, Format format );
00142 
00144     static void     SurfaceChannelOrderToDataFormatAndType( const SurfaceChannelOrder &sco, GLint *dataFormat, GLenum *type );
00146     static bool     dataFormatHasAlpha( GLint dataFormat );
00148     static bool     dataFormatHasColor( GLint dataFormat );
00149 
00151     Texture         weakClone() const;
00152 
00153 #if ! defined( CINDER_GLES )    
00154 
00155     operator    ImageSourceRef() const;
00156 #endif
00157     
00158     struct Format {
00160         Format();
00161         
00163         void    setTarget( GLenum target ) { mTarget = target; }
00165 #ifndef CINDER_GLES
00166         void    setTargetRect() { mTarget = GL_TEXTURE_RECTANGLE_ARB; }
00167 #endif      
00168 
00170         void    enableMipmapping( bool enableMipmapping = true ) { mMipmapping = enableMipmapping; }
00171 
00173         void    setInternalFormat( GLint internalFormat ) { mInternalFormat = internalFormat; }
00175         void    setAutoInternalFormat() { mInternalFormat = -1; }       
00176         
00178         void    setWrap( GLenum wrapS, GLenum wrapT ) { setWrapS( wrapS ); setWrapT( wrapT ); }
00181         void    setWrapS( GLenum wrapS ) { mWrapS = wrapS; }
00184         void    setWrapT( GLenum wrapT ) { mWrapT = wrapT; }
00187         void    setMinFilter( GLenum minFilter ) { mMinFilter = minFilter; }
00190         void    setMagFilter( GLenum magFilter ) { mMagFilter = magFilter; }
00191                 
00193         GLenum  getTarget() const { return mTarget; }
00195         bool    hasMipmapping() const { return mMipmapping; }
00196 
00198         GLint   getInternalFormat() const { return mInternalFormat; }
00200         bool    isAutoInternalFormat() const { return mInternalFormat == -1; }
00201         
00203         GLenum  getWrapS() const { return mWrapS; }
00205         GLenum  getWrapT() const { return mWrapT; }
00207         GLenum  getMinFilter() const { return mMinFilter; }
00209         GLenum  getMagFilter() const { return mMagFilter; }
00210         
00211       protected:
00212         GLenum          mTarget;
00213         GLenum          mWrapS, mWrapT;
00214         GLenum          mMinFilter, mMagFilter;
00215         bool            mMipmapping;
00216         GLint           mInternalFormat;
00217         
00218         friend class Texture;
00219     };
00220 
00221  protected:
00222     void    init( const unsigned char *data, int unpackRowLength, GLenum dataFormat, GLenum type, const Format &format );   
00223     void    init( const float *data, GLint dataFormat, const Format &format );
00224     void    init( ImageSourceRef imageSource, const Format &format );   
00225             
00226     struct Obj {
00227         Obj() : mWidth( -1 ), mHeight( -1 ), mCleanWidth( -1 ), mCleanHeight( -1 ), mInternalFormat( -1 ), mTextureID( 0 ), mFlipped( false ), mDeallocatorFunc( 0 ) {}
00228         Obj( int aWidth, int aHeight ) : mInternalFormat( -1 ), mWidth( aWidth ), mHeight( aHeight ), mCleanWidth( aWidth ), mCleanHeight( aHeight ), mFlipped( false ), mTextureID( 0 ), mDeallocatorFunc( 0 )  {}
00229         ~Obj();
00230 
00231         mutable GLint   mWidth, mHeight, mCleanWidth, mCleanHeight;
00232         float           mMaxU, mMaxV;
00233         mutable GLint   mInternalFormat;
00234         GLenum          mTarget;
00235         GLuint          mTextureID;
00236         bool            mDoNotDispose;
00237         bool            mFlipped;   
00238         void            (*mDeallocatorFunc)(void *refcon);
00239         void            *mDeallocatorRefcon;            
00240     };
00241     std::shared_ptr<Obj>        mObj;
00242 
00243   public:
00245 
00246     typedef std::shared_ptr<Obj> Texture::*unspecified_bool_type;
00247     operator unspecified_bool_type() const { return ( mObj.get() == 0 ) ? 0 : &Texture::mObj; }
00248     void reset() { mObj.reset(); }
00250 };
00251 
00252 class TextureCache {
00253  public:
00254     TextureCache() {}
00255     TextureCache( const Surface8u &prototypeSurface, const Texture::Format &format );
00256     
00257     gl::Texture     cache( const Surface8u &data );
00258     
00259   protected:
00260     struct Obj {
00261         Obj( const Surface8u &prototypeSurface, const Texture::Format &format );
00262 
00263         void        markTextureAsFree( int id );
00264 
00265         int             mWidth, mHeight;
00266         Texture::Format mFormat;
00267         
00268         int                                         mNextId;
00269         std::vector<std::pair<int,gl::Texture> >    mTextures;
00270         
00271         static void TextureCacheDeallocator( void *aDeallocatorRefcon );
00272     };
00273  
00274     std::shared_ptr<Obj>        mObj;
00275 
00276   public:
00278 
00279     typedef std::shared_ptr<Obj> TextureCache::*unspecified_bool_type;
00280     operator unspecified_bool_type() const { return ( mObj.get() == 0 ) ? 0 : &TextureCache::mObj; }
00281     void reset() { mObj.reset(); }
00283 };
00284 
00285 
00286 class SurfaceConstraintsGLTexture : public SurfaceConstraints {
00287  public:
00288     virtual SurfaceChannelOrder getChannelOrder( bool alpha ) const { return ( alpha ) ? SurfaceChannelOrder::BGRA : SurfaceChannelOrder::BGR; }
00289     virtual int32_t             getRowBytes( int requestedWidth, const SurfaceChannelOrder &sco, int elementSize ) const { return requestedWidth * elementSize * sco.getPixelInc(); }
00290 };
00291 
00292 class TextureDataExc : public std::exception {
00293 public: 
00294     TextureDataExc( const std::string &log ) throw();
00295     virtual const char* what() const throw()
00296     {
00297         return mMessage;
00298     }
00299 
00300 private:
00301     char    mMessage[16001];
00302     GLint   mShaderType;
00303 };
00304 
00305 
00306 } } // namespace cinder::gl