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     GLint           getCleanWidth() const;
00108     GLint           getCleanHeight() const;
00110     Vec2i           getSize() const { return Vec2i( getWidth(), getHeight() ); }    
00112     float           getAspectRatio() const { return getWidth() / (float)getHeight(); }
00114     Area            getBounds() const { return Area( 0, 0, getWidth(), getHeight() ); }
00116     Area            getCleanBounds() const { return Area( 0, 0, getCleanWidth(), getCleanHeight() ); }
00118     bool            hasAlpha() const;
00120     float           getLeft() const;
00121     float           getRight() const;   
00122     float           getTop() const;     
00123     float           getBottom() const;  
00125     float           getMaxU() const;
00126     float           getMaxV() const;
00128     Rectf           getAreaTexCoords( const Area &area ) const;
00130     GLint           getInternalFormat() const;
00132     GLuint          getTextureId() const { return mObj->mTextureID; }
00134     GLenum          getTarget() const { return mObj->mTarget; }
00136     bool            isFlipped() const { return mObj->mFlipped; }
00138     void            setFlipped( bool aFlipped = true ) { mObj->mFlipped = aFlipped; }
00139 
00142     void            enableAndBind() const;
00144     void            disable() const;
00146     void            bind( GLuint textureUnit = 0 ) const;
00148     void            unbind( GLuint textureUnit = 0 ) const;
00149 
00151     static Texture  loadDds( IStreamRef ddsStream, Format format );
00152 
00154     static void     SurfaceChannelOrderToDataFormatAndType( const SurfaceChannelOrder &sco, GLint *dataFormat, GLenum *type );
00156     static bool     dataFormatHasAlpha( GLint dataFormat );
00158     static bool     dataFormatHasColor( GLint dataFormat );
00159 
00161     Texture         weakClone() const;
00162 
00163 #if ! defined( CINDER_GLES )    
00164 
00165     operator    ImageSourceRef() const;
00166 #endif
00167     
00168     struct Format {
00170         Format();
00171         
00173         void    setTarget( GLenum target ) { mTarget = target; }
00175 #ifndef CINDER_GLES
00176         void    setTargetRect() { mTarget = GL_TEXTURE_RECTANGLE_ARB; }
00177 #endif      
00178 
00180         void    enableMipmapping( bool enableMipmapping = true ) { mMipmapping = enableMipmapping; }
00181 
00183         void    setInternalFormat( GLint internalFormat ) { mInternalFormat = internalFormat; }
00185         void    setAutoInternalFormat() { mInternalFormat = -1; }       
00186         
00188         void    setWrap( GLenum wrapS, GLenum wrapT ) { setWrapS( wrapS ); setWrapT( wrapT ); }
00191         void    setWrapS( GLenum wrapS ) { mWrapS = wrapS; }
00194         void    setWrapT( GLenum wrapT ) { mWrapT = wrapT; }
00197         void    setMinFilter( GLenum minFilter ) { mMinFilter = minFilter; }
00200         void    setMagFilter( GLenum magFilter ) { mMagFilter = magFilter; }
00201                 
00203         GLenum  getTarget() const { return mTarget; }
00205         bool    hasMipmapping() const { return mMipmapping; }
00206 
00208         GLint   getInternalFormat() const { return mInternalFormat; }
00210         bool    isAutoInternalFormat() const { return mInternalFormat == -1; }
00211         
00213         GLenum  getWrapS() const { return mWrapS; }
00215         GLenum  getWrapT() const { return mWrapT; }
00217         GLenum  getMinFilter() const { return mMinFilter; }
00219         GLenum  getMagFilter() const { return mMagFilter; }
00220         
00221       protected:
00222         GLenum          mTarget;
00223         GLenum          mWrapS, mWrapT;
00224         GLenum          mMinFilter, mMagFilter;
00225         bool            mMipmapping;
00226         GLint           mInternalFormat;
00227         
00228         friend class Texture;
00229     };
00230 
00231  protected:
00232     void    init( const unsigned char *data, int unpackRowLength, GLenum dataFormat, GLenum type, const Format &format );   
00233     void    init( const float *data, GLint dataFormat, const Format &format );
00234     void    init( ImageSourceRef imageSource, const Format &format );   
00235             
00236     struct Obj {
00237         Obj() : mWidth( -1 ), mHeight( -1 ), mCleanWidth( -1 ), mCleanHeight( -1 ), mInternalFormat( -1 ), mTextureID( 0 ), mFlipped( false ), mDeallocatorFunc( 0 ) {}
00238         Obj( int aWidth, int aHeight ) : mInternalFormat( -1 ), mWidth( aWidth ), mHeight( aHeight ), mCleanWidth( aWidth ), mCleanHeight( aHeight ), mFlipped( false ), mTextureID( 0 ), mDeallocatorFunc( 0 )  {}
00239         ~Obj();
00240 
00241         mutable GLint   mWidth, mHeight, mCleanWidth, mCleanHeight;
00242         float           mMaxU, mMaxV;
00243         mutable GLint   mInternalFormat;
00244         GLenum          mTarget;
00245         GLuint          mTextureID;
00246         bool            mDoNotDispose;
00247         bool            mFlipped;   
00248         void            (*mDeallocatorFunc)(void *refcon);
00249         void            *mDeallocatorRefcon;            
00250     };
00251     shared_ptr<Obj>     mObj;
00252 
00253   public:
00255 
00256     typedef shared_ptr<Obj> Texture::*unspecified_bool_type;
00257     operator unspecified_bool_type() { return ( mObj.get() == 0 ) ? 0 : &Texture::mObj; }
00258     void reset() { mObj.reset(); }
00260 };
00261 
00262 class TextureCache {
00263  public:
00264     TextureCache() {}
00265     TextureCache( const Surface8u &prototypeSurface, const Texture::Format &format );
00266     
00267     gl::Texture     cache( const Surface8u &data );
00268     
00269   protected:
00270     struct Obj {
00271         Obj( const Surface8u &prototypeSurface, const Texture::Format &format );
00272 
00273         void        markTextureAsFree( int id );
00274 
00275         int             mWidth, mHeight;
00276         Texture::Format mFormat;
00277         
00278         int                                         mNextId;
00279         std::vector<std::pair<int,gl::Texture> >    mTextures;
00280         
00281         static void TextureCacheDeallocator( void *aDeallocatorRefcon );
00282     };
00283  
00284     shared_ptr<Obj>     mObj;
00285 
00286   public:
00288 
00289     TextureCache( const TextureCache &other ) { mObj = other.mObj; }    
00290     TextureCache& operator=( const TextureCache &other ) { mObj = other.mObj; return *this; }
00291     bool operator==( const TextureCache &other ) { return mObj == other.mObj; }
00292     typedef shared_ptr<Obj> TextureCache::*unspecified_bool_type;
00293     operator unspecified_bool_type() { return ( mObj.get() == 0 ) ? 0 : &TextureCache::mObj; }
00294     void reset() { mObj.reset(); }
00296 };
00297 
00298 
00299 class SurfaceConstraintsGLTexture : public SurfaceConstraints {
00300  public:
00301     virtual SurfaceChannelOrder getChannelOrder( bool alpha ) const { return ( alpha ) ? SurfaceChannelOrder::BGRA : SurfaceChannelOrder::BGR; }
00302     virtual int32_t             getRowBytes( int requestedWidth, const SurfaceChannelOrder &sco, int elementSize ) const { return requestedWidth * elementSize * sco.getPixelInc(); }
00303 };
00304 
00305 class TextureDataExc : public std::exception {
00306 public: 
00307     TextureDataExc( const std::string &log ) throw();
00308     virtual const char* what() const throw()
00309     {
00310         return mMessage;
00311     }
00312 
00313 private:
00314     char    mMessage[16001];
00315     GLint   mShaderType;
00316 };
00317 
00318 
00319 } } // namespace cinder::gl