#include "preferences.h"
-enum ETexturesMode {
- eTextures_NEAREST = 0,
- eTextures_NEAREST_MIPMAP_NEAREST = 1,
- eTextures_NEAREST_MIPMAP_LINEAR = 2,
- eTextures_LINEAR = 3,
- eTextures_LINEAR_MIPMAP_NEAREST = 4,
- eTextures_LINEAR_MIPMAP_LINEAR = 5,
- eTextures_MAX_ANISOTROPY = 6,
-};
-enum TextureCompressionFormat {
- TEXTURECOMPRESSION_NONE = 0,
- TEXTURECOMPRESSION_RGBA = 1,
- TEXTURECOMPRESSION_RGBA_S3TC_DXT1 = 2,
- TEXTURECOMPRESSION_RGBA_S3TC_DXT3 = 3,
- TEXTURECOMPRESSION_RGBA_S3TC_DXT5 = 4,
+enum ETexturesMode
+{
+ eTextures_NEAREST = 0,
+ eTextures_NEAREST_MIPMAP_NEAREST = 1,
+ eTextures_NEAREST_MIPMAP_LINEAR = 2,
+ eTextures_LINEAR = 3,
+ eTextures_LINEAR_MIPMAP_NEAREST = 4,
+ eTextures_LINEAR_MIPMAP_LINEAR = 5,
+ eTextures_MAX_ANISOTROPY = 6,
};
-struct texture_globals_t {
- // RIANT
- // texture compression format
- TextureCompressionFormat m_nTextureCompressionFormat;
-
- float fGamma;
-
- bool bTextureCompressionSupported; // is texture compression supported by hardware?
- GLint texture_components;
-
- // temporary values that should be initialised only once at run-time
- bool m_bOpenGLCompressionSupported;
- bool m_bS3CompressionSupported;
-
- texture_globals_t(GLint components) :
- m_nTextureCompressionFormat(TEXTURECOMPRESSION_NONE),
- fGamma(1.0f),
- bTextureCompressionSupported(false),
- texture_components(components),
- m_bOpenGLCompressionSupported(false),
- m_bS3CompressionSupported(false)
- {
- }
+enum TextureCompressionFormat
+{
+ TEXTURECOMPRESSION_NONE = 0,
+ TEXTURECOMPRESSION_RGBA = 1,
+ TEXTURECOMPRESSION_RGBA_S3TC_DXT1 = 2,
+ TEXTURECOMPRESSION_RGBA_S3TC_DXT3 = 3,
+ TEXTURECOMPRESSION_RGBA_S3TC_DXT5 = 4,
};
-texture_globals_t g_texture_globals(GL_RGBA);
-
-void SetTexParameters(ETexturesMode mode)
+struct texture_globals_t
{
- float maxAniso = QGL_maxTextureAnisotropy();
- if (maxAniso > 1) {
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.0f);
- } else if (mode == eTextures_MAX_ANISOTROPY) {
- mode = eTextures_LINEAR_MIPMAP_LINEAR;
- }
+ // RIANT
+ // texture compression format
+ TextureCompressionFormat m_nTextureCompressionFormat;
+
+ float fGamma;
+
+ bool bTextureCompressionSupported; // is texture compression supported by hardware?
+ GLint texture_components;
+
+ // temporary values that should be initialised only once at run-time
+ bool m_bOpenGLCompressionSupported;
+ bool m_bS3CompressionSupported;
+
+ texture_globals_t( GLint components ) :
+ m_nTextureCompressionFormat( TEXTURECOMPRESSION_NONE ),
+ fGamma( 1.0f ),
+ bTextureCompressionSupported( false ),
+ texture_components( components ),
+ m_bOpenGLCompressionSupported( false ),
+ m_bS3CompressionSupported( false ){
+ }
+};
- switch (mode) {
- case eTextures_NEAREST:
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- break;
- case eTextures_NEAREST_MIPMAP_NEAREST:
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- break;
- case eTextures_NEAREST_MIPMAP_LINEAR:
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- break;
- case eTextures_LINEAR:
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- break;
- case eTextures_LINEAR_MIPMAP_NEAREST:
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- break;
- case eTextures_LINEAR_MIPMAP_LINEAR:
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- break;
- case eTextures_MAX_ANISOTROPY:
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, maxAniso);
- break;
- default:
- globalOutputStream() << "invalid texture mode\n";
- }
+texture_globals_t g_texture_globals( GL_RGBA );
+
+void SetTexParameters( ETexturesMode mode ){
+ float maxAniso = QGL_maxTextureAnisotropy();
+ if ( maxAniso > 1 ) {
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.0f );
+ }
+ else
+ if ( mode == eTextures_MAX_ANISOTROPY ) {
+ mode = eTextures_LINEAR_MIPMAP_LINEAR;
+ }
+
+ switch ( mode )
+ {
+ case eTextures_NEAREST:
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
+ break;
+ case eTextures_NEAREST_MIPMAP_NEAREST:
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
+ break;
+ case eTextures_NEAREST_MIPMAP_LINEAR:
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
+ break;
+ case eTextures_LINEAR:
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
+ break;
+ case eTextures_LINEAR_MIPMAP_NEAREST:
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
+ break;
+ case eTextures_LINEAR_MIPMAP_LINEAR:
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
+ break;
+ case eTextures_MAX_ANISOTROPY:
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, maxAniso );
+ break;
+ default:
+ globalOutputStream() << "invalid texture mode\n";
+ }
}
ETexturesMode g_texture_mode = eTextures_LINEAR_MIPMAP_LINEAR;
-byte g_gammatable[256];
-void ResampleGamma(float fGamma)
-{
- int i, inf;
- if (fGamma == 1.0) {
- for (i = 0; i < 256; i++) {
- g_gammatable[i] = i;
- }
- } else {
- for (i = 0; i < 256; i++) {
- inf = (int) (255 * pow(static_cast<double>((i + 0.5) / 255.5 ), static_cast<double>( fGamma )) + 0.5);
- if (inf < 0) {
- inf = 0;
- }
- if (inf > 255) {
- inf = 255;
- }
- g_gammatable[i] = inf;
- }
- }
+
+byte g_gammatable[256];
+void ResampleGamma( float fGamma ){
+ int i,inf;
+ if ( fGamma == 1.0 ) {
+ for ( i = 0; i < 256; i++ )
+ g_gammatable[i] = i;
+ }
+ else
+ {
+ for ( i = 0; i < 256; i++ )
+ {
+ inf = (int)( 255 * pow( static_cast<double>( ( i + 0.5 ) / 255.5 ), static_cast<double>( fGamma ) ) + 0.5 );
+ if ( inf < 0 ) {
+ inf = 0;
+ }
+ if ( inf > 255 ) {
+ inf = 255;
+ }
+ g_gammatable[i] = inf;
+ }
+ }
}
-inline const int &min_int(const int &left, const int &right)
-{
- return std::min(left, right);
+inline const int& min_int( const int& left, const int& right ){
+ return std::min( left, right );
}
int max_tex_size = 0;
const int max_texture_quality = 3;
-LatchedValue<int> g_Textures_textureQuality(3, "Texture Quality");
+LatchedValue<int> g_Textures_textureQuality( 3, "Texture Quality" );
/// \brief This function does the actual processing of raw RGBA data into a GL texture.
/// It will also resample to power-of-two dimensions, generate the mipmaps and adjust gamma.
-void LoadTextureRGBA(qtexture_t *q, unsigned char *pPixels, int nWidth, int nHeight)
-{
- static float fGamma = -1;
- float total[3];
- byte *outpixels = 0;
- int nCount = nWidth * nHeight;
-
- if (fGamma != g_texture_globals.fGamma) {
- fGamma = g_texture_globals.fGamma;
- ResampleGamma(fGamma);
- }
-
- q->width = nWidth;
- q->height = nHeight;
-
- total[0] = total[1] = total[2] = 0.0f;
-
- // resample texture gamma according to user settings
- for (int i = 0; i < (nCount * 4); i += 4) {
- for (int j = 0; j < 3; j++) {
- total[j] += (pPixels + i)[j];
- byte b = (pPixels + i)[j];
- (pPixels + i)[j] = g_gammatable[b];
- }
- }
-
- q->color[0] = total[0] / (nCount * 255);
- q->color[1] = total[1] / (nCount * 255);
- q->color[2] = total[2] / (nCount * 255);
-
- glGenTextures(1, &q->texture_number);
-
- glBindTexture(GL_TEXTURE_2D, q->texture_number);
-
- SetTexParameters(g_texture_mode);
-
- int gl_width = 1;
- while (gl_width < nWidth) {
- gl_width <<= 1;
- }
-
- int gl_height = 1;
- while (gl_height < nHeight) {
- gl_height <<= 1;
- }
-
- bool resampled = false;
- if (!(gl_width == nWidth && gl_height == nHeight)) {
- resampled = true;
- outpixels = (byte *) malloc(gl_width * gl_height * 4);
- R_ResampleTexture(pPixels, nWidth, nHeight, outpixels, gl_width, gl_height, 4);
- } else {
- outpixels = pPixels;
- }
-
- int quality_reduction = max_texture_quality - g_Textures_textureQuality.m_value;
- int target_width = min_int(gl_width >> quality_reduction, max_tex_size);
- int target_height = min_int(gl_height >> quality_reduction, max_tex_size);
-
- while (gl_width > target_width || gl_height > target_height) {
- GL_MipReduce(outpixels, outpixels, gl_width, gl_height, target_width, target_height);
-
- if (gl_width > target_width) {
- gl_width >>= 1;
- }
- if (gl_height > target_height) {
- gl_height >>= 1;
- }
- }
-
- int mip = 0;
- glTexImage2D(GL_TEXTURE_2D, mip++, g_texture_globals.texture_components, gl_width, gl_height, 0, GL_RGBA,
- GL_UNSIGNED_BYTE, outpixels);
- while (gl_width > 1 || gl_height > 1) {
- GL_MipReduce(outpixels, outpixels, gl_width, gl_height, 1, 1);
-
- if (gl_width > 1) {
- gl_width >>= 1;
- }
- if (gl_height > 1) {
- gl_height >>= 1;
- }
-
- glTexImage2D(GL_TEXTURE_2D, mip++, g_texture_globals.texture_components, gl_width, gl_height, 0, GL_RGBA,
- GL_UNSIGNED_BYTE, outpixels);
- }
-
- glBindTexture(GL_TEXTURE_2D, 0);
- if (resampled) {
- free(outpixels);
- }
+void LoadTextureRGBA( qtexture_t* q, unsigned char* pPixels, int nWidth, int nHeight ){
+ static float fGamma = -1;
+ float total[3];
+ byte *outpixels = 0;
+ int nCount = nWidth * nHeight;
+
+ if ( fGamma != g_texture_globals.fGamma ) {
+ fGamma = g_texture_globals.fGamma;
+ ResampleGamma( fGamma );
+ }
+
+ q->width = nWidth;
+ q->height = nHeight;
+
+ total[0] = total[1] = total[2] = 0.0f;
+
+ // resample texture gamma according to user settings
+ for ( int i = 0; i < ( nCount * 4 ); i += 4 )
+ {
+ for ( int j = 0; j < 3; j++ )
+ {
+ total[j] += ( pPixels + i )[j];
+ byte b = ( pPixels + i )[j];
+ ( pPixels + i )[j] = g_gammatable[b];
+ }
+ }
+
+ q->color[0] = total[0] / ( nCount * 255 );
+ q->color[1] = total[1] / ( nCount * 255 );
+ q->color[2] = total[2] / ( nCount * 255 );
+
+ glGenTextures( 1, &q->texture_number );
+
+ glBindTexture( GL_TEXTURE_2D, q->texture_number );
+
+ SetTexParameters( g_texture_mode );
+
+ int gl_width = 1;
+ while ( gl_width < nWidth )
+ gl_width <<= 1;
+
+ int gl_height = 1;
+ while ( gl_height < nHeight )
+ gl_height <<= 1;
+
+ bool resampled = false;
+ if ( !( gl_width == nWidth && gl_height == nHeight ) ) {
+ resampled = true;
+ outpixels = (byte *)malloc( gl_width * gl_height * 4 );
+ R_ResampleTexture( pPixels, nWidth, nHeight, outpixels, gl_width, gl_height, 4 );
+ }
+ else
+ {
+ outpixels = pPixels;
+ }
+
+ int quality_reduction = max_texture_quality - g_Textures_textureQuality.m_value;
+ int target_width = min_int( gl_width >> quality_reduction, max_tex_size );
+ int target_height = min_int( gl_height >> quality_reduction, max_tex_size );
+
+ while ( gl_width > target_width || gl_height > target_height )
+ {
+ GL_MipReduce( outpixels, outpixels, gl_width, gl_height, target_width, target_height );
+
+ if ( gl_width > target_width ) {
+ gl_width >>= 1;
+ }
+ if ( gl_height > target_height ) {
+ gl_height >>= 1;
+ }
+ }
+
+ int mip = 0;
+ glTexImage2D( GL_TEXTURE_2D, mip++, g_texture_globals.texture_components, gl_width, gl_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, outpixels );
+ while ( gl_width > 1 || gl_height > 1 )
+ {
+ GL_MipReduce( outpixels, outpixels, gl_width, gl_height, 1, 1 );
+
+ if ( gl_width > 1 ) {
+ gl_width >>= 1;
+ }
+ if ( gl_height > 1 ) {
+ gl_height >>= 1;
+ }
+
+ glTexImage2D( GL_TEXTURE_2D, mip++, g_texture_globals.texture_components, gl_width, gl_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, outpixels );
+ }
+
+ glBindTexture( GL_TEXTURE_2D, 0 );
+ if ( resampled ) {
+ free( outpixels );
+ }
}
#if 0
==============
*/
void Texture_InitPalette( byte *pal ){
- int r,g,b;
- int i;
- int inf;
- byte gammatable[256];
- float gamma;
-
- gamma = g_texture_globals.fGamma;
-
- if ( gamma == 1.0 ) {
- for ( i = 0 ; i < 256 ; i++ )
- gammatable[i] = i;
- }
- else
- {
- for ( i = 0 ; i < 256 ; i++ )
- {
- inf = (int)( 255 * pow( ( i + 0.5 ) / 255.5, gamma ) + 0.5 );
- if ( inf < 0 ) {
- inf = 0;
- }
- if ( inf > 255 ) {
- inf = 255;
- }
- gammatable[i] = inf;
- }
- }
-
- for ( i = 0 ; i < 256 ; i++ )
- {
- r = gammatable[pal[0]];
- g = gammatable[pal[1]];
- b = gammatable[pal[2]];
- pal += 3;
-
- //v = (r<<24) + (g<<16) + (b<<8) + 255;
- //v = BigLong (v);
-
- //tex_palette[i] = v;
- tex_palette[i * 3 + 0] = r;
- tex_palette[i * 3 + 1] = g;
- tex_palette[i * 3 + 2] = b;
- }
+ int r,g,b;
+ int i;
+ int inf;
+ byte gammatable[256];
+ float gamma;
+
+ gamma = g_texture_globals.fGamma;
+
+ if ( gamma == 1.0 ) {
+ for ( i = 0 ; i < 256 ; i++ )
+ gammatable[i] = i;
+ }
+ else
+ {
+ for ( i = 0 ; i < 256 ; i++ )
+ {
+ inf = (int)( 255 * pow( ( i + 0.5 ) / 255.5, gamma ) + 0.5 );
+ if ( inf < 0 ) {
+ inf = 0;
+ }
+ if ( inf > 255 ) {
+ inf = 255;
+ }
+ gammatable[i] = inf;
+ }
+ }
+
+ for ( i = 0 ; i < 256 ; i++ )
+ {
+ r = gammatable[pal[0]];
+ g = gammatable[pal[1]];
+ b = gammatable[pal[2]];
+ pal += 3;
+
+ //v = (r<<24) + (g<<16) + (b<<8) + 255;
+ //v = BigLong (v);
+
+ //tex_palette[i] = v;
+ tex_palette[i * 3 + 0] = r;
+ tex_palette[i * 3 + 1] = g;
+ tex_palette[i * 3 + 2] = b;
+ }
}
#endif
{
public:
TestHashtable(){
- HashTable<CopiedString, CopiedString, HashStringNoCase, StringEqualNoCase> strings;
- strings["Monkey"] = "bleh";
- strings["MonkeY"] = "blah";
+ HashTable<CopiedString, CopiedString, HashStringNoCase, StringEqualNoCase> strings;
+ strings["Monkey"] = "bleh";
+ strings["MonkeY"] = "blah";
}
};
typedef std::pair<LoadImageCallback, CopiedString> TextureKey;
-void qtexture_realise(qtexture_t &texture, const TextureKey &key)
-{
- texture.texture_number = 0;
- if (!string_empty(key.second.c_str())) {
- Image *image = key.first.loadImage(key.second.c_str());
- if (image != 0) {
- LoadTextureRGBA(&texture, image->getRGBAPixels(), image->getWidth(), image->getHeight());
- texture.surfaceFlags = image->getSurfaceFlags();
- texture.contentFlags = image->getContentFlags();
- texture.value = image->getValue();
- image->release();
- globalOutputStream() << "Loaded Texture: \"" << key.second.c_str() << "\"\n";
- GlobalOpenGL_debugAssertNoErrors();
- } else {
- globalErrorStream() << "Texture load failed: \"" << key.second.c_str() << "\"\n";
- }
- }
+void qtexture_realise( qtexture_t& texture, const TextureKey& key ){
+ texture.texture_number = 0;
+ if ( !string_empty( key.second.c_str() ) ) {
+ Image* image = key.first.loadImage( key.second.c_str() );
+ if ( image != 0 ) {
+ LoadTextureRGBA( &texture, image->getRGBAPixels(), image->getWidth(), image->getHeight() );
+ texture.surfaceFlags = image->getSurfaceFlags();
+ texture.contentFlags = image->getContentFlags();
+ texture.value = image->getValue();
+ image->release();
+ globalOutputStream() << "Loaded Texture: \"" << key.second.c_str() << "\"\n";
+ GlobalOpenGL_debugAssertNoErrors();
+ }
+ else
+ {
+ globalErrorStream() << "Texture load failed: \"" << key.second.c_str() << "\"\n";
+ }
+ }
}
-void qtexture_unrealise(qtexture_t &texture)
-{
- if (GlobalOpenGL().contextValid && texture.texture_number != 0) {
- glDeleteTextures(1, &texture.texture_number);
- GlobalOpenGL_debugAssertNoErrors();
- }
+void qtexture_unrealise( qtexture_t& texture ){
+ if ( GlobalOpenGL().contextValid && texture.texture_number != 0 ) {
+ glDeleteTextures( 1, &texture.texture_number );
+ GlobalOpenGL_debugAssertNoErrors();
+ }
}
-class TextureKeyEqualNoCase {
+class TextureKeyEqualNoCase
+{
public:
- bool operator()(const TextureKey &key, const TextureKey &other) const
- {
- return key.first == other.first && string_equal_nocase(key.second.c_str(), other.second.c_str());
- }
+bool operator()( const TextureKey& key, const TextureKey& other ) const {
+ return key.first == other.first && string_equal_nocase( key.second.c_str(), other.second.c_str() );
+}
};
-class TextureKeyHashNoCase {
+class TextureKeyHashNoCase
+{
public:
- typedef hash_t hash_type;
-
- hash_t operator()(const TextureKey &key) const
- {
- return hash_combine(string_hash_nocase(key.second.c_str()), pod_hash(key.first));
- }
+typedef hash_t hash_type;
+hash_t operator()( const TextureKey& key ) const {
+ return hash_combine( string_hash_nocase( key.second.c_str() ), pod_hash( key.first ) );
+}
};
#define DEBUG_TEXTURES 0
-class TexturesMap : public TexturesCache {
- class TextureConstructor {
- TexturesMap *m_cache;
- public:
- explicit TextureConstructor(TexturesMap *cache)
- : m_cache(cache)
- {
- }
-
- qtexture_t *construct(const TextureKey &key)
- {
- qtexture_t *texture = new qtexture_t(key.first, key.second.c_str());
- if (m_cache->realised()) {
- qtexture_realise(*texture, key);
- }
- return texture;
- }
-
- void destroy(qtexture_t *texture)
- {
- if (m_cache->realised()) {
- qtexture_unrealise(*texture);
- }
- delete texture;
- }
- };
-
- typedef HashedCache<TextureKey, qtexture_t, TextureKeyHashNoCase, TextureKeyEqualNoCase, TextureConstructor> qtextures_t;
- qtextures_t m_qtextures;
- TexturesCacheObserver *m_observer;
- std::size_t m_unrealised;
-
+class TexturesMap : public TexturesCache
+{
+class TextureConstructor
+{
+TexturesMap* m_cache;
public:
- virtual ~TexturesMap() = default;
-
- TexturesMap() : m_qtextures(TextureConstructor(this)), m_observer(0), m_unrealised(1)
- {
- }
-
- typedef qtextures_t::iterator iterator;
-
- iterator begin()
- {
- return m_qtextures.begin();
- }
+explicit TextureConstructor( TexturesMap* cache )
+ : m_cache( cache ){
+}
+qtexture_t* construct( const TextureKey& key ){
+ qtexture_t* texture = new qtexture_t( key.first, key.second.c_str() );
+ if ( m_cache->realised() ) {
+ qtexture_realise( *texture, key );
+ }
+ return texture;
+}
+void destroy( qtexture_t* texture ){
+ if ( m_cache->realised() ) {
+ qtexture_unrealise( *texture );
+ }
+ delete texture;
+}
+};
- iterator end()
- {
- return m_qtextures.end();
- }
+typedef HashedCache<TextureKey, qtexture_t, TextureKeyHashNoCase, TextureKeyEqualNoCase, TextureConstructor> qtextures_t;
+qtextures_t m_qtextures;
+TexturesCacheObserver* m_observer;
+std::size_t m_unrealised;
- LoadImageCallback defaultLoader() const
- {
- return LoadImageCallback(0, QERApp_LoadImage);
- }
-
- Image *loadImage(const char *name)
- {
- return defaultLoader().loadImage(name);
- }
+public:
+virtual ~TexturesMap() = default;
+TexturesMap() : m_qtextures( TextureConstructor( this ) ), m_observer( 0 ), m_unrealised( 1 ){
+}
+typedef qtextures_t::iterator iterator;
- qtexture_t *capture(const char *name)
- {
- return capture(defaultLoader(), name);
- }
+iterator begin(){
+ return m_qtextures.begin();
+}
+iterator end(){
+ return m_qtextures.end();
+}
- qtexture_t *capture(const LoadImageCallback &loader, const char *name)
- {
+LoadImageCallback defaultLoader() const {
+ return LoadImageCallback( 0, QERApp_LoadImage );
+}
+Image* loadImage( const char* name ){
+ return defaultLoader().loadImage( name );
+}
+qtexture_t* capture( const char* name ){
+ return capture( defaultLoader(), name );
+}
+qtexture_t* capture( const LoadImageCallback& loader, const char* name ){
#if DEBUG_TEXTURES
- globalOutputStream() << "textures capture: " << makeQuoted( name ) << '\n';
+ globalOutputStream() << "textures capture: " << makeQuoted( name ) << '\n';
#endif
- return m_qtextures.capture(TextureKey(loader, name)).get();
- }
-
- void release(qtexture_t *texture)
- {
+ return m_qtextures.capture( TextureKey( loader, name ) ).get();
+}
+void release( qtexture_t* texture ){
#if DEBUG_TEXTURES
- globalOutputStream() << "textures release: " << makeQuoted( texture->name ) << '\n';
+ globalOutputStream() << "textures release: " << makeQuoted( texture->name ) << '\n';
#endif
- m_qtextures.release(TextureKey(texture->load, texture->name));
- }
-
- void attach(TexturesCacheObserver &observer)
- {
- ASSERT_MESSAGE(m_observer == 0, "TexturesMap::attach: cannot attach observer");
- m_observer = &observer;
- }
-
- void detach(TexturesCacheObserver &observer)
- {
- ASSERT_MESSAGE(m_observer == &observer, "TexturesMap::detach: cannot detach observer");
- m_observer = 0;
- }
-
- void realise()
- {
- if (--m_unrealised == 0) {
- g_texture_globals.bTextureCompressionSupported = false;
-
- if (GlobalOpenGL().ARB_texture_compression()) {
- g_texture_globals.bTextureCompressionSupported = true;
- g_texture_globals.m_bOpenGLCompressionSupported = true;
- }
-
- if (GlobalOpenGL().EXT_texture_compression_s3tc()) {
- g_texture_globals.bTextureCompressionSupported = true;
- g_texture_globals.m_bS3CompressionSupported = true;
- }
-
- switch (g_texture_globals.texture_components) {
- case GL_RGBA:
- break;
- case GL_COMPRESSED_RGBA_ARB:
- if (!g_texture_globals.m_bOpenGLCompressionSupported) {
- globalOutputStream()
- << "OpenGL extension GL_ARB_texture_compression not supported by current graphics drivers\n";
- g_texture_globals.m_nTextureCompressionFormat = TEXTURECOMPRESSION_NONE;
- g_texture_globals.texture_components = GL_RGBA;
- }
- break;
- case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
- case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
- case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
- if (!g_texture_globals.m_bS3CompressionSupported) {
- globalOutputStream()
- << "OpenGL extension GL_EXT_texture_compression_s3tc not supported by current graphics drivers\n";
- if (g_texture_globals.m_bOpenGLCompressionSupported) {
- g_texture_globals.m_nTextureCompressionFormat = TEXTURECOMPRESSION_RGBA;
- g_texture_globals.texture_components = GL_COMPRESSED_RGBA_ARB;
- } else {
- g_texture_globals.m_nTextureCompressionFormat = TEXTURECOMPRESSION_NONE;
- g_texture_globals.texture_components = GL_RGBA;
- }
- }
- break;
- default:
- globalOutputStream() << "Unknown texture compression selected, reverting\n";
- g_texture_globals.m_nTextureCompressionFormat = TEXTURECOMPRESSION_NONE;
- g_texture_globals.texture_components = GL_RGBA;
- break;
- }
-
-
- glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_tex_size);
- if (max_tex_size == 0) {
- max_tex_size = 1024;
- }
-
- for (qtextures_t::iterator i = m_qtextures.begin(); i != m_qtextures.end(); ++i) {
- if (!(*i).value.empty()) {
- qtexture_realise(*(*i).value, (*i).key);
- }
- }
- if (m_observer != 0) {
- m_observer->realise();
- }
- }
- }
-
- void unrealise()
- {
- if (++m_unrealised == 1) {
- if (m_observer != 0) {
- m_observer->unrealise();
- }
- for (qtextures_t::iterator i = m_qtextures.begin(); i != m_qtextures.end(); ++i) {
- if (!(*i).value.empty()) {
- qtexture_unrealise(*(*i).value);
- }
- }
- }
- }
-
- bool realised()
- {
- return m_unrealised == 0;
- }
+ m_qtextures.release( TextureKey( texture->load, texture->name ) );
+}
+void attach( TexturesCacheObserver& observer ){
+ ASSERT_MESSAGE( m_observer == 0, "TexturesMap::attach: cannot attach observer" );
+ m_observer = &observer;
+}
+void detach( TexturesCacheObserver& observer ){
+ ASSERT_MESSAGE( m_observer == &observer, "TexturesMap::detach: cannot detach observer" );
+ m_observer = 0;
+}
+void realise(){
+ if ( --m_unrealised == 0 ) {
+ g_texture_globals.bTextureCompressionSupported = false;
+
+ if ( GlobalOpenGL().ARB_texture_compression() ) {
+ g_texture_globals.bTextureCompressionSupported = true;
+ g_texture_globals.m_bOpenGLCompressionSupported = true;
+ }
+
+ if ( GlobalOpenGL().EXT_texture_compression_s3tc() ) {
+ g_texture_globals.bTextureCompressionSupported = true;
+ g_texture_globals.m_bS3CompressionSupported = true;
+ }
+
+ switch ( g_texture_globals.texture_components )
+ {
+ case GL_RGBA:
+ break;
+ case GL_COMPRESSED_RGBA_ARB:
+ if ( !g_texture_globals.m_bOpenGLCompressionSupported ) {
+ globalOutputStream() << "OpenGL extension GL_ARB_texture_compression not supported by current graphics drivers\n";
+ g_texture_globals.m_nTextureCompressionFormat = TEXTURECOMPRESSION_NONE;
+ g_texture_globals.texture_components = GL_RGBA;
+ }
+ break;
+ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
+ if ( !g_texture_globals.m_bS3CompressionSupported ) {
+ globalOutputStream() << "OpenGL extension GL_EXT_texture_compression_s3tc not supported by current graphics drivers\n";
+ if ( g_texture_globals.m_bOpenGLCompressionSupported ) {
+ g_texture_globals.m_nTextureCompressionFormat = TEXTURECOMPRESSION_RGBA;
+ g_texture_globals.texture_components = GL_COMPRESSED_RGBA_ARB;
+ }
+ else
+ {
+ g_texture_globals.m_nTextureCompressionFormat = TEXTURECOMPRESSION_NONE;
+ g_texture_globals.texture_components = GL_RGBA;
+ }
+ }
+ break;
+ default:
+ globalOutputStream() << "Unknown texture compression selected, reverting\n";
+ g_texture_globals.m_nTextureCompressionFormat = TEXTURECOMPRESSION_NONE;
+ g_texture_globals.texture_components = GL_RGBA;
+ break;
+ }
+
+
+ glGetIntegerv( GL_MAX_TEXTURE_SIZE, &max_tex_size );
+ if ( max_tex_size == 0 ) {
+ max_tex_size = 1024;
+ }
+
+ for ( qtextures_t::iterator i = m_qtextures.begin(); i != m_qtextures.end(); ++i )
+ {
+ if ( !( *i ).value.empty() ) {
+ qtexture_realise( *( *i ).value, ( *i ).key );
+ }
+ }
+ if ( m_observer != 0 ) {
+ m_observer->realise();
+ }
+ }
+}
+void unrealise(){
+ if ( ++m_unrealised == 1 ) {
+ if ( m_observer != 0 ) {
+ m_observer->unrealise();
+ }
+ for ( qtextures_t::iterator i = m_qtextures.begin(); i != m_qtextures.end(); ++i )
+ {
+ if ( !( *i ).value.empty() ) {
+ qtexture_unrealise( *( *i ).value );
+ }
+ }
+ }
+}
+bool realised(){
+ return m_unrealised == 0;
+}
};
-TexturesMap *g_texturesmap;
+TexturesMap* g_texturesmap;
-TexturesCache &GetTexturesCache()
-{
- return *g_texturesmap;
+TexturesCache& GetTexturesCache(){
+ return *g_texturesmap;
}
-void Textures_Realise()
-{
- g_texturesmap->realise();
+void Textures_Realise(){
+ g_texturesmap->realise();
}
-void Textures_Unrealise()
-{
- g_texturesmap->unrealise();
+void Textures_Unrealise(){
+ g_texturesmap->unrealise();
}
Callback<void()> g_texturesModeChangedNotify;
-void Textures_setModeChangedNotify(const Callback<void()> ¬ify)
-{
- g_texturesModeChangedNotify = notify;
+void Textures_setModeChangedNotify( const Callback<void()>& notify ){
+ g_texturesModeChangedNotify = notify;
}
-void Textures_ModeChanged()
-{
- if (g_texturesmap->realised()) {
- SetTexParameters(g_texture_mode);
+void Textures_ModeChanged(){
+ if ( g_texturesmap->realised() ) {
+ SetTexParameters( g_texture_mode );
- for (TexturesMap::iterator i = g_texturesmap->begin(); i != g_texturesmap->end(); ++i) {
- glBindTexture(GL_TEXTURE_2D, (*i).value->texture_number);
- SetTexParameters(g_texture_mode);
- }
+ for ( TexturesMap::iterator i = g_texturesmap->begin(); i != g_texturesmap->end(); ++i )
+ {
+ glBindTexture( GL_TEXTURE_2D, ( *i ).value->texture_number );
+ SetTexParameters( g_texture_mode );
+ }
- glBindTexture(GL_TEXTURE_2D, 0);
- }
- g_texturesModeChangedNotify();
+ glBindTexture( GL_TEXTURE_2D, 0 );
+ }
+ g_texturesModeChangedNotify();
}
-void Textures_SetMode(ETexturesMode mode)
-{
- if (g_texture_mode != mode) {
- g_texture_mode = mode;
+void Textures_SetMode( ETexturesMode mode ){
+ if ( g_texture_mode != mode ) {
+ g_texture_mode = mode;
- Textures_ModeChanged();
- }
+ Textures_ModeChanged();
+ }
}
-void Textures_setTextureComponents(GLint texture_components)
-{
- if (g_texture_globals.texture_components != texture_components) {
- Textures_Unrealise();
- g_texture_globals.texture_components = texture_components;
- Textures_Realise();
- }
+void Textures_setTextureComponents( GLint texture_components ){
+ if ( g_texture_globals.texture_components != texture_components ) {
+ Textures_Unrealise();
+ g_texture_globals.texture_components = texture_components;
+ Textures_Realise();
+ }
}
-void Textures_UpdateTextureCompressionFormat()
-{
- GLint texture_components = GL_RGBA;
-
- switch (g_texture_globals.m_nTextureCompressionFormat) {
- case (TEXTURECOMPRESSION_NONE): {
- texture_components = GL_RGBA;
- break;
- }
- case (TEXTURECOMPRESSION_RGBA): {
- texture_components = GL_COMPRESSED_RGBA_ARB;
- break;
- }
- case (TEXTURECOMPRESSION_RGBA_S3TC_DXT1): {
- texture_components = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
- break;
- }
- case (TEXTURECOMPRESSION_RGBA_S3TC_DXT3): {
- texture_components = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
- break;
- }
- case (TEXTURECOMPRESSION_RGBA_S3TC_DXT5): {
- texture_components = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
- break;
- }
- }
-
- Textures_setTextureComponents(texture_components);
+void Textures_UpdateTextureCompressionFormat(){
+ GLint texture_components = GL_RGBA;
+
+ switch ( g_texture_globals.m_nTextureCompressionFormat )
+ {
+ case ( TEXTURECOMPRESSION_NONE ):
+ {
+ texture_components = GL_RGBA;
+ break;
+ }
+ case ( TEXTURECOMPRESSION_RGBA ):
+ {
+ texture_components = GL_COMPRESSED_RGBA_ARB;
+ break;
+ }
+ case ( TEXTURECOMPRESSION_RGBA_S3TC_DXT1 ):
+ {
+ texture_components = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
+ break;
+ }
+ case ( TEXTURECOMPRESSION_RGBA_S3TC_DXT3 ):
+ {
+ texture_components = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
+ break;
+ }
+ case ( TEXTURECOMPRESSION_RGBA_S3TC_DXT5 ):
+ {
+ texture_components = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
+ break;
+ }
+ }
+
+ Textures_setTextureComponents( texture_components );
}
struct TextureCompression {
- static void Export(const TextureCompressionFormat &self, const Callback<void(int)> &returnz)
- {
+ static void Export(const TextureCompressionFormat &self, const Callback<void(int)> &returnz) {
returnz(self);
}
- static void Import(TextureCompressionFormat &self, int value)
- {
+ static void Import(TextureCompressionFormat &self, int value) {
if (!g_texture_globals.m_bOpenGLCompressionSupported
&& g_texture_globals.m_bS3CompressionSupported
&& value >= 1) {
};
struct TextureGamma {
- static void Export(const float &self, const Callback<void(float)> &returnz)
- {
- returnz(self);
- }
-
- static void Import(float &self, float value)
- {
- if (value != self) {
- Textures_Unrealise();
- self = value;
- Textures_Realise();
- }
- }
+ static void Export(const float &self, const Callback<void(float)> &returnz) {
+ returnz(self);
+ }
+
+ static void Import(float &self, float value) {
+ if (value != self) {
+ Textures_Unrealise();
+ self = value;
+ Textures_Realise();
+ }
+ }
};
struct TextureMode {
- static void Export(const ETexturesMode &self, const Callback<void(int)> &returnz)
- {
+ static void Export(const ETexturesMode &self, const Callback<void(int)> &returnz) {
switch (self) {
case eTextures_NEAREST:
returnz(0);
}
}
- static void Import(ETexturesMode &self, int value)
- {
+ static void Import(ETexturesMode &self, int value) {
switch (value) {
case 0:
Textures_SetMode(eTextures_NEAREST);
}
};
-void Textures_constructPreferences(PreferencesPage &page)
-{
- {
- const char *percentages[] = {"12.5%", "25%", "50%", "100%",};
- page.appendRadio(
- "Texture Quality",
- STRING_ARRAY_RANGE(percentages),
- make_property(g_Textures_textureQuality)
- );
- }
- page.appendSpinner(
- "Texture Gamma",
- 1.0,
- 0.0,
- 1.0,
- make_property<TextureGamma>(g_texture_globals.fGamma)
- );
- {
- const char *texture_mode[] = {"Nearest", "Nearest Mipmap", "Linear", "Bilinear", "Bilinear Mipmap", "Trilinear",
- "Anisotropy"};
- page.appendCombo(
- "Texture Render Mode",
- STRING_ARRAY_RANGE(texture_mode),
- make_property<TextureMode>(g_texture_mode)
- );
- }
- {
- const char *compression_none[] = {"None"};
- const char *compression_opengl[] = {"None", "OpenGL ARB"};
- const char *compression_s3tc[] = {"None", "S3TC DXT1", "S3TC DXT3", "S3TC DXT5"};
- const char *compression_opengl_s3tc[] = {"None", "OpenGL ARB", "S3TC DXT1", "S3TC DXT3", "S3TC DXT5"};
- StringArrayRange compression(
- (g_texture_globals.m_bOpenGLCompressionSupported)
- ? (g_texture_globals.m_bS3CompressionSupported)
- ? STRING_ARRAY_RANGE(compression_opengl_s3tc)
- : STRING_ARRAY_RANGE(compression_opengl)
- : (g_texture_globals.m_bS3CompressionSupported)
- ? STRING_ARRAY_RANGE(compression_s3tc)
- : STRING_ARRAY_RANGE(compression_none)
- );
- page.appendCombo(
- "Hardware Texture Compression",
- compression,
- make_property<TextureCompression>(g_texture_globals.m_nTextureCompressionFormat)
- );
- }
+void Textures_constructPreferences( PreferencesPage& page ){
+ {
+ const char* percentages[] = { "12.5%", "25%", "50%", "100%", };
+ page.appendRadio(
+ "Texture Quality",
+ STRING_ARRAY_RANGE( percentages ),
+ make_property( g_Textures_textureQuality )
+ );
+ }
+ page.appendSpinner(
+ "Texture Gamma",
+ 1.0,
+ 0.0,
+ 1.0,
+ make_property<TextureGamma>(g_texture_globals.fGamma)
+ );
+ {
+ const char* texture_mode[] = { "Nearest", "Nearest Mipmap", "Linear", "Bilinear", "Bilinear Mipmap", "Trilinear", "Anisotropy" };
+ page.appendCombo(
+ "Texture Render Mode",
+ STRING_ARRAY_RANGE( texture_mode ),
+ make_property<TextureMode>(g_texture_mode)
+ );
+ }
+ {
+ const char* compression_none[] = { "None" };
+ const char* compression_opengl[] = { "None", "OpenGL ARB" };
+ const char* compression_s3tc[] = { "None", "S3TC DXT1", "S3TC DXT3", "S3TC DXT5" };
+ const char* compression_opengl_s3tc[] = { "None", "OpenGL ARB", "S3TC DXT1", "S3TC DXT3", "S3TC DXT5" };
+ StringArrayRange compression(
+ ( g_texture_globals.m_bOpenGLCompressionSupported )
+ ? ( g_texture_globals.m_bS3CompressionSupported )
+ ? STRING_ARRAY_RANGE( compression_opengl_s3tc )
+ : STRING_ARRAY_RANGE( compression_opengl )
+ : ( g_texture_globals.m_bS3CompressionSupported )
+ ? STRING_ARRAY_RANGE( compression_s3tc )
+ : STRING_ARRAY_RANGE( compression_none )
+ );
+ page.appendCombo(
+ "Hardware Texture Compression",
+ compression,
+ make_property<TextureCompression>(g_texture_globals.m_nTextureCompressionFormat)
+ );
+ }
}
-
-void Textures_constructPage(PreferenceGroup &group)
-{
- PreferencesPage page(group.createPage("Textures", "Texture Settings"));
- Textures_constructPreferences(page);
+void Textures_constructPage( PreferenceGroup& group ){
+ PreferencesPage page( group.createPage( "Textures", "Texture Settings" ) );
+ Textures_constructPreferences( page );
}
-
-void Textures_registerPreferencesPage()
-{
- PreferencesDialog_addDisplayPage(makeCallbackF(Textures_constructPage));
+void Textures_registerPreferencesPage(){
+ PreferencesDialog_addDisplayPage( makeCallbackF(Textures_constructPage) );
}
struct TextureCompressionPreference {
- static void Export(const Callback<void(int)> &returnz)
- {
- returnz(g_texture_globals.m_nTextureCompressionFormat);
- }
-
- static void Import(int value)
- {
- g_texture_globals.m_nTextureCompressionFormat = static_cast<TextureCompressionFormat>( value );
- Textures_UpdateTextureCompressionFormat();
- }
+ static void Export(const Callback<void(int)> &returnz) {
+ returnz(g_texture_globals.m_nTextureCompressionFormat);
+ }
+
+ static void Import(int value) {
+ g_texture_globals.m_nTextureCompressionFormat = static_cast<TextureCompressionFormat>( value );
+ Textures_UpdateTextureCompressionFormat();
+ }
};
-void Textures_Construct()
-{
- g_texturesmap = new TexturesMap;
+void Textures_Construct(){
+ g_texturesmap = new TexturesMap;
- GlobalPreferenceSystem().registerPreference("TextureCompressionFormat",
- make_property_string<TextureCompressionPreference>());
- GlobalPreferenceSystem().registerPreference("TextureFiltering",
- make_property_string(reinterpret_cast<int &>( g_texture_mode )));
- GlobalPreferenceSystem().registerPreference("TextureQuality",
- make_property_string(g_Textures_textureQuality.m_latched));
- GlobalPreferenceSystem().registerPreference("SI_Gamma", make_property_string(g_texture_globals.fGamma));
+ GlobalPreferenceSystem().registerPreference( "TextureCompressionFormat", make_property_string<TextureCompressionPreference>() );
+ GlobalPreferenceSystem().registerPreference( "TextureFiltering", make_property_string( reinterpret_cast<int&>( g_texture_mode ) ) );
+ GlobalPreferenceSystem().registerPreference( "TextureQuality", make_property_string( g_Textures_textureQuality.m_latched ) );
+ GlobalPreferenceSystem().registerPreference( "SI_Gamma", make_property_string( g_texture_globals.fGamma ) );
- g_Textures_textureQuality.useLatched();
+ g_Textures_textureQuality.useLatched();
- Textures_registerPreferencesPage();
+ Textures_registerPreferencesPage();
- Textures_ModeChanged();
+ Textures_ModeChanged();
}
-
-void Textures_Destroy()
-{
- delete g_texturesmap;
+void Textures_Destroy(){
+ delete g_texturesmap;
}
#include "modulesystem/moduleregistry.h"
class TexturesDependencies :
- public GlobalRadiantModuleRef,
- public GlobalOpenGLModuleRef,
- public GlobalPreferenceSystemModuleRef {
- ImageModulesRef m_image_modules;
+ public GlobalRadiantModuleRef,
+ public GlobalOpenGLModuleRef,
+ public GlobalPreferenceSystemModuleRef
+{
+ImageModulesRef m_image_modules;
+ImageModulesRef m_fallback_image_modules;
public:
- TexturesDependencies() :
- m_image_modules(GlobalRadiant().getRequiredGameDescriptionKeyValue("texturetypes"))
- {
- }
-
- ImageModules &getImageModules()
- {
- return m_image_modules.get();
- }
+TexturesDependencies() :
+ m_image_modules( GlobalRadiant().getRequiredGameDescriptionKeyValue( "texturetypes" ) ),
+ m_fallback_image_modules( "png" ){
+}
+ImageModules& getImageModules(){
+ return m_image_modules.get();
+}
+ImageModules& getFallbackImageModules(){
+ return m_fallback_image_modules.get();
+}
};
-class TexturesAPI {
- TexturesCache *m_textures;
+class TexturesAPI
+{
+TexturesCache* m_textures;
public:
- typedef TexturesCache Type;
+typedef TexturesCache Type;
+STRING_CONSTANT( Name, "*" );
- STRING_CONSTANT(Name, "*");
+TexturesAPI(){
+ Textures_Construct();
- TexturesAPI()
- {
- Textures_Construct();
-
- m_textures = &GetTexturesCache();
- }
-
- ~TexturesAPI()
- {
- Textures_Destroy();
- }
-
- TexturesCache *getTable()
- {
- return m_textures;
- }
+ m_textures = &GetTexturesCache();
+}
+~TexturesAPI(){
+ Textures_Destroy();
+}
+TexturesCache* getTable(){
+ return m_textures;
+}
};
typedef SingletonModule<TexturesAPI, TexturesDependencies> TexturesModule;
typedef Static<TexturesModule> StaticTexturesModule;
-StaticRegisterModule staticRegisterTextures(StaticTexturesModule::instance());
+StaticRegisterModule staticRegisterTextures( StaticTexturesModule::instance() );
-ImageModules &Textures_getImageModules()
-{
- return StaticTexturesModule::instance().getDependencies().getImageModules();
+ImageModules& Textures_getImageModules(){
+ return StaticTexturesModule::instance().getDependencies().getImageModules();
+}
+ImageModules& Textures_getFallbackImageModules(){
+ return StaticTexturesModule::instance().getDependencies().getFallbackImageModules();
}