From bb0022175b31a4db5969935ff821422686f44c3d Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 5 Sep 2002 11:42:55 +0000 Subject: [PATCH] Added new buffered_value template class which encapsulates a std::vector but initializes the array to the number of graphics contexts, and automatically expands the array when indices outside the current size are required. Added new osg::Texture::Extensions nested class to handle extensions on a per context basis. --- include/osg/Texture | 63 +++++---- include/osg/Texture3D | 20 +++ include/osg/buffered_value | 59 +++++++++ src/Demos/osgtexture3D/osgtexture3D.cpp | 2 +- src/osg/Texture.cpp | 42 +++--- src/osg/Texture1D.cpp | 13 +- src/osg/Texture2D.cpp | 13 +- src/osg/Texture3D.cpp | 169 +++++++++++++++--------- src/osg/TextureCubeMap.cpp | 18 +-- src/osgUtil/Tesselator.cpp | 55 +++++--- 10 files changed, 287 insertions(+), 167 deletions(-) create mode 100644 include/osg/buffered_value diff --git a/include/osg/Texture b/include/osg/Texture index dc94a3fe0..211104ab3 100644 --- a/include/osg/Texture +++ b/include/osg/Texture @@ -11,10 +11,8 @@ #include #include #include +#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 @@ -179,34 +177,55 @@ class SG_EXPORT Texture : public osg::StateAttribute bool isCompressedInternalFormat() const; +// /** Get the handle to the texture object for the current context.*/ +// /** return the OpenGL texture object for specified context.*/ +// inline GLuint& getTextureObject(uint contextID) const +// { +// // pad out handle list if required. +// if (_handleList.size()<=contextID) +// _handleList.resize(contextID+1,0); +// +// // get the globj for the current contextID. +// return _handleList[contextID]; +// } +// +// inline uint& getModifiedTag(uint contextID) const +// { +// // pad out handle list if required. +// if (_modifiedTag.size()<=contextID) +// _modifiedTag.resize(contextID+1,0); +// +// // get the modified tag for the current contextID. +// return _modifiedTag[contextID]; +// } +// +// inline uint& getTextureParameterDity(uint contextID) const +// { +// // pad out handle list if required. +// if (_texParametersDirtyList.size()<=contextID) +// _texParametersDirtyList.resize(contextID+1,0); +// +// // get the dirty flag for the current contextID. +// return _texParametersDirtyList[contextID]; +// } + + /** Get the handle to the texture object for the current context.*/ /** return the OpenGL texture object for specified context.*/ inline GLuint& getTextureObject(uint contextID) const { - // pad out handle list if required. - if (_handleList.size()<=contextID) - _handleList.resize(contextID+1,0); - // get the globj for the current contextID. return _handleList[contextID]; } inline uint& getModifiedTag(uint contextID) const { - // pad out handle list if required. - if (_modifiedTag.size()<=contextID) - _modifiedTag.resize(contextID+1,0); - // get the modified tag for the current contextID. return _modifiedTag[contextID]; } inline uint& getTextureParameterDity(uint contextID) const { - // pad out handle list if required. - if (_texParametersDirtyList.size()<=contextID) - _texParametersDirtyList.resize(contextID+1,0); - // get the dirty flag for the current contextID. return _texParametersDirtyList[contextID]; } @@ -259,13 +278,16 @@ class SG_EXPORT Texture : public osg::StateAttribute /** return -1 if *this < *rhs, 0 if *this==*rhs, 1 if *this>*rhs.*/ int compareTexture(const Texture& rhs) const; - typedef std::vector TextureNameList; +// typedef std::vector TextureNameList; + typedef buffered_value TextureNameList; mutable TextureNameList _handleList; - typedef std::vector ImageModifiedTag; +// typedef std::vector ImageModifiedTag; + typedef buffered_value ImageModifiedTag; mutable ImageModifiedTag _modifiedTag; - typedef std::vector TexParameterDirtyList; +// typedef std::vector TexParameterDirtyList; + typedef buffered_value TexParameterDirtyList; mutable TexParameterDirtyList _texParametersDirtyList; WrapMode _wrap_s; @@ -281,11 +303,6 @@ class SG_EXPORT Texture : public osg::StateAttribute InternalFormatMode _internalFormatMode; mutable GLint _internalFormat; - // static cache of deleted display lists which can only - // by completely deleted once the appropriate OpenGL context - // is set. - typedef std::map > DeletedTextureObjectCache; - static DeletedTextureObjectCache s_deletedTextureObjectCache; }; } diff --git a/include/osg/Texture3D b/include/osg/Texture3D index 8ac65294b..ee46d8ce5 100644 --- a/include/osg/Texture3D +++ b/include/osg/Texture3D @@ -92,6 +92,26 @@ class SG_EXPORT Texture3D : public Texture /** On first apply (unless already compiled), create the minmapped * texture and bind it, subsequent apply will simple bind to texture.*/ virtual void apply(State& state) const; + + + struct Extensions : public osg::Referenced + { + Extensions(); + + + bool isTexture3DSupported; + bool isTexture3DFast; + GLint maxTexture3DSize; + + + void glTexImage3D( GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels); + void glTexSubImage3D( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels); + void glCopyTexSubImage3D( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height ); + void gluBuild3DMipmaps( GLenum target, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *data); + + }; + + static Extensions* getExtensions(uint contextID=0); protected : diff --git a/include/osg/buffered_value b/include/osg/buffered_value new file mode 100644 index 000000000..2bb2a60c0 --- /dev/null +++ b/include/osg/buffered_value @@ -0,0 +1,59 @@ +//C++ header - Open Scene Graph - Copyright (C) 1998-2002 Robert Osfield +//Distributed under the terms of the GNU Library General Public License (LGPL) +//as published by the Free Software Foundation. + +#ifndef OSG_BUFFERED_VALUE +#define OSG_BUFFERED_VALUE 1 + +#include +#include + +namespace osg { + +/** Simple buffered value array which is used for values that need to multibuffered on + * one per graphics context basis.*/ + +template +class buffered_value +{ + public: + + inline buffered_value(): + _array(DisplaySettings::instance()->getMaxNumberOfGraphicsContexts(),0) + {} + + buffered_value& operator = (const buffered_value& rhs) + { + _array = rhs._array; + return *this; + } + + inline void clear() { _array.clear(); } + + inline bool empty() const { return _array.empty(); } + + inline unsigned int size() const { return _array.size(); } + + inline T& operator[] (unsigned int pos) + { + // automatically resize array. + if (_array.size()<=pos) + _array.resize(pos+1,0); + + return _array[pos]; + } +/* // do we implement the const version??? + inline T operator[] (unsigned int pos) const + { + return 0; + } +*/ + + protected: + + std::vector _array; +}; + +} + +#endif diff --git a/src/Demos/osgtexture3D/osgtexture3D.cpp b/src/Demos/osgtexture3D/osgtexture3D.cpp index 37a7466cc..e73f34759 100644 --- a/src/Demos/osgtexture3D/osgtexture3D.cpp +++ b/src/Demos/osgtexture3D/osgtexture3D.cpp @@ -49,7 +49,7 @@ class ConstructStateCallback : public osg::NodeCallback } // get max 3D texture size - int textureSize; + GLint textureSize; glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, &textureSize); if (textureSize > 256) textureSize = 256; diff --git a/src/osg/Texture.cpp b/src/osg/Texture.cpp index a97502982..15dd1a383 100644 --- a/src/osg/Texture.cpp +++ b/src/osg/Texture.cpp @@ -10,8 +10,6 @@ typedef void (APIENTRY * MyCompressedTexImage2DArbProc) (GLenum target, GLint le using namespace osg; -Texture::DeletedTextureObjectCache Texture::s_deletedTextureObjectCache; - Texture::Texture(): _wrap_s(CLAMP), _wrap_t(CLAMP), @@ -23,9 +21,9 @@ Texture::Texture(): _internalFormatMode(USE_IMAGE_DATA_FORMAT), _internalFormat(0) { - _handleList.resize(DisplaySettings::instance()->getMaxNumberOfGraphicsContexts(),0); - _modifiedTag.resize(DisplaySettings::instance()->getMaxNumberOfGraphicsContexts(),0); - _texParametersDirtyList.resize(DisplaySettings::instance()->getMaxNumberOfGraphicsContexts(),true); +// _handleList.resize(DisplaySettings::instance()->getMaxNumberOfGraphicsContexts(),0); +// _modifiedTag.resize(DisplaySettings::instance()->getMaxNumberOfGraphicsContexts(),0); +// _texParametersDirtyList.resize(DisplaySettings::instance()->getMaxNumberOfGraphicsContexts(),true); } Texture::Texture(const Texture& text,const CopyOp& copyop): @@ -40,9 +38,9 @@ Texture::Texture(const Texture& text,const CopyOp& copyop): _internalFormatMode(text._internalFormatMode), _internalFormat(text._internalFormat) { - _handleList.resize(DisplaySettings::instance()->getMaxNumberOfGraphicsContexts(),0); - _modifiedTag.resize(DisplaySettings::instance()->getMaxNumberOfGraphicsContexts(),0); - _texParametersDirtyList.resize(DisplaySettings::instance()->getMaxNumberOfGraphicsContexts(),true); +// _handleList.resize(DisplaySettings::instance()->getMaxNumberOfGraphicsContexts(),0); +// _modifiedTag.resize(DisplaySettings::instance()->getMaxNumberOfGraphicsContexts(),0); +// _texParametersDirtyList.resize(DisplaySettings::instance()->getMaxNumberOfGraphicsContexts(),true); } Texture::~Texture() @@ -136,11 +134,9 @@ void Texture::dirtyTextureObject() void Texture::dirtyTextureParameters() { - for(TexParameterDirtyList::iterator itr=_texParametersDirtyList.begin(); - itr!=_texParametersDirtyList.end(); - ++itr) + for(uint i=0;i<_texParametersDirtyList.size();++i) { - *itr = true; + _texParametersDirtyList[i] = 0; } } @@ -435,10 +431,20 @@ void Texture::applyTexImage2D(GLenum target, Image* image, State& state, GLsizei } -/** 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 map to manage the deletion of texture objects are the right time. +////////////////////////////////////////////////////////////////////////////////////////////// +#include +#include + +// static cache of deleted display lists which can only +// by completely deleted once the appropriate OpenGL context +// is set. +typedef std::map > DeletedTextureObjectCache; +static DeletedTextureObjectCache s_deletedTextureObjectCache; + + void Texture::deleteTextureObject(uint contextID,GLuint handle) { if (handle!=0) @@ -449,8 +455,6 @@ void Texture::deleteTextureObject(uint contextID,GLuint handle) } -/** flush all the cached display list which need to be deleted - * in the OpenGL context related to contextID.*/ void Texture::flushDeletedTextureObjects(uint contextID) { DeletedTextureObjectCache::iterator citr = s_deletedTextureObjectCache.find(contextID); @@ -461,7 +465,7 @@ void Texture::flushDeletedTextureObjects(uint contextID) titr!=textureObjectSet.end(); ++titr) { - glDeleteTextures( 1L, (const GLuint *)&(*titr )); + glDeleteTextures( 1L, &(*titr )); } s_deletedTextureObjectCache.erase(citr); } diff --git a/src/osg/Texture1D.cpp b/src/osg/Texture1D.cpp index de5de92b9..01d4664cc 100644 --- a/src/osg/Texture1D.cpp +++ b/src/osg/Texture1D.cpp @@ -65,18 +65,7 @@ int Texture1D::compare(const StateAttribute& sa) const void Texture1D::setImage(Image* image) { // delete old texture objects. - for(TextureNameList::iterator itr=_handleList.begin(); - itr!=_handleList.end(); - ++itr) - { - if (*itr != 0) - { - // contact global texture object handler to delete texture objects - // in appropriate context. - // glDeleteTextures( 1L, (const GLuint *)itr ); - *itr = 0; - } - } + dirtyTextureObject(); _image = image; } diff --git a/src/osg/Texture2D.cpp b/src/osg/Texture2D.cpp index 5669586ae..414bbf122 100644 --- a/src/osg/Texture2D.cpp +++ b/src/osg/Texture2D.cpp @@ -68,18 +68,7 @@ int Texture2D::compare(const StateAttribute& sa) const void Texture2D::setImage(Image* image) { // delete old texture objects. - for(TextureNameList::iterator itr=_handleList.begin(); - itr!=_handleList.end(); - ++itr) - { - if (*itr != 0) - { - // contact global texture object handler to delete texture objects - // in appropriate context. - // glDeleteTextures( 1L, (const GLuint *)itr ); - *itr = 0; - } - } + dirtyTextureObject(); _image = image; } diff --git a/src/osg/Texture3D.cpp b/src/osg/Texture3D.cpp index 5c8c27931..e1f889da7 100644 --- a/src/osg/Texture3D.cpp +++ b/src/osg/Texture3D.cpp @@ -6,10 +6,6 @@ #include -typedef void (APIENTRY * GLTexImage3DProc) ( GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels); -typedef void (APIENTRY * GLTexSubImage3DProc) ( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels); -typedef void (APIENTRY * GLCopyTexSubImageProc) ( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height ); -typedef void (APIENTRY * GLUBuild3DMipMapsProc) ( GLenum target, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *data); using namespace osg; @@ -78,18 +74,7 @@ int Texture3D::compare(const StateAttribute& sa) const void Texture3D::setImage(Image* image) { // delete old texture objects. - for(TextureNameList::iterator itr=_handleList.begin(); - itr!=_handleList.end(); - ++itr) - { - if (*itr != 0) - { - // contact global texture object handler to delete texture objects - // in appropriate context. - // glDeleteTextures( 1L, (const GLuint *)itr ); - *itr = 0; - } - } + dirtyTextureObject(); _image = image; } @@ -97,18 +82,18 @@ void Texture3D::setImage(Image* image) void Texture3D::apply(State& state) const { - static bool s_texturing_supported = strncmp((const char*)glGetString(GL_VERSION),"1.2",3)>=0 || - isGLExtensionSupported("GL_EXT_texture3D"); - - if (!s_texturing_supported) - { - notify(WARN)<<"Warning: Texture3D::apply(..) failed, 3D texturing is not support by your OpenGL drivers."<isTexture3DSupported) + { + notify(WARN)<<"Warning: Texture3D::apply(..) failed, 3D texturing is not support by OpenGL driver."<data()) return; - static GLTexImage3DProc s_glTexImage3D = (GLTexImage3DProc) getGLExtensionFuncPtr("glTexImage3D","glTexImage3DEXT"); - if (!s_glTexImage3D) - { - notify(WARN) << "Warning:: Texture3D::applyTexImage3D(..) failed, 3D texturing not supported by your OpenGL drivers."<getModifiedTag(); @@ -209,30 +190,23 @@ void Texture3D::applyTexImage3D(GLenum target, Image* image, State& state, GLsiz if( _min_filter == LINEAR || _min_filter == NEAREST ) { numMimpmapLevels = 1; - s_glTexImage3D( target, 0, _internalFormat, - image->s(), image->t(), image->r(), 0, - (GLenum)image->getPixelFormat(), - (GLenum)image->getDataType(), - image->data() ); + extensions->glTexImage3D( target, 0, _internalFormat, + image->s(), image->t(), image->r(), 0, + (GLenum)image->getPixelFormat(), + (GLenum)image->getDataType(), + image->data() ); } else { if(!image->isMipmap()) { - static GLUBuild3DMipMapsProc s_gluBuild3DMipmaps = (GLUBuild3DMipMapsProc) getGLUExtensionFuncPtr("gluBuild3DMipmaps"); - if (!s_gluBuild3DMipmaps) - { - notify(WARN) << "Warning:: Texture3D::applyTexImage3D(..) failed, gluBuild3DMipmaps not supported by your OpenGL drivers."<s(),image->t(),image->r(), - (GLenum)image->getPixelFormat(), (GLenum)image->getDataType(), - image->data() ); + extensions->gluBuild3DMipmaps( target, _internalFormat, + image->s(),image->t(),image->r(), + (GLenum)image->getPixelFormat(), (GLenum)image->getDataType(), + image->data() ); } else @@ -253,11 +227,11 @@ void Texture3D::applyTexImage3D(GLenum target, Image* image, State& state, GLsiz if (depth == 0) depth = 1; - s_glTexImage3D( target, k, _internalFormat, - width, height, depth, 0, - (GLenum)image->getPixelFormat(), - (GLenum)image->getDataType(), - image->getMipmapData(k)); + extensions->glTexImage3D( target, k, _internalFormat, + width, height, depth, 0, + (GLenum)image->getPixelFormat(), + (GLenum)image->getDataType(), + image->getMipmapData(k)); width >>= 1; height >>= 1; @@ -275,18 +249,11 @@ 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 ) { - static GLCopyTexSubImageProc s_glCopyTexSubImage3D = (GLCopyTexSubImageProc) getGLExtensionFuncPtr("glCopyTexSubImage3D","glCopyTexSubImage3DEXT"); - if (!s_glCopyTexSubImage3D) - { - notify(WARN) << "Warning:: Texture3D::copyTexSubImage3D(..) failed, 3D texture copy sub image not supported by your OpenGL drivers."<glCopyTexSubImage3D( GL_TEXTURE_3D, 0, xoffset,yoffset,zoffset, x, y, width, height); /* Redundant, delete later */ glBindTexture( GL_TEXTURE_3D, handle ); @@ -308,3 +275,83 @@ void Texture3D::copyTexSubImage3D(State& state, int xoffset, int yoffset, int zo notify(WARN)<<"Warning: Texture3D::copyTexSubImage3D(..) failed, cannot not copy to a non existant texture."< > BufferedExtensions; + static BufferedExtensions s_extensions; + + if (!s_extensions[contextID]) s_extensions[contextID] = new Extensions; + + return s_extensions[contextID].get(); +} + +Texture3D::Extensions::Extensions() +{ + isTexture3DFast = isGLExtensionSupported("GL_EXT_texture3D"); + + if (isTexture3DFast) isTexture3DSupported = true; + else isTexture3DSupported = strncmp((const char*)glGetString(GL_VERSION),"1.2",3)>=0; + + glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, &maxTexture3DSize); +} + +void Texture3D::Extensions::glTexImage3D( GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels) +{ + typedef void (APIENTRY * GLTexImage3DProc) ( GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels); + static GLTexImage3DProc s_glTexImage3D = (GLTexImage3DProc) getGLExtensionFuncPtr("glTexImage3D","glTexImage3DEXT"); + + if (s_glTexImage3D) + { + (*s_glTexImage3D)( target, level, internalFormat, width, height, depth, border, format, type, pixels); + } + else + { + notify(WARN)<<"Error: glTexImage3D not supported by OpenGL driver"<_v,vertex); -// cout<<"\t"<<*vertex<get(); - - osg::DrawElementsUShort* elements = new osg::DrawElementsUShort(prim->_mode); - for(Prim::VecList::iterator vitr=prim->_vertices.begin(); + { + Prim* prim = primItr->get(); + osg::Vec3 norm(0.0f,0.0f,0.0f); + + osg::DrawElementsUShort* elements = new osg::DrawElementsUShort(prim->_mode); + for(Prim::VecList::iterator vitr=prim->_vertices.begin(); vitr!=prim->_vertices.end(); ++vitr) - { - elements->push_back(vertexPtrToIndexMap[*vitr]); - } - - if (primItr==_primList.begin()) - { - // first new primitive so overwrite the previous polygon. - geom.getPrimitiveList()[primNo] = elements; - } - else - { - // subsequence primtives add to the back of the primitive list. - geom.addPrimitive(elements); + { + elements->push_back(vertexPtrToIndexMap[*vitr]); + } + + if (primItr==_primList.begin()) + { + // first new primitive so overwrite the previous polygon. + geom.getPrimitiveList()[primNo] = elements; + if (normals) { + norm=(*normals)[iprim]; // GWM Sep 2002 the flat shaded normal + } + } + else + { + // subsequence primitives add to the back of the primitive list. + geom.addPrimitive(elements); + if (normals) normals->push_back(norm); // GWM Sep 2002 add flat shaded normal for new facet + } + iprim++; // GWM Sep 2002 count which normal we should use } }