Added support for texture object manager, which provides an automatic mechansim
for reusing deleted textures.
This commit is contained in:
parent
94d8e72ad3
commit
1b9d7d458a
@ -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)
|
||||
{
|
||||
|
@ -69,6 +69,7 @@ class SG_EXPORT StateSet : public Object
|
||||
|
||||
/** set this StateSet to contain specified GLMode and value.*/
|
||||
void setMode(StateAttribute::GLMode mode, StateAttribute::GLModeValue value);
|
||||
|
||||
/** set this StateSet to inherit specified GLMode type from parents.
|
||||
* has the effect of deleting any GlMode of specified type from StateSet.*/
|
||||
void setModeToInherit(StateAttribute::GLMode mode);
|
||||
|
@ -21,6 +21,8 @@
|
||||
#include <osg/Vec4>
|
||||
#include <osg/buffered_value>
|
||||
|
||||
#include <list>
|
||||
#include <map>
|
||||
|
||||
// if not defined by gl.h use the definition found in:
|
||||
// http://oss.sgi.com/projects/ogl-sample/registry/EXT/texture_filter_anisotropic.txt
|
||||
@ -204,12 +206,20 @@ class SG_EXPORT Texture : public osg::StateAttribute
|
||||
bool isCompressedInternalFormat() const;
|
||||
|
||||
|
||||
class TextureObject;
|
||||
|
||||
/** Get the handle to the texture object for the current context.*/
|
||||
inline GLuint& getTextureObject(unsigned int contextID) const
|
||||
inline TextureObject* getTextureObject(unsigned int contextID) const
|
||||
{
|
||||
return _handleList[contextID];
|
||||
return _textureObjectBuffer[contextID].get();
|
||||
}
|
||||
|
||||
/** Force a recompile on next apply() of associated OpenGL texture objects.*/
|
||||
void dirtyTextureObject();
|
||||
|
||||
/** return true if the texture objects for all the required graphics contexts are loaded.*/
|
||||
bool areAllTextureObjectsLoaded() const;
|
||||
|
||||
|
||||
/** get the dirty flag for the current contextID.*/
|
||||
inline unsigned int& getTextureParameterDirty(unsigned int contextID) const
|
||||
@ -217,22 +227,12 @@ class SG_EXPORT Texture : public osg::StateAttribute
|
||||
return _texParametersDirtyList[contextID];
|
||||
}
|
||||
|
||||
/** Force a recompile on next apply() of associated OpenGL texture objects.*/
|
||||
void dirtyTextureObject();
|
||||
|
||||
/** Force a resetting on next apply() of associated OpenGL texture parameters.*/
|
||||
void dirtyTextureParameters();
|
||||
|
||||
|
||||
/** use deleteTextureObject instead of glDeleteTextures to allow
|
||||
* OpenGL texture objects to cached until they can be deleted
|
||||
* by the OpenGL context in which they were created, specified
|
||||
* by contextID.*/
|
||||
static void deleteTextureObject(unsigned int contextID,GLuint handle);
|
||||
|
||||
/** flush all the cached display list which need to be deleted
|
||||
* in the OpenGL context related to contextID.*/
|
||||
static void flushDeletedTextureObjects(unsigned int contextID);
|
||||
|
||||
/** Texture is pure virtual base class, apply must be overriden. */
|
||||
virtual void apply(State& state) const = 0;
|
||||
@ -326,13 +326,14 @@ class SG_EXPORT Texture : public osg::StateAttribute
|
||||
* but need to ensure that they all use the same low common denominator extensions.*/
|
||||
static void setExtensions(unsigned int contextID,Extensions* extensions);
|
||||
|
||||
|
||||
/** Helper method which does the creation of the texture itself, but does not set or use texture binding.
|
||||
* Note, do not call this method directly unless you are implementing your own Subload callback*/
|
||||
void applyTexImage2D_load(GLenum target, const Image* image, State& state, GLsizei& width, GLsizei& height,GLsizei& numMimpmapLevels) const;
|
||||
void applyTexImage2D_load(State& state, GLenum target, const Image* image, GLsizei width, GLsizei height,GLsizei numMipmapLevels) const;
|
||||
|
||||
/** Helper method which subloads images to the texture itself, but does not set or use texture binding.
|
||||
* Note, do not call this method directly unless you are implementing your own Subload callback*/
|
||||
void applyTexImage2D_subload(GLenum target, const Image* image, State& state, GLsizei& width, GLsizei& height,GLsizei& numMimpmapLevels) const;
|
||||
void applyTexImage2D_subload(State& state, GLenum target, const Image* image, GLsizei width, GLsizei height,GLsizei numMipmapLevels) const;
|
||||
|
||||
protected :
|
||||
|
||||
@ -342,18 +343,18 @@ class SG_EXPORT Texture : public osg::StateAttribute
|
||||
|
||||
void computeInternalFormatWithImage(const osg::Image& image) const;
|
||||
|
||||
void computeRequiredTextureDimensions(State& state, const osg::Image& image,GLsizei& width, GLsizei& height,GLsizei& numMipmapLevels) const;
|
||||
|
||||
bool isCompressedInternalFormat(GLint internalFormat) const;
|
||||
|
||||
/** Helper method which does setting of texture paramters. */
|
||||
void applyTexParameters(GLenum target, State& state) const;
|
||||
|
||||
|
||||
|
||||
/** return -1 if *this < *rhs, 0 if *this==*rhs, 1 if *this>*rhs.*/
|
||||
int compareTexture(const Texture& rhs) const;
|
||||
|
||||
typedef buffered_value<GLuint> TextureNameList;
|
||||
mutable TextureNameList _handleList;
|
||||
|
||||
typedef buffered_value<unsigned int> TexParameterDirtyList;
|
||||
mutable TexParameterDirtyList _texParametersDirtyList;
|
||||
|
||||
@ -371,6 +372,172 @@ class SG_EXPORT Texture : public osg::StateAttribute
|
||||
|
||||
InternalFormatMode _internalFormatMode;
|
||||
mutable GLint _internalFormat;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
class TextureObject : public osg::Referenced
|
||||
{
|
||||
public:
|
||||
|
||||
inline TextureObject(GLuint id,GLenum target):
|
||||
_id(id),
|
||||
_target(target),
|
||||
_numMipmapLevels(0),
|
||||
_internalFormat(0),
|
||||
_width(0),
|
||||
_height(0),
|
||||
_depth(0),
|
||||
_border(0),
|
||||
_allocated(false),
|
||||
_timeStamp(0) {}
|
||||
|
||||
inline TextureObject(GLuint id,
|
||||
GLenum target,
|
||||
GLint numMipmapLevels,
|
||||
GLenum internalFormat,
|
||||
GLsizei width,
|
||||
GLsizei height,
|
||||
GLsizei depth,
|
||||
GLint border):
|
||||
_id(id),
|
||||
_target(target),
|
||||
_numMipmapLevels(numMipmapLevels),
|
||||
_internalFormat(internalFormat),
|
||||
_width(width),
|
||||
_height(height),
|
||||
_depth(depth),
|
||||
_border(border),
|
||||
_allocated(false),
|
||||
_timeStamp(0) {}
|
||||
|
||||
inline bool match(GLenum target,
|
||||
GLint numMipmapLevels,
|
||||
GLenum internalFormat,
|
||||
GLsizei width,
|
||||
GLsizei height,
|
||||
GLsizei depth,
|
||||
GLint border)
|
||||
{
|
||||
return isReusable() &&
|
||||
(_target == target) &&
|
||||
(_numMipmapLevels == numMipmapLevels) &&
|
||||
(_internalFormat == internalFormat) &&
|
||||
(_width == width) &&
|
||||
(_height == height) &&
|
||||
(_depth == depth) &&
|
||||
(_border == border);
|
||||
}
|
||||
|
||||
|
||||
inline void bind()
|
||||
{
|
||||
glBindTexture( _target, _id);
|
||||
}
|
||||
|
||||
|
||||
inline void setAllocated(bool allocated=true) { _allocated = allocated; }
|
||||
|
||||
inline void setAllocated(GLint numMipmapLevels,
|
||||
GLenum internalFormat,
|
||||
GLsizei width,
|
||||
GLsizei height,
|
||||
GLsizei depth,
|
||||
GLint border)
|
||||
{
|
||||
_allocated=true;
|
||||
_numMipmapLevels = numMipmapLevels;
|
||||
_internalFormat = internalFormat;
|
||||
_width = width;
|
||||
_height = height;
|
||||
_depth = depth;
|
||||
_border = border;
|
||||
}
|
||||
|
||||
inline bool isAllocated() const { return _allocated; }
|
||||
|
||||
inline bool isReusable() const { return _allocated && _width!=0; }
|
||||
|
||||
GLuint _id;
|
||||
GLenum _target;
|
||||
GLint _numMipmapLevels;
|
||||
GLenum _internalFormat;
|
||||
GLsizei _width;
|
||||
GLsizei _height;
|
||||
GLsizei _depth;
|
||||
GLint _border;
|
||||
|
||||
bool _allocated;
|
||||
double _timeStamp;
|
||||
};
|
||||
|
||||
typedef std::list< ref_ptr<TextureObject> > TextureObjectList;
|
||||
typedef std::map<unsigned int, TextureObjectList > TextureObjectListMap;
|
||||
|
||||
/** take the active texture objects from the Texture and place them in the specified TextureObjectListMap.*/
|
||||
void takeTextureObjects(TextureObjectListMap& toblm);
|
||||
|
||||
typedef buffered_object< ref_ptr<TextureObject> > TextureObjectBuffer;
|
||||
mutable TextureObjectBuffer _textureObjectBuffer;
|
||||
|
||||
|
||||
class TextureObjectManager : public osg::Referenced
|
||||
{
|
||||
public:
|
||||
|
||||
virtual TextureObject* generateTextureObject(unsigned int contextID,GLenum target);
|
||||
|
||||
virtual TextureObject* generateTextureObject(unsigned int contextID,
|
||||
GLenum target,
|
||||
GLint numMipmapLevels,
|
||||
GLenum internalFormat,
|
||||
GLsizei width,
|
||||
GLsizei height,
|
||||
GLsizei depth,
|
||||
GLint border);
|
||||
|
||||
virtual TextureObject* reuseTextureObject(unsigned int contextID,
|
||||
GLenum target,
|
||||
GLint numMipmapLevels,
|
||||
GLenum internalFormat,
|
||||
GLsizei width,
|
||||
GLsizei height,
|
||||
GLsizei depth,
|
||||
GLint border);
|
||||
|
||||
inline TextureObject* reuseOrGenerateTextureObject(unsigned int contextID,
|
||||
GLenum target,
|
||||
GLint numMipmapLevels,
|
||||
GLenum internalFormat,
|
||||
GLsizei width,
|
||||
GLsizei height,
|
||||
GLsizei depth,
|
||||
GLint border)
|
||||
{
|
||||
TextureObject* to = reuseTextureObject(contextID,target,numMipmapLevels,internalFormat,width,height,depth,border);
|
||||
if (to) return to;
|
||||
else return generateTextureObject(contextID,target,numMipmapLevels,internalFormat,width,height,depth,border);
|
||||
}
|
||||
|
||||
virtual void addTextureObjects(TextureObjectListMap& toblm);
|
||||
|
||||
virtual void addTextureObjectsFrom(Texture& texture);
|
||||
|
||||
virtual void deleteTextureObjects(unsigned int contextID,double currentTime);
|
||||
|
||||
|
||||
// how long to keep unsed texture objects around for before deleting.
|
||||
double _expiryDelay;
|
||||
|
||||
TextureObjectListMap _textureObjectListMap;
|
||||
|
||||
};
|
||||
|
||||
|
||||
static void setTextureObjectManager(TextureObjectManager* tom);
|
||||
static TextureObjectManager* getTextureObjectManager();
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
@ -87,10 +87,10 @@ class SG_EXPORT Texture1D : public Texture
|
||||
|
||||
/** Set the number of mip map levels the the texture has been created with,
|
||||
should only be called within an osg::Texuture::apply() and custom OpenGL texture load.*/
|
||||
void setNumMipmapLevels(unsigned int num) const { _numMimpmapLevels=num; }
|
||||
void setNumMipmapLevels(unsigned int num) const { _numMipmapLevels=num; }
|
||||
|
||||
/** Get the number of mip map levels the the texture has been created with.*/
|
||||
unsigned int getNumMipmapLevels() const { return _numMimpmapLevels; }
|
||||
unsigned int getNumMipmapLevels() const { return _numMipmapLevels; }
|
||||
|
||||
|
||||
/** Copy pixels into a 1D texture image.As per glCopyTexImage1D.
|
||||
@ -118,7 +118,7 @@ class SG_EXPORT Texture1D : public Texture
|
||||
|
||||
/** Helper method which does the creation of the texture itself, and
|
||||
* does not set or use texture binding. */
|
||||
void applyTexImage1D(GLenum target, Image* image, State& state, GLsizei& width, GLsizei& numMimpmapLevels) const;
|
||||
void applyTexImage1D(GLenum target, Image* image, State& state, GLsizei& width, GLsizei& numMipmapLevels) const;
|
||||
|
||||
|
||||
// not ideal that _image is mutable, but its required since
|
||||
@ -131,7 +131,7 @@ class SG_EXPORT Texture1D : public Texture
|
||||
mutable GLsizei _textureWidth;
|
||||
|
||||
// number of mip map levels the the texture has been created with,
|
||||
mutable GLsizei _numMimpmapLevels;
|
||||
mutable GLsizei _numMipmapLevels;
|
||||
|
||||
ref_ptr<SubloadCallback> _subloadCallback;
|
||||
|
||||
|
@ -88,10 +88,10 @@ class SG_EXPORT Texture3D : public Texture
|
||||
|
||||
/** Set the number of mip map levels the the texture has been created with,
|
||||
should only be called within an osg::Texuture::apply() and custom OpenGL texture load.*/
|
||||
void setNumMipmapLevels(unsigned int num) const { _numMimpmapLevels=num; }
|
||||
void setNumMipmapLevels(unsigned int num) const { _numMipmapLevels=num; }
|
||||
|
||||
/** Get the number of mip map levels the the texture has been created with.*/
|
||||
unsigned int getNumMipmapLevels() const { return _numMimpmapLevels; }
|
||||
unsigned int getNumMipmapLevels() const { return _numMipmapLevels; }
|
||||
|
||||
|
||||
/** Copy a two-dimensional texture subimage. As per glCopyTexSubImage2D.
|
||||
@ -175,7 +175,7 @@ class SG_EXPORT Texture3D : public Texture
|
||||
|
||||
virtual void computeInternalFormat() const;
|
||||
|
||||
void applyTexImage3D(GLenum target, Image* image, State& state, GLsizei& inwidth, GLsizei& inheight, GLsizei& indepth, GLsizei& numMimpmapLevels) const;
|
||||
void applyTexImage3D(GLenum target, Image* image, State& state, GLsizei& inwidth, GLsizei& inheight, GLsizei& indepth, GLsizei& numMipmapLevels) const;
|
||||
|
||||
// not ideal that _image is mutable, but its required since
|
||||
// Image::ensureDimensionsArePowerOfTwo() can only be called
|
||||
@ -187,7 +187,7 @@ class SG_EXPORT Texture3D : public Texture
|
||||
mutable GLsizei _textureWidth, _textureHeight, _textureDepth;
|
||||
|
||||
// number of mip map levels the the texture has been created with,
|
||||
mutable GLsizei _numMimpmapLevels;
|
||||
mutable GLsizei _numMipmapLevels;
|
||||
|
||||
ref_ptr<SubloadCallback> _subloadCallback;
|
||||
|
||||
|
@ -202,9 +202,8 @@ public:
|
||||
enum DrawModeMask
|
||||
{
|
||||
TEXT = 1, /// default
|
||||
TEXT_PIXMAP = 2,
|
||||
BOUNDINGBOX = 4,
|
||||
ALIGNMENT = 8
|
||||
BOUNDINGBOX = 2,
|
||||
ALIGNMENT = 4
|
||||
};
|
||||
|
||||
void setDrawMode(unsigned int mode);
|
||||
|
@ -79,8 +79,8 @@ CXXFILES =\
|
||||
TexGen.cpp\
|
||||
TexMat.cpp\
|
||||
Texture.cpp\
|
||||
Texture1D.cpp\
|
||||
Texture2D.cpp\
|
||||
Texture1D.cpp\
|
||||
Texture3D.cpp\
|
||||
TextureCubeMap.cpp\
|
||||
TextureRectangle.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<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
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
// }
|
||||
|
||||
|
||||
}
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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())
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user