00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
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 } }