Added support for texture object manager, which provides an automatic mechansim
for reusing deleted textures.
This commit is contained in:
@@ -69,6 +69,7 @@ class SG_EXPORT StateSet : public Object
|
||||
|
||||
/** set this StateSet to contain specified GLMode and value.*/
|
||||
void setMode(StateAttribute::GLMode mode, StateAttribute::GLModeValue value);
|
||||
|
||||
/** set this StateSet to inherit specified GLMode type from parents.
|
||||
* has the effect of deleting any GlMode of specified type from StateSet.*/
|
||||
void setModeToInherit(StateAttribute::GLMode mode);
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
#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
|
||||
@@ -204,12 +206,20 @@ class SG_EXPORT Texture : public osg::StateAttribute
|
||||
bool isCompressedInternalFormat() const;
|
||||
|
||||
|
||||
class TextureObject;
|
||||
|
||||
/** Get the handle to the texture object for the current context.*/
|
||||
inline GLuint& getTextureObject(unsigned int contextID) const
|
||||
inline TextureObject* getTextureObject(unsigned int contextID) const
|
||||
{
|
||||
return _handleList[contextID];
|
||||
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
|
||||
@@ -217,22 +227,12 @@ class SG_EXPORT Texture : public osg::StateAttribute
|
||||
return _texParametersDirtyList[contextID];
|
||||
}
|
||||
|
||||
/** Force a recompile on next apply() of associated OpenGL texture objects.*/
|
||||
void dirtyTextureObject();
|
||||
|
||||
/** Force a resetting on next apply() of associated OpenGL texture parameters.*/
|
||||
void dirtyTextureParameters();
|
||||
|
||||
|
||||
/** use deleteTextureObject instead of glDeleteTextures to allow
|
||||
* OpenGL texture objects to cached until they can be deleted
|
||||
* by the OpenGL context in which they were created, specified
|
||||
* by contextID.*/
|
||||
static void deleteTextureObject(unsigned int contextID,GLuint handle);
|
||||
|
||||
/** flush all the cached display list which need to be deleted
|
||||
* in the OpenGL context related to contextID.*/
|
||||
static void flushDeletedTextureObjects(unsigned int contextID);
|
||||
|
||||
/** Texture is pure virtual base class, apply must be overriden. */
|
||||
virtual void apply(State& state) const = 0;
|
||||
@@ -326,13 +326,14 @@ class SG_EXPORT Texture : public osg::StateAttribute
|
||||
* 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(GLenum target, const Image* image, State& state, GLsizei& width, GLsizei& height,GLsizei& numMimpmapLevels) const;
|
||||
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(GLenum target, const Image* image, State& state, GLsizei& width, GLsizei& height,GLsizei& numMimpmapLevels) const;
|
||||
void applyTexImage2D_subload(State& state, GLenum target, const Image* image, GLsizei width, GLsizei height,GLsizei numMipmapLevels) const;
|
||||
|
||||
protected :
|
||||
|
||||
@@ -342,18 +343,18 @@ class SG_EXPORT Texture : public osg::StateAttribute
|
||||
|
||||
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<GLuint> TextureNameList;
|
||||
mutable TextureNameList _handleList;
|
||||
|
||||
typedef buffered_value<unsigned int> TexParameterDirtyList;
|
||||
mutable TexParameterDirtyList _texParametersDirtyList;
|
||||
|
||||
@@ -371,6 +372,172 @@ class SG_EXPORT Texture : public osg::StateAttribute
|
||||
|
||||
InternalFormatMode _internalFormatMode;
|
||||
mutable GLint _internalFormat;
|
||||
|
||||
|
||||
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 TextureObjectManager : public osg::Referenced
|
||||
{
|
||||
public:
|
||||
|
||||
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 deleteTextureObjects(unsigned int contextID,double currentTime);
|
||||
|
||||
|
||||
// how long to keep unsed texture objects around for before deleting.
|
||||
double _expiryDelay;
|
||||
|
||||
TextureObjectListMap _textureObjectListMap;
|
||||
|
||||
};
|
||||
|
||||
|
||||
static void setTextureObjectManager(TextureObjectManager* tom);
|
||||
static TextureObjectManager* getTextureObjectManager();
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -87,10 +87,10 @@ class SG_EXPORT Texture1D : public Texture
|
||||
|
||||
/** Set the number of mip map levels the the texture has been created with,
|
||||
should only be called within an osg::Texuture::apply() and custom OpenGL texture load.*/
|
||||
void setNumMipmapLevels(unsigned int num) const { _numMimpmapLevels=num; }
|
||||
void setNumMipmapLevels(unsigned int num) const { _numMipmapLevels=num; }
|
||||
|
||||
/** Get the number of mip map levels the the texture has been created with.*/
|
||||
unsigned int getNumMipmapLevels() const { return _numMimpmapLevels; }
|
||||
unsigned int getNumMipmapLevels() const { return _numMipmapLevels; }
|
||||
|
||||
|
||||
/** Copy pixels into a 1D texture image.As per glCopyTexImage1D.
|
||||
@@ -118,7 +118,7 @@ class SG_EXPORT Texture1D : public Texture
|
||||
|
||||
/** Helper method which does the creation of the texture itself, and
|
||||
* does not set or use texture binding. */
|
||||
void applyTexImage1D(GLenum target, Image* image, State& state, GLsizei& width, GLsizei& numMimpmapLevels) const;
|
||||
void applyTexImage1D(GLenum target, Image* image, State& state, GLsizei& width, GLsizei& numMipmapLevels) const;
|
||||
|
||||
|
||||
// not ideal that _image is mutable, but its required since
|
||||
@@ -131,7 +131,7 @@ class SG_EXPORT Texture1D : public Texture
|
||||
mutable GLsizei _textureWidth;
|
||||
|
||||
// number of mip map levels the the texture has been created with,
|
||||
mutable GLsizei _numMimpmapLevels;
|
||||
mutable GLsizei _numMipmapLevels;
|
||||
|
||||
ref_ptr<SubloadCallback> _subloadCallback;
|
||||
|
||||
|
||||
@@ -88,10 +88,10 @@ class SG_EXPORT Texture3D : public Texture
|
||||
|
||||
/** Set the number of mip map levels the the texture has been created with,
|
||||
should only be called within an osg::Texuture::apply() and custom OpenGL texture load.*/
|
||||
void setNumMipmapLevels(unsigned int num) const { _numMimpmapLevels=num; }
|
||||
void setNumMipmapLevels(unsigned int num) const { _numMipmapLevels=num; }
|
||||
|
||||
/** Get the number of mip map levels the the texture has been created with.*/
|
||||
unsigned int getNumMipmapLevels() const { return _numMimpmapLevels; }
|
||||
unsigned int getNumMipmapLevels() const { return _numMipmapLevels; }
|
||||
|
||||
|
||||
/** Copy a two-dimensional texture subimage. As per glCopyTexSubImage2D.
|
||||
@@ -175,7 +175,7 @@ class SG_EXPORT Texture3D : public Texture
|
||||
|
||||
virtual void computeInternalFormat() const;
|
||||
|
||||
void applyTexImage3D(GLenum target, Image* image, State& state, GLsizei& inwidth, GLsizei& inheight, GLsizei& indepth, GLsizei& numMimpmapLevels) const;
|
||||
void applyTexImage3D(GLenum target, Image* image, State& state, GLsizei& inwidth, GLsizei& inheight, GLsizei& indepth, GLsizei& numMipmapLevels) const;
|
||||
|
||||
// not ideal that _image is mutable, but its required since
|
||||
// Image::ensureDimensionsArePowerOfTwo() can only be called
|
||||
@@ -187,7 +187,7 @@ class SG_EXPORT Texture3D : public Texture
|
||||
mutable GLsizei _textureWidth, _textureHeight, _textureDepth;
|
||||
|
||||
// number of mip map levels the the texture has been created with,
|
||||
mutable GLsizei _numMimpmapLevels;
|
||||
mutable GLsizei _numMipmapLevels;
|
||||
|
||||
ref_ptr<SubloadCallback> _subloadCallback;
|
||||
|
||||
|
||||
@@ -202,9 +202,8 @@ public:
|
||||
enum DrawModeMask
|
||||
{
|
||||
TEXT = 1, /// default
|
||||
TEXT_PIXMAP = 2,
|
||||
BOUNDINGBOX = 4,
|
||||
ALIGNMENT = 8
|
||||
BOUNDINGBOX = 2,
|
||||
ALIGNMENT = 4
|
||||
};
|
||||
|
||||
void setDrawMode(unsigned int mode);
|
||||
|
||||
Reference in New Issue
Block a user