Added support for texture object manager, which provides an automatic mechansim

for reusing deleted textures.
This commit is contained in:
Robert Osfield 2003-07-14 14:42:10 +00:00
parent 94d8e72ad3
commit 1b9d7d458a
18 changed files with 795 additions and 387 deletions

View File

@ -46,30 +46,6 @@ osg::Node* createLabel(const osg::Vec3& pos, float size, const std::string& labe
return geode;
}
osg::Node* createLabel2(const osg::Vec3& pos, float size, const std::string& label)
{
osg::Geode* geode = new osg::Geode();
std::string timesFont("fonts/arial.ttf");
{
osgText::Text* text = new osgText::Text;
geode->addDrawable( text );
text->setFont(timesFont);
text->setPosition(pos);
text->setFontResolution(40,40);
text->setCharacterSize(size);
text->setCharacterSizeMode(osgText::Text::SCREEN_COORDS);
text->setAlignment(osgText::Text::CENTER_CENTER);
text->setAutoRotateToScreen(true);
text->setDrawMode(osgText::Text::TEXT_PIXMAP);
text->setText(label);
}
return geode;
}
osg::Node* createLabel3(const osg::Vec3& pos, float size, const std::string& label)
{

View File

@ -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);

View File

@ -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();
};

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -79,8 +79,8 @@ CXXFILES =\
TexGen.cpp\
TexMat.cpp\
Texture.cpp\
Texture1D.cpp\
Texture2D.cpp\
Texture1D.cpp\
Texture3D.cpp\
TextureCubeMap.cpp\
TextureRectangle.cpp\

View File

@ -23,42 +23,126 @@ using namespace osg;
#define GL_TEXTURE_WRAP_R 0x8072
#endif
// static cache of deleted display lists which can only
// by completely deleted once the appropriate OpenGL context
// is set.
typedef std::vector<GLuint> TextureObjectVector;
typedef std::map<unsigned int,TextureObjectVector> DeletedTextureObjectCache;
static DeletedTextureObjectCache s_deletedTextureObjectCache;
void Texture::deleteTextureObject(unsigned int contextID,GLuint handle)
Texture::TextureObject* Texture::TextureObjectManager::generateTextureObject(unsigned int /*contextID*/,GLenum target)
{
if (handle!=0)
GLuint id;
glGenTextures( 1L, &id );
return new Texture::TextureObject(id,target);
}
Texture::TextureObject* Texture::TextureObjectManager::generateTextureObject(unsigned int /*contextID*/,
GLenum target,
GLint numMipmapLevels,
GLenum internalFormat,
GLsizei width,
GLsizei height,
GLsizei depth,
GLint border)
{
// no useable texture object found so return 0
GLuint id;
glGenTextures( 1L, &id );
return new Texture::TextureObject(id,target,numMipmapLevels,internalFormat,width,height,depth,border);
}
Texture::TextureObject* Texture::TextureObjectManager::reuseTextureObject(unsigned int contextID,
GLenum target,
GLint numMipmapLevels,
GLenum internalFormat,
GLsizei width,
GLsizei height,
GLsizei depth,
GLint border)
{
TextureObjectList& tol = _textureObjectListMap[contextID];
for(TextureObjectList::iterator itr = tol.begin();
itr != tol.end();
++itr)
{
// insert the handle into the cache for the appropriate context.
s_deletedTextureObjectCache[contextID].push_back(handle);
if ((*itr)->match(target,numMipmapLevels,internalFormat,width,height,depth,border))
{
// found usable texture object.
Texture::TextureObject* textureObject = (*itr).release();
tol.erase(itr);
//std::cout<<"reusing texture object "<<textureObject<<std::endl;
return textureObject;
}
}
return 0;
}
void Texture::TextureObjectManager::addTextureObjects(Texture::TextureObjectListMap& toblm)
{
for(TextureObjectListMap::iterator itr = toblm.begin();
itr != toblm.end();
++itr)
{
TextureObjectList& tol = _textureObjectListMap[itr->first];
tol.insert(tol.end(),itr->second.begin(),itr->second.end());
}
}
void Texture::flushDeletedTextureObjects(unsigned int contextID)
void Texture::TextureObjectManager::addTextureObjectsFrom(Texture& texture)
{
DeletedTextureObjectCache::iterator citr = s_deletedTextureObjectCache.find(contextID);
if (citr!=s_deletedTextureObjectCache.end())
texture.takeTextureObjects(_textureObjectListMap);
}
void Texture::TextureObjectManager::deleteTextureObjects(unsigned int contextID,double currentTime)
{
TextureObjectList& tol = _textureObjectListMap[contextID];
// reset the time of any uninitialized objects.
TextureObjectList::iterator itr;
for(itr=tol.begin();
itr!=tol.end();
++itr)
{
TextureObjectVector textureObjectSet;
textureObjectSet.reserve(1000);
// this swap will transfer the content of and empty citr->second
// in one quick pointer change.
textureObjectSet.swap(citr->second);
for(TextureObjectVector::iterator titr=textureObjectSet.begin();
titr!=textureObjectSet.end();
++titr)
if ((*itr)->_timeStamp==0.0) (*itr)->_timeStamp=currentTime;
}
_expiryDelay = 10.0;
double expiryTime = currentTime-_expiryDelay;
//unsigned int numTexturesDeleted = 0;
for(itr=tol.begin();
itr!=tol.end();
)
{
if ((*itr)->_timeStamp<expiryTime)
{
glDeleteTextures( 1L, &(*titr ));
glDeleteTextures( 1L, &((*itr)->_id));
itr = tol.erase(itr);
//++numTexturesDeleted;
}
else
{
++itr;
}
}
//if (numTexturesDeleted) std::cout<<" deleted "<<numTexturesDeleted<<" textures"<<std::endl;
}
static ref_ptr<Texture::TextureObjectManager> s_textureObjectManager;
void Texture::setTextureObjectManager(Texture::TextureObjectManager* tom)
{
s_textureObjectManager = tom;
}
Texture::TextureObjectManager* Texture::getTextureObjectManager()
{
if (!s_textureObjectManager) s_textureObjectManager = new Texture::TextureObjectManager;
return s_textureObjectManager.get();
}
@ -173,14 +257,20 @@ void Texture::setMaxAnisotropy(float anis)
/** Force a recompile on next apply() of associated OpenGL texture objects.*/
void Texture::dirtyTextureObject()
{
for(unsigned int i=0;i<_handleList.size();++i)
getTextureObjectManager()->addTextureObjectsFrom(*this);
}
void Texture::takeTextureObjects(Texture::TextureObjectListMap& toblm)
{
for(unsigned int i = 0; i<_textureObjectBuffer.size();++i)
{
if (_handleList[i] != 0)
if (_textureObjectBuffer[i].valid())
{
Texture::deleteTextureObject(i,_handleList[i]);
_handleList[i] = 0;
//std::cout << "releasing texure "<<toblm[i].size()<<std::endl;
toblm[i].push_back(_textureObjectBuffer[i]);
}
}
_textureObjectBuffer.setAllElementsTo(0);
}
void Texture::dirtyTextureParameters()
@ -369,7 +459,47 @@ void Texture::applyTexParameters(GLenum target, State& state) const
}
void Texture::applyTexImage2D_load(GLenum target, const Image* image, State& state, GLsizei& inwidth, GLsizei& inheight,GLsizei& numMimpmapLevels) const
void Texture::computeRequiredTextureDimensions(State& state, const osg::Image& image,GLsizei& inwidth, GLsizei& inheight,GLsizei& numMipmapLevels) const
{
const unsigned int contextID = state.getContextID();
const Extensions* extensions = getExtensions(contextID,true);
int width = Image::computeNearestPowerOfTwo(image.s());
int height = Image::computeNearestPowerOfTwo(image.t());
// cap the size to what the graphics hardware can handle.
if (width>extensions->maxTextureSize()) width = extensions->maxTextureSize();
if (height>extensions->maxTextureSize()) height = extensions->maxTextureSize();
inwidth = width;
inheight = height;
numMipmapLevels = 0;
for( ; (width || height) ;++numMipmapLevels)
{
if (width == 0)
width = 1;
if (height == 0)
height = 1;
width >>= 1;
height >>= 1;
}
}
bool Texture::areAllTextureObjectsLoaded() const
{
for(unsigned int i=0;i<DisplaySettings::instance()->getMaxNumberOfGraphicsContexts();++i)
{
if (_textureObjectBuffer[i]==0) return true;
}
return false;
}
void Texture::applyTexImage2D_load(State& state, GLenum target, const Image* image, GLsizei inwidth, GLsizei inheight,GLsizei numMipmapLevels) const
{
// if we don't have a valid image we can't create a texture!
if (!image || !image->data())
@ -382,24 +512,15 @@ void Texture::applyTexImage2D_load(GLenum target, const Image* image, State& sta
bool generateMipMapSupported = extensions->isGenerateMipMapSupported();
// compute the internal texture format, this set the _internalFormat to an appropriate value.
computeInternalFormat();
// select the internalFormat required for the texture.
; bool compressed_image = isCompressedInternalFormat((GLenum)image->getPixelFormat());
bool compressed_image = isCompressedInternalFormat((GLenum)image->getPixelFormat());
glPixelStorei(GL_UNPACK_ALIGNMENT,image->getPacking());
unsigned char* data = (unsigned char*)image->data();
int s_powerOfTwo = Image::computeNearestPowerOfTwo(image->s());
int t_powerOfTwo = Image::computeNearestPowerOfTwo(image->t());
// cap the size to what the graphics hardware can handle.
if (s_powerOfTwo>extensions->maxTextureSize()) s_powerOfTwo = extensions->maxTextureSize();
if (t_powerOfTwo>extensions->maxTextureSize()) t_powerOfTwo = extensions->maxTextureSize();
bool needImageRescale = s_powerOfTwo!=image->s() || t_powerOfTwo!=image->t();
bool needImageRescale = inwidth!=image->s() || inheight!=image->t();
if (needImageRescale)
{
@ -416,7 +537,7 @@ void Texture::applyTexImage2D_load(GLenum target, const Image* image, State& sta
return;
}
unsigned int newTotalSize = osg::Image::computeRowWidthInBytes(s_powerOfTwo,image->getPixelFormat(),image->getDataType(),image->getPacking())*t_powerOfTwo;
unsigned int newTotalSize = osg::Image::computeRowWidthInBytes(inwidth,image->getPixelFormat(),image->getDataType(),image->getPacking())*inheight;
data = new unsigned char [newTotalSize];
if (!data)
@ -425,14 +546,14 @@ void Texture::applyTexImage2D_load(GLenum target, const Image* image, State& sta
return;
}
if (!image->getFileName().empty()) notify(NOTICE) << "Scaling image '"<<image->getFileName()<<"' from ("<<image->s()<<","<<image->t()<<") to ("<<s_powerOfTwo<<","<<t_powerOfTwo<<")"<<std::endl;
else notify(NOTICE) << "Scaling image from ("<<image->s()<<","<<image->t()<<") to ("<<s_powerOfTwo<<","<<t_powerOfTwo<<")"<<std::endl;
if (!image->getFileName().empty()) notify(NOTICE) << "Scaling image '"<<image->getFileName()<<"' from ("<<image->s()<<","<<image->t()<<") to ("<<inwidth<<","<<inheight<<")"<<std::endl;
else notify(NOTICE) << "Scaling image from ("<<image->s()<<","<<image->t()<<") to ("<<inwidth<<","<<inheight<<")"<<std::endl;
// rescale the image to the correct size.
glPixelStorei(GL_PACK_ALIGNMENT,image->getPacking());
gluScaleImage(image->getPixelFormat(),
image->s(),image->t(),image->getDataType(),image->data(),
s_powerOfTwo,t_powerOfTwo,image->getDataType(),data);
inwidth,inheight,image->getDataType(),data);
}
@ -449,10 +570,10 @@ void Texture::applyTexImage2D_load(GLenum target, const Image* image, State& sta
if ( !compressed_image)
{
numMimpmapLevels = 1;
numMipmapLevels = 1;
glTexImage2D( target, 0, _internalFormat,
s_powerOfTwo, t_powerOfTwo, 0,
inwidth, inheight, 0,
(GLenum)image->getPixelFormat(),
(GLenum)image->getDataType(),
data );
@ -460,13 +581,13 @@ void Texture::applyTexImage2D_load(GLenum target, const Image* image, State& sta
}
else if (extensions->isCompressedTexImage2DSupported())
{
numMimpmapLevels = 1;
numMipmapLevels = 1;
GLint blockSize = ( _internalFormat == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ? 8 : 16 );
GLint size = ((s_powerOfTwo+3)/4)*((t_powerOfTwo+3)/4)*blockSize;
GLint size = ((inwidth+3)/4)*((inheight+3)/4)*blockSize;
extensions->glCompressedTexImage2D(target, 0, _internalFormat,
s_powerOfTwo, t_powerOfTwo,0,
inwidth, inheight,0,
size,
data);
}
@ -480,14 +601,14 @@ void Texture::applyTexImage2D_load(GLenum target, const Image* image, State& sta
{
// image is mip mapped so we take the mip map levels from the image.
numMimpmapLevels = image->getNumMipmapLevels();
numMipmapLevels = image->getNumMipmapLevels();
int width = s_powerOfTwo;
int height = t_powerOfTwo;
int width = inwidth;
int height = inheight;
if( !compressed_image )
{
for( GLsizei k = 0 ; k < numMimpmapLevels && (width || height) ;k++)
for( GLsizei k = 0 ; k < numMipmapLevels && (width || height) ;k++)
{
if (width == 0)
@ -509,7 +630,7 @@ void Texture::applyTexImage2D_load(GLenum target, const Image* image, State& sta
{
GLint blockSize = ( _internalFormat == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ? 8 : 16 );
GLint size = 0;
for( GLsizei k = 0 ; k < numMimpmapLevels && (width || height) ;k++)
for( GLsizei k = 0 ; k < numMipmapLevels && (width || height) ;k++)
{
if (width == 0)
width = 1;
@ -531,16 +652,16 @@ void Texture::applyTexImage2D_load(GLenum target, const Image* image, State& sta
if ( !compressed_image)
{
numMimpmapLevels = 0;
numMipmapLevels = 0;
gluBuild2DMipmaps( target, _internalFormat,
s_powerOfTwo,t_powerOfTwo,
inwidth,inheight,
(GLenum)image->getPixelFormat(), (GLenum)image->getDataType(),
data );
int width = image->s();
int height = image->t();
for( numMimpmapLevels = 0 ; (width || height) ; ++numMimpmapLevels)
for( numMipmapLevels = 0 ; (width || height) ; ++numMipmapLevels)
{
width >>= 1;
height >>= 1;
@ -555,9 +676,6 @@ void Texture::applyTexImage2D_load(GLenum target, const Image* image, State& sta
}
inwidth = s_powerOfTwo;
inheight = t_powerOfTwo;
if (needImageRescale)
{
// clean up the resized image.
@ -566,7 +684,9 @@ void Texture::applyTexImage2D_load(GLenum target, const Image* image, State& sta
}
void Texture::applyTexImage2D_subload(GLenum target, const Image* image, State& state, GLsizei& inwidth, GLsizei& inheight,GLsizei& numMimpmapLevels) const
void Texture::applyTexImage2D_subload(State& state, GLenum target, const Image* image, GLsizei inwidth, GLsizei inheight,GLsizei numMipmapLevels) const
{
// if we don't have a valid image we can't create a texture!
if (!image || !image->data())
@ -576,7 +696,7 @@ void Texture::applyTexImage2D_subload(GLenum target, const Image* image, State&
if (image->s()!=inwidth || image->t()!=inheight)
{
applyTexImage2D_load(target, image, state, inwidth, inheight,numMimpmapLevels);
applyTexImage2D_load(state, target, image, inwidth, inheight,numMipmapLevels);
return;
}
// else image size the same as when loaded so we can go ahead and subload
@ -590,9 +710,6 @@ void Texture::applyTexImage2D_subload(GLenum target, const Image* image, State&
bool generateMipMapSupported = extensions->isGenerateMipMapSupported();
// compute the internal texture format, this set the _internalFormat to an appropriate value.
computeInternalFormat();
// select the internalFormat required for the texture.
bool compressed_image = isCompressedInternalFormat((GLenum)image->getPixelFormat());
@ -600,14 +717,8 @@ void Texture::applyTexImage2D_subload(GLenum target, const Image* image, State&
unsigned char* data = (unsigned char*)image->data();
int s_powerOfTwo = Image::computeNearestPowerOfTwo(image->s());
int t_powerOfTwo = Image::computeNearestPowerOfTwo(image->t());
// cap the size to what the graphics hardware can handle.
if (s_powerOfTwo>extensions->maxTextureSize()) s_powerOfTwo = extensions->maxTextureSize();
if (t_powerOfTwo>extensions->maxTextureSize()) t_powerOfTwo = extensions->maxTextureSize();
bool needImageRescale = s_powerOfTwo!=image->s() || t_powerOfTwo!=image->t();
bool needImageRescale = inwidth!=image->s() || inheight!=image->t();
if (needImageRescale)
{
@ -624,7 +735,7 @@ void Texture::applyTexImage2D_subload(GLenum target, const Image* image, State&
return;
}
unsigned int newTotalSize = osg::Image::computeRowWidthInBytes(s_powerOfTwo,image->getPixelFormat(),image->getDataType(),image->getPacking())*t_powerOfTwo;
unsigned int newTotalSize = osg::Image::computeRowWidthInBytes(inwidth,image->getPixelFormat(),image->getDataType(),image->getPacking())*inheight;
data = new unsigned char [newTotalSize];
if (!data)
@ -633,14 +744,14 @@ void Texture::applyTexImage2D_subload(GLenum target, const Image* image, State&
return;
}
if (!image->getFileName().empty()) notify(NOTICE) << "Scaling image '"<<image->getFileName()<<"' from ("<<image->s()<<","<<image->t()<<") to ("<<s_powerOfTwo<<","<<t_powerOfTwo<<")"<<std::endl;
else notify(NOTICE) << "Scaling image from ("<<image->s()<<","<<image->t()<<") to ("<<s_powerOfTwo<<","<<t_powerOfTwo<<")"<<std::endl;
if (!image->getFileName().empty()) notify(NOTICE) << "Scaling image '"<<image->getFileName()<<"' from ("<<image->s()<<","<<image->t()<<") to ("<<inwidth<<","<<inheight<<")"<<std::endl;
else notify(NOTICE) << "Scaling image from ("<<image->s()<<","<<image->t()<<") to ("<<inwidth<<","<<inheight<<")"<<std::endl;
// rescale the image to the correct size.
glPixelStorei(GL_PACK_ALIGNMENT,image->getPacking());
gluScaleImage(image->getPixelFormat(),
image->s(),image->t(),image->getDataType(),image->data(),
s_powerOfTwo,t_powerOfTwo,image->getDataType(),data);
inwidth,inheight,image->getDataType(),data);
}
@ -661,7 +772,7 @@ void Texture::applyTexImage2D_subload(GLenum target, const Image* image, State&
{
glTexSubImage2D( target, 0,
0, 0,
s_powerOfTwo, t_powerOfTwo,
inwidth, inheight,
(GLenum)image->getPixelFormat(),
(GLenum)image->getDataType(),
data );
@ -669,11 +780,14 @@ void Texture::applyTexImage2D_subload(GLenum target, const Image* image, State&
}
else if (extensions->isCompressedTexImage2DSupported())
{
GLint blockSize = ( _internalFormat == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ? 8 : 16 );
GLint size = ((inwidth+3)/4)*((inheight+3)/4)*blockSize;
extensions->glCompressedTexSubImage2D(target, 0,
0,0,
s_powerOfTwo, t_powerOfTwo,
inwidth, inheight,
(GLenum)image->getPixelFormat(),
(GLenum)image->getDataType(),
size,
data );
}
@ -683,14 +797,14 @@ void Texture::applyTexImage2D_subload(GLenum target, const Image* image, State&
{
if (image->isMipmap())
{
numMimpmapLevels = image->getNumMipmapLevels();
numMipmapLevels = image->getNumMipmapLevels();
int width = s_powerOfTwo;
int height = t_powerOfTwo;
int width = inwidth;
int height = inheight;
if( !compressed_image )
{
for( GLsizei k = 0 ; k < numMimpmapLevels && (width || height) ;k++)
for( GLsizei k = 0 ; k < numMipmapLevels && (width || height) ;k++)
{
if (width == 0)
@ -713,7 +827,7 @@ void Texture::applyTexImage2D_subload(GLenum target, const Image* image, State&
{
GLint blockSize = ( _internalFormat == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ? 8 : 16 );
GLint size = 0;
for( GLsizei k = 0 ; k < numMimpmapLevels && (width || height) ;k++)
for( GLsizei k = 0 ; k < numMipmapLevels && (width || height) ;k++)
{
if (width == 0)
width = 1;
@ -722,16 +836,21 @@ void Texture::applyTexImage2D_subload(GLenum target, const Image* image, State&
size = ((width+3)/4)*((height+3)/4)*blockSize;
state.checkGLErrors("before extensions->glCompressedTexSubImage2D(");
extensions->glCompressedTexSubImage2D(target, k,
0, 0,
width, height,
(GLenum)image->getPixelFormat(),
(GLenum)image->getDataType(),
size,
image->getMipmapData(k));
state.checkGLErrors("after extensions->glCompressedTexSubImage2D(");
width >>= 1;
height >>= 1;
}
}
}
else
@ -739,10 +858,10 @@ void Texture::applyTexImage2D_subload(GLenum target, const Image* image, State&
if (!compressed_image)
{
numMimpmapLevels = 0;
numMipmapLevels = 0;
int width = s_powerOfTwo;
int height = t_powerOfTwo;
int width = inwidth;
int height = inheight;
glPixelStorei(GL_PACK_ALIGNMENT,image->getPacking());
@ -918,7 +1037,7 @@ void Texture::Extensions::setupGLExtenions()
}
_glCompressedTexImage2D = getGLExtensionFuncPtr("glCompressedTexImage2D","glCompressedTexImage2DARB");
_glCompressedTexSubImage2D = getGLExtensionFuncPtr("glCompressedTexSubImage2D","glCompressedTexSubImage2DARB");;
_glCompressedTexSubImage2D = getGLExtensionFuncPtr("glCompressedTexSubImage2D","glCompressedTexSubImage2DARB");
_glGetCompressedTexImage = getGLExtensionFuncPtr("glGetCompressedTexImage","glGetCompressedTexImageARB");;
}
@ -936,12 +1055,12 @@ void Texture::Extensions::glCompressedTexImage2D(GLenum target, GLint level, GLe
}
void Texture::Extensions::glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei type, const GLvoid *data) const
void Texture::Extensions::glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data) const
{
if (_glCompressedTexImage2D)
{
typedef void (APIENTRY * CompressedTexSubImage2DArbProc) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei type, const GLvoid *data);
((CompressedTexSubImage2DArbProc)_glCompressedTexSubImage2D)(target, level, xoffset, yoffset, width, height, format, type, data);
typedef void (APIENTRY * CompressedTexSubImage2DArbProc) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data);
((CompressedTexSubImage2DArbProc)_glCompressedTexSubImage2D)(target, level, xoffset, yoffset, width, height, format, imageSize, data);
}
else
{

View File

@ -21,7 +21,7 @@ using namespace osg;
Texture1D::Texture1D():
_textureWidth(0),
_numMimpmapLevels(0)
_numMipmapLevels(0)
{
}
@ -29,7 +29,7 @@ Texture1D::Texture1D(const Texture1D& text,const CopyOp& copyop):
Texture(text,copyop),
_image(copyop(text._image.get())),
_textureWidth(text._textureWidth),
_numMimpmapLevels(text._numMimpmapLevels),
_numMipmapLevels(text._numMipmapLevels),
_subloadCallback(text._subloadCallback)
{
}
@ -92,13 +92,13 @@ void Texture1D::apply(State& state) const
// current OpenGL context.
const unsigned int contextID = state.getContextID();
// get the globj for the current contextID.
GLuint& handle = getTextureObject(contextID);
// get the texture object for the current contextID.
TextureObject* textureObject = getTextureObject(contextID);
if (handle != 0)
if (textureObject != 0)
{
textureObject->bind();
glBindTexture( GL_TEXTURE_1D, handle );
if (getTextureParameterDirty(state.getContextID())) applyTexParameters(GL_TEXTURE_1D,state);
if (_subloadCallback.valid())
@ -107,7 +107,7 @@ void Texture1D::apply(State& state) const
}
else if (_image.valid() && getModifiedTag(contextID) != _image->getModifiedTag())
{
applyTexImage1D(GL_TEXTURE_1D,_image.get(),state, _textureWidth, _numMimpmapLevels);
applyTexImage1D(GL_TEXTURE_1D,_image.get(),state, _textureWidth, _numMipmapLevels);
// update the modified tag to show that it is upto date.
getModifiedTag(contextID) = _image->getModifiedTag();
@ -117,53 +117,52 @@ void Texture1D::apply(State& state) const
else if (_subloadCallback.valid())
{
glGenTextures( 1L, (GLuint *)&handle );
glBindTexture( GL_TEXTURE_1D, handle );
// we don't have a applyTexImage1D_subload yet so can't reuse.. so just generate a new texture object.
_textureObjectBuffer[contextID] = textureObject = getTextureObjectManager()->generateTextureObject(contextID,GL_TEXTURE_2D);
textureObject->bind();
applyTexParameters(GL_TEXTURE_1D,state);
_subloadCallback->load(*this,state);
textureObject->setAllocated(_numMipmapLevels,_internalFormat,_textureWidth,1,1,0);
// in theory the following line is redundent, but in practice
// have found that the first frame drawn doesn't apply the textures
// unless a second bind is called?!!
// perhaps it is the first glBind which is not required...
glBindTexture( GL_TEXTURE_1D, handle );
//glBindTexture( GL_TEXTURE_1D, handle );
}
else if (_image.valid() && _image->data())
{
glGenTextures( 1L, (GLuint *)&handle );
glBindTexture( GL_TEXTURE_1D, handle );
// we don't have a applyTexImage1D_subload yet so can't reuse.. so just generate a new texture object.
_textureObjectBuffer[contextID] = textureObject = getTextureObjectManager()->generateTextureObject(contextID,GL_TEXTURE_2D);
textureObject->bind();
applyTexParameters(GL_TEXTURE_1D,state);
applyTexImage1D(GL_TEXTURE_1D,_image.get(),state, _textureWidth, _numMimpmapLevels);
applyTexImage1D(GL_TEXTURE_1D,_image.get(),state, _textureWidth, _numMipmapLevels);
textureObject->setAllocated(_numMipmapLevels,_internalFormat,_textureWidth,1,1,0);
// update the modified tag to show that it is upto date.
getModifiedTag(contextID) = _image->getModifiedTag();
if (_unrefImageDataAfterApply)
if (_unrefImageDataAfterApply && areAllTextureObjectsLoaded())
{
// only unref image once all the graphics contexts has been set up.
unsigned int numLeftToBind=0;
for(unsigned int i=0;i<DisplaySettings::instance()->getMaxNumberOfGraphicsContexts();++i)
{
if (_handleList[i]==0) ++numLeftToBind;
}
if (numLeftToBind==0)
{
Texture1D* non_const_this = const_cast<Texture1D*>(this);
non_const_this->_image = 0;
}
Texture1D* non_const_this = const_cast<Texture1D*>(this);
non_const_this->_image = 0;
}
// in theory the following line is redundent, but in practice
// have found that the first frame drawn doesn't apply the textures
// unless a second bind is called?!!
// perhaps it is the first glBind which is not required...
glBindTexture( GL_TEXTURE_1D, handle );
//glBindTexture( GL_TEXTURE_1D, handle );
}
else
@ -177,7 +176,7 @@ void Texture1D::computeInternalFormat() const
if (_image.valid()) computeInternalFormatWithImage(*_image);
}
void Texture1D::applyTexImage1D(GLenum target, Image* image, State& state, GLsizei& inwidth, GLsizei& numMimpmapLevels) const
void Texture1D::applyTexImage1D(GLenum target, Image* image, State& state, GLsizei& inwidth, GLsizei& numMipmapLevels) const
{
// if we don't have a valid image we can't create a texture!
if (!image || !image->data())
@ -206,7 +205,7 @@ void Texture1D::applyTexImage1D(GLenum target, Image* image, State& state, GLsiz
{
if ( !compressed )
{
numMimpmapLevels = 1;
numMipmapLevels = 1;
glTexImage1D( target, 0, _internalFormat,
image->s(), 0,
(GLenum)image->getPixelFormat(),
@ -216,7 +215,7 @@ void Texture1D::applyTexImage1D(GLenum target, Image* image, State& state, GLsiz
}
else if(glCompressedTexImage1D_ptr)
{
numMimpmapLevels = 1;
numMipmapLevels = 1;
GLint blockSize = ( _internalFormat == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ? 8 : 16 );
GLint size = ((image->s()+3)/4)*((image->t()+3)/4)*blockSize;
glCompressedTexImage1D_ptr(target, 0, _internalFormat,
@ -232,7 +231,7 @@ void Texture1D::applyTexImage1D(GLenum target, Image* image, State& state, GLsiz
if(!image->isMipmap())
{
numMimpmapLevels = 1;
numMipmapLevels = 1;
gluBuild1DMipmaps( target, _internalFormat,
image->s(),
@ -242,13 +241,13 @@ void Texture1D::applyTexImage1D(GLenum target, Image* image, State& state, GLsiz
}
else
{
numMimpmapLevels = image->getNumMipmapLevels();
numMipmapLevels = image->getNumMipmapLevels();
int width = image->s();
if( !compressed )
{
for( GLsizei k = 0 ; k < numMimpmapLevels && width ;k++)
for( GLsizei k = 0 ; k < numMipmapLevels && width ;k++)
{
glTexImage1D( target, k, _internalFormat,
@ -264,7 +263,7 @@ void Texture1D::applyTexImage1D(GLenum target, Image* image, State& state, GLsiz
{
GLint blockSize = ( _internalFormat == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ? 8 : 16 );
GLint size = 0;
for( GLsizei k = 0 ; k < numMimpmapLevels && width ;k++)
for( GLsizei k = 0 ; k < numMipmapLevels && width ;k++)
{
size = ((width+3)/4)*blockSize;
@ -285,10 +284,10 @@ void Texture1D::copyTexImage1D(State& state, int x, int y, int width)
{
const unsigned int contextID = state.getContextID();
// get the globj for the current contextID.
GLuint& handle = getTextureObject(contextID);
if (handle)
// get the texture object for the current contextID.
TextureObject* textureObject = getTextureObject(contextID);
if (textureObject != 0)
{
if (width==(int)_textureWidth)
{
@ -317,15 +316,19 @@ void Texture1D::copyTexImage1D(State& state, int x, int y, int width)
_min_filter = LINEAR;
_mag_filter = LINEAR;
// Get a new 2d texture handle.
glGenTextures( 1, &handle );
_textureObjectBuffer[contextID] = textureObject = getTextureObjectManager()->generateTextureObject(contextID,GL_TEXTURE_2D);
textureObject->bind();
glBindTexture( GL_TEXTURE_1D, handle );
applyTexParameters(GL_TEXTURE_1D,state);
glCopyTexImage1D( GL_TEXTURE_1D, 0, GL_RGBA, x, y, width, 0 );
_textureWidth = width;
_numMipmapLevels = 1;
textureObject->setAllocated(_numMipmapLevels,_internalFormat,_textureWidth,1,1,0);
// inform state that this texture is the current one bound.
state.haveAppliedAttribute(this);
}
@ -334,19 +337,20 @@ void Texture1D::copyTexSubImage1D(State& state, int xoffset, int x, int y, int w
{
const unsigned int contextID = state.getContextID();
// get the globj for the current contextID.
GLuint& handle = getTextureObject(contextID);
if (handle)
// get the texture object for the current contextID.
TextureObject* textureObject = getTextureObject(contextID);
if (textureObject != 0)
{
textureObject->bind();
// we have a valid image
glBindTexture( GL_TEXTURE_1D, handle );
applyTexParameters(GL_TEXTURE_1D,state);
glCopyTexSubImage1D( GL_TEXTURE_1D, 0, xoffset, x, y, width);
/* Redundant, delete later */
glBindTexture( GL_TEXTURE_1D, handle );
//glBindTexture( GL_TEXTURE_1D, handle );
// inform state that this texture is the current one bound.
state.haveAppliedAttribute(this);

View File

@ -98,16 +98,19 @@ void Texture2D::setImage(Image* image)
void Texture2D::apply(State& state) const
{
state.setReportGLErrors(true);
// get the contextID (user defined ID of 0 upwards) for the
// current OpenGL context.
const unsigned int contextID = state.getContextID();
// get the globj for the current contextID.
GLuint& handle = getTextureObject(contextID);
// get the texture object for the current contextID.
TextureObject* textureObject = getTextureObject(contextID);
if (handle != 0)
if (textureObject != 0)
{
glBindTexture( GL_TEXTURE_2D, handle );
textureObject->bind();
if (getTextureParameterDirty(state.getContextID()))
applyTexParameters(GL_TEXTURE_2D,state);
@ -117,7 +120,7 @@ void Texture2D::apply(State& state) const
}
else if (_image.valid() && getModifiedTag(contextID) != _image->getModifiedTag())
{
applyTexImage2D_subload(GL_TEXTURE_2D,_image.get(),state,
applyTexImage2D_subload(state,GL_TEXTURE_2D,_image.get(),
_textureWidth, _textureHeight, _numMipmapLevels);
// update the modified tag to show that it is upto date.
@ -129,55 +132,71 @@ void Texture2D::apply(State& state) const
else if (_subloadCallback.valid())
{
glGenTextures( 1L, (GLuint *)&handle );
glBindTexture( GL_TEXTURE_2D, handle );
_textureObjectBuffer[contextID] = textureObject = getTextureObjectManager()->generateTextureObject(contextID,GL_TEXTURE_2D);
textureObject->bind();
applyTexParameters(GL_TEXTURE_2D,state);
_subloadCallback->load(*this,state);
textureObject->setAllocated(_numMipmapLevels,_internalFormat,_textureWidth,_textureHeight,1,0);
// in theory the following line is redundent, but in practice
// have found that the first frame drawn doesn't apply the textures
// unless a second bind is called?!!
// perhaps it is the first glBind which is not required...
glBindTexture( GL_TEXTURE_2D, handle );
//glBindTexture( GL_TEXTURE_2D, handle );
}
else if (_image.valid() && _image->data())
{
glGenTextures( 1L, (GLuint *)&handle );
glBindTexture( GL_TEXTURE_2D, handle );
// compute the internal texture format, this set the _internalFormat to an appropriate value.
computeInternalFormat();
// compute the dimensions of the texture.
computeRequiredTextureDimensions(state,*_image,_textureWidth, _textureHeight, _numMipmapLevels);
_textureObjectBuffer[contextID] = textureObject = getTextureObjectManager()->reuseOrGenerateTextureObject(
contextID,GL_TEXTURE_2D,_numMipmapLevels,_internalFormat,_textureWidth,_textureHeight,1,0);
textureObject->bind();
applyTexParameters(GL_TEXTURE_2D,state);
applyTexImage2D_load(GL_TEXTURE_2D,_image.get(),state,
_textureWidth, _textureHeight, _numMipmapLevels);
if (textureObject->isAllocated())
{
//std::cout<<"Reusing texture object"<<std::endl;
applyTexImage2D_subload(state,GL_TEXTURE_2D,_image.get(),
_textureWidth, _textureHeight, _numMipmapLevels);
}
else
{
//std::cout<<"Creating new texture object"<<std::endl;
applyTexImage2D_load(state,GL_TEXTURE_2D,_image.get(),
_textureWidth, _textureHeight, _numMipmapLevels);
textureObject->setAllocated(true);
}
// update the modified tag to show that it is upto date.
getModifiedTag(contextID) = _image->getModifiedTag();
if (_unrefImageDataAfterApply)
if (_unrefImageDataAfterApply && areAllTextureObjectsLoaded())
{
// only unref image once all the graphics contexts has been set up.
unsigned int numLeftToBind=0;
for(unsigned int i=0;i<DisplaySettings::instance()->getMaxNumberOfGraphicsContexts();++i)
{
if (_handleList[i]==0) ++numLeftToBind;
}
if (numLeftToBind==0)
{
Texture2D* non_const_this = const_cast<Texture2D*>(this);
non_const_this->_image = 0;
}
Texture2D* non_const_this = const_cast<Texture2D*>(this);
non_const_this->_image = 0;
}
// in theory the following line is redundent, but in practice
// have found that the first frame drawn doesn't apply the textures
// unless a second bind is called?!!
// perhaps it is the first glBind which is not required...
glBindTexture( GL_TEXTURE_2D, handle );
//glBindTexture( GL_TEXTURE_2D, handle );
}
else
@ -197,9 +216,9 @@ void Texture2D::copyTexImage2D(State& state, int x, int y, int width, int height
const unsigned int contextID = state.getContextID();
// get the globj for the current contextID.
GLuint& handle = getTextureObject(contextID);
TextureObject* textureObject = getTextureObject(contextID);
if (handle)
if (textureObject)
{
if (width==(int)_textureWidth && height==(int)_textureHeight)
{
@ -228,15 +247,19 @@ void Texture2D::copyTexImage2D(State& state, int x, int y, int width, int height
_min_filter = LINEAR;
_mag_filter = LINEAR;
// Get a new 2d texture handle.
glGenTextures( 1, &handle );
_textureObjectBuffer[contextID] = textureObject = getTextureObjectManager()->generateTextureObject(contextID,GL_TEXTURE_2D);
glBindTexture( GL_TEXTURE_2D, handle );
textureObject->bind();
applyTexParameters(GL_TEXTURE_2D,state);
glCopyTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, x, y, width, height, 0 );
_textureWidth = width;
_textureHeight = height;
_numMipmapLevels = 1;
textureObject->setAllocated(_numMipmapLevels,_internalFormat,_textureWidth,_textureHeight,1,0);
// inform state that this texture is the current one bound.
state.haveAppliedAttribute(this);
@ -246,19 +269,19 @@ void Texture2D::copyTexSubImage2D(State& state, int xoffset, int yoffset, int x,
{
const unsigned int contextID = state.getContextID();
// get the globj for the current contextID.
GLuint& handle = getTextureObject(contextID);
// get the texture object for the current contextID.
TextureObject* textureObject = getTextureObject(contextID);
if (handle)
if (textureObject)
{
// we have a valid image
glBindTexture( GL_TEXTURE_2D, handle );
textureObject->bind();
applyTexParameters(GL_TEXTURE_2D,state);
glCopyTexSubImage2D( GL_TEXTURE_2D, 0, xoffset,yoffset, x, y, width, height);
/* Redundant, delete later */
glBindTexture( GL_TEXTURE_2D, handle );
//glBindTexture( GL_TEXTURE_2D, handle );
// inform state that this texture is the current one bound.
state.haveAppliedAttribute(this);

View File

@ -26,7 +26,7 @@ Texture3D::Texture3D():
_textureWidth(0),
_textureHeight(0),
_textureDepth(0),
_numMimpmapLevels(0)
_numMipmapLevels(0)
{
}
@ -36,7 +36,7 @@ Texture3D::Texture3D(const Texture3D& text,const CopyOp& copyop):
_textureWidth(text._textureWidth),
_textureHeight(text._textureHeight),
_textureDepth(text._textureDepth),
_numMimpmapLevels(text._numMimpmapLevels),
_numMipmapLevels(text._numMipmapLevels),
_subloadCallback(text._subloadCallback)
{
}
@ -109,13 +109,14 @@ void Texture3D::apply(State& state) const
return;
}
// get the globj for the current contextID.
GLuint& handle = getTextureObject(contextID);
if (handle != 0)
// get the texture object for the current contextID.
TextureObject* textureObject = getTextureObject(contextID);
if (textureObject)
{
// we have a valid image
textureObject->bind();
glBindTexture( GL_TEXTURE_3D, handle );
if (getTextureParameterDirty(state.getContextID())) applyTexParameters(GL_TEXTURE_3D,state);
if (_subloadCallback.valid())
@ -124,7 +125,7 @@ void Texture3D::apply(State& state) const
}
else if (_image.get() && getModifiedTag(contextID) != _image->getModifiedTag())
{
applyTexImage3D(GL_TEXTURE_3D,_image.get(),state, _textureWidth, _textureHeight, _textureDepth,_numMimpmapLevels);
applyTexImage3D(GL_TEXTURE_3D,_image.get(),state, _textureWidth, _textureHeight, _textureDepth,_numMipmapLevels);
// update the modified tag to show that it is upto date.
getModifiedTag(contextID) = _image->getModifiedTag();
@ -134,53 +135,50 @@ void Texture3D::apply(State& state) const
else if (_subloadCallback.valid())
{
glGenTextures( 1L, (GLuint *)&handle );
glBindTexture( GL_TEXTURE_3D, handle );
_textureObjectBuffer[contextID] = textureObject = getTextureObjectManager()->generateTextureObject(contextID,GL_TEXTURE_2D);
textureObject->bind();
applyTexParameters(GL_TEXTURE_3D,state);
_subloadCallback->load(*this,state);
textureObject->setAllocated(_numMipmapLevels,_internalFormat,_textureWidth,_textureHeight,_textureDepth,0);
// in theory the following line is redundent, but in practice
// have found that the first frame drawn doesn't apply the textures
// unless a second bind is called?!!
// perhaps it is the first glBind which is not required...
glBindTexture( GL_TEXTURE_3D, handle );
//glBindTexture( GL_TEXTURE_3D, handle );
}
else if (_image.valid() && _image->data())
{
glGenTextures( 1L, (GLuint *)&handle );
glBindTexture( GL_TEXTURE_3D, handle );
_textureObjectBuffer[contextID] = textureObject = getTextureObjectManager()->generateTextureObject(contextID,GL_TEXTURE_2D);
textureObject->bind();
applyTexParameters(GL_TEXTURE_3D,state);
applyTexImage3D(GL_TEXTURE_3D,_image.get(),state, _textureWidth, _textureHeight, _textureDepth,_numMimpmapLevels);
applyTexImage3D(GL_TEXTURE_3D,_image.get(),state, _textureWidth, _textureHeight, _textureDepth,_numMipmapLevels);
textureObject->setAllocated(_numMipmapLevels,_internalFormat,_textureWidth,_textureHeight,_textureDepth,0);
// update the modified tag to show that it is upto date.
getModifiedTag(contextID) = _image->getModifiedTag();
if (_unrefImageDataAfterApply)
if (_unrefImageDataAfterApply && areAllTextureObjectsLoaded())
{
// only unref image once all the graphics contexts has been set up.
unsigned int numLeftToBind=0;
for(unsigned int i=0;i<DisplaySettings::instance()->getMaxNumberOfGraphicsContexts();++i)
{
if (_handleList[i]==0) ++numLeftToBind;
}
if (numLeftToBind==0)
{
Texture3D* non_const_this = const_cast<Texture3D*>(this);
non_const_this->_image = 0;
}
Texture3D* non_const_this = const_cast<Texture3D*>(this);
non_const_this->_image = 0;
}
// in theory the following line is redundent, but in practice
// have found that the first frame drawn doesn't apply the textures
// unless a second bind is called?!!
// perhaps it is the first glBind which is not required...
glBindTexture( GL_TEXTURE_3D, handle );
//glBindTexture( GL_TEXTURE_3D, handle );
}
else
@ -194,7 +192,7 @@ void Texture3D::computeInternalFormat() const
if (_image.valid()) computeInternalFormatWithImage(*_image);
}
void Texture3D::applyTexImage3D(GLenum target, Image* image, State& state, GLsizei& inwidth, GLsizei& inheight, GLsizei& indepth, GLsizei& numMimpmapLevels) const
void Texture3D::applyTexImage3D(GLenum target, Image* image, State& state, GLsizei& inwidth, GLsizei& inheight, GLsizei& indepth, GLsizei& numMipmapLevels) const
{
// if we don't have a valid image we can't create a texture!
if (!image || !image->data())
@ -223,7 +221,7 @@ void Texture3D::applyTexImage3D(GLenum target, Image* image, State& state, GLsiz
if( _min_filter == LINEAR || _min_filter == NEAREST )
{
numMimpmapLevels = 1;
numMipmapLevels = 1;
extensions->glTexImage3D( target, 0, _internalFormat,
image->s(), image->t(), image->r(), 0,
(GLenum)image->getPixelFormat(),
@ -235,7 +233,7 @@ void Texture3D::applyTexImage3D(GLenum target, Image* image, State& state, GLsiz
if(!image->isMipmap())
{
numMimpmapLevels = 1;
numMipmapLevels = 1;
extensions->gluBuild3DMipmaps( target, _internalFormat,
image->s(),image->t(),image->r(),
@ -245,13 +243,13 @@ void Texture3D::applyTexImage3D(GLenum target, Image* image, State& state, GLsiz
}
else
{
numMimpmapLevels = image->getNumMipmapLevels();
numMipmapLevels = image->getNumMipmapLevels();
int width = image->s();
int height = image->t();
int depth = image->r();
for( GLsizei k = 0 ; k < numMimpmapLevels && (width || height || depth) ;k++)
for( GLsizei k = 0 ; k < numMipmapLevels && (width || height || depth) ;k++)
{
if (width == 0)
@ -284,21 +282,20 @@ void Texture3D::applyTexImage3D(GLenum target, Image* image, State& state, GLsiz
void Texture3D::copyTexSubImage3D(State& state, int xoffset, int yoffset, int zoffset, int x, int y, int width, int height )
{
const unsigned int contextID = state.getContextID();
// get the globj for the current contextID.
GLuint& handle = getTextureObject(contextID);
const Extensions* extensions = getExtensions(contextID,true);
if (handle)
{
// we have a valid image
glBindTexture( GL_TEXTURE_3D, handle );
// get the texture object for the current contextID.
TextureObject* textureObject = getTextureObject(contextID);
if (textureObject != 0)
{
textureObject->bind();
applyTexParameters(GL_TEXTURE_3D,state);
extensions->glCopyTexSubImage3D( GL_TEXTURE_3D, 0, xoffset,yoffset,zoffset, x, y, width, height);
/* Redundant, delete later */
glBindTexture( GL_TEXTURE_3D, handle );
//glBindTexture( GL_TEXTURE_3D, handle );
// inform state that this texture is the current one bound.
state.haveAppliedAttribute(this);

View File

@ -205,12 +205,13 @@ void TextureCubeMap::apply(State& state) const
if (!extensions->isCubeMapSupported())
return;
// get the globj for the current contextID.
GLuint& handle = getTextureObject(contextID);
// get the texture object for the current contextID.
TextureObject* textureObject = getTextureObject(contextID);
if (handle != 0)
if (textureObject != 0)
{
glBindTexture( GL_TEXTURE_CUBE_MAP, handle );
textureObject->bind();
if (getTextureParameterDirty(state.getContextID())) applyTexParameters(GL_TEXTURE_CUBE_MAP,state);
if (_subloadCallback.valid())
@ -224,7 +225,7 @@ void TextureCubeMap::apply(State& state) const
const osg::Image* image = _images[n].get();
if (image && getModifiedTag((Face)n,contextID) != image->getModifiedTag())
{
applyTexImage2D_subload( faceTarget[n], _images[n].get(), state, _textureWidth, _textureHeight, _numMipmapLevels);
applyTexImage2D_subload( state, faceTarget[n], _images[n].get(), _textureWidth, _textureHeight, _numMipmapLevels);
getModifiedTag((Face)n,contextID) = image->getModifiedTag();
}
}
@ -233,8 +234,9 @@ void TextureCubeMap::apply(State& state) const
}
else if (_subloadCallback.valid())
{
glGenTextures( 1L, (GLuint *)&handle );
glBindTexture( GL_TEXTURE_CUBE_MAP, handle );
_textureObjectBuffer[contextID] = textureObject = getTextureObjectManager()->generateTextureObject(contextID,GL_TEXTURE_CUBE_MAP);
textureObject->bind();
applyTexParameters(GL_TEXTURE_CUBE_MAP,state);
@ -244,14 +246,22 @@ void TextureCubeMap::apply(State& state) const
// have found that the first frame drawn doesn't apply the textures
// unless a second bind is called?!!
// perhaps it is the first glBind which is not required...
glBindTexture( GL_TEXTURE_CUBE_MAP, handle );
//glBindTexture( GL_TEXTURE_CUBE_MAP, handle );
}
else if (imagesValid())
{
glGenTextures( 1L, (GLuint *)&handle );
glBindTexture( GL_TEXTURE_CUBE_MAP, handle );
// compute the internal texture format, this set the _internalFormat to an appropriate value.
computeInternalFormat();
// compute the dimensions of the texture.
computeRequiredTextureDimensions(state,*_images[0],_textureWidth, _textureHeight, _numMipmapLevels);
_textureObjectBuffer[contextID] = textureObject = getTextureObjectManager()->reuseOrGenerateTextureObject(
contextID,GL_TEXTURE_CUBE_MAP,_numMipmapLevels,_internalFormat,_textureWidth,_textureHeight,1,0);
textureObject->bind();
applyTexParameters(GL_TEXTURE_CUBE_MAP,state);
@ -260,28 +270,26 @@ void TextureCubeMap::apply(State& state) const
const osg::Image* image = _images[n].get();
if (image)
{
applyTexImage2D_load( faceTarget[n], image, state, _textureWidth, _textureHeight, _numMipmapLevels);
if (textureObject->isAllocated())
{
applyTexImage2D_subload( state, faceTarget[n], image, _textureWidth, _textureHeight, _numMipmapLevels);
}
else
{
applyTexImage2D_load( state, faceTarget[n], image, _textureWidth, _textureHeight, _numMipmapLevels);
}
getModifiedTag((Face)n,contextID) = image->getModifiedTag();
}
}
if (_unrefImageDataAfterApply)
if (_unrefImageDataAfterApply && areAllTextureObjectsLoaded())
{
// only unref image once all the graphics contexts has been set up.
unsigned int numLeftToBind=0;
for(unsigned int i=0;i<DisplaySettings::instance()->getMaxNumberOfGraphicsContexts();++i)
TextureCubeMap* non_const_this = const_cast<TextureCubeMap*>(this);
for (int n=0; n<6; n++)
{
if (_handleList[i]==0) ++numLeftToBind;
}
if (numLeftToBind==0)
{
TextureCubeMap* non_const_this = const_cast<TextureCubeMap*>(this);
for (int n=0; n<6; n++)
{
non_const_this->_images[n] = 0;
}
non_const_this->_images[n] = 0;
}
}
@ -289,7 +297,7 @@ void TextureCubeMap::apply(State& state) const
// have found that the first frame drawn doesn't apply the textures
// unless a second bind is called?!!
// perhaps it is the first glBind which is not required...
glBindTexture( GL_TEXTURE_CUBE_MAP, handle );
//glBindTexture( GL_TEXTURE_CUBE_MAP, handle );
}
else

View File

@ -103,12 +103,12 @@ void TextureRectangle::apply(State& state) const
// current OpenGL context.
const unsigned int contextID = state.getContextID();
// get the globj for the current contextID.
GLuint& handle = getTextureObject(contextID);
// get the texture object for the current contextID.
TextureObject* textureObject = getTextureObject(contextID);
if (handle != 0)
if (textureObject != 0)
{
glBindTexture(GL_TEXTURE_RECTANGLE_NV, handle);
textureObject->bind();
if (getTextureParameterDirty(state.getContextID()))
applyTexParameters(GL_TEXTURE_RECTANGLE_NV, state);
@ -117,33 +117,41 @@ void TextureRectangle::apply(State& state) const
}
else if (_subloadCallback.valid())
{
glGenTextures(1L, (GLuint *)&handle);
glBindTexture(GL_TEXTURE_RECTANGLE_NV, handle);
// we don't have a applyTexImage1D_subload yet so can't reuse.. so just generate a new texture object.
_textureObjectBuffer[contextID] = textureObject = getTextureObjectManager()->generateTextureObject(contextID,GL_TEXTURE_RECTANGLE_NV);
textureObject->bind();
applyTexParameters(GL_TEXTURE_RECTANGLE_NV, state);
_subloadCallback->load(*this, state);
textureObject->setAllocated(1,_internalFormat,_textureWidth,_textureHeight,1,0);
// in theory the following line is redundant, but in practice
// have found that the first frame drawn doesn't apply the textures
// unless a second bind is called?!!
// perhaps it is the first glBind which is not required...
glBindTexture(GL_TEXTURE_RECTANGLE_NV, handle);
//glBindTexture(GL_TEXTURE_RECTANGLE_NV, handle);
}
else if (_image.valid() && _image->data())
{
glGenTextures(1L, (GLuint *)&handle);
glBindTexture(GL_TEXTURE_RECTANGLE_NV, handle);
// we don't have a applyTexImage1D_subload yet so can't reuse.. so just generate a new texture object.
_textureObjectBuffer[contextID] = textureObject = getTextureObjectManager()->generateTextureObject(contextID,GL_TEXTURE_RECTANGLE_NV);
textureObject->bind();
applyTexParameters(GL_TEXTURE_RECTANGLE_NV, state);
applyTexImage(GL_TEXTURE_RECTANGLE_NV, _image.get(), state, _textureWidth, _textureHeight);
textureObject->setAllocated(1,_internalFormat,_textureWidth,_textureHeight,1,0);
// in theory the following line is redundant, but in practice
// have found that the first frame drawn doesn't apply the textures
// unless a second bind is called?!!
// perhaps it is the first glBind which is not required...
glBindTexture(GL_TEXTURE_RECTANGLE_NV, handle);
//glBindTexture(GL_TEXTURE_RECTANGLE_NV, handle);
}
else
{

View File

@ -21,6 +21,8 @@
#include <osg/Object>
#include <osg/Node>
#include <osg/Notify>
#include <osg/Geode>
#include <osg/Texture>
#include <osgDB/Registry>
#include <osgDB/FileUtils>
@ -378,6 +380,68 @@ void OSGPageManager::UpdatePositionThread(double inLocX,double inLocY)
osgSetEvent(locationChangeEvent);
}
class ReleaseTexturesAndDrawablesVisitor : public osg::NodeVisitor
{
public:
ReleaseTexturesAndDrawablesVisitor():
osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN)
{
}
virtual void apply(osg::Node& node)
{
apply(node.getStateSet());
traverse(node);
}
virtual void apply(osg::Geode& geode)
{
apply(geode.getStateSet());
for(unsigned int i=0;i<geode.getNumDrawables();++i)
{
apply(geode.getDrawable(i));
}
traverse(geode);
}
inline void apply(osg::StateSet* stateset)
{
if (stateset)
{
// search for the existance of any texture object attributes
bool foundTextureState = false;
osg::StateSet::TextureAttributeList& tal = stateset->getTextureAttributeList();
for(osg::StateSet::TextureAttributeList::iterator itr=tal.begin();
itr!=tal.end() && !foundTextureState;
++itr)
{
osg::StateSet::AttributeList& al = *itr;
osg::StateSet::AttributeList::iterator alitr = al.find(osg::StateAttribute::TEXTURE);
if (alitr!=al.end())
{
// found texture, so place it in the texture list.
osg::Texture* texture = static_cast<osg::Texture*>(alitr->second.first.get());
texture->dirtyTextureObject();
}
}
}
}
inline void apply(osg::Drawable* drawable)
{
apply(drawable->getStateSet());
if (drawable->getUseDisplayList() || drawable->getUseVertexBufferObjects());
{
drawable->dirtyDisplayList();
}
}
};
/* Merge Updates
Merge in the new tiles and unhook the ones we'll be deleting.
Actually, we'll hand these back to the paging thread for deletion.
@ -418,9 +482,13 @@ bool OSGPageManager::MergeUpdateThread(osg::Group *rootNode)
#ifdef USE_THREADLOOP_DELETE
// Put the unhooked things on the list to delete
{
ReleaseTexturesAndDrawablesVisitor rtadv;
osgLockMutex(changeListMutex);
for (unsigned int di=0;di<unhookList.size();di++)
{
toDelete.push_back(unhookList[di]);
unhookList[di]->accept(rtadv);
}
osgUnLockMutex(changeListMutex);
}
#endif

View File

@ -2,6 +2,7 @@
#include <osgDB/ReadFile>
#include <osg/Geode>
#include <osg/Timer>
#include <osg/Texture>
#ifdef WIN32
#include <windows.h>
@ -301,6 +302,68 @@ void DatabasePager::addLoadedDataToSceneGraph(double timeStamp)
}
class ReleaseTexturesAndDrawablesVisitor : public osg::NodeVisitor
{
public:
ReleaseTexturesAndDrawablesVisitor():
osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN)
{
}
virtual void apply(osg::Node& node)
{
apply(node.getStateSet());
traverse(node);
}
virtual void apply(osg::Geode& geode)
{
apply(geode.getStateSet());
for(unsigned int i=0;i<geode.getNumDrawables();++i)
{
apply(geode.getDrawable(i));
}
traverse(geode);
}
inline void apply(osg::StateSet* stateset)
{
if (stateset)
{
// search for the existance of any texture object attributes
bool foundTextureState = false;
osg::StateSet::TextureAttributeList& tal = stateset->getTextureAttributeList();
for(osg::StateSet::TextureAttributeList::iterator itr=tal.begin();
itr!=tal.end() && !foundTextureState;
++itr)
{
osg::StateSet::AttributeList& al = *itr;
osg::StateSet::AttributeList::iterator alitr = al.find(osg::StateAttribute::TEXTURE);
if (alitr!=al.end())
{
// found texture, so place it in the texture list.
osg::Texture* texture = static_cast<osg::Texture*>(alitr->second.first.get());
texture->dirtyTextureObject();
}
}
}
}
inline void apply(osg::Drawable* drawable)
{
apply(drawable->getStateSet());
if (drawable->getUseDisplayList() || drawable->getUseVertexBufferObjects());
{
drawable->dirtyDisplayList();
}
}
};
void DatabasePager::removeExpiredSubgraphs(double currentFrameTime)
{
double expiryTime = currentFrameTime - _expiryDelay;
@ -333,7 +396,20 @@ void DatabasePager::removeExpiredSubgraphs(double currentFrameTime)
//std::cout<<" PagedLOD "<<plod<<" refcount "<<plod->referenceCount()<<std::endl;
}
}
// for all the subgraphs to remove find all the textures and drawables and
// strip them from the display lists.
{
ReleaseTexturesAndDrawablesVisitor rtadv;
for(osg::NodeList::iterator nitr=childrenRemoved.begin();
nitr!=childrenRemoved.end();
++nitr)
{
(*nitr)->accept(rtadv);
}
}
if (_deleteRemovedSubgraphsInDatabaseThread)
{
// transfer the removed children over to the to delete list so the database thread can delete them.
@ -418,7 +494,7 @@ void DatabasePager::compileRenderingObjects(osg::State& state)
itr!=sslist.end() && elapsedTime<_maximumTimeForCompiling;
++itr)
{
std::cout<<" Compiling stateset "<<(*itr).get()<<std::endl;
//std::cout<<" Compiling stateset "<<(*itr).get()<<std::endl;
(*itr)->compile(state);
elapsedTime = timer.delta_s(start_tick,timer.tick());
}
@ -435,7 +511,7 @@ void DatabasePager::compileRenderingObjects(osg::State& state)
itr!=dwlist.end() && elapsedTime<_maximumTimeForCompiling;
++itr)
{
std::cout<<" Compiling drawable "<<(*itr).get()<<std::endl;
//std::cout<<" Compiling drawable "<<(*itr).get()<<std::endl;
(*itr)->compile(state);
elapsedTime = timer.delta_s(start_tick,timer.tick());
}
@ -478,7 +554,7 @@ void DatabasePager::compileRenderingObjects(osg::State& state)
}
else
{
std::cout<<"Not all compiled"<<std::endl;
//std::cout<<"Not all compiled"<<std::endl;
databaseRequest = 0;
}

View File

@ -387,16 +387,19 @@ void Font::GlyphTexture::apply(osg::State& state) const
const Extensions* extensions = getExtensions(contextID,true);
bool generateMipMapSupported = extensions->isGenerateMipMapSupported();
// get the globj for the current contextID.
GLuint& handle = getTextureObject(contextID);
// get the texture object for the current contextID.
TextureObject* textureObject = getTextureObject(contextID);
bool generateMipMapOn = false;
if (handle == 0)
if (textureObject == 0)
{
// being bound for the first time, need to allocate the texture
glGenTextures( 1L, (GLuint *)&handle );
glBindTexture( GL_TEXTURE_2D, handle );
_textureObjectBuffer[contextID] = textureObject = getTextureObjectManager()->reuseOrGenerateTextureObject(
contextID,GL_TEXTURE_2D,1,GL_LUMINANCE_ALPHA,getTextureWidth(), getTextureHeight(),1,0);
textureObject->bind();
applyTexParameters(GL_TEXTURE_2D,state);
@ -411,7 +414,6 @@ void Font::GlyphTexture::apply(osg::State& state) const
if (generateMipMapSupported)
{
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS,GL_TRUE);
generateMipMapOn = true;
}
else glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, LINEAR);
break;
@ -432,31 +434,31 @@ void Font::GlyphTexture::apply(osg::State& state) const
else
{
// reuse texture by binding.
glBindTexture( GL_TEXTURE_2D, handle );
textureObject->bind();
if (getTextureParameterDirty(contextID))
{
applyTexParameters(GL_TEXTURE_2D,state);
}
bool generateMipMapOn = false;
// need to look at generate mip map extension if mip mapping required.
switch(_min_filter)
{
case NEAREST_MIPMAP_NEAREST:
case NEAREST_MIPMAP_LINEAR:
case LINEAR_MIPMAP_NEAREST:
case LINEAR_MIPMAP_LINEAR:
if (generateMipMapSupported)
{
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS,GL_TRUE);
generateMipMapOn = true;
}
else glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, LINEAR);
break;
default:
// not mip mapping so no problems.
break;
}
// // need to look at generate mip map extension if mip mapping required.
// switch(_min_filter)
// {
// case NEAREST_MIPMAP_NEAREST:
// case NEAREST_MIPMAP_LINEAR:
// case LINEAR_MIPMAP_NEAREST:
// case LINEAR_MIPMAP_LINEAR:
// if (generateMipMapSupported)
// {
// glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS,GL_TRUE);
// generateMipMapOn = true;
// }
// else glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, LINEAR);
// break;
// default:
// // not mip mapping so no problems.
// break;
// }
}
@ -557,10 +559,10 @@ void Font::GlyphTexture::apply(osg::State& state) const
if (generateMipMapOn)
{
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS,GL_FALSE);
}
// if (generateMipMapTurnedOn)
// {
// glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS,GL_FALSE);
// }
}

View File

@ -207,20 +207,7 @@ void Text::setDrawMode(unsigned int mode)
{
if (_drawMode==mode) return;
if ((_drawMode&3) != (mode&3))
{
_drawMode=mode;
if (_drawMode&TEXT_PIXMAP)
{
setCharacterSizeMode(SCREEN_COORDS);
setAutoRotateToScreen(true);
}
computeGlyphRepresentation();
}
else
{
_drawMode=mode;
}
_drawMode=mode;
}
@ -660,7 +647,7 @@ void Text::drawImplementation(osg::State& state) const
glNormal3fv(_normal.ptr());
glColor4fv(_color.ptr());
if (_drawMode & TEXT && !(_drawMode & TEXT_PIXMAP))
if (_drawMode & TEXT)
{
state.disableAllVertexArrays();
@ -681,36 +668,6 @@ void Text::drawImplementation(osg::State& state) const
}
}
if (_drawMode & TEXT_PIXMAP)
{
state.applyTextureMode(0,GL_TEXTURE_2D,osg::StateAttribute::OFF);
for(TextureGlyphQuadMap::const_iterator titr=_textureGlyphQuadMap.begin();
titr!=_textureGlyphQuadMap.end();
++titr)
{
const GlyphQuads& glyphquad = titr->second;
int ci=1;
for(GlyphQuads::Glyphs::const_iterator gitr=glyphquad._glyphs.begin();
gitr!=glyphquad._glyphs.end();
++gitr, ci+=4)
{
Font::Glyph* glyph = *gitr;
glRasterPos3fv(glyphquad._transformedCoords[contextID][ci].ptr());
glyph->draw(state);
}
}
}
if (_drawMode & BOUNDINGBOX)
{

View File

@ -538,9 +538,12 @@ void SceneView::draw()
// context we are in so can flush the appropriate caches.
osg::Drawable::flushDeletedDisplayLists(_state->getContextID());
osg::Drawable::flushDeletedVertexBufferObjects(_state->getContextID());
osg::Texture::flushDeletedTextureObjects(_state->getContextID());
osg::VertexProgram::flushDeletedVertexProgramObjects(_state->getContextID());
double currentTime = _state->getFrameStamp()?_state->getFrameStamp()->getReferenceTime():0.0;
osg::Texture::getTextureObjectManager()->deleteTextureObjects(_state->getContextID(),currentTime);
RenderLeaf* previous = NULL;
if (_displaySettings.valid() && _displaySettings->getStereo())
{