Files
OpenSceneGraph/include/osg/Texture
Robert Osfield aa833acfd3 Added support for releasing GLObjects, and renamed DisplayListVisitor the
GLObjectVisitor to better fit its function, and added support for releasing
objects as well as compiling them.
2004-07-20 05:37:59 +00:00

664 lines
28 KiB
C++

/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
#ifndef OSG_TEXTURE
#define OSG_TEXTURE 1
#include <osg/GL>
#include <osg/Image>
#include <osg/StateAttribute>
#include <osg/ref_ptr>
#include <osg/Vec4>
#include <osg/buffered_value>
#include <list>
#include <map>
// if not defined by gl.h use the definition found in:
// http://oss.sgi.com/projects/ogl-sample/registry/EXT/texture_filter_anisotropic.txt
#ifndef GL_TEXTURE_MAX_ANISOTROPY_EXT
#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE
#endif
#ifndef GL_ARB_texture_compression
#define GL_COMPRESSED_ALPHA_ARB 0x84E9
#define GL_COMPRESSED_LUMINANCE_ARB 0x84EA
#define GL_COMPRESSED_LUMINANCE_ALPHA_ARB 0x84EB
#define GL_COMPRESSED_INTENSITY_ARB 0x84EC
#define GL_COMPRESSED_RGB_ARB 0x84ED
#define GL_COMPRESSED_RGBA_ARB 0x84EE
#define GL_TEXTURE_COMPRESSION_HINT_ARB 0x84EF
#define GL_TEXTURE_COMPRESSED_ARB 0x86A1
#define GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A2
#define GL_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A3
#endif
#ifndef GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB
#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB 0x86A0
#endif
#ifndef GL_EXT_texture_compression_s3tc
#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0
#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1
#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2
#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3
#endif
#ifndef GL_NV_texture_shader
#define GL_HILO_NV 0x86F4
#define GL_DSDT_NV 0x86F5
#define GL_DSDT_MAG_NV 0x86F6
#define GL_DSDT_MAG_VIB_NV 0x86F7
#define GL_HILO16_NV 0x86F8
#define GL_SIGNED_HILO_NV 0x86F9
#define GL_SIGNED_HILO16_NV 0x86FA
#define GL_SIGNED_RGBA_NV 0x86FB
#define GL_SIGNED_RGBA8_NV 0x86FC
#define GL_SIGNED_RGB_NV 0x86FE
#define GL_SIGNED_RGB8_NV 0x86FF
#define GL_SIGNED_LUMINANCE_NV 0x8701
#define GL_SIGNED_LUMINANCE8_NV 0x8702
#define GL_SIGNED_LUMINANCE_ALPHA_NV 0x8703
#define GL_SIGNED_LUMINANCE8_ALPHA8_NV 0x8704
#define GL_SIGNED_ALPHA_NV 0x8705
#define GL_SIGNED_ALPHA8_NV 0x8706
#define GL_SIGNED_INTENSITY_NV 0x8707
#define GL_SIGNED_INTENSITY8_NV 0x8708
#define GL_DSDT8_NV 0x8709
#define GL_DSDT8_MAG8_NV 0x870A
#define GL_DSDT8_MAG8_INTENSITY8_NV 0x870B
#define GL_SIGNED_RGB_UNSIGNED_ALPHA_NV 0x870C
#define GL_SIGNED_RGB8_UNSIGNED_ALPHA8_NV 0x870D
#endif
#ifndef GL_MIRRORED_REPEAT_IBM
#define GL_MIRRORED_REPEAT_IBM 0x8370
#endif
#ifndef GL_CLAMP_TO_EDGE
#define GL_CLAMP_TO_EDGE 0x812F
#endif
#ifndef GL_CLAMP_TO_BORDER_ARB
#define GL_CLAMP_TO_BORDER_ARB 0x812D
#endif
#ifndef GL_GENERATE_MIPMAP_SGIS
#define GL_GENERATE_MIPMAP_SGIS 0x8191
#define GL_GENERATE_MIPMAP_HINT_SGIS 0x8192
#endif
#ifndef GL_TEXTURE_3D
#define GL_TEXTURE_3D 0x806F
#endif
#ifndef GL_TEXTURE_COMPARE_MODE_ARB
#define GL_DEPTH_TEXTURE_MODE_ARB 0x884B
#define GL_TEXTURE_COMPARE_MODE_ARB 0x884C
#define GL_TEXTURE_COMPARE_FUNC_ARB 0x884D
#define GL_COMPARE_R_TO_TEXTURE_ARB 0x884E
#endif
#ifndef TEXTURE_COMPARE_FAIL_VALUE_ARB
#define TEXTURE_COMPARE_FAIL_VALUE_ARB 0x80BF
#endif
#if !defined( GL_MAX_TEXTURE_UNITS )
#define GL_MAX_TEXTURE_UNITS 0x84E2
#endif
#ifndef GL_TEXTURE_DEPTH
#define GL_TEXTURE_DEPTH 0x8071
#endif
namespace osg {
/** Texture base class which encapsulates OpenGl texture functionality which common betweent the various types of OpenGL textures.*/
class SG_EXPORT Texture : public osg::StateAttribute
{
public :
Texture();
/** Copy constructor using CopyOp to manage deep vs shallow copy.*/
Texture(const Texture& text,const CopyOp& copyop=CopyOp::SHALLOW_COPY);
virtual osg::Object* cloneType() const = 0;
virtual osg::Object* clone(const CopyOp& copyop) const = 0;
virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast<const Texture *>(obj)!=NULL; }
virtual const char* libraryName() const { return "osg"; }
virtual const char* className() const { return "Texture"; }
virtual Type getType() const { return TEXTURE; }
virtual bool isTextureAttribute() const { return true; }
enum WrapParameter {
WRAP_S,
WRAP_T,
WRAP_R
};
enum WrapMode {
CLAMP = GL_CLAMP,
CLAMP_TO_EDGE = GL_CLAMP_TO_EDGE,
CLAMP_TO_BORDER = GL_CLAMP_TO_BORDER_ARB,
REPEAT = GL_REPEAT,
MIRROR = GL_MIRRORED_REPEAT_IBM
};
/** Set the texture wrap mode.*/
void setWrap(WrapParameter which, WrapMode wrap);
/** Get the texture wrap mode.*/
WrapMode getWrap(WrapParameter which) const;
/** Set the border color for this texture. Makes difference only if
* wrap mode is CLAMP_TO_BORDER */
void setBorderColor(const Vec4& color) { _borderColor = color; dirtyTextureParameters(); }
/** Get the border color for this texture.*/
const Vec4& getBorderColor() const { return _borderColor; }
/** Set the border width.*/
void setBorderWidth(GLint width) { _borderWidth = width; dirtyTextureParameters(); }
GLint getBorderWidth() const { return _borderWidth; }
enum FilterParameter {
MIN_FILTER,
MAG_FILTER
};
enum FilterMode {
LINEAR = GL_LINEAR,
LINEAR_MIPMAP_LINEAR = GL_LINEAR_MIPMAP_LINEAR,
LINEAR_MIPMAP_NEAREST = GL_LINEAR_MIPMAP_NEAREST,
NEAREST = GL_NEAREST,
NEAREST_MIPMAP_LINEAR = GL_NEAREST_MIPMAP_LINEAR,
NEAREST_MIPMAP_NEAREST = GL_NEAREST_MIPMAP_NEAREST
};
/** Set the texture filter mode.*/
void setFilter(FilterParameter which, FilterMode filter);
/** Get the texture filter mode.*/
FilterMode getFilter(FilterParameter which) const;
/** Set the maximum anisotropy value, default value is 1.0 for
* no anisotropic filtering. If hardware does not support anisotropic
* filtering then normal filtering is used, equivilant to a max anisotropy value of 1.0.
* valid range is 1.0f upwards. The maximum value depends on the graphics
* system being used.*/
void setMaxAnisotropy(float anis);
/** Get the maximum anisotropy value.*/
inline float getMaxAnisotropy() const { return _maxAnisotropy; }
/** Set the hint of whether to use hardware mip map generation where available.*/
inline void setUseHardwareMipMapGeneration(bool useHardwareMipMapGeneration) { _useHardwareMipMapGeneration = useHardwareMipMapGeneration; }
/** Get the hint of whether to use hardware mip map generation where available.*/
inline bool getUseHardwareMipMapGeneration() const { return _useHardwareMipMapGeneration; }
/** Set the automatic unreference of image data after the texture has been set up in apply, on (true) or off (false).
* If the image data is only referened by this Texture then the image data will be autoamtically deleted.*/
inline void setUnRefImageDataAfterApply(bool flag) { _unrefImageDataAfterApply = flag; }
/** Get the automatic unreference of image data after the texture has been set up in apply.*/
inline bool getUnRefImageDataAfterApply() const { return _unrefImageDataAfterApply; }
/** Set whether to use client storage of the texture where supported by OpenGL drivers.
* Note, if UseClientStorageHint is set, and the OpenGL drivers support it, the osg::Image(s) associated with
* this texture cannot be deleted, so the UnRefImageDataAfterApply flag is then ignored.*/
inline void setClientStorageHint(bool flag) { _clientStorageHint = flag; }
/** Get whether to use client storage of the texture where supported by OpenGL drivers.*/
inline bool getClientStorageHint() const { return _clientStorageHint; }
enum InternalFormatMode {
USE_IMAGE_DATA_FORMAT,
USE_USER_DEFINED_FORMAT,
USE_ARB_COMPRESSION,
USE_S3TC_DXT1_COMPRESSION,
USE_S3TC_DXT3_COMPRESSION,
USE_S3TC_DXT5_COMPRESSION
};
/** Set the internal format mode.
* Note, If the mode is set USE_IMAGE_DATA_FORMAT, USE_ARB_COMPRESSION,
* USE_S3TC_COMPRESSION the internalFormat is automatically selected,
* and will overwrite the previous _internalFormat.
*/
inline void setInternalFormatMode(InternalFormatMode mode) { _internalFormatMode = mode; }
/** Get the internal format mode.*/
inline InternalFormatMode getInternalFormatMode() const { return _internalFormatMode; }
/** Set the internal format to use when creating OpenGL textures.
* Also sets the internalFormatMode to USE_USER_DEFINED_FORMAT.
*/
inline void setInternalFormat(GLint internalFormat)
{
_internalFormatMode = USE_USER_DEFINED_FORMAT;
_internalFormat = internalFormat;
}
/** Get the internal format to use when creating OpenGL textures.*/
inline GLint getInternalFormat() const { if (_internalFormat==0) computeInternalFormat(); return _internalFormat; }
bool isCompressedInternalFormat() const;
class TextureObject;
/** Get the handle to the texture object for the current context.*/
inline TextureObject* getTextureObject(unsigned int contextID) const
{
return _textureObjectBuffer[contextID].get();
}
/** Force a recompile on next apply() of associated OpenGL texture objects.*/
void dirtyTextureObject();
/** return true if the texture objects for all the required graphics contexts are loaded.*/
bool areAllTextureObjectsLoaded() const;
/** get the dirty flag for the current contextID.*/
inline unsigned int& getTextureParameterDirty(unsigned int contextID) const
{
return _texParametersDirtyList[contextID];
}
/** Force a resetting on next apply() of associated OpenGL texture parameters.*/
void dirtyTextureParameters();
// set mode of GL_TEXTURE_COMPARE_MODE_ARB to GL_COMPARE_R_TO_TEXTURE_ARB
// See http://oss.sgi.com/projects/ogl-sample/registry/ARB/shadow.txt
void setShadowComparison(bool flag) { _use_shadow_comparison = flag; }
enum ShadowCompareFunc {
LEQUAL = GL_LEQUAL,
GEQUAL = GL_GEQUAL
};
// set shadow texture comparison function
void setShadowCompareFunc(ShadowCompareFunc func) { _shadow_compare_func = func; }
ShadowCompareFunc getShadowCompareFunc() { return _shadow_compare_func; }
enum ShadowTextureMode {
LUMINANCE = GL_LUMINANCE,
INTENSITY = GL_INTENSITY,
ALPHA = GL_ALPHA
};
// set shadow texture mode after comparison
void setShadowTextureMode(ShadowTextureMode mode) { _shadow_texture_mode = mode; }
ShadowTextureMode getShadowTextureMode() { return _shadow_texture_mode; }
// set value of TEXTURE_COMPARE_FAIL_VALUE_ARB texture parameter
// http://oss.sgi.com/projects/ogl-sample/registry/ARB/shadow_ambient.txt
void setShadowAmbient(float shadow_ambient) { _shadow_ambient = shadow_ambient; }
float getShadowAmbient() { return _shadow_ambient; }
/** Texture is pure virtual base class, apply must be overriden. */
virtual void apply(State& state) const = 0;
/** Calls apply(state) to compile the texture. */
virtual void compileGLObjects(State& state) const;
/** release an OpenGL objects in specified graphics context if State
object is passed, otherwise release OpenGL objexts for all graphics context if
State object pointer NULL.*/
virtual void releaseGLObjects(State* state=0) const;
/** Extensions class which encapsulates the querring of extensions and
* associated function pointers, and provide convinience wrappers to
* check for the extensions or use the associated functions.*/
class SG_EXPORT Extensions : public osg::Referenced
{
public:
Extensions();
Extensions(const Extensions& rhs);
void lowestCommonDenominator(const Extensions& rhs);
void setupGLExtensions();
void setMultiTexturingSupported(bool flag) { _isMultiTexturingSupported=flag; }
bool isMultiTexturingSupported() const { return _isMultiTexturingSupported; }
void setTextureFilterAnisotropicSupported(bool flag) { _isTextureFilterAnisotropicSupported=flag; }
bool isTextureFilterAnisotropicSupported() const { return _isTextureFilterAnisotropicSupported; }
void setTextureCompressionARBSupported(bool flag) { _isTextureCompressionARBSupported=flag; }
bool isTextureCompressionARBSupported() const { return _isTextureCompressionARBSupported; }
void setTextureCompressionS3TCSupported(bool flag) { _isTextureCompressionS3TCSupported=flag; }
bool isTextureCompressionS3TCSupported() const { return _isTextureCompressionS3TCSupported; }
void setTextureMirroredRepeatSupported(bool flag) { _isTextureMirroredRepeatSupported=flag; }
bool isTextureMirroredRepeatSupported() const { return _isTextureMirroredRepeatSupported; }
void setTextureEdgeClampSupported(bool flag) { _isTextureEdgeClampSupported=flag; }
bool isTextureEdgeClampSupported() const { return _isTextureEdgeClampSupported; }
void setTextureBorderClampSupported(bool flag) { _isTextureBorderClampSupported=flag; }
bool isTextureBorderClampSupported() const { return _isTextureBorderClampSupported; }
void setGenerateMipMapSupported(bool flag) { _isGenerateMipMapSupported=flag; }
bool isGenerateMipMapSupported() const { return _isGenerateMipMapSupported; }
void setShadowSupported(bool flag) { _isShadowSupported = flag; }
bool isShadowSupported() const { return _isShadowSupported; }
void setShadowAmbientSupported(bool flag) { _isShadowAmbientSupported = flag; }
bool isShadowAmbientSupported() const { return _isShadowAmbientSupported; }
void setMaxTextureSize(GLint maxsize) { _maxTextureSize=maxsize; }
GLint maxTextureSize() const { return _maxTextureSize; }
void setNumTextureUnits(GLint nunits ) { _numTextureUnits=nunits; }
GLint numTextureUnits() const { return _numTextureUnits; }
bool isCompressedTexImage2DSupported() const { return _glCompressedTexImage2D!=0; }
void setCompressedTexImage2DProc(void* ptr) { _glCompressedTexImage2D = ptr; }
void glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data) const;
void setCompressedTexSubImage2DProc(void* ptr) { _glCompressedTexSubImage2D = ptr; }
void glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei type, const GLvoid *data) const;
void setGetCompressedTexImageProc(void* ptr) { _glGetCompressedTexImage = ptr; }
void glGetCompressedTexImage(GLenum target, GLint level, GLvoid *data) const;
bool isClientStorageSupported() const { return _isClientStorageSupported; }
protected:
~Extensions() {}
bool _isMultiTexturingSupported;
bool _isTextureFilterAnisotropicSupported;
bool _isTextureCompressionARBSupported;
bool _isTextureCompressionS3TCSupported;
bool _isTextureMirroredRepeatSupported;
bool _isTextureEdgeClampSupported;
bool _isTextureBorderClampSupported;
bool _isGenerateMipMapSupported;
bool _isShadowSupported;
bool _isShadowAmbientSupported;
bool _isClientStorageSupported;
GLint _maxTextureSize;
GLint _numTextureUnits;
void* _glCompressedTexImage2D;
void* _glCompressedTexSubImage2D;
void* _glGetCompressedTexImage;
};
/** Function to call to get the extension of a specified context.
* If the Exentsion object for that context has not yet been created then
* and the 'createIfNotInitalized' flag been set to false then returns NULL.
* If 'createIfNotInitalized' is true then the Extensions object is
* automatically created. However, in this case the extension object
* only be created with the graphics context associated with ContextID..*/
static Extensions* getExtensions(unsigned int contextID,bool createIfNotInitalized);
/** setExtensions allows users to override the extensions across graphics contexts.
* typically used when you have different extensions supported across graphics pipes
* but need to ensure that they all use the same low common denominator extensions.*/
static void setExtensions(unsigned int contextID,Extensions* extensions);
/** Helper method which does the creation of the texture itself, but does not set or use texture binding.
* Note, do not call this method directly unless you are implementing your own Subload callback*/
void applyTexImage2D_load(State& state, GLenum target, const Image* image, GLsizei width, GLsizei height,GLsizei numMipmapLevels) const;
/** Helper method which subloads images to the texture itself, but does not set or use texture binding.
* Note, do not call this method directly unless you are implementing your own Subload callback*/
void applyTexImage2D_subload(State& state, GLenum target, const Image* image, GLsizei width, GLsizei height, GLint inInternalFormat, GLsizei numMipmapLevels) const;
protected :
virtual ~Texture();
virtual void computeInternalFormat() const = 0;
void computeInternalFormatWithImage(const osg::Image& image) const;
void computeRequiredTextureDimensions(State& state, const osg::Image& image,GLsizei& width, GLsizei& height,GLsizei& numMipmapLevels) const;
bool isCompressedInternalFormat(GLint internalFormat) const;
/** Helper method which does setting of texture paramters. */
void applyTexParameters(GLenum target, State& state) const;
/** return -1 if *this < *rhs, 0 if *this==*rhs, 1 if *this>*rhs.*/
int compareTexture(const Texture& rhs) const;
typedef buffered_value<unsigned int> TexParameterDirtyList;
mutable TexParameterDirtyList _texParametersDirtyList;
WrapMode _wrap_s;
WrapMode _wrap_t;
WrapMode _wrap_r;
FilterMode _min_filter;
FilterMode _mag_filter;
float _maxAnisotropy;
bool _useHardwareMipMapGeneration;
bool _unrefImageDataAfterApply;
bool _clientStorageHint;
Vec4 _borderColor;
GLint _borderWidth;
InternalFormatMode _internalFormatMode;
mutable GLint _internalFormat;
bool _use_shadow_comparison;
ShadowCompareFunc _shadow_compare_func;
ShadowTextureMode _shadow_texture_mode;
float _shadow_ambient;
public:
class TextureObject : public osg::Referenced
{
public:
inline TextureObject(GLuint id,GLenum target):
_id(id),
_target(target),
_numMipmapLevels(0),
_internalFormat(0),
_width(0),
_height(0),
_depth(0),
_border(0),
_allocated(false),
_timeStamp(0) {}
inline TextureObject(GLuint id,
GLenum target,
GLint numMipmapLevels,
GLenum internalFormat,
GLsizei width,
GLsizei height,
GLsizei depth,
GLint border):
_id(id),
_target(target),
_numMipmapLevels(numMipmapLevels),
_internalFormat(internalFormat),
_width(width),
_height(height),
_depth(depth),
_border(border),
_allocated(false),
_timeStamp(0) {}
inline bool match(GLenum target,
GLint numMipmapLevels,
GLenum internalFormat,
GLsizei width,
GLsizei height,
GLsizei depth,
GLint border)
{
return isReusable() &&
(_target == target) &&
(_numMipmapLevels == numMipmapLevels) &&
(_internalFormat == internalFormat) &&
(_width == width) &&
(_height == height) &&
(_depth == depth) &&
(_border == border);
}
inline void bind()
{
glBindTexture( _target, _id);
}
inline void setAllocated(bool allocated=true) { _allocated = allocated; }
inline void setAllocated(GLint numMipmapLevels,
GLenum internalFormat,
GLsizei width,
GLsizei height,
GLsizei depth,
GLint border)
{
_allocated=true;
_numMipmapLevels = numMipmapLevels;
_internalFormat = internalFormat;
_width = width;
_height = height;
_depth = depth;
_border = border;
}
inline bool isAllocated() const { return _allocated; }
inline bool isReusable() const { return _allocated && _width!=0; }
GLuint _id;
GLenum _target;
GLint _numMipmapLevels;
GLenum _internalFormat;
GLsizei _width;
GLsizei _height;
GLsizei _depth;
GLint _border;
bool _allocated;
double _timeStamp;
};
typedef std::list< ref_ptr<TextureObject> > TextureObjectList;
typedef std::map<unsigned int, TextureObjectList > TextureObjectListMap;
/** take the active texture objects from the Texture and place them in the specified TextureObjectListMap.*/
void takeTextureObjects(TextureObjectListMap& toblm);
typedef buffered_object< ref_ptr<TextureObject> > TextureObjectBuffer;
mutable TextureObjectBuffer _textureObjectBuffer;
class SG_EXPORT TextureObjectManager : public osg::Referenced
{
public:
TextureObjectManager():
_expiryDelay(0.0) {}
virtual TextureObject* generateTextureObject(unsigned int contextID,GLenum target);
virtual TextureObject* generateTextureObject(unsigned int contextID,
GLenum target,
GLint numMipmapLevels,
GLenum internalFormat,
GLsizei width,
GLsizei height,
GLsizei depth,
GLint border);
virtual TextureObject* reuseTextureObject(unsigned int contextID,
GLenum target,
GLint numMipmapLevels,
GLenum internalFormat,
GLsizei width,
GLsizei height,
GLsizei depth,
GLint border);
inline TextureObject* reuseOrGenerateTextureObject(unsigned int contextID,
GLenum target,
GLint numMipmapLevels,
GLenum internalFormat,
GLsizei width,
GLsizei height,
GLsizei depth,
GLint border)
{
TextureObject* to = reuseTextureObject(contextID,target,numMipmapLevels,internalFormat,width,height,depth,border);
if (to) return to;
else return generateTextureObject(contextID,target,numMipmapLevels,internalFormat,width,height,depth,border);
}
virtual void addTextureObjects(TextureObjectListMap& toblm);
virtual void addTextureObjectsFrom(Texture& texture);
virtual void flushTextureObjects(unsigned int contextID,double currentTime, double& availableTime);
void setExpiryDelay(double expiryDelay) { _expiryDelay = expiryDelay; }
double getExpiryDelay() const { return _expiryDelay; }
// how long to keep unsed texture objects around for before deleting.
double _expiryDelay;
TextureObjectListMap _textureObjectListMap;
};
static void setTextureObjectManager(TextureObjectManager* tom);
static TextureObjectManager* getTextureObjectManager();
static void flushTextureObjects(unsigned int contextID,double currentTime, double& availableTime);
};
}
#endif