diff --git a/examples/osgautotransform/osgautotransform.cpp b/examples/osgautotransform/osgautotransform.cpp index ba1a8e121..292ac4660 100644 --- a/examples/osgautotransform/osgautotransform.cpp +++ b/examples/osgautotransform/osgautotransform.cpp @@ -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) { diff --git a/include/osg/StateSet b/include/osg/StateSet index f3ed8198c..d93c7a4d9 100644 --- a/include/osg/StateSet +++ b/include/osg/StateSet @@ -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); diff --git a/include/osg/Texture b/include/osg/Texture index 79c40743c..05172fe27 100644 --- a/include/osg/Texture +++ b/include/osg/Texture @@ -21,6 +21,8 @@ #include #include +#include +#include // 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 TextureNameList; - mutable TextureNameList _handleList; - typedef buffered_value 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 > TextureObjectList; + typedef std::map 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 > 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(); + + }; diff --git a/include/osg/Texture1D b/include/osg/Texture1D index c90784c0b..8dfdeed9c 100644 --- a/include/osg/Texture1D +++ b/include/osg/Texture1D @@ -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; diff --git a/include/osg/Texture3D b/include/osg/Texture3D index 6984fdcf8..af63fba63 100644 --- a/include/osg/Texture3D +++ b/include/osg/Texture3D @@ -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; diff --git a/include/osgText/Text b/include/osgText/Text index 0d95cc0be..cebd1b801 100644 --- a/include/osgText/Text +++ b/include/osgText/Text @@ -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); diff --git a/src/osg/GNUmakefile b/src/osg/GNUmakefile index ea8bb9652..081f49efb 100644 --- a/src/osg/GNUmakefile +++ b/src/osg/GNUmakefile @@ -79,8 +79,8 @@ CXXFILES =\ TexGen.cpp\ TexMat.cpp\ Texture.cpp\ - Texture1D.cpp\ Texture2D.cpp\ + Texture1D.cpp\ Texture3D.cpp\ TextureCubeMap.cpp\ TextureRectangle.cpp\ diff --git a/src/osg/Texture.cpp b/src/osg/Texture.cpp index 431753c60..5ccded03a 100644 --- a/src/osg/Texture.cpp +++ b/src/osg/Texture.cpp @@ -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 TextureObjectVector; -typedef std::map 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 "<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_id)); + itr = tol.erase(itr); + //++numTexturesDeleted; + } + else + { + ++itr; } } + //if (numTexturesDeleted) std::cout<<" deleted "< 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 "<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;igetMaxNumberOfGraphicsContexts();++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 '"<getFileName()<<"' from ("<s()<<","<t()<<") to ("<s()<<","<t()<<") to ("<getFileName().empty()) notify(NOTICE) << "Scaling image '"<getFileName()<<"' from ("<s()<<","<t()<<") to ("<s()<<","<t()<<") to ("<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 '"<getFileName()<<"' from ("<s()<<","<t()<<") to ("<s()<<","<t()<<") to ("<getFileName().empty()) notify(NOTICE) << "Scaling image '"<getFileName()<<"' from ("<s()<<","<t()<<") to ("<s()<<","<t()<<") to ("<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 { diff --git a/src/osg/Texture1D.cpp b/src/osg/Texture1D.cpp index b335041dc..c0c51083e 100644 --- a/src/osg/Texture1D.cpp +++ b/src/osg/Texture1D.cpp @@ -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;igetMaxNumberOfGraphicsContexts();++i) - { - if (_handleList[i]==0) ++numLeftToBind; - } - if (numLeftToBind==0) - { - Texture1D* non_const_this = const_cast(this); - non_const_this->_image = 0; - } + Texture1D* non_const_this = const_cast(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); diff --git a/src/osg/Texture2D.cpp b/src/osg/Texture2D.cpp index d925abeba..6fb58bbbd 100644 --- a/src/osg/Texture2D.cpp +++ b/src/osg/Texture2D.cpp @@ -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"<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;igetMaxNumberOfGraphicsContexts();++i) - { - if (_handleList[i]==0) ++numLeftToBind; - } - if (numLeftToBind==0) - { - Texture2D* non_const_this = const_cast(this); - non_const_this->_image = 0; - } + Texture2D* non_const_this = const_cast(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); diff --git a/src/osg/Texture3D.cpp b/src/osg/Texture3D.cpp index e65c940e6..d837939c7 100644 --- a/src/osg/Texture3D.cpp +++ b/src/osg/Texture3D.cpp @@ -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;igetMaxNumberOfGraphicsContexts();++i) - { - if (_handleList[i]==0) ++numLeftToBind; - } - if (numLeftToBind==0) - { - Texture3D* non_const_this = const_cast(this); - non_const_this->_image = 0; - } + Texture3D* non_const_this = const_cast(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); diff --git a/src/osg/TextureCubeMap.cpp b/src/osg/TextureCubeMap.cpp index be99be309..622dff561 100644 --- a/src/osg/TextureCubeMap.cpp +++ b/src/osg/TextureCubeMap.cpp @@ -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;igetMaxNumberOfGraphicsContexts();++i) + TextureCubeMap* non_const_this = const_cast(this); + for (int n=0; n<6; n++) { - if (_handleList[i]==0) ++numLeftToBind; - } - if (numLeftToBind==0) - { - TextureCubeMap* non_const_this = const_cast(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 diff --git a/src/osg/TextureRectangle.cpp b/src/osg/TextureRectangle.cpp index 009475f53..2cd0215b6 100644 --- a/src/osg/TextureRectangle.cpp +++ b/src/osg/TextureRectangle.cpp @@ -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 { diff --git a/src/osgPlugins/txp/trPagePageManager.cpp b/src/osgPlugins/txp/trPagePageManager.cpp index 16688d6cc..8cf585669 100644 --- a/src/osgPlugins/txp/trPagePageManager.cpp +++ b/src/osgPlugins/txp/trPagePageManager.cpp @@ -21,6 +21,8 @@ #include #include #include +#include +#include #include #include @@ -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;igetTextureAttributeList(); + 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(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;diaccept(rtadv); + } osgUnLockMutex(changeListMutex); } #endif diff --git a/src/osgProducer/DatabasePager.cpp b/src/osgProducer/DatabasePager.cpp index 251da2a2b..58f4f4443 100644 --- a/src/osgProducer/DatabasePager.cpp +++ b/src/osgProducer/DatabasePager.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #ifdef WIN32 #include @@ -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;igetTextureAttributeList(); + 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(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 "<referenceCount()<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()<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()<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"<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); +// } } diff --git a/src/osgText/Text.cpp b/src/osgText/Text.cpp index f95b41b98..f349ad89a 100644 --- a/src/osgText/Text.cpp +++ b/src/osgText/Text.cpp @@ -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) { diff --git a/src/osgUtil/SceneView.cpp b/src/osgUtil/SceneView.cpp index 208122cc7..66f905284 100644 --- a/src/osgUtil/SceneView.cpp +++ b/src/osgUtil/SceneView.cpp @@ -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()) {