From 239068f2230683ca8fe3f2d32cc597926d7b8a17 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sat, 24 Aug 2002 19:39:39 +0000 Subject: [PATCH] Added new osg::TextureBase, osg::Texture1D, osg::Texture2D, and osg::Texture3D classes, and changed osg::Texture and osg::TextureCubeMap so that they now derive from osg::TextureBase. --- VisualStudio/osg/osg.dsp | 32 + VisualStudio/osgPlugins/osg/dot_osg.dsp | 8 + .../osgParticle/dot_osgParticle.dsp | 80 --- include/osg/CopyOp | 6 +- include/osg/ImpostorSprite | 10 +- include/osg/Texture | 270 +-------- include/osg/Texture1D | 126 ++++ include/osg/Texture2D | 127 ++++ include/osg/Texture3D | 121 ++++ include/osg/TextureBase | 283 +++++++++ include/osg/TextureCubeMap | 61 +- include/osgUtil/RenderToTextureStage | 8 +- src/Demos/osgcopy/osgcopy.cpp | 4 +- src/Demos/osgprerender/osgprerender.cpp | 178 ++++-- src/Demos/osgtexture/osgtexture.cpp | 78 +-- src/osg/CopyOp.cpp | 33 +- src/osg/Image.cpp | 6 +- src/osg/ImpostorSprite.cpp | 10 +- src/osg/Makefile | 4 + src/osg/Point.cpp | 2 +- src/osg/State.cpp | 2 +- src/osg/TexEnvCombine.cpp | 2 +- src/osg/Texture.cpp | 561 +----------------- src/osg/Texture1D.cpp | 335 +++++++++++ src/osg/Texture2D.cpp | 234 ++++++++ src/osg/Texture3D.cpp | 280 +++++++++ src/osg/TextureBase.cpp | 493 +++++++++++++++ src/osg/TextureCubeMap.cpp | 118 ++-- src/osgPlugins/dx/DXWriter.cpp | 8 - src/osgPlugins/osg/Makefile | 4 +- src/osgPlugins/osg/Texture.cpp | 108 +--- src/osgPlugins/osg/Texture2D.cpp | 71 +++ src/osgPlugins/osg/TextureBase.cpp | 263 ++++++++ src/osgPlugins/osg/TextureCubeMap.cpp | 13 +- src/osgUtil/CullVisitor.cpp | 2 +- 35 files changed, 2801 insertions(+), 1140 deletions(-) create mode 100644 include/osg/Texture1D create mode 100644 include/osg/Texture2D create mode 100644 include/osg/Texture3D create mode 100644 include/osg/TextureBase create mode 100644 src/osg/Texture1D.cpp create mode 100644 src/osg/Texture2D.cpp create mode 100644 src/osg/Texture3D.cpp create mode 100644 src/osg/TextureBase.cpp create mode 100644 src/osgPlugins/osg/Texture2D.cpp create mode 100644 src/osgPlugins/osg/TextureBase.cpp diff --git a/VisualStudio/osg/osg.dsp b/VisualStudio/osg/osg.dsp index e0501cf5d..1ba9d81ba 100755 --- a/VisualStudio/osg/osg.dsp +++ b/VisualStudio/osg/osg.dsp @@ -381,6 +381,22 @@ SOURCE=..\..\src\osg\Texture.cpp # End Source File # Begin Source File +SOURCE=..\..\src\osg\TextureBase.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\src\osg\Texture1D.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\src\osg\Texture2D.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\src\osg\Texture3D.cpp +# End Source File +# Begin Source File + SOURCE=..\..\src\osg\TextureCubeMap.cpp # End Source File # Begin Source File @@ -753,6 +769,22 @@ SOURCE=..\..\Include\Osg\Texture # End Source File # Begin Source File +SOURCE=..\..\Include\Osg\TextureBase +# End Source File +# Begin Source File + +SOURCE=..\..\Include\Osg\Texture1D +# End Source File +# Begin Source File + +SOURCE=..\..\Include\Osg\Texture2D +# End Source File +# Begin Source File + +SOURCE=..\..\Include\Osg\Texture3D +# End Source File +# Begin Source File + SOURCE=..\..\Include\Osg\TextureCubeMap # End Source File # Begin Source File diff --git a/VisualStudio/osgPlugins/osg/dot_osg.dsp b/VisualStudio/osgPlugins/osg/dot_osg.dsp index 446ebecf6..ce7c897a1 100755 --- a/VisualStudio/osgPlugins/osg/dot_osg.dsp +++ b/VisualStudio/osgPlugins/osg/dot_osg.dsp @@ -278,6 +278,14 @@ SOURCE=..\..\..\src\osgPlugins\osg\Texture.cpp # End Source File # Begin Source File +SOURCE=..\..\..\src\osgPlugins\osg\TextureBase.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\osgPlugins\osg\Texture2D.cpp +# End Source File +# Begin Source File + SOURCE=..\..\..\src\osgPlugins\osg\TextureCubeMap.cpp # End Source File # Begin Source File diff --git a/VisualStudio/osgPlugins/osgParticle/dot_osgParticle.dsp b/VisualStudio/osgPlugins/osgParticle/dot_osgParticle.dsp index 08c218948..63b85d7a7 100644 --- a/VisualStudio/osgPlugins/osgParticle/dot_osgParticle.dsp +++ b/VisualStudio/osgPlugins/osgParticle/dot_osgParticle.dsp @@ -94,164 +94,84 @@ LINK32=link.exe # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File - - SOURCE=..\..\..\src\osgPlugins\osgParticle\IO_AccelOperator.cpp - # End Source File - # Begin Source File - - SOURCE=..\..\..\src\osgPlugins\osgParticle\IO_CenteredPlacer.cpp - # End Source File - # Begin Source File - - SOURCE=..\..\..\src\osgPlugins\osgParticle\IO_Emitter.cpp - # End Source File - # Begin Source File - - SOURCE=..\..\..\src\osgPlugins\osgParticle\IO_FluidFrictionOperator.cpp - # End Source File - # Begin Source File - - SOURCE=..\..\..\src\osgPlugins\osgParticle\IO_ForceOperator.cpp - # End Source File - # Begin Source File - - SOURCE=..\..\..\src\osgPlugins\osgParticle\IO_LinearInterpolator.cpp - # End Source File - # Begin Source File - - SOURCE=..\..\..\src\osgPlugins\osgParticle\IO_ModularEmitter.cpp - # End Source File - # Begin Source File - - SOURCE=..\..\..\src\osgPlugins\osgParticle\IO_ModularProgram.cpp - # End Source File - # Begin Source File - - SOURCE=..\..\..\src\osgPlugins\osgParticle\IO_MultiSegmentPlacer.cpp - # End Source File - # Begin Source File - - SOURCE=..\..\..\src\osgPlugins\osgParticle\IO_Particle.cpp - # End Source File - # Begin Source File - - SOURCE=..\..\..\src\osgPlugins\osgParticle\IO_ParticleProcessor.cpp - # End Source File - # Begin Source File - - SOURCE=..\..\..\src\osgPlugins\osgParticle\IO_ParticleSystem.cpp - # End Source File - # Begin Source File - - SOURCE=..\..\..\src\osgPlugins\osgParticle\IO_ParticleSystemUpdater.cpp - # End Source File - # Begin Source File - - SOURCE=..\..\..\src\osgPlugins\osgParticle\IO_PointPlacer.cpp - # End Source File - # Begin Source File - - SOURCE=..\..\..\src\osgPlugins\osgParticle\IO_Program.cpp - # End Source File - # Begin Source File - - SOURCE=..\..\..\src\osgPlugins\osgParticle\IO_RadialShooter.cpp - # End Source File - # Begin Source File - - SOURCE=..\..\..\src\osgPlugins\osgParticle\IO_RandomRateCounter.cpp - # End Source File - # Begin Source File - - SOURCE=..\..\..\src\osgPlugins\osgParticle\IO_SectorPlacer.cpp - # End Source File - # Begin Source File - - SOURCE=..\..\..\src\osgPlugins\osgParticle\IO_SegmentPlacer.cpp - # End Source File - # Begin Source File - - SOURCE=..\..\..\src\osgPlugins\osgParticle\IO_VariableRateCounter.cpp - # End Source File - # End Group # Begin Group "Header Files" diff --git a/include/osg/CopyOp b/include/osg/CopyOp index f80cbc9e5..e2702a3d9 100644 --- a/include/osg/CopyOp +++ b/include/osg/CopyOp @@ -12,7 +12,8 @@ namespace osg { class Referenced; class Object; class Image; -class Texture; +//class Texture; +class TextureBase; class StateSet; class StateAttribute; class Node; @@ -53,7 +54,8 @@ class SG_EXPORT CopyOp virtual Drawable* operator() (const Drawable* drawable) const; virtual StateSet* operator() (const StateSet* stateset) const; virtual StateAttribute* operator() (const StateAttribute* attr) const; - virtual Texture* operator() (const Texture* text) const; +// virtual Texture* operator() (const Texture* text) const; + virtual TextureBase* operator() (const TextureBase* text) const; virtual Image* operator() (const Image* image) const; virtual Array* operator() (const Array* image) const; virtual Primitive* operator() (const Primitive* image) const; diff --git a/include/osg/ImpostorSprite b/include/osg/ImpostorSprite index 541b607fe..0de18c86e 100644 --- a/include/osg/ImpostorSprite +++ b/include/osg/ImpostorSprite @@ -14,7 +14,7 @@ namespace osg { -class Texture; +class Texture2D; class Impostor; class ImpostorSpriteManager; @@ -106,10 +106,10 @@ class SG_EXPORT ImpostorSprite : public Drawable * which transform local coords into screen space.*/ const float calcPixelError(const Matrix& MVPW) const; - void setTexture(Texture* tex,int s,int t); + void setTexture(Texture2D* tex,int s,int t); - Texture* getTexture() { return _texture; } - const Texture* getTexture() const { return _texture; } + Texture2D* getTexture() { return _texture; } + const Texture2D* getTexture() const { return _texture; } const int s() const { return _s; } const int t() const { return _t; } @@ -149,7 +149,7 @@ class SG_EXPORT ImpostorSprite : public Drawable Vec2 _texcoords[4]; Vec3 _controlcoords[4]; - Texture* _texture; + Texture2D* _texture; int _s; int _t; diff --git a/include/osg/Texture b/include/osg/Texture index 5071f2510..cc89efe17 100644 --- a/include/osg/Texture +++ b/include/osg/Texture @@ -4,72 +4,17 @@ // -*-c++-*- +#define TEXTURE_USE_DEPRECATED_API +#ifdef TEXTURE_USE_DEPRECATED_API + #ifndef OSG_TEXTURE #define OSG_TEXTURE 1 -#include -#include -#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 -#ifndef GL_TEXTURE_MAX_ANISOTROPY_EXT -#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE -#endif - -#ifndef GL_ARB_texture_compression -#define GL_COMPRESSED_ALPHA_ARB 0x84E9 -#define GL_COMPRESSED_LUMINANCE_ARB 0x84EA -#define GL_COMPRESSED_LUMINANCE_ALPHA_ARB 0x84EB -#define GL_COMPRESSED_INTENSITY_ARB 0x84EC -#define GL_COMPRESSED_RGB_ARB 0x84ED -#define GL_COMPRESSED_RGBA_ARB 0x84EE -#define GL_TEXTURE_COMPRESSION_HINT_ARB 0x84EF -#define GL_TEXTURE_IMAGE_SIZE_ARB 0x86A0 -#define GL_TEXTURE_COMPRESSED_ARB 0x86A1 -#define GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A2 -#define GL_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A3 -#endif - -#ifndef GL_EXT_texture_compression_s3tc -#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 -#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 -#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2 -#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3 -#endif - -#ifndef GL_MIRRORED_REPEAT_IBM -#define GL_MIRRORED_REPEAT_IBM 0x8370 -#endif - -#ifndef GL_CLAMP_TO_EDGE -#define GL_CLAMP_TO_EDGE 0x812F -#endif - -#ifndef GL_CLAMP_TO_BORDER_ARB -#define GL_CLAMP_TO_BORDER_ARB 0x812D -#endif - -#ifndef GL_GENERATE_MIPMAP_SGIS -#define GL_GENERATE_MIPMAP_SGIS 0x8191 -#define GL_GENERATE_MIPMAP_HINT_SGIS 0x8192 -#endif - -#ifndef GL_TEXTURE_3D -#define GL_TEXTURE_3D 0x806F -#endif - +#include namespace osg { /** Texture state class which encapsulates OpenGl texture functionality.*/ -class SG_EXPORT Texture : public StateAttribute +class SG_EXPORT Texture : public TextureBase { public : @@ -80,15 +25,13 @@ class SG_EXPORT Texture : public StateAttribute Texture(const Texture& text,const CopyOp& copyop=CopyOp::SHALLOW_COPY); META_StateAttribute(osg, Texture,TEXTURE); - - virtual bool isTextureAttribute() const { return true; } /** return -1 if *this < *rhs, 0 if *this==*rhs, 1 if *this>*rhs.*/ virtual int compare(const StateAttribute& rhs) const; virtual void getAssociatedModes(std::vector& modes) const { - modes.push_back(_target); + modes.push_back(GL_TEXTURE_2D); } /** Set the texture image. */ @@ -100,17 +43,6 @@ class SG_EXPORT Texture : public StateAttribute /** Get the const texture image. */ inline const Image* getImage() const { return _image.get(); } - /** Set the unreference image after apply flag, default value is false. - * If set to true the attached image is unreferenced via a _image = 0; - * if the image has no other references to it, it will be automatically - * deleted. Note, this should only by used in case where only a single - * graphics context is being used, otherwise only the first context will - * be set, with the rest left with no image to apply.*/ - void setUnrefImageAfterApply(bool unrefImage) { _unrefImageAfterApply = unrefImage; } - - /** Get the unreference image after apply flag.*/ - bool getUnrefImageAfterApply() const { return _unrefImageAfterApply; } - /** Copy pixels into a 2D texture image.As per glCopyTexImage2D. * Creates an OpenGL texture object from the current OpenGL background * framebuffer contents at pos \a x, \a y with width \a width and @@ -126,82 +58,7 @@ class SG_EXPORT Texture : public StateAttribute */ void copyTexSubImage2D(State& state, int xoffset, int yoffset, int x, int y, int width, int height ); - enum WrapParameter { - WRAP_S, - WRAP_T, - WRAP_R - }; - enum WrapMode { - CLAMP = GL_CLAMP, - CLAMP_TO_EDGE = GL_CLAMP_TO_EDGE, - CLAMP_TO_BORDER = GL_CLAMP_TO_BORDER_ARB, - REPEAT = GL_REPEAT, - MIRROR = GL_MIRRORED_REPEAT_IBM - }; - - /** Set the texture wrap mode.*/ - void setWrap(const WrapParameter which, const WrapMode wrap); - /** Get the texture wrap mode.*/ - const WrapMode getWrap(const WrapParameter which) const; - - - /** Sets the border color for this texture. Makes difference only if - * wrap mode is CLAMP_TO_BORDER */ - void setBorderColor(const Vec4& color) { _borderColor = color; _texParamtersDirty = true; } - - const Vec4& borderColor(void) const { return _borderColor; } - - - enum FilterParameter { - MIN_FILTER, - MAG_FILTER - }; - - enum FilterMode { - LINEAR = GL_LINEAR, - LINEAR_MIPMAP_LINEAR = GL_LINEAR_MIPMAP_LINEAR, - LINEAR_MIPMAP_NEAREST = GL_LINEAR_MIPMAP_NEAREST, - NEAREST = GL_NEAREST, - NEAREST_MIPMAP_LINEAR = GL_NEAREST_MIPMAP_LINEAR, - NEAREST_MIPMAP_NEAREST = GL_NEAREST_MIPMAP_NEAREST, - }; - - - /** Set the texture filter mode.*/ - void setFilter(const FilterParameter which, const FilterMode filter); - - /** Get the texture filter mode.*/ - const FilterMode getFilter(const FilterParameter which) const; - - /** Set the maximum anisotropy value, default value is 1.0 for - * no anisotropic filtering. If hardware does not support anisotropic - * filtering then normal filtering is used, equivilant to a max anisotropy value of 1.0. - * valid range is 1.0f upwards. The maximum value depends on the graphics - * system being used.*/ - void setMaxAnisotropy(float anis); - - /** Get the maximum anisotropy value.*/ - inline float getMaxAnisotropy() const { return _maxAnisotropy; } - - enum InternalFormatMode { - USE_IMAGE_DATA_FORMAT, - USE_USER_DEFINED_FORMAT, - USE_ARB_COMPRESSION, - USE_S3TC_DXT1_COMPRESSION, - USE_S3TC_DXT3_COMPRESSION, - USE_S3TC_DXT5_COMPRESSION - }; - - /** Set the internal format mode. - * Note, If the mode is set USE_IMAGE_DATA_FORMAT, USE_ARB_COMPRESSION, - * USE_S3TC_COMPRESSION the internalFormat is automatically selected, - * and will overwrite the previous _internalFormatValue. - */ - inline void setInternalFormatMode(const InternalFormatMode mode) { _internalFormatMode = mode; } - - /** Get the internal format mode.*/ - inline const InternalFormatMode getInternalFormatMode() const { return _internalFormatMode; } /** Set the internal format to use when creating OpenGL textures. * Also sets the internalFormatMode to USE_USER_DEFINED_FORMAT. @@ -209,11 +66,11 @@ class SG_EXPORT Texture : public StateAttribute inline void setInternalFormatValue(const int internalFormat) { _internalFormatMode = USE_USER_DEFINED_FORMAT; - _internalFormatValue = internalFormat; + _internalFormat = internalFormat; } /** Get the internal format to use when creating OpenGL textures.*/ - inline const int getInternalFormatValue() const { return _internalFormatValue; } + inline const int getInternalFormatValue() const { return _internalFormat; } enum SubloadMode { @@ -301,41 +158,6 @@ class SG_EXPORT Texture : public StateAttribute const SubloadCallback* getSubloadCallback() const { return _subloadCallback.get(); } - - - /** Get the handle to the texture object for the current context.*/ - /** return the OpenGL texture object for specified context.*/ - inline GLuint& getTextureObject(const 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(const 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]; - } - - /** Force a recompile on next apply() of associated OpenGL texture objects.*/ - void dirtyTextureObject(); - - /** 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; - - /** Compile the texture mip maps. Implemented by simply calling apply().*/ - virtual void compile(State& state) const; - - /** 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; } @@ -343,41 +165,15 @@ class SG_EXPORT Texture : public StateAttribute /** Get the number of mip map levels the the texture has been created with.*/ unsigned int getNumMipmapLevels() const { return _numMimpmapLevels; } - - - /** 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(uint contextID,GLuint handle); - - /** flush all the cached display list which need to be deleted - * in the OpenGL context related to contextID.*/ - static void flushDeletedTextureObjects(uint contextID); - - /** Get the maximum texture size supported, this is the - normally define by GL_MAX_TEXTURE_SIZE, but can be overridden - by the OSG_MAX_TEXTURE_SIZE environmental variable.*/ - static GLint getMaxTextureSize(); + /** 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; protected : virtual ~Texture(); - - /** Method which does setting of texture paramters. */ - void applyTexParameters(GLenum target, State& state) const; - - /** Method which does the creation of the texture itself, and - * does not set or use texture binding. */ - virtual void applyTexImage(GLenum target, Image* image, State& state) const; - - typedef std::vector TextureNameList; - mutable TextureNameList _handleList; - - typedef std::vector ImageModifiedTag; - mutable ImageModifiedTag _modifiedTag; - + virtual void computeInternalFormat() const; // not ideal that _image is mutable, but its required since // Image::ensureDimensionsArePowerOfTwo() can only be called @@ -385,32 +181,11 @@ class SG_EXPORT Texture : public StateAttribute // which is const... mutable ref_ptr _image; - bool _unrefImageAfterApply; - - GLenum _target; // defaults to GL_TEXTURE_2D - - WrapMode _wrap_s; - WrapMode _wrap_t; - WrapMode _wrap_r; - - FilterMode _min_filter; - FilterMode _mag_filter; - float _maxAnisotropy; - - // true if apply tex parameters required. - mutable bool _texParamtersDirty; - - - InternalFormatMode _internalFormatMode; - mutable GLint _internalFormatValue; - - Vec4 _borderColor; - // subloaded images can have different texture and image sizes. mutable GLsizei _textureWidth, _textureHeight; // number of mip map levels the the texture has been created with, - mutable unsigned int _numMimpmapLevels; + mutable GLsizei _numMimpmapLevels; SubloadMode _subloadMode; GLint _subloadTextureOffsetX, _subloadTextureOffsetY; @@ -418,14 +193,21 @@ class SG_EXPORT Texture : public StateAttribute GLsizei _subloadImageWidth, _subloadImageHeight; ref_ptr _subloadCallback; - - // 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; }; } + #endif + +#else // USE_DEPRECATED_API + +#include + +namespace osg { + + typedef Texture2D Texture; + +} + +#endif // USE_DEPRECATED_API diff --git a/include/osg/Texture1D b/include/osg/Texture1D new file mode 100644 index 000000000..cd110e97f --- /dev/null +++ b/include/osg/Texture1D @@ -0,0 +1,126 @@ +//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. + +// -*-c++-*- + +#ifndef OSG_TEXTURE1D +#define OSG_TEXTURE1D 1 + +#include + +namespace osg { + +/** Texture state class which encapsulates OpenGl 1D texture functionality.*/ +class SG_EXPORT Texture1D : public TextureBase +{ + + public : + + Texture1D(); + + /** Copy constructor using CopyOp to manage deep vs shallow copy.*/ + Texture1D(const Texture1D& text,const CopyOp& copyop=CopyOp::SHALLOW_COPY); + + META_StateAttribute(osg, Texture1D,TEXTURE); + + /** return -1 if *this < *rhs, 0 if *this==*rhs, 1 if *this>*rhs.*/ + virtual int compare(const StateAttribute& rhs) const; + + virtual void getAssociatedModes(std::vector& modes) const + { + modes.push_back(GL_TEXTURE_1D); + } + + /** Set the texture image. */ + void setImage(Image* image); + + /** Get the texture image. */ + Image* getImage() { return _image.get(); } + + /** Get the const texture image. */ + inline const Image* getImage() const { return _image.get(); } + + + /** Set the texture width and height. If width or height are zero then + * the repsective size value is calculated from the source image sizes. */ + inline void setTextureSize(const int width) const + { + _textureWidth = width; + } + + /** Get the texture subload width. */ + inline void getTextureSize(int& width) const + { + width = _textureWidth; + } + + + class SubloadCallback : public Referenced + { + public: + virtual void load(const Texture1D& texture,State& state) const = 0; + virtual void subload(const Texture1D& texture,State& state) const = 0; + }; + + void setSubloadCallback(SubloadCallback* cb) { _subloadCallback = cb;; } + + SubloadCallback* getSubloadCallback() { return _subloadCallback.get(); } + + const SubloadCallback* getSubloadCallback() const { return _subloadCallback.get(); } + + + /** 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; } + + /** Get the number of mip map levels the the texture has been created with.*/ + unsigned int getNumMipmapLevels() const { return _numMimpmapLevels; } + + + /** Copy pixels into a 1D texture image.As per glCopyTexImage1D. + * Creates an OpenGL texture object from the current OpenGL background + * framebuffer contents at pos \a x, \a y with width \a width. \a width must be a power of two. + */ + void copyTexImage1D(State& state, int x, int y, int width); + + /** Copy a one-dimensional texture subimage. As per glCopyTexSubImage1D. + * Updates portion of an existing OpenGL texture object from the current OpenGL background + * framebuffer contents at pos \a x, \a y with width \a width. + */ + void copyTexSubImage1D(State& state, int xoffset, int x, int y, int width); + + + /** 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; + + protected : + + virtual ~Texture1D(); + + virtual void computeInternalFormat() const; + + /** 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; + + + // not ideal that _image is mutable, but its required since + // Image::ensureDimensionsArePowerOfTwo() can only be called + // in a valid OpenGL context, a therefore within an Texture::apply + // which is const... + mutable ref_ptr _image; + + // subloaded images can have different texture and image sizes. + mutable GLsizei _textureWidth; + + // number of mip map levels the the texture has been created with, + mutable GLsizei _numMimpmapLevels; + + ref_ptr _subloadCallback; +}; + +} + +#endif diff --git a/include/osg/Texture2D b/include/osg/Texture2D new file mode 100644 index 000000000..c48d2c59f --- /dev/null +++ b/include/osg/Texture2D @@ -0,0 +1,127 @@ +//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. + +// -*-c++-*- + +#ifndef OSG_TEXTURE2D +#define OSG_TEXTURE2D 1 + +#include + +namespace osg { + +/** Texture state class which encapsulates OpenGl texture functionality.*/ +class SG_EXPORT Texture2D : public TextureBase +{ + + public : + + Texture2D(); + + /** Copy constructor using CopyOp to manage deep vs shallow copy.*/ + Texture2D(const Texture2D& text,const CopyOp& copyop=CopyOp::SHALLOW_COPY); + + META_StateAttribute(osg, Texture2D,TEXTURE); + + /** return -1 if *this < *rhs, 0 if *this==*rhs, 1 if *this>*rhs.*/ + virtual int compare(const StateAttribute& rhs) const; + + virtual void getAssociatedModes(std::vector& modes) const + { + modes.push_back(GL_TEXTURE_2D); + } + + /** Set the texture image. */ + void setImage(Image* image); + + /** Get the texture image. */ + Image* getImage() { return _image.get(); } + + /** Get the const texture image. */ + inline const Image* getImage() const { return _image.get(); } + + + /** Set the texture width and height. If width or height are zero then + * the repsective size value is calculated from the source image sizes. */ + inline void setTextureSize(const int width, const int height) const + { + _textureWidth = width; + _textureHeight = height; + } + + /** Get the texture subload width. */ + inline void getTextureSize(int& width, int& height) const + { + width = _textureWidth; + height = _textureHeight; + } + + + class SubloadCallback : public Referenced + { + public: + virtual void load(const Texture2D& texture,State& state) const = 0; + virtual void subload(const Texture2D& texture,State& state) const = 0; + }; + + void setSubloadCallback(SubloadCallback* cb) { _subloadCallback = cb;; } + + SubloadCallback* getSubloadCallback() { return _subloadCallback.get(); } + + const SubloadCallback* getSubloadCallback() const { return _subloadCallback.get(); } + + + /** 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; } + + /** Get the number of mip map levels the the texture has been created with.*/ + unsigned int getNumMipmapLevels() const { return _numMimpmapLevels; } + + + /** Copy pixels into a 2D texture image.As per glCopyTexImage2D. + * Creates an OpenGL texture object from the current OpenGL background + * framebuffer contents at pos \a x, \a y with width \a width and + * height \a height. \a width and \a height must be a power of two. + */ + void copyTexImage2D(State& state, int x, int y, int width, int height ); + + /** Copy a two-dimensional texture subimage. As per glCopyTexSubImage2D. + * Updates portion of an existing OpenGL texture object from the current OpenGL background + * framebuffer contents at pos \a x, \a y with width \a width and + * height \a height. \a width and \a height must be a power of two, + * and writing into the texture with offset \a xoffset and \a yoffset. + */ + void copyTexSubImage2D(State& state, int xoffset, int yoffset, int x, int y, int width, int height ); + + + /** 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; + + protected : + + virtual ~Texture2D(); + + virtual void computeInternalFormat() const; + + + // not ideal that _image is mutable, but its required since + // Image::ensureDimensionsArePowerOfTwo() can only be called + // in a valid OpenGL context, a therefore within an Texture::apply + // which is const... + mutable ref_ptr _image; + + // subloaded images can have different texture and image sizes. + mutable GLsizei _textureWidth, _textureHeight; + + // number of mip map levels the the texture has been created with, + mutable GLsizei _numMimpmapLevels; + + ref_ptr _subloadCallback; +}; + +} + +#endif diff --git a/include/osg/Texture3D b/include/osg/Texture3D new file mode 100644 index 000000000..3047d0266 --- /dev/null +++ b/include/osg/Texture3D @@ -0,0 +1,121 @@ +//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. + +// -*-c++-*- + +#ifndef OSG_TEXTURE3D +#define OSG_TEXTURE3D 1 + +#include + +namespace osg { + +/** Texture state class which encapsulates OpenGl 3D texture functionality.*/ +class SG_EXPORT Texture3D : public TextureBase +{ + + public : + + Texture3D(); + + /** Copy constructor using CopyOp to manage deep vs shallow copy.*/ + Texture3D(const Texture3D& text,const CopyOp& copyop=CopyOp::SHALLOW_COPY); + + META_StateAttribute(osg, Texture3D,TEXTURE); + + /** return -1 if *this < *rhs, 0 if *this==*rhs, 1 if *this>*rhs.*/ + virtual int compare(const StateAttribute& rhs) const; + + virtual void getAssociatedModes(std::vector& modes) const + { + modes.push_back(GL_TEXTURE_3D); + } + + /** Set the texture image. */ + void setImage(Image* image); + + /** Get the texture image. */ + Image* getImage() { return _image.get(); } + + /** Get the const texture image. */ + inline const Image* getImage() const { return _image.get(); } + + + /** Set the texture width and height. If width or height are zero then + * the repsective size value is calculated from the source image sizes. */ + inline void setTextureSize(const int width, const int height, const int depth) const + { + _textureWidth = width; + _textureHeight = height; + _textureDepth = depth; + } + + /** Get the texture subload width. */ + inline void getTextureSize(int& width, int& height, int& depth) const + { + width = _textureWidth; + height = _textureHeight; + depth = _textureDepth; + } + + + class SubloadCallback : public Referenced + { + public: + virtual void load(const Texture3D& texture,State& state) const = 0; + virtual void subload(const Texture3D& texture,State& state) const = 0; + }; + + void setSubloadCallback(SubloadCallback* cb) { _subloadCallback = cb;; } + + SubloadCallback* getSubloadCallback() { return _subloadCallback.get(); } + + const SubloadCallback* getSubloadCallback() const { return _subloadCallback.get(); } + + + /** 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; } + + /** Get the number of mip map levels the the texture has been created with.*/ + unsigned int getNumMipmapLevels() const { return _numMimpmapLevels; } + + + /** Copy a two-dimensional texture subimage. As per glCopyTexSubImage2D. + * Updates portion of an existing OpenGL texture object from the current OpenGL background + * framebuffer contents at pos \a x, \a y with width \a width and + * height \a height. */ + void copyTexSubImage3D(State& state, int xoffset, int yoffset, int zoffset, int x, int y, int width, int height); + + + /** 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; + + protected : + + virtual ~Texture3D(); + + virtual void computeInternalFormat() const; + + void applyTexImage3D(GLenum target, Image* image, State& state, GLsizei& inwidth, GLsizei& inheight, GLsizei& indepth, GLsizei& numMimpmapLevels) const; + + // not ideal that _image is mutable, but its required since + // Image::ensureDimensionsArePowerOfTwo() can only be called + // in a valid OpenGL context, a therefore within an Texture::apply + // which is const... + mutable ref_ptr _image; + + // subloaded images can have different texture and image sizes. + mutable GLsizei _textureWidth, _textureHeight, _textureDepth; + + // number of mip map levels the the texture has been created with, + mutable GLsizei _numMimpmapLevels; + + ref_ptr _subloadCallback; +}; + +} + +#endif diff --git a/include/osg/TextureBase b/include/osg/TextureBase new file mode 100644 index 000000000..23676d5df --- /dev/null +++ b/include/osg/TextureBase @@ -0,0 +1,283 @@ +//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_TEXTUREBASE +#define OSG_TEXTUREBASE 1 + +#include +#include +#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 +#ifndef GL_TEXTURE_MAX_ANISOTROPY_EXT +#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE +#endif + +#ifndef GL_ARB_texture_compression +#define GL_COMPRESSED_ALPHA_ARB 0x84E9 +#define GL_COMPRESSED_LUMINANCE_ARB 0x84EA +#define GL_COMPRESSED_LUMINANCE_ALPHA_ARB 0x84EB +#define GL_COMPRESSED_INTENSITY_ARB 0x84EC +#define GL_COMPRESSED_RGB_ARB 0x84ED +#define GL_COMPRESSED_RGBA_ARB 0x84EE +#define GL_TEXTURE_COMPRESSION_HINT_ARB 0x84EF +#define GL_TEXTURE_IMAGE_SIZE_ARB 0x86A0 +#define GL_TEXTURE_COMPRESSED_ARB 0x86A1 +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A2 +#define GL_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A3 +#endif + +#ifndef GL_EXT_texture_compression_s3tc +#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 +#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 +#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2 +#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3 +#endif + +#ifndef GL_MIRRORED_REPEAT_IBM +#define GL_MIRRORED_REPEAT_IBM 0x8370 +#endif + +#ifndef GL_CLAMP_TO_EDGE +#define GL_CLAMP_TO_EDGE 0x812F +#endif + +#ifndef GL_CLAMP_TO_BORDER_ARB +#define GL_CLAMP_TO_BORDER_ARB 0x812D +#endif + +#ifndef GL_GENERATE_MIPMAP_SGIS +#define GL_GENERATE_MIPMAP_SGIS 0x8191 +#define GL_GENERATE_MIPMAP_HINT_SGIS 0x8192 +#endif + +#ifndef GL_TEXTURE_3D +#define GL_TEXTURE_3D 0x806F +#endif + +namespace osg { + +/** Texture base class which encapsulates OpenGl texture functionality which common betweent the various types of OpenGL textures.*/ +class SG_EXPORT TextureBase : public osg::StateAttribute +{ + + public : + + + TextureBase(); + + /** Copy constructor using CopyOp to manage deep vs shallow copy.*/ + TextureBase(const TextureBase& text,const CopyOp& copyop=CopyOp::SHALLOW_COPY); + + virtual osg::Object* cloneType() const = 0; + virtual osg::Object* clone(const CopyOp& copyop) const = 0; + virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast(obj)!=NULL; } + virtual const char* libraryName() const { return "osg"; } + virtual const char* className() const { return "TextureBase"; } + virtual const Type getType() const { return TEXTURE; } + + virtual bool isTextureAttribute() const { return true; } + + enum WrapParameter { + WRAP_S, + WRAP_T, + WRAP_R + }; + + enum WrapMode { + CLAMP = GL_CLAMP, + CLAMP_TO_EDGE = GL_CLAMP_TO_EDGE, + CLAMP_TO_BORDER = GL_CLAMP_TO_BORDER_ARB, + REPEAT = GL_REPEAT, + MIRROR = GL_MIRRORED_REPEAT_IBM + }; + + /** Set the texture wrap mode.*/ + void setWrap(const WrapParameter which, const WrapMode wrap); + /** Get the texture wrap mode.*/ + const WrapMode getWrap(const WrapParameter which) const; + + + /** Sets the border color for this texture. Makes difference only if + * wrap mode is CLAMP_TO_BORDER */ + void setBorderColor(const Vec4& color) { _borderColor = color; _texParamtersDirty = true; } + + const Vec4& borderColor(void) const { return _borderColor; } + + + enum FilterParameter { + MIN_FILTER, + MAG_FILTER + }; + + enum FilterMode { + LINEAR = GL_LINEAR, + LINEAR_MIPMAP_LINEAR = GL_LINEAR_MIPMAP_LINEAR, + LINEAR_MIPMAP_NEAREST = GL_LINEAR_MIPMAP_NEAREST, + NEAREST = GL_NEAREST, + NEAREST_MIPMAP_LINEAR = GL_NEAREST_MIPMAP_LINEAR, + NEAREST_MIPMAP_NEAREST = GL_NEAREST_MIPMAP_NEAREST + }; + + + /** Set the texture filter mode.*/ + void setFilter(const FilterParameter which, const FilterMode filter); + + /** Get the texture filter mode.*/ + const FilterMode getFilter(const FilterParameter which) const; + + /** Set the maximum anisotropy value, default value is 1.0 for + * no anisotropic filtering. If hardware does not support anisotropic + * filtering then normal filtering is used, equivilant to a max anisotropy value of 1.0. + * valid range is 1.0f upwards. The maximum value depends on the graphics + * system being used.*/ + void setMaxAnisotropy(float anis); + + /** Get the maximum anisotropy value.*/ + inline float getMaxAnisotropy() const { return _maxAnisotropy; } + + enum InternalFormatMode { + USE_IMAGE_DATA_FORMAT, + USE_USER_DEFINED_FORMAT, + USE_ARB_COMPRESSION, + USE_S3TC_DXT1_COMPRESSION, + USE_S3TC_DXT3_COMPRESSION, + USE_S3TC_DXT5_COMPRESSION + }; + + /** Set the internal format mode. + * Note, If the mode is set USE_IMAGE_DATA_FORMAT, USE_ARB_COMPRESSION, + * USE_S3TC_COMPRESSION the internalFormat is automatically selected, + * and will overwrite the previous _internalFormat. + */ + inline void setInternalFormatMode(const InternalFormatMode mode) { _internalFormatMode = mode; } + + /** Get the internal format mode.*/ + inline const InternalFormatMode getInternalFormatMode() const { return _internalFormatMode; } + + /** Set the internal format to use when creating OpenGL textures. + * Also sets the internalFormatMode to USE_USER_DEFINED_FORMAT. + */ + inline void setInternalFormat(const int internalFormat) + { + _internalFormatMode = USE_USER_DEFINED_FORMAT; + _internalFormat = internalFormat; + } + + /** Get the internal format to use when creating OpenGL textures.*/ + inline const int getInternalFormat() const { if (_internalFormat==0) computeInternalFormat(); return _internalFormat; } + + 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(const 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(const 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]; + } + + /** Force a recompile on next apply() of associated OpenGL texture objects.*/ + void dirtyTextureObject(); + + + + /** 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(uint contextID,GLuint handle); + + /** flush all the cached display list which need to be deleted + * in the OpenGL context related to contextID.*/ + static void flushDeletedTextureObjects(uint contextID); + + /** Get the maximum texture size supported, this is the + normally define by GL_MAX_TEXTURE_SIZE, but can be overridden + by the OSG_MAX_TEXTURE_SIZE environmental variable.*/ + static GLint getMaxTextureSize(); + + /** TextureBase is pure virtual base class, apply must be overriden. */ + virtual void apply(State& state) const = 0; + + /** Calls apply(state) to compile the texture. */ + virtual void compile(State& state) const; + + protected : + + virtual ~TextureBase(); + + virtual void computeInternalFormat() const = 0; + + void computeInternalFormatWithImage(osg::Image& image) const; + + bool isCompressedInternalFormat(GLint internalFormat) const; + + /** Helper method which does setting of texture paramters. */ + void applyTexParameters(GLenum target, State& state) const; + + /** Helper method which does the creation of the texture itself, and + * does not set or use texture binding. */ + void applyTexImage2D(GLenum target, Image* image, State& state, GLsizei& width, GLsizei& height,GLsizei& numMimpmapLevels) const; + + /** return -1 if *this < *rhs, 0 if *this==*rhs, 1 if *this>*rhs.*/ + int compareTextureBase(const TextureBase& rhs) const; + + typedef std::vector TextureNameList; + mutable TextureNameList _handleList; + + typedef std::vector ImageModifiedTag; + mutable ImageModifiedTag _modifiedTag; + + + WrapMode _wrap_s; + WrapMode _wrap_t; + WrapMode _wrap_r; + + FilterMode _min_filter; + FilterMode _mag_filter; + float _maxAnisotropy; + + Vec4 _borderColor; + + // true if apply tex parameters required. + mutable bool _texParamtersDirty; + + + 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; +}; + +} + +#endif diff --git a/include/osg/TextureCubeMap b/include/osg/TextureCubeMap index 4db20af5a..a60efff80 100644 --- a/include/osg/TextureCubeMap +++ b/include/osg/TextureCubeMap @@ -7,7 +7,7 @@ #ifndef OSG_TEXTURECUBEMAP #define OSG_TEXTURECUBEMAP 1 -#include +#include #ifndef GL_TEXTURE_CUBE_MAP #define GL_TEXTURE_CUBE_MAP 0x8513 @@ -16,7 +16,7 @@ namespace osg { /** TextureCubeMap state class which encapsulates OpenGl texture cubemap functionality.*/ -class SG_EXPORT TextureCubeMap : public Texture +class SG_EXPORT TextureCubeMap : public TextureBase { public : @@ -24,8 +24,7 @@ class SG_EXPORT TextureCubeMap : public Texture TextureCubeMap(); /** Copy constructor using CopyOp to manage deep vs shallow copy.*/ - TextureCubeMap(const TextureCubeMap& cm,const CopyOp& copyop=CopyOp::SHALLOW_COPY): - Texture(cm,copyop) {} + TextureCubeMap(const TextureCubeMap& cm,const CopyOp& copyop=CopyOp::SHALLOW_COPY); META_StateAttribute(osg, TextureCubeMap,TEXTURE); @@ -50,19 +49,65 @@ class SG_EXPORT TextureCubeMap : public Texture /** Get the const texture image for specified face. */ const Image* getImage(const Face) const; + + /** Set the texture width and height. If width or height are zero then + * the repsective size value is calculated from the source image sizes. */ + inline void setTextureSize(const int width, const int height) const + { + _textureWidth = width; + _textureHeight = height; + } + + /** Get the texture subload width. */ + inline void getTextureSize(int& width, int& height) const + { + width = _textureWidth; + height = _textureHeight; + } + + + class SubloadCallback : public Referenced + { + public: + virtual void load(const TextureCubeMap& texture,State& state) const = 0; + virtual void subload(const TextureCubeMap& texture,State& state) const = 0; + }; + + void setSubloadCallback(SubloadCallback* cb) { _subloadCallback = cb;; } + + SubloadCallback* getSubloadCallback() { return _subloadCallback.get(); } + + const SubloadCallback* getSubloadCallback() const { return _subloadCallback.get(); } + + + /** 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; } + + /** Get the number of mip map levels the the texture has been created with.*/ + unsigned int getNumMipmapLevels() const { return _numMimpmapLevels; } + /** 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; - + protected : virtual ~TextureCubeMap(); + bool imagesValid() const; - void setImage(Image*) {} // prevent call to Texture::setImage(Image* image) - Image* getImage() { return _image.get(); } // prevent call to Texture::setImage(Image* image) - const Image* getImage() const { return _image.get(); } // prevent call to Texture::setImage(Image* image) + + virtual void computeInternalFormat() const; mutable ref_ptr _images[6]; + + // subloaded images can have different texture and image sizes. + mutable GLsizei _textureWidth, _textureHeight; + + // number of mip map levels the the texture has been created with, + mutable GLsizei _numMimpmapLevels; + + ref_ptr _subloadCallback; }; } diff --git a/include/osgUtil/RenderToTextureStage b/include/osgUtil/RenderToTextureStage index de4181158..72b114b78 100644 --- a/include/osgUtil/RenderToTextureStage +++ b/include/osgUtil/RenderToTextureStage @@ -5,7 +5,7 @@ #ifndef OSGUTIL_RENDERTOTEXTURESTAGE #define OSGUTIL_RENDERTOTEXTURESTAGE 1 -#include +#include #include @@ -31,8 +31,8 @@ class OSGUTIL_EXPORT RenderToTextureStage : public RenderStage virtual void reset(); - void setTexture(osg::Texture* texture) { _texture = texture; } - osg::Texture* getTexture() { return _texture.get(); } + void setTexture(osg::Texture2D* texture) { _texture = texture; } + osg::Texture2D* getTexture() { return _texture.get(); } void setImage(osg::Image* image) { _image = image; } osg::Image* getImage() { return _image.get(); } @@ -46,7 +46,7 @@ class OSGUTIL_EXPORT RenderToTextureStage : public RenderStage virtual ~RenderToTextureStage(); - osg::ref_ptr _texture; + osg::ref_ptr _texture; osg::ref_ptr _image; }; diff --git a/src/Demos/osgcopy/osgcopy.cpp b/src/Demos/osgcopy/osgcopy.cpp index 4af4b5559..9e792a008 100644 --- a/src/Demos/osgcopy/osgcopy.cpp +++ b/src/Demos/osgcopy/osgcopy.cpp @@ -134,13 +134,13 @@ class MyCopyOp : public osg::CopyOp return ret_attr; } - virtual Texture* operator() (const Texture* text) const + virtual TextureBase* operator() (const TextureBase* text) const { writeIndent(); std::cout << "copying Texture "<className(); std::cout< _subgraph; - osg::ref_ptr _texture; - osg::ref_ptr _image; + osg::ref_ptr _subgraph; + osg::ref_ptr _texture; + osg::ref_ptr _image; }; @@ -286,69 +286,140 @@ class MyGeometryCallback : // Custom Texture subload callback, just acts the the standard subload modes in osg::Texture right now // but code be used to define your own style callbacks. -class MyTextureSubloadCallback : public osg::Texture::SubloadCallback +class MyTextureSubloadCallback : public osg::Texture2D::SubloadCallback { public: - virtual void load(GLenum target, const osg::Texture& texture,osg::State&) const + + MyTextureSubloadCallback(): + _subloadMode(AUTO), + _subloadTextureOffsetX(0), + _subloadTextureOffsetY(0), + _subloadImageOffsetX(0), + _subloadImageOffsetY(0), + _subloadImageWidth(0), + _subloadImageHeight(0) + { + } + + enum SubloadMode { + OFF, + AUTO, + IF_DIRTY + }; + + /** Set the texture subload mode. */ + inline void setSubloadMode(const SubloadMode mode) { _subloadMode = mode; } + + /** Get the texture subload mode. */ + inline const SubloadMode getSubloadMode() const { return _subloadMode; } + + /** Set the texture subload texture offsets. */ + inline void setSubloadTextureOffset(const int x, const int y) + { + _subloadTextureOffsetX = x; + _subloadTextureOffsetY = y; + } + + /** Get the texture subload texture offsets. */ + inline void getSubloadTextureOffset(int& x, int& y) const + { + x = _subloadTextureOffsetX; + y = _subloadTextureOffsetY; + } + + /** Set the texture subload width. If width or height are zero then + * the repsective size value is calculated from the source image sizes. */ + inline void setSubloadTextureSize(const int width, const int height) + { + _textureWidth = width; + _textureHeight = height; + } + + /** Get the texture subload width. */ + inline void getSubloadTextureSize(int& width, int& height) const + { + width = _textureWidth; + height = _textureHeight; + } + + + /** Set the subload image offsets. */ + inline void setSubloadImageOffset(const int x, const int y) + { + _subloadImageOffsetX = x; + _subloadImageOffsetY = y; + } + + /** Get the subload image offsets. */ + inline void getSubloadImageOffset(int& x, int& y) const + { + x = _subloadImageOffsetX; + y = _subloadImageOffsetY; + } + + /** Set the image subload width. If width or height are zero then + * the repsective size value is calculated from the source image sizes. */ + inline void setSubloadImageSize(const int width, const int height) + { + _subloadImageWidth = width; + _subloadImageHeight = height; + } + + /** Get the image subload width. */ + inline void getSubloadImageSize(int& width, int& height) const + { + width = _subloadImageWidth; + height = _subloadImageHeight; + } + + + + virtual void load(const osg::Texture2D& texture,osg::State&) const { osg::notify(osg::INFO)<<"doing load"<0)?subloadImageWidth:texture.getImage()->s(); - GLsizei height = (subloadImageHeight>0)?subloadImageHeight:texture.getImage()->t(); + GLsizei width = (_subloadImageWidth>0)?_subloadImageWidth:texture.getImage()->s(); + GLsizei height = (_subloadImageHeight>0)?_subloadImageHeight:texture.getImage()->t(); - int subloadTextureOffsetX; - int subloadTextureOffsetY; - texture.getSubloadTextureOffset(subloadTextureOffsetX,subloadTextureOffsetY); - - int textureWidth; - int textureHeight; - texture.getSubloadTextureSize(textureWidth, textureHeight); bool sizeChanged = false; - if (textureWidth==0) + if (_textureWidth==0) { // need to calculate texture dimension sizeChanged = true; - textureWidth = 1; - for (; textureWidth < (static_cast(subloadTextureOffsetX) + width); textureWidth <<= 1) {} + _textureWidth = 1; + for (; _textureWidth < (static_cast(_subloadTextureOffsetX) + width); _textureWidth <<= 1) {} } - if (textureHeight==0) + if (_textureHeight==0) { // need to calculate texture dimension sizeChanged = true; - textureHeight = 1; - for (; textureHeight < (static_cast(subloadTextureOffsetY) + height); textureHeight <<= 1) {} + _textureHeight = 1; + for (; _textureHeight < (static_cast(_subloadTextureOffsetY) + height); _textureHeight <<= 1) {} } if (sizeChanged) { - texture.setSubloadTextureSize(textureWidth, textureHeight); + texture.setTextureSize(_textureWidth, _textureHeight); } // reserve appropriate texture memory - glTexImage2D(target, 0, texture.getInternalFormatValue(), - textureWidth, textureHeight, 0, + glTexImage2D(GL_TEXTURE_2D, 0, texture.getInternalFormat(), + _textureWidth, _textureHeight, 0, (GLenum) texture.getImage()->getPixelFormat(), (GLenum) texture.getImage()->getDataType(), NULL); @@ -356,42 +427,37 @@ class MyTextureSubloadCallback : public osg::Texture::SubloadCallback glPixelStorei(GL_UNPACK_ROW_LENGTH,texture.getImage()->s()); - glTexSubImage2D(target, 0, - subloadTextureOffsetX, subloadTextureOffsetY, + glTexSubImage2D(GL_TEXTURE_2D, 0, + _subloadTextureOffsetX, _subloadTextureOffsetY, width, height, (GLenum) texture.getImage()->getPixelFormat(), (GLenum) texture.getImage()->getDataType(), - texture.getImage()->data(subloadImageOffsetX,subloadImageOffsetY)); + texture.getImage()->data(_subloadImageOffsetX,_subloadImageOffsetY)); glPixelStorei(GL_UNPACK_ROW_LENGTH,0); } - virtual void subload(GLenum target, const osg::Texture& texture,osg::State&) const + virtual void subload(const osg::Texture2D& texture,osg::State&) const { osg::notify(osg::INFO)<<"doing subload"<s()); - int subloadTextureOffsetX; - int subloadTextureOffsetY; - texture.getSubloadTextureOffset(subloadTextureOffsetX,subloadTextureOffsetY); - - int subloadImageOffsetX; - int subloadImageOffsetY; - texture.getSubloadImageOffset(subloadImageOffsetX,subloadImageOffsetY); - - int subloadImageWidth; - int subloadImageHeight; - texture.getSubloadImageSize(subloadImageWidth,subloadImageHeight); - - glTexSubImage2D(target, 0, - subloadTextureOffsetX, subloadTextureOffsetY, - (subloadImageWidth>0)?subloadImageWidth:texture.getImage()->s(), (subloadImageHeight>0)?subloadImageHeight:texture.getImage()->t(), + glTexSubImage2D(GL_TEXTURE_2D, 0, + _subloadTextureOffsetX, _subloadTextureOffsetY, + (_subloadImageWidth>0)?_subloadImageWidth:texture.getImage()->s(), (_subloadImageHeight>0)?_subloadImageHeight:texture.getImage()->t(), (GLenum) texture.getImage()->getPixelFormat(), (GLenum) texture.getImage()->getDataType(), - texture.getImage()->data(subloadImageOffsetX,subloadImageOffsetY)); + texture.getImage()->data(_subloadImageOffsetX,_subloadImageOffsetY)); glPixelStorei(GL_UNPACK_ROW_LENGTH,0); } + + + SubloadMode _subloadMode; + mutable GLsizei _textureWidth, _textureHeight; + GLint _subloadTextureOffsetX, _subloadTextureOffsetY; + GLint _subloadImageOffsetX, _subloadImageOffsetY; + GLsizei _subloadImageWidth, _subloadImageHeight; }; @@ -460,12 +526,12 @@ osg::Node* createPreRenderSubGraph(osg::Node* subgraph) osg::Image* image = new osg::Image; image->setInternalTextureFormat(GL_RGBA); - osg::Texture* texture = new osg::Texture; + osg::Texture2D* texture = new osg::Texture2D; //texture->setSubloadMode(osg::Texture::IF_DIRTY); texture->setSubloadCallback(new MyTextureSubloadCallback()); texture->setImage(image); - texture->setFilter(osg::Texture::MIN_FILTER,osg::Texture::LINEAR); - texture->setFilter(osg::Texture::MAG_FILTER,osg::Texture::LINEAR); + texture->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::LINEAR); + texture->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::LINEAR); stateset->setTextureAttributeAndModes(0, texture,osg::StateAttribute::ON); polyGeom->setStateSet(stateset); diff --git a/src/Demos/osgtexture/osgtexture.cpp b/src/Demos/osgtexture/osgtexture.cpp index ae4539e40..04ee5daf8 100644 --- a/src/Demos/osgtexture/osgtexture.cpp +++ b/src/Demos/osgtexture/osgtexture.cpp @@ -2,7 +2,7 @@ #include #include #include -#include +#include #include #include @@ -24,22 +24,22 @@ typedef std::vector< osg::ref_ptr > ImageList; -class TextureCallback : public osg::NodeCallback +class Texture2DCallback : public osg::NodeCallback { public: - TextureCallback(osg::Texture* texture):_texture(texture) + Texture2DCallback(osg::Texture2D* texture):_texture(texture) { - _filterRange.push_back(osg::Texture::LINEAR); - _filterRange.push_back(osg::Texture::LINEAR_MIPMAP_LINEAR); - _filterRange.push_back(osg::Texture::LINEAR_MIPMAP_NEAREST); - _filterRange.push_back(osg::Texture::NEAREST); - _filterRange.push_back(osg::Texture::NEAREST_MIPMAP_LINEAR); - _filterRange.push_back(osg::Texture::NEAREST_MIPMAP_NEAREST); + _filterRange.push_back(osg::Texture2D::LINEAR); + _filterRange.push_back(osg::Texture2D::LINEAR_MIPMAP_LINEAR); + _filterRange.push_back(osg::Texture2D::LINEAR_MIPMAP_NEAREST); + _filterRange.push_back(osg::Texture2D::NEAREST); + _filterRange.push_back(osg::Texture2D::NEAREST_MIPMAP_LINEAR); + _filterRange.push_back(osg::Texture2D::NEAREST_MIPMAP_NEAREST); _currPos = 0; _prevTime = 0.0; } - virtual ~TextureCallback() {} + virtual ~Texture2DCallback() {} virtual void operator()(osg::Node*, osg::NodeVisitor* nv) { @@ -49,7 +49,7 @@ class TextureCallback : public osg::NodeCallback if (currTime-_prevTime>1.0) { std::cout<<"Updating texturing filter to "<setFilter(osg::Texture::MAG_FILTER,_filterRange[_currPos]); + _texture->setFilter(osg::Texture2D::MAG_FILTER,_filterRange[_currPos]); _currPos++; if (_currPos>=_filterRange.size()) _currPos=0; _prevTime = currTime; @@ -57,8 +57,8 @@ class TextureCallback : public osg::NodeCallback } } - osg::ref_ptr _texture; - std::vector _filterRange; + osg::ref_ptr _texture; + std::vector _filterRange; osg::uint _currPos; double _prevTime; }; @@ -127,7 +127,7 @@ osg::Drawable* createSquare(float textureCoordMax=1.0f) return geom; } -osg::Node* createTexturedItem(const osg::Vec3& offset,osg::Texture* texture,osg::Node* geometry) +osg::Node* createTexturedItem(const osg::Vec3& offset,osg::Texture2D* texture,osg::Node* geometry) { // create a tranform node to position each square in appropriate // place and also to add individual texture set to it, so that @@ -183,7 +183,7 @@ osg::Node* createLayer(const osg::Vec3& offset,osg::Image* image,osg::Node* geom // defaults mipmapped texturing. { // create the texture attribute - osg::Texture* texture = new osg::Texture; + osg::Texture2D* texture = new osg::Texture2D; texture->setImage(image); // add the transform node to root group node. @@ -199,12 +199,12 @@ osg::Node* createLayer(const osg::Vec3& offset,osg::Image* image,osg::Node* geom // bilinear { // create the texture attribute - osg::Texture* texture = new osg::Texture; + osg::Texture2D* texture = new osg::Texture2D; texture->setImage(image); // set up bilinear filtering. - texture->setFilter(osg::Texture::MIN_FILTER,osg::Texture::LINEAR_MIPMAP_NEAREST); - texture->setFilter(osg::Texture::MAG_FILTER,osg::Texture::LINEAR); + texture->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::LINEAR_MIPMAP_NEAREST); + texture->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::LINEAR); // add the transform node to root group node. top_transform->addChild(createTexturedItem(local_offset,texture,geometry)); @@ -216,12 +216,12 @@ osg::Node* createLayer(const osg::Vec3& offset,osg::Image* image,osg::Node* geom // trilinear { // create the texture attribute - osg::Texture* texture = new osg::Texture; + osg::Texture2D* texture = new osg::Texture2D; texture->setImage(image); // set up trilinear filtering. - texture->setFilter(osg::Texture::MIN_FILTER,osg::Texture::LINEAR_MIPMAP_LINEAR); - texture->setFilter(osg::Texture::MAG_FILTER,osg::Texture::LINEAR); + texture->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::LINEAR_MIPMAP_LINEAR); + texture->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::LINEAR); // add the transform node to root group node. top_transform->addChild(createTexturedItem(local_offset,texture,geometry)); @@ -234,12 +234,12 @@ osg::Node* createLayer(const osg::Vec3& offset,osg::Image* image,osg::Node* geom // anisotropic { // create the texture attribute - osg::Texture* texture = new osg::Texture; + osg::Texture2D* texture = new osg::Texture2D; texture->setImage(image); // set up anistropic filtering. - texture->setFilter(osg::Texture::MIN_FILTER,osg::Texture::LINEAR_MIPMAP_LINEAR); - texture->setFilter(osg::Texture::MAG_FILTER,osg::Texture::LINEAR); + texture->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::LINEAR_MIPMAP_LINEAR); + texture->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::LINEAR); texture->setMaxAnisotropy(2.0f); // add the transform node to root group node. @@ -252,10 +252,10 @@ osg::Node* createLayer(const osg::Vec3& offset,osg::Image* image,osg::Node* geom // arb compression { // create the texture attribute - osg::Texture* texture = new osg::Texture; + osg::Texture2D* texture = new osg::Texture2D; texture->setImage(image); - texture->setInternalFormatMode(osg::Texture::USE_ARB_COMPRESSION); + texture->setInternalFormatMode(osg::Texture2D::USE_ARB_COMPRESSION); // add the transform node to root group node. top_transform->addChild(createTexturedItem(local_offset,texture,geometry)); @@ -267,10 +267,10 @@ osg::Node* createLayer(const osg::Vec3& offset,osg::Image* image,osg::Node* geom // s3tc_dxt1 compression { // create the texture attribute - osg::Texture* texture = new osg::Texture; + osg::Texture2D* texture = new osg::Texture2D; texture->setImage(image); - texture->setInternalFormatMode(osg::Texture::USE_S3TC_DXT1_COMPRESSION); + texture->setInternalFormatMode(osg::Texture2D::USE_S3TC_DXT1_COMPRESSION); // add the transform node to root group node. top_transform->addChild(createTexturedItem(local_offset,texture,geometry)); @@ -279,10 +279,10 @@ osg::Node* createLayer(const osg::Vec3& offset,osg::Image* image,osg::Node* geom } - // default wrap mode. (osg::Texture::CLAMP) + // default wrap mode. (osg::Texture2D::CLAMP) { // create the texture attribute - osg::Texture* texture = new osg::Texture; + osg::Texture2D* texture = new osg::Texture2D; texture->setImage(image); // add the transform node to root group node. @@ -295,11 +295,11 @@ osg::Node* createLayer(const osg::Vec3& offset,osg::Image* image,osg::Node* geom // clamp-to-edge mode. { // create the texture attribute - osg::Texture* texture = new osg::Texture; + osg::Texture2D* texture = new osg::Texture2D; texture->setImage(image); - texture->setWrap(osg::Texture::WRAP_S,osg::Texture::CLAMP_TO_EDGE); - texture->setWrap(osg::Texture::WRAP_T,osg::Texture::CLAMP_TO_EDGE); + texture->setWrap(osg::Texture2D::WRAP_S,osg::Texture2D::CLAMP_TO_EDGE); + texture->setWrap(osg::Texture2D::WRAP_T,osg::Texture2D::CLAMP_TO_EDGE); // add the transform node to root group node. top_transform->addChild(createTexturedItem(local_offset,texture,geometryRep)); @@ -311,11 +311,11 @@ osg::Node* createLayer(const osg::Vec3& offset,osg::Image* image,osg::Node* geom // repeat wrap mode. { // create the texture attribute - osg::Texture* texture = new osg::Texture; + osg::Texture2D* texture = new osg::Texture2D; texture->setImage(image); - texture->setWrap(osg::Texture::WRAP_S,osg::Texture::REPEAT); - texture->setWrap(osg::Texture::WRAP_T,osg::Texture::REPEAT); + texture->setWrap(osg::Texture2D::WRAP_S,osg::Texture2D::REPEAT); + texture->setWrap(osg::Texture2D::WRAP_T,osg::Texture2D::REPEAT); // add the transform node to root group node. top_transform->addChild(createTexturedItem(local_offset,texture,geometryRep)); @@ -327,11 +327,11 @@ osg::Node* createLayer(const osg::Vec3& offset,osg::Image* image,osg::Node* geom // mirror wrap mode. { // create the texture attribute - osg::Texture* texture = new osg::Texture; + osg::Texture2D* texture = new osg::Texture2D; texture->setImage(image); - texture->setWrap(osg::Texture::WRAP_S,osg::Texture::MIRROR); - texture->setWrap(osg::Texture::WRAP_T,osg::Texture::MIRROR); + texture->setWrap(osg::Texture2D::WRAP_S,osg::Texture2D::MIRROR); + texture->setWrap(osg::Texture2D::WRAP_T,osg::Texture2D::MIRROR); // add the transform node to root group node. top_transform->addChild(createTexturedItem(local_offset,texture,geometryRep)); diff --git a/src/osg/CopyOp.cpp b/src/osg/CopyOp.cpp index 62ebc11be..cece1db86 100644 --- a/src/osg/CopyOp.cpp +++ b/src/osg/CopyOp.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -48,26 +49,42 @@ StateAttribute* CopyOp::operator() (const StateAttribute* attr) const { if (attr && _flags&DEEP_COPY_STATEATTRIBUTES) { - const Texture* text = dynamic_cast(attr); - if (text) + const TextureBase* textbase = dynamic_cast(attr); + if (textbase) { - return operator()(text); + return operator()(textbase); + } + else + { +// const Texture* text = dynamic_cast(attr); +// if (text) +// { +// return operator()(text); +// } +// else + return dynamic_cast(attr->clone(*this)); } - else - return dynamic_cast(attr->clone(*this)); } else return const_cast(attr); } -Texture* CopyOp::operator() (const Texture* text) const +TextureBase* CopyOp::operator() (const TextureBase* text) const { if (text && _flags&DEEP_COPY_TEXTURES) - return dynamic_cast(text->clone(*this)); + return dynamic_cast(text->clone(*this)); else - return const_cast(text); + return const_cast(text); } +// Texture* CopyOp::operator() (const Texture* text) const +// { +// if (text && _flags&DEEP_COPY_TEXTURES) +// return dynamic_cast(text->clone(*this)); +// else +// return const_cast(text); +// } + Image* CopyOp::operator() (const Image* image) const { if (image && _flags&DEEP_COPY_IMAGES) diff --git a/src/osg/Image.cpp b/src/osg/Image.cpp index dccffda4e..c11357c01 100644 --- a/src/osg/Image.cpp +++ b/src/osg/Image.cpp @@ -7,7 +7,7 @@ #include #include #include -#include +#include using namespace osg; @@ -415,7 +415,7 @@ void Image::ensureValidSizeForTexturing() int new_s = computeNearestPowerOfTwo(_s); int new_t = computeNearestPowerOfTwo(_t); - static GLint max_size=Texture::getMaxTextureSize(); + static GLint max_size=TextureBase::getMaxTextureSize(); if (new_s>max_size) new_s = max_size; if (new_t>max_size) new_t = max_size; @@ -454,7 +454,7 @@ Geode* osg::createGeodeForImage(osg::Image* image,const float s,const float t) float x = y*(s/t); // set up the texture. - osg::Texture* texture = osgNew osg::Texture; + osg::Texture2D* texture = osgNew osg::Texture2D; texture->setImage(image); // set up the drawstate. diff --git a/src/osg/ImpostorSprite.cpp b/src/osg/ImpostorSprite.cpp index 00fda605d..cfdefaae2 100644 --- a/src/osg/ImpostorSprite.cpp +++ b/src/osg/ImpostorSprite.cpp @@ -8,7 +8,7 @@ #include #include -#include +#include #include #include #include @@ -107,7 +107,7 @@ const bool ImpostorSprite::computeBound() const return true; } -void ImpostorSprite::setTexture(Texture* tex,int s,int t) +void ImpostorSprite::setTexture(Texture2D* tex,int s,int t) { _texture = tex; _s = s; @@ -253,9 +253,9 @@ ImpostorSprite* ImpostorSpriteManager::createOrReuseImpostorSprite(int s,int t,i stateset->setAttributeAndModes( _alphafunc.get(), StateAttribute::ON ); - Texture* texture = osgNew Texture; - texture->setFilter(Texture::MIN_FILTER,Texture::LINEAR); - texture->setFilter(Texture::MAG_FILTER,Texture::LINEAR); + Texture2D* texture = osgNew Texture2D; + texture->setFilter(Texture2D::MIN_FILTER,Texture2D::LINEAR); + texture->setFilter(Texture2D::MAG_FILTER,Texture2D::LINEAR); stateset->setTextureAttributeAndModes(0,texture,StateAttribute::ON); stateset->setTextureAttribute(0,_texenv.get()); diff --git a/src/osg/Makefile b/src/osg/Makefile index d7c82a2e1..3911dc71c 100644 --- a/src/osg/Makefile +++ b/src/osg/Makefile @@ -75,6 +75,10 @@ CXXFILES =\ TexGen.cpp\ TexMat.cpp\ Texture.cpp\ + TextureBase.cpp\ + Texture1D.cpp\ + Texture2D.cpp\ + Texture3D.cpp\ TextureCubeMap.cpp\ Timer.cpp\ Transform.cpp\ diff --git a/src/osg/Point.cpp b/src/osg/Point.cpp index ae9fe3b8b..38b96c2b5 100644 --- a/src/osg/Point.cpp +++ b/src/osg/Point.cpp @@ -1,8 +1,8 @@ // Ideas and code borrowed from GLUT pointburst demo // written by Mark J. Kilgard -#include #include +#include #include #include diff --git a/src/osg/State.cpp b/src/osg/State.cpp index 255ec81ca..5d26bba49 100644 --- a/src/osg/State.cpp +++ b/src/osg/State.cpp @@ -1,6 +1,6 @@ +#include #include #include -#include #include #include diff --git a/src/osg/TexEnvCombine.cpp b/src/osg/TexEnvCombine.cpp index e18b86015..789751d4f 100644 --- a/src/osg/TexEnvCombine.cpp +++ b/src/osg/TexEnvCombine.cpp @@ -1,5 +1,5 @@ -#include #include +#include using namespace osg; diff --git a/src/osg/Texture.cpp b/src/osg/Texture.cpp index 6c16f2eb9..bc332d118 100644 --- a/src/osg/Texture.cpp +++ b/src/osg/Texture.cpp @@ -1,36 +1,22 @@ +#include +#include + +#ifdef TEXTURE_USE_DEPRECATED_API + #if defined(_MSC_VER) #pragma warning( disable : 4786 ) #endif #include #include -#include #include #include -#include #include -typedef void (APIENTRY * MyCompressedTexImage2DArbProc) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); - using namespace osg; - -Texture::DeletedTextureObjectCache Texture::s_deletedTextureObjectCache; - Texture::Texture(): - _unrefImageAfterApply(false), - _target(GL_TEXTURE_2D), - _wrap_s(CLAMP), - _wrap_t(CLAMP), - _wrap_r(CLAMP), - _min_filter(LINEAR_MIPMAP_LINEAR), // trilinear - _mag_filter(LINEAR), - _maxAnisotropy(1.0f), - _texParamtersDirty(true), - _internalFormatMode(USE_IMAGE_DATA_FORMAT), - _internalFormatValue(0), - _borderColor(0.0, 0.0, 0.0, 0.0), _textureWidth(0), _textureHeight(0), _numMimpmapLevels(0), @@ -42,28 +28,11 @@ Texture::Texture(): _subloadImageWidth(0), _subloadImageHeight(0) { - _handleList.resize(DisplaySettings::instance()->getMaxNumberOfGraphicsContexts(),0); - _modifiedTag.resize(DisplaySettings::instance()->getMaxNumberOfGraphicsContexts(),0); - } Texture::Texture(const Texture& text,const CopyOp& copyop): - StateAttribute(text,copyop), - _handleList(), - _modifiedTag(), + TextureBase(text,copyop), _image(copyop(text._image.get())), - _unrefImageAfterApply(text._unrefImageAfterApply), - _target(text._target), - _wrap_s(text._wrap_s), - _wrap_t(text._wrap_t), - _wrap_r(text._wrap_r), - _min_filter(text._min_filter), - _mag_filter(text._mag_filter), - _maxAnisotropy(text._maxAnisotropy), - _texParamtersDirty(false), - _internalFormatMode(text._internalFormatMode), - _internalFormatValue(text._internalFormatValue), - _borderColor(text._borderColor), _textureWidth(text._textureWidth), _textureHeight(text._textureHeight), _numMimpmapLevels(text._numMimpmapLevels), @@ -79,8 +48,6 @@ Texture::Texture(const Texture& text,const CopyOp& copyop): Texture::~Texture() { - // delete old texture objects. - dirtyTextureObject(); } int Texture::compare(const StateAttribute& sa) const @@ -109,14 +76,12 @@ int Texture::compare(const StateAttribute& sa) const } } + + int result = compareTextureBase(rhs); + if (result!=0) return result; + + // compare each paramter in turn against the rhs. - COMPARE_StateAttribute_Parameter(_wrap_s) - COMPARE_StateAttribute_Parameter(_wrap_t) - COMPARE_StateAttribute_Parameter(_wrap_r) - COMPARE_StateAttribute_Parameter(_min_filter) - COMPARE_StateAttribute_Parameter(_mag_filter) - COMPARE_StateAttribute_Parameter(_internalFormatMode) - COMPARE_StateAttribute_Parameter(_internalFormatValue) COMPARE_StateAttribute_Parameter(_textureWidth) COMPARE_StateAttribute_Parameter(_textureHeight) COMPARE_StateAttribute_Parameter(_subloadMode) @@ -149,75 +114,6 @@ void Texture::setImage(Image* image) _image = image; } - -void Texture::setWrap(const WrapParameter which, const WrapMode wrap) -{ - switch( which ) - { - case WRAP_S : _wrap_s = wrap; _texParamtersDirty = true; break; - case WRAP_T : _wrap_t = wrap; _texParamtersDirty = true; break; - case WRAP_R : _wrap_r = wrap; _texParamtersDirty = true; break; - default : notify(WARN)<<"Error: invalid 'which' passed Texture::setWrap("<<(unsigned int)which<<","<<(unsigned int)wrap<<")"<data()) { - glBindTexture( _target, handle ); - if (_texParamtersDirty) applyTexParameters(_target,state); + glBindTexture( GL_TEXTURE_2D, handle ); + if (_texParamtersDirty) applyTexParameters(GL_TEXTURE_2D,state); uint& modifiedTag = getModifiedTag(contextID); if (_subloadMode == AUTO || @@ -246,7 +142,7 @@ void Texture::apply(State& state) const { glPixelStorei(GL_UNPACK_ROW_LENGTH,_image->s()); - glTexSubImage2D(_target, 0, + glTexSubImage2D(GL_TEXTURE_2D, 0, _subloadTextureOffsetX, _subloadTextureOffsetY, (_subloadImageWidth>0)?_subloadImageWidth:_image->s(), (_subloadImageHeight>0)?_subloadImageHeight:_image->t(), (GLenum) _image->getPixelFormat(), (GLenum) _image->getDataType(), @@ -259,7 +155,7 @@ void Texture::apply(State& state) const } else if (_subloadMode == USE_CALLBACK) { - _subloadCallback->subload(_target,*this,state); + _subloadCallback->subload(GL_TEXTURE_2D,*this,state); } } @@ -268,392 +164,30 @@ void Texture::apply(State& state) const { glGenTextures( 1L, (GLuint *)&handle ); - glBindTexture( _target, handle ); + glBindTexture( GL_TEXTURE_2D, handle ); - applyTexParameters(_target,state); - applyTexImage(_target,_image.get(),state); + applyTexParameters(GL_TEXTURE_2D,state); + applyTexImage2D(GL_TEXTURE_2D,_image.get(),state, _textureWidth, _textureHeight, _numMimpmapLevels); // 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( _target, handle ); - - if (_unrefImageAfterApply) - _image = 0; + glBindTexture( GL_TEXTURE_2D, handle ); } -} - -void Texture::compile(State& state) const -{ - apply(state); -} - - -void Texture::applyTexParameters(GLenum target, State&) const -{ - WrapMode ws = _wrap_s, wt = _wrap_t; - - // GL_IBM_texture_mirrored_repeat, fall-back REPEAT - static bool s_mirroredSupported = isGLExtensionSupported("GL_IBM_texture_mirrored_repeat"); - if (!s_mirroredSupported) - { - if (ws == MIRROR) - ws = REPEAT; - if (wt == MIRROR) - wt = REPEAT; - } - - // GL_EXT_texture_edge_clamp, fall-back CLAMP - static bool s_edgeClampSupported = isGLExtensionSupported("GL_EXT_texture_edge_clamp"); - if (!s_edgeClampSupported) - { - if (ws == CLAMP_TO_EDGE) - ws = CLAMP; - if (wt == CLAMP_TO_EDGE) - wt = CLAMP; - } - - static bool s_borderClampSupported = isGLExtensionSupported("GL_ARB_texture_border_clamp"); - if(!s_borderClampSupported) - { - if(ws == CLAMP_TO_BORDER) - ws = CLAMP; - if(wt == CLAMP_TO_BORDER) - wt = CLAMP; - } - - glTexParameteri( target, GL_TEXTURE_WRAP_S, ws ); - glTexParameteri( target, GL_TEXTURE_WRAP_T, wt ); - - glTexParameteri( target, GL_TEXTURE_MIN_FILTER, _min_filter); - glTexParameteri( target, GL_TEXTURE_MAG_FILTER, _mag_filter); - - if (_maxAnisotropy>1.0f) - { - // check for support for anisotropic filter, - // note since this is static varible it is intialised - // only on the first time entering this code block, - // is then never reevaluated on subsequent calls. - static bool s_anisotropicSupported = - isGLExtensionSupported("GL_EXT_texture_filter_anisotropic"); - - if (s_anisotropicSupported) - { - // note, GL_TEXTURE_MAX_ANISOTROPY_EXT will either be defined - // by gl.h (or via glext.h) or by include/osg/Texture. - glTexParameterf(target, GL_TEXTURE_MAX_ANISOTROPY_EXT, _maxAnisotropy); - } - } - - if (s_borderClampSupported) - { - glTexParameterfv(target, GL_TEXTURE_BORDER_COLOR, _borderColor.ptr()); - } - - - _texParamtersDirty=false; - -} - -void Texture::applyTexImage(GLenum target, Image* image, State& state) const -{ - // if we don't have a valid image we can't create a texture! - if (!image || !image->data()) - return; - - // get the contextID (user defined ID of 0 upwards) for the - // current OpenGL context. - const uint contextID = state.getContextID(); - - // update the modified tag to show that it is upto date. - getModifiedTag(contextID) = image->getModifiedTag(); - - - if (_subloadMode == OFF) - image->ensureValidSizeForTexturing(); - - glPixelStorei(GL_UNPACK_ALIGNMENT,image->getPacking()); - - static bool s_ARB_Compression = isGLExtensionSupported("GL_ARB_texture_compression"); - static bool s_S3TC_Compression = isGLExtensionSupported("GL_EXT_texture_compression_s3tc"); - - // select the internalFormat required for the texture. - bool compressed = false; - GLint internalFormat = image->getInternalTextureFormat(); - switch(_internalFormatMode) - { - case(USE_IMAGE_DATA_FORMAT): - internalFormat = image->getInternalTextureFormat(); - break; - - case(USE_ARB_COMPRESSION): - if (s_ARB_Compression) - { - compressed = true; - switch(image->getPixelFormat()) - { - case(1): internalFormat = GL_COMPRESSED_ALPHA_ARB; break; - case(2): internalFormat = GL_COMPRESSED_LUMINANCE_ALPHA_ARB; break; - case(3): internalFormat = GL_COMPRESSED_RGB_ARB; break; - case(4): internalFormat = GL_COMPRESSED_RGBA_ARB; break; - case(GL_RGB): internalFormat = GL_COMPRESSED_RGB_ARB; break; - case(GL_RGBA): internalFormat = GL_COMPRESSED_RGBA_ARB; break; - case(GL_ALPHA): internalFormat = GL_COMPRESSED_ALPHA_ARB; break; - case(GL_LUMINANCE): internalFormat = GL_COMPRESSED_LUMINANCE_ARB; break; - case(GL_LUMINANCE_ALPHA): internalFormat = GL_COMPRESSED_LUMINANCE_ALPHA_ARB; break; - case(GL_INTENSITY): internalFormat = GL_COMPRESSED_INTENSITY_ARB; break; - } - } - else internalFormat = image->getInternalTextureFormat(); - break; - - case(USE_S3TC_DXT1_COMPRESSION): - if (s_S3TC_Compression) - { - compressed = true; - switch(image->getPixelFormat()) - { - case(3): internalFormat = GL_COMPRESSED_RGB_S3TC_DXT1_EXT; break; - case(4): internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; break; - case(GL_RGB): internalFormat = GL_COMPRESSED_RGB_S3TC_DXT1_EXT; break; - case(GL_RGBA): internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; break; - default: internalFormat = image->getInternalTextureFormat(); break; - } - } - else internalFormat = image->getInternalTextureFormat(); - break; - - case(USE_S3TC_DXT3_COMPRESSION): - if (s_S3TC_Compression) - { - compressed = true; - switch(image->getPixelFormat()) - { - case(3): - case(GL_RGB): internalFormat = GL_COMPRESSED_RGB_S3TC_DXT1_EXT; break; - case(4): - case(GL_RGBA): internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; break; - default: internalFormat = _image->getInternalTextureFormat(); break; - } - } - else internalFormat = image->getInternalTextureFormat(); - break; - - case(USE_S3TC_DXT5_COMPRESSION): - if (s_S3TC_Compression) - { - compressed = true; - switch(image->getPixelFormat()) - { - case(3): - case(GL_RGB): internalFormat = GL_COMPRESSED_RGB_S3TC_DXT1_EXT; break; - case(4): - case(GL_RGBA): internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; break; - default: internalFormat = image->getInternalTextureFormat(); break; - } - } - else internalFormat = image->getInternalTextureFormat(); - break; - - case(USE_USER_DEFINED_FORMAT): - internalFormat = _internalFormatValue; - break; - - } - - _internalFormatValue = internalFormat; - - // an experiment to look at the changes in performance - // when use 16 bit textures rather than 24/32bit textures. - // internalFormat = GL_RGBA4; - - - static MyCompressedTexImage2DArbProc glCompressedTexImage2D_ptr = - (MyCompressedTexImage2DArbProc)getGLExtensionFuncPtr("glCompressedTexImage2DARB"); - - if (_subloadMode == OFF) { - - if( _min_filter == LINEAR || _min_filter == NEAREST ) - { - if ( !compressed ) - { - _numMimpmapLevels = 1; - glTexImage2D( target, 0, internalFormat, - image->s(), image->t(), 0, - (GLenum)image->getPixelFormat(), - (GLenum)image->getDataType(), - image->data() ); - - } - else if(glCompressedTexImage2D_ptr) - { - _numMimpmapLevels = 1; - GLint blockSize = ( internalFormat == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ? 8 : 16 ); - GLint size = ((image->s()+3)/4)*((image->t()+3)/4)*blockSize; - glCompressedTexImage2D_ptr(target, 0, internalFormat, - image->s(), image->t(),0, - size, - image->data()); - - } - - } - else - { - if(!image->isMipmap()) - { - - _numMimpmapLevels = 1; - - - gluBuild2DMipmaps( target, internalFormat, - image->s(),image->t(), - (GLenum)image->getPixelFormat(), (GLenum)image->getDataType(), - image->data() ); - - } - else - { - _numMimpmapLevels = image->getNumMipmapLevels(); - - int width = image->s(); - int height = image->t(); - - if( !compressed ) - { - for( size_t k = 0 ; k < _numMimpmapLevels && (width || height) ;k++) - { - - if (width == 0) - width = 1; - if (height == 0) - height = 1; - - glTexImage2D( target, k, internalFormat, - width, height, 0, - (GLenum)image->getPixelFormat(), - (GLenum)image->getDataType(), - image->getMipmapData(k)); - - width >>= 1; - height >>= 1; - } - } - else if(glCompressedTexImage2D_ptr) - { - GLint blockSize = ( internalFormat == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ? 8 : 16 ); - GLint size = 0; - for( size_t k = 0 ; k < _numMimpmapLevels && (width || height) ;k++) - { - if (width == 0) - width = 1; - if (height == 0) - height = 1; - - size = ((width+3)/4)*((height+3)/4)*blockSize; - glCompressedTexImage2D_ptr(target, k, internalFormat, - width, height, 0, size, image->getMipmapData(k)); - - width >>= 1; - height >>= 1; - } - } - } - - } - - _textureWidth = image->s(); - _textureHeight = image->t(); - } - else if (_subloadMode == USE_CALLBACK) - { - _subloadCallback->load(target,*this,state); - } else { - static bool s_SGIS_GenMipmap = isGLExtensionSupported("GL_SGIS_generate_mipmap"); - - if (s_SGIS_GenMipmap && (_min_filter != LINEAR && _min_filter != NEAREST)) - { - _numMimpmapLevels = 1; // will leave this at one, since the mipmap will be created internally by OpenGL. - glTexParameteri(target, GL_GENERATE_MIPMAP_SGIS, GL_TRUE); - } - else - { - _numMimpmapLevels = 1; - } - - GLsizei width = (_subloadImageWidth>0)?_subloadImageWidth:image->s(); - GLsizei height = (_subloadImageHeight>0)?_subloadImageHeight:image->t(); - - if (_textureWidth==0) - { - // need to calculate texture dimension - _textureWidth = 1; - for (; _textureWidth < (static_cast(_subloadTextureOffsetX) + width); _textureWidth <<= 1) {} - } - - if (_textureHeight==0) - { - // need to calculate texture dimension - _textureHeight = 1; - for (; _textureHeight < (static_cast(_subloadTextureOffsetY) + height); _textureHeight <<= 1) {} - } - - // reserve appropriate texture memory - glTexImage2D(target, 0, internalFormat, - _textureWidth, _textureHeight, 0, - (GLenum) image->getPixelFormat(), (GLenum) image->getDataType(), - NULL); - - - glPixelStorei(GL_UNPACK_ROW_LENGTH,image->s()); - - glTexSubImage2D(target, 0, - _subloadTextureOffsetX, _subloadTextureOffsetY, - width, height, - (GLenum) image->getPixelFormat(), (GLenum) image->getDataType(), - image->data(_subloadImageOffsetX,_subloadImageOffsetY)); - - glPixelStorei(GL_UNPACK_ROW_LENGTH,0); + glBindTexture( GL_TEXTURE_2D, 0 ); } - } -/** 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.*/ -void Texture::deleteTextureObject(uint contextID,GLuint handle) +void Texture::computeInternalFormat() const { - if (handle!=0) - { - // insert the handle into the cache for the appropriate context. - s_deletedTextureObjectCache[contextID].insert(handle); - } + if (_image.valid()) computeInternalFormatWithImage(*_image); } -/** 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); - if (citr!=s_deletedTextureObjectCache.end()) - { - std::set& textureObjectSet = citr->second; - for(std::set::iterator titr=textureObjectSet.begin(); - titr!=textureObjectSet.end(); - ++titr) - { - glDeleteTextures( 1L, (const GLuint *)&(*titr )); - } - s_deletedTextureObjectCache.erase(citr); - } -} - void Texture::copyTexImage2D(State& state, int x, int y, int width, int height ) { const uint contextID = state.getContextID(); @@ -693,18 +227,13 @@ void Texture::copyTexImage2D(State& state, int x, int y, int width, int height ) // Get a new 2d texture handle. glGenTextures( 1, &handle ); - glBindTexture( _target, handle ); - applyTexParameters(_target,state); - glCopyTexImage2D( _target, 0, GL_RGBA, x, y, width, height, 0 ); + glBindTexture( GL_TEXTURE_2D, handle ); + applyTexParameters(GL_TEXTURE_2D,state); + glCopyTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, x, y, width, height, 0 ); - /* Redundant, delete later */ -// glBindTexture( _target, handle ); - _textureWidth = width; _textureHeight = height; - -// cout<<"copyTexImage2D x="< +#include +#include +#include + +typedef void (APIENTRY * MyCompressedTexImage1DArbProc) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data); + +using namespace osg; + +Texture1D::Texture1D(): + _textureWidth(0), + _numMimpmapLevels(0) +{ +} + +Texture1D::Texture1D(const Texture1D& text,const CopyOp& copyop): + TextureBase(text,copyop), + _image(copyop(text._image.get())), + _textureWidth(text._textureWidth), + _numMimpmapLevels(text._numMimpmapLevels), + _subloadCallback(text._subloadCallback) +{ +} + +Texture1D::~Texture1D() +{ +} + +int Texture1D::compare(const StateAttribute& sa) const +{ + // check the types are equal and then create the rhs variable + // used by the COMPARE_StateAttribute_Paramter macro's below. + COMPARE_StateAttribute_Types(Texture1D,sa) + + if (_image!=rhs._image) // smart pointer comparison. + { + if (_image.valid()) + { + if (rhs._image.valid()) + { + if (_image->getFileName()getFileName()) return -1; + else if (_image->getFileName()>rhs._image->getFileName()) return 1;; + } + else + { + return 1; // valid lhs._image is greater than null. + } + } + else if (rhs._image.valid()) + { + return -1; // valid rhs._image is greater than null. + } + } + + int result = compareTextureBase(rhs); + if (result!=0) return result; + + // compare each paramter in turn against the rhs. + COMPARE_StateAttribute_Parameter(_textureWidth) + COMPARE_StateAttribute_Parameter(_subloadCallback) + + return 0; // passed all the above comparison macro's, must be equal. +} + +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; + } + } + + _image = image; +} + + +void Texture1D::apply(State& state) const +{ + + // get the contextID (user defined ID of 0 upwards) for the + // current OpenGL context. + const uint contextID = state.getContextID(); + + // get the globj for the current contextID. + GLuint& handle = getTextureObject(contextID); + + if (handle != 0) + { + + glBindTexture( GL_TEXTURE_1D, handle ); + if (_texParamtersDirty) applyTexParameters(GL_TEXTURE_1D,state); + + if (_subloadCallback.valid()) + { + _subloadCallback->subload(*this,state); + } + + } + else if (_subloadCallback.valid()) + { + + glGenTextures( 1L, (GLuint *)&handle ); + glBindTexture( GL_TEXTURE_1D, handle ); + + applyTexParameters(GL_TEXTURE_1D,state); + + _subloadCallback->load(*this,state); + + // 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 ); + + } + else if (_image.valid() && _image->data()) + { + + glGenTextures( 1L, (GLuint *)&handle ); + glBindTexture( GL_TEXTURE_1D, handle ); + + applyTexParameters(GL_TEXTURE_1D,state); + + applyTexImage1D(GL_TEXTURE_1D,_image.get(),state, _textureWidth, _numMimpmapLevels); + + // 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 ); + + } + else + { + glBindTexture( GL_TEXTURE_1D, 0 ); + } +} + +void Texture1D::computeInternalFormat() const +{ + if (_image.valid()) computeInternalFormatWithImage(*_image); +} + +void Texture1D::applyTexImage1D(GLenum target, Image* image, State& state, GLsizei& inwidth, GLsizei& numMimpmapLevels) const +{ + // if we don't have a valid image we can't create a texture! + if (!image || !image->data()) + return; + + // get the contextID (user defined ID of 0 upwards) for the + // current OpenGL context. + const uint contextID = state.getContextID(); + + // update the modified tag to show that it is upto date. + getModifiedTag(contextID) = image->getModifiedTag(); + + + // compute the internal texture format, this set the _internalFormat to an appropriate value. + computeInternalFormat(); + + // select the internalFormat required for the texture. + bool compressed = isCompressedInternalFormat(_internalFormat); + + image->ensureValidSizeForTexturing(); + + glPixelStorei(GL_UNPACK_ALIGNMENT,image->getPacking()); + + static MyCompressedTexImage1DArbProc glCompressedTexImage1D_ptr = + (MyCompressedTexImage1DArbProc)getGLExtensionFuncPtr("glCompressedTexImage1DARB"); + + if( _min_filter == LINEAR || _min_filter == NEAREST ) + { + if ( !compressed ) + { + numMimpmapLevels = 1; + glTexImage1D( target, 0, _internalFormat, + image->s(), 0, + (GLenum)image->getPixelFormat(), + (GLenum)image->getDataType(), + image->data() ); + + } + else if(glCompressedTexImage1D_ptr) + { + numMimpmapLevels = 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, + image->s(), 0, + size, + image->data()); + + } + + } + else + { + if(!image->isMipmap()) + { + + numMimpmapLevels = 1; + + gluBuild1DMipmaps( target, _internalFormat, + image->s(), + (GLenum)image->getPixelFormat(), (GLenum)image->getDataType(), + image->data() ); + + } + else + { + numMimpmapLevels = image->getNumMipmapLevels(); + + int width = image->s(); + + if( !compressed ) + { + for( GLsizei k = 0 ; k < numMimpmapLevels && width ;k++) + { + + glTexImage1D( target, k, _internalFormat, + width,0, + (GLenum)image->getPixelFormat(), + (GLenum)image->getDataType(), + image->getMipmapData(k)); + + width >>= 1; + } + } + else if(glCompressedTexImage1D_ptr) + { + GLint blockSize = ( _internalFormat == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ? 8 : 16 ); + GLint size = 0; + for( GLsizei k = 0 ; k < numMimpmapLevels && width ;k++) + { + + size = ((width+3)/4)*blockSize; + glCompressedTexImage1D_ptr(target, k, _internalFormat, + width, 0, size, image->getMipmapData(k)); + + width >>= 1; + } + } + } + + } + + inwidth = image->s(); +} + +void Texture1D::copyTexImage1D(State& state, int x, int y, int width) +{ + const uint contextID = state.getContextID(); + + // get the globj for the current contextID. + GLuint& handle = getTextureObject(contextID); + + if (handle) + { + if (width==(int)_textureWidth) + { + // we have a valid texture object which is the right size + // so lets play clever and use copyTexSubImage2D instead. + // this allows use to reuse the texture object and avoid + // expensive memory allocations. + copyTexSubImage1D(state,0 ,x, y, width); + return; + } + // the relevent texture object is not of the right size so + // needs to been deleted + // remove previously bound textures. + dirtyTextureObject(); + // note, dirtyTextureObject() dirties all the texture objects for + // this texture, is this right? Perhaps we should dirty just the + // one for this context. Note sure yet will leave till later. + // RO July 2001. + } + + + // remove any previously assigned images as these are nolonger valid. + _image = NULL; + + // switch off mip-mapping. + _min_filter = LINEAR; + _mag_filter = LINEAR; + + // Get a new 2d texture handle. + glGenTextures( 1, &handle ); + + glBindTexture( GL_TEXTURE_1D, handle ); + applyTexParameters(GL_TEXTURE_1D,state); + glCopyTexImage1D( GL_TEXTURE_1D, 0, GL_RGBA, x, y, width, 0 ); + + _textureWidth = width; + + // inform state that this texture is the current one bound. + state.haveAppliedAttribute(this); +} + +void Texture1D::copyTexSubImage1D(State& state, int xoffset, int x, int y, int width) +{ + const uint contextID = state.getContextID(); + + // get the globj for the current contextID. + GLuint& handle = getTextureObject(contextID); + + if (handle) + { + + // 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 ); + + // inform state that this texture is the current one bound. + state.haveAppliedAttribute(this); + + } + else + { + // no texture object already exsits for this context so need to + // create it upfront - simply call copyTexImage1D. + copyTexImage1D(state,x,y,width); + } +} diff --git a/src/osg/Texture2D.cpp b/src/osg/Texture2D.cpp new file mode 100644 index 000000000..0887c7a8d --- /dev/null +++ b/src/osg/Texture2D.cpp @@ -0,0 +1,234 @@ +#include +#include +#include +#include + +typedef void (APIENTRY * MyCompressedTexImage2DArbProc) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); + +using namespace osg; + +Texture2D::Texture2D(): + _textureWidth(0), + _textureHeight(0), + _numMimpmapLevels(0) +{ +} + +Texture2D::Texture2D(const Texture2D& text,const CopyOp& copyop): + TextureBase(text,copyop), + _image(copyop(text._image.get())), + _textureWidth(text._textureWidth), + _textureHeight(text._textureHeight), + _numMimpmapLevels(text._numMimpmapLevels), + _subloadCallback(text._subloadCallback) +{ +} + +Texture2D::~Texture2D() +{ +} + +int Texture2D::compare(const StateAttribute& sa) const +{ + // check the types are equal and then create the rhs variable + // used by the COMPARE_StateAttribute_Paramter macro's below. + COMPARE_StateAttribute_Types(Texture2D,sa) + + if (_image!=rhs._image) // smart pointer comparison. + { + if (_image.valid()) + { + if (rhs._image.valid()) + { + if (_image->getFileName()getFileName()) return -1; + else if (_image->getFileName()>rhs._image->getFileName()) return 1;; + } + else + { + return 1; // valid lhs._image is greater than null. + } + } + else if (rhs._image.valid()) + { + return -1; // valid rhs._image is greater than null. + } + } + + int result = compareTextureBase(rhs); + if (result!=0) return result; + + // compare each paramter in turn against the rhs. + COMPARE_StateAttribute_Parameter(_textureWidth) + COMPARE_StateAttribute_Parameter(_textureHeight) + COMPARE_StateAttribute_Parameter(_subloadCallback) + + return 0; // passed all the above comparison macro's, must be equal. +} + +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; + } + } + + _image = image; +} + + +void Texture2D::apply(State& state) const +{ + + // get the contextID (user defined ID of 0 upwards) for the + // current OpenGL context. + const uint contextID = state.getContextID(); + + // get the globj for the current contextID. + GLuint& handle = getTextureObject(contextID); + + if (handle != 0) + { + + glBindTexture( GL_TEXTURE_2D, handle ); + if (_texParamtersDirty) applyTexParameters(GL_TEXTURE_2D,state); + + if (_subloadCallback.valid()) + { + _subloadCallback->subload(*this,state); + } + + } + else if (_subloadCallback.valid()) + { + + glGenTextures( 1L, (GLuint *)&handle ); + glBindTexture( GL_TEXTURE_2D, handle ); + + applyTexParameters(GL_TEXTURE_2D,state); + + _subloadCallback->load(*this,state); + + // 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 ); + + } + else if (_image.valid() && _image->data()) + { + + glGenTextures( 1L, (GLuint *)&handle ); + glBindTexture( GL_TEXTURE_2D, handle ); + + applyTexParameters(GL_TEXTURE_2D,state); + + applyTexImage2D(GL_TEXTURE_2D,_image.get(),state, _textureWidth, _textureHeight, _numMimpmapLevels); + + // 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 ); + + } + else + { + glBindTexture( GL_TEXTURE_2D, 0 ); + } +} + +void Texture2D::computeInternalFormat() const +{ + if (_image.valid()) computeInternalFormatWithImage(*_image); +} + + +void Texture2D::copyTexImage2D(State& state, int x, int y, int width, int height ) +{ + const uint contextID = state.getContextID(); + + // get the globj for the current contextID. + GLuint& handle = getTextureObject(contextID); + + if (handle) + { + if (width==(int)_textureWidth && height==(int)_textureHeight) + { + // we have a valid texture object which is the right size + // so lets play clever and use copyTexSubImage2D instead. + // this allows use to reuse the texture object and avoid + // expensive memory allocations. + copyTexSubImage2D(state,0 ,0, x, y, width, height); + return; + } + // the relevent texture object is not of the right size so + // needs to been deleted + // remove previously bound textures. + dirtyTextureObject(); + // note, dirtyTextureObject() dirties all the texture objects for + // this texture, is this right? Perhaps we should dirty just the + // one for this context. Note sure yet will leave till later. + // RO July 2001. + } + + + // remove any previously assigned images as these are nolonger valid. + _image = NULL; + + // switch off mip-mapping. + _min_filter = LINEAR; + _mag_filter = LINEAR; + + // Get a new 2d texture handle. + glGenTextures( 1, &handle ); + + glBindTexture( GL_TEXTURE_2D, handle ); + applyTexParameters(GL_TEXTURE_2D,state); + glCopyTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, x, y, width, height, 0 ); + + _textureWidth = width; + _textureHeight = height; + + // inform state that this texture is the current one bound. + state.haveAppliedAttribute(this); +} + +void Texture2D::copyTexSubImage2D(State& state, int xoffset, int yoffset, int x, int y, int width, int height ) +{ + const uint contextID = state.getContextID(); + + // get the globj for the current contextID. + GLuint& handle = getTextureObject(contextID); + + if (handle) + { + + // we have a valid image + glBindTexture( GL_TEXTURE_2D, handle ); + applyTexParameters(GL_TEXTURE_2D,state); + glCopyTexSubImage2D( GL_TEXTURE_2D, 0, xoffset,yoffset, x, y, width, height); + + /* Redundant, delete later */ + glBindTexture( GL_TEXTURE_2D, handle ); + + // inform state that this texture is the current one bound. + state.haveAppliedAttribute(this); + + } + else + { + // no texture object already exsits for this context so need to + // create it upfront - simply call copyTexImage2D. + copyTexImage2D(state,x,y,width,height); + } +} diff --git a/src/osg/Texture3D.cpp b/src/osg/Texture3D.cpp new file mode 100644 index 000000000..4cc5bdd48 --- /dev/null +++ b/src/osg/Texture3D.cpp @@ -0,0 +1,280 @@ +#include +#include +#include +#include +#include + +#define TEMPORARY_COMMENT_OUT_WHILE_ESTABLISHING_X_PLATFORM_SUPPORT_FOR_3D_TEXTURES + +using namespace osg; + +Texture3D::Texture3D(): + _textureWidth(0), + _textureHeight(0), + _textureDepth(0), + _numMimpmapLevels(0) +{ +} + +Texture3D::Texture3D(const Texture3D& text,const CopyOp& copyop): + TextureBase(text,copyop), + _image(copyop(text._image.get())), + _textureWidth(text._textureWidth), + _textureHeight(text._textureHeight), + _textureDepth(text._textureDepth), + _numMimpmapLevels(text._numMimpmapLevels), + _subloadCallback(text._subloadCallback) +{ +} + +Texture3D::~Texture3D() +{ +} + +int Texture3D::compare(const StateAttribute& sa) const +{ + // check the types are equal and then create the rhs variable + // used by the COMPARE_StateAttribute_Paramter macro's below. + COMPARE_StateAttribute_Types(Texture3D,sa) + + if (_image!=rhs._image) // smart pointer comparison. + { + if (_image.valid()) + { + if (rhs._image.valid()) + { + if (_image->getFileName()getFileName()) return -1; + else if (_image->getFileName()>rhs._image->getFileName()) return 1;; + } + else + { + return 1; // valid lhs._image is greater than null. + } + } + else if (rhs._image.valid()) + { + return -1; // valid rhs._image is greater than null. + } + } + + int result = compareTextureBase(rhs); + if (result!=0) return result; + + // compare each paramter in turn against the rhs. + COMPARE_StateAttribute_Parameter(_textureWidth) + COMPARE_StateAttribute_Parameter(_textureHeight) + COMPARE_StateAttribute_Parameter(_textureDepth) + COMPARE_StateAttribute_Parameter(_subloadCallback) + + return 0; // passed all the above comparison macro's, must be equal. +} + +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; + } + } + + _image = image; +} + + +void Texture3D::apply(State& state) const +{ + + // get the contextID (user defined ID of 0 upwards) for the + // current OpenGL context. + const uint contextID = state.getContextID(); + + // get the globj for the current contextID. + GLuint& handle = getTextureObject(contextID); + + if (handle != 0) + { + + glBindTexture( GL_TEXTURE_3D, handle ); + if (_texParamtersDirty) applyTexParameters(GL_TEXTURE_3D,state); + + if (_subloadCallback.valid()) + { + _subloadCallback->subload(*this,state); + } + + } + else if (_subloadCallback.valid()) + { + + glGenTextures( 1L, (GLuint *)&handle ); + glBindTexture( GL_TEXTURE_3D, handle ); + + applyTexParameters(GL_TEXTURE_3D,state); + + _subloadCallback->load(*this,state); + + // 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 ); + + } + else if (_image.valid() && _image->data()) + { + + glGenTextures( 1L, (GLuint *)&handle ); + glBindTexture( GL_TEXTURE_3D, handle ); + + applyTexParameters(GL_TEXTURE_3D,state); + + applyTexImage3D(GL_TEXTURE_3D,_image.get(),state, _textureWidth, _textureHeight, _textureDepth,_numMimpmapLevels); + + // 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 ); + + } + else + { + glBindTexture( GL_TEXTURE_3D, 0 ); + } +} + +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 +{ +#ifndef TEMPORARY_COMMENT_OUT_WHILE_ESTABLISHING_X_PLATFORM_SUPPORT_FOR_3D_TEXTURES + + // if we don't have a valid image we can't create a texture! + if (!image || !image->data()) + return; + + // get the contextID (user defined ID of 0 upwards) for the + // current OpenGL context. + const uint contextID = state.getContextID(); + + // update the modified tag to show that it is upto date. + getModifiedTag(contextID) = image->getModifiedTag(); + + + // compute the internal texture format, this set the _internalFormat to an appropriate value. + computeInternalFormat(); + + // select the internalFormat required for the texture. + bool compressed = isCompressedInternalFormat(_internalFormat); + if (compressed) + { + notify(WARN)<<"Warning::cannot currently use compressed format with 3D textures."<ensureValidSizeForTexturing(); + + glPixelStorei(GL_UNPACK_ALIGNMENT,image->getPacking()); + + if( _min_filter == LINEAR || _min_filter == NEAREST ) + { + numMimpmapLevels = 1; + glTexImage3D( target, 0, _internalFormat, + image->s(), image->t(), image->r(), 0, + (GLenum)image->getPixelFormat(), + (GLenum)image->getDataType(), + image->data() ); + } + else + { + if(!image->isMipmap()) + { + + numMimpmapLevels = 1; + + gluBuild3DMipmaps( target, _internalFormat, + image->s(),image->t(),image->r(), + (GLenum)image->getPixelFormat(), (GLenum)image->getDataType(), + image->data() ); + + } + else + { + numMimpmapLevels = image->getNumMipmapLevels(); + + int width = image->s(); + int height = image->t(); + int depth = image->r(); + + for( GLsizei k = 0 ; k < numMimpmapLevels && (width || height || depth) ;k++) + { + + if (width == 0) + width = 1; + if (height == 0) + height = 1; + if (depth == 0) + depth = 1; + + glTexImage3D( target, k, _internalFormat, + width, height, depth, 0, + (GLenum)image->getPixelFormat(), + (GLenum)image->getDataType(), + image->getMipmapData(k)); + + width >>= 1; + height >>= 1; + depth >>= 1; + } + } + + } + + inwidth = image->s(); + inheight = image->t(); + indepth = image->r(); + +#endif // TEMPORARY_COMMENT_OUT_WHILE_ESTABLISHING_X_PLATFORM_SUPPORT_FOR_3D_TEXTURES + +} + +void Texture3D::copyTexSubImage3D(State& state, int xoffset, int yoffset, int zoffset, int x, int y, int width, int height ) +{ +#ifndef TEMPORARY_COMMENT_OUT_WHILE_ESTABLISHING_X_PLATFORM_SUPPORT_FOR_3D_TEXTURES + const uint contextID = state.getContextID(); + + // get the globj for the current contextID. + GLuint& handle = getTextureObject(contextID); + + if (handle) + { + + // we have a valid image + glBindTexture( GL_TEXTURE_3D, handle ); + applyTexParameters(GL_TEXTURE_3D,state); + glCopyTexSubImage3D( GL_TEXTURE_3D, 0, xoffset,yoffset,zoffset, x, y, width, height); + + /* Redundant, delete later */ + glBindTexture( GL_TEXTURE_3D, handle ); + + // inform state that this texture is the current one bound. + state.haveAppliedAttribute(this); + + } + else + { + notify(WARN)<<"Warning: Texture3D::copyTexSubImage3D(..) failed, cannot not copy to a non existant texture."< +#include +#include +#include +#include +#include + +typedef void (APIENTRY * MyCompressedTexImage2DArbProc) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); + +using namespace osg; + + +TextureBase::DeletedTextureObjectCache TextureBase::s_deletedTextureObjectCache; + +TextureBase::TextureBase(): + _wrap_s(CLAMP), + _wrap_t(CLAMP), + _wrap_r(CLAMP), + _min_filter(LINEAR_MIPMAP_LINEAR), // trilinear + _mag_filter(LINEAR), + _maxAnisotropy(1.0f), + _borderColor(0.0, 0.0, 0.0, 0.0), + _texParamtersDirty(true), + _internalFormatMode(USE_IMAGE_DATA_FORMAT), + _internalFormat(0) +{ + _handleList.resize(DisplaySettings::instance()->getMaxNumberOfGraphicsContexts(),0); + _modifiedTag.resize(DisplaySettings::instance()->getMaxNumberOfGraphicsContexts(),0); +} + +TextureBase::TextureBase(const TextureBase& text,const CopyOp& copyop): + StateAttribute(text,copyop), + _wrap_s(text._wrap_s), + _wrap_t(text._wrap_t), + _wrap_r(text._wrap_r), + _min_filter(text._min_filter), + _mag_filter(text._mag_filter), + _maxAnisotropy(text._maxAnisotropy), + _borderColor(text._borderColor), + _texParamtersDirty(false), + _internalFormatMode(text._internalFormatMode), + _internalFormat(text._internalFormat) +{ + _handleList.resize(DisplaySettings::instance()->getMaxNumberOfGraphicsContexts(),0); + _modifiedTag.resize(DisplaySettings::instance()->getMaxNumberOfGraphicsContexts(),0); +} + +TextureBase::~TextureBase() +{ + // delete old texture objects. + dirtyTextureObject(); +} + +int TextureBase::compareTextureBase(const TextureBase& rhs) const +{ + COMPARE_StateAttribute_Parameter(_wrap_s) + COMPARE_StateAttribute_Parameter(_wrap_t) + COMPARE_StateAttribute_Parameter(_wrap_r) + COMPARE_StateAttribute_Parameter(_min_filter) + COMPARE_StateAttribute_Parameter(_mag_filter) + COMPARE_StateAttribute_Parameter(_maxAnisotropy) + COMPARE_StateAttribute_Parameter(_internalFormatMode) + COMPARE_StateAttribute_Parameter(_internalFormat) + + return 0; +} + + +void TextureBase::setWrap(const WrapParameter which, const WrapMode wrap) +{ + switch( which ) + { + case WRAP_S : _wrap_s = wrap; _texParamtersDirty = true; break; + case WRAP_T : _wrap_t = wrap; _texParamtersDirty = true; break; + case WRAP_R : _wrap_r = wrap; _texParamtersDirty = true; break; + default : notify(WARN)<<"Error: invalid 'which' passed TextureBase::setWrap("<<(unsigned int)which<<","<<(unsigned int)wrap<<")"<1.0f) + { + // check for support for anisotropic filter, + // note since this is static varible it is intialised + // only on the first time entering this code block, + // is then never reevaluated on subsequent calls. + static bool s_anisotropicSupported = + isGLExtensionSupported("GL_EXT_texture_filter_anisotropic"); + + if (s_anisotropicSupported) + { + // note, GL_TEXTURE_MAX_ANISOTROPY_EXT will either be defined + // by gl.h (or via glext.h) or by include/osg/Texture. + glTexParameterf(target, GL_TEXTURE_MAX_ANISOTROPY_EXT, _maxAnisotropy); + } + } + + if (s_borderClampSupported) + { + glTexParameterfv(target, GL_TEXTURE_BORDER_COLOR, _borderColor.ptr()); + } + + + _texParamtersDirty=false; + +} + +void TextureBase::applyTexImage2D(GLenum target, Image* image, State& state, GLsizei& inwidth, GLsizei& inheight,GLsizei& numMimpmapLevels) const +{ + // if we don't have a valid image we can't create a texture! + if (!image || !image->data()) + return; + + // get the contextID (user defined ID of 0 upwards) for the + // current OpenGL context. + const uint contextID = state.getContextID(); + + // update the modified tag to show that it is upto date. + getModifiedTag(contextID) = image->getModifiedTag(); + + + // compute the internal texture format, this set the _internalFormat to an appropriate value. + computeInternalFormat(); + + // select the internalFormat required for the texture. + bool compressed = isCompressedInternalFormat(_internalFormat); + + image->ensureValidSizeForTexturing(); + + glPixelStorei(GL_UNPACK_ALIGNMENT,image->getPacking()); + + static MyCompressedTexImage2DArbProc glCompressedTexImage2D_ptr = + (MyCompressedTexImage2DArbProc)getGLExtensionFuncPtr("glCompressedTexImage2DARB"); + + if( _min_filter == LINEAR || _min_filter == NEAREST ) + { + if ( !compressed ) + { + numMimpmapLevels = 1; + glTexImage2D( target, 0, _internalFormat, + image->s(), image->t(), 0, + (GLenum)image->getPixelFormat(), + (GLenum)image->getDataType(), + image->data() ); + + } + else if(glCompressedTexImage2D_ptr) + { + numMimpmapLevels = 1; + GLint blockSize = ( _internalFormat == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ? 8 : 16 ); + GLint size = ((image->s()+3)/4)*((image->t()+3)/4)*blockSize; + glCompressedTexImage2D_ptr(target, 0, _internalFormat, + image->s(), image->t(),0, + size, + image->data()); + + } + + } + else + { + if(!image->isMipmap()) + { + + numMimpmapLevels = 1; + + gluBuild2DMipmaps( target, _internalFormat, + image->s(),image->t(), + (GLenum)image->getPixelFormat(), (GLenum)image->getDataType(), + image->data() ); + + } + else + { + numMimpmapLevels = image->getNumMipmapLevels(); + + int width = image->s(); + int height = image->t(); + + if( !compressed ) + { + for( GLsizei k = 0 ; k < numMimpmapLevels && (width || height) ;k++) + { + + if (width == 0) + width = 1; + if (height == 0) + height = 1; + + glTexImage2D( target, k, _internalFormat, + width, height, 0, + (GLenum)image->getPixelFormat(), + (GLenum)image->getDataType(), + image->getMipmapData(k)); + + width >>= 1; + height >>= 1; + } + } + else if(glCompressedTexImage2D_ptr) + { + GLint blockSize = ( _internalFormat == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ? 8 : 16 ); + GLint size = 0; + for( GLsizei k = 0 ; k < numMimpmapLevels && (width || height) ;k++) + { + if (width == 0) + width = 1; + if (height == 0) + height = 1; + + size = ((width+3)/4)*((height+3)/4)*blockSize; + glCompressedTexImage2D_ptr(target, k, _internalFormat, + width, height, 0, size, image->getMipmapData(k)); + + width >>= 1; + height >>= 1; + } + } + } + + } + + inwidth = image->s(); + inheight = image->t(); + +} + +/** 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.*/ +void TextureBase::deleteTextureObject(uint contextID,GLuint handle) +{ + if (handle!=0) + { + // insert the handle into the cache for the appropriate context. + s_deletedTextureObjectCache[contextID].insert(handle); + } +} + + +/** flush all the cached display list which need to be deleted + * in the OpenGL context related to contextID.*/ +void TextureBase::flushDeletedTextureObjects(uint contextID) +{ + DeletedTextureObjectCache::iterator citr = s_deletedTextureObjectCache.find(contextID); + if (citr!=s_deletedTextureObjectCache.end()) + { + std::set& textureObjectSet = citr->second; + for(std::set::iterator titr=textureObjectSet.begin(); + titr!=textureObjectSet.end(); + ++titr) + { + glDeleteTextures( 1L, (const GLuint *)&(*titr )); + } + s_deletedTextureObjectCache.erase(citr); + } +} + + +GLint TextureBase::getMaxTextureSize() +{ + static GLint s_maxTextureSize = 0; + if (s_maxTextureSize == 0) + { + + glGetIntegerv(GL_MAX_TEXTURE_SIZE,&s_maxTextureSize); + notify(INFO) << "GL_MAX_TEXTURE_SIZE "< #include #include #include #include #include -#include #include @@ -79,11 +79,29 @@ static GLenum faceTarget[6] = #endif -TextureCubeMap::TextureCubeMap():Texture() +TextureCubeMap::TextureCubeMap(): + _textureWidth(0), + _textureHeight(0), + _numMimpmapLevels(0) { - _target = GL_TEXTURE_CUBE_MAP; // default to ARB extension } +TextureCubeMap::TextureCubeMap(const TextureCubeMap& text,const CopyOp& copyop): + TextureBase(text,copyop), + _textureWidth(text._textureWidth), + _textureHeight(text._textureHeight), + _numMimpmapLevels(text._numMimpmapLevels), + _subloadCallback(text._subloadCallback) +{ + _images[0] = copyop(text._images[0].get()); + _images[1] = copyop(text._images[1].get()); + _images[2] = copyop(text._images[2].get()); + _images[3] = copyop(text._images[3].get()); + _images[4] = copyop(text._images[4].get()); + _images[5] = copyop(text._images[5].get()); + +} + TextureCubeMap::~TextureCubeMap() { @@ -119,6 +137,14 @@ int TextureCubeMap::compare(const StateAttribute& sa) const } } + int result = compareTextureBase(rhs); + if (result!=0) return result; + + // compare each paramter in turn against the rhs. + COMPARE_StateAttribute_Parameter(_textureWidth) + COMPARE_StateAttribute_Parameter(_textureHeight) + COMPARE_StateAttribute_Parameter(_subloadCallback) + return 0; // passed all the above comparison macro's, must be equal. } @@ -165,6 +191,10 @@ bool TextureCubeMap::imagesValid() const return true; } +void TextureCubeMap::computeInternalFormat() const +{ + if (imagesValid()) computeInternalFormatWithImage(*_images[0]); +} void TextureCubeMap::apply(State& state) const { @@ -183,65 +213,55 @@ void TextureCubeMap::apply(State& state) const if (handle != 0) { - if (_subloadMode == OFF) + glBindTexture( GL_TEXTURE_CUBE_MAP, handle ); + if (_texParamtersDirty) applyTexParameters(GL_TEXTURE_CUBE_MAP,state); + + if (_subloadCallback.valid()) { - glBindTexture( _target, handle ); - if (_texParamtersDirty) applyTexParameters(_target,state); + _subloadCallback->subload(*this,state); } - else if (imagesValid()) - { - uint& modifiedTag = getModifiedTag(contextID); - modifiedTag = 0; - glBindTexture( _target, handle ); - if (_texParamtersDirty) applyTexParameters(_target,state); - - int rowwidth = 0; - for (int n=0; n<6; n++) - { - if ((_subloadMode == AUTO) || - (_subloadMode == IF_DIRTY && modifiedTag != _images[n]->getModifiedTag())) - { - - if (rowwidth != _images[n]->s()) - { - rowwidth = _images[n]->s(); - glPixelStorei(GL_UNPACK_ROW_LENGTH,rowwidth); - } - - glTexSubImage2D(faceTarget[n], 0, - _subloadTextureOffsetX, _subloadTextureOffsetX, - (_subloadImageWidth>0)?_subloadImageWidth:_images[n]->s(), (_subloadImageHeight>0)?_subloadImageHeight:_images[n]->t(), - (GLenum) _images[n]->getPixelFormat(), (GLenum) _images[n]->getDataType(), - _images[n]->data(_subloadImageOffsetX,_subloadImageOffsetY)); - // update the modified flag to show that the image has been loaded. - modifiedTag += _images[n]->getModifiedTag(); - } - else if (_subloadMode == USE_CALLBACK) - { - _subloadCallback->subload(faceTarget[n],*this,state); - } - } - glPixelStorei(GL_UNPACK_ROW_LENGTH,0); - } } - else if (imagesValid()) + else if (_subloadCallback.valid()) { glGenTextures( 1L, (GLuint *)&handle ); - glBindTexture( _target, handle ); + glBindTexture( GL_TEXTURE_CUBE_MAP, handle ); - applyTexParameters(_target,state); + applyTexParameters(GL_TEXTURE_CUBE_MAP,state); - for (int n=0; n<6; n++) - { - applyTexImage( faceTarget[n], _images[n].get(), state); - } + _subloadCallback->load(*this,state); // 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( _target, handle ); + glBindTexture( GL_TEXTURE_CUBE_MAP, handle ); } + else if (imagesValid()) + { + + glGenTextures( 1L, (GLuint *)&handle ); + glBindTexture( GL_TEXTURE_CUBE_MAP, handle ); + + applyTexParameters(GL_TEXTURE_CUBE_MAP,state); + + + for (int n=0; n<6; n++) + { + applyTexImage2D( faceTarget[n], _images[n].get(), state, _textureWidth, _textureHeight, _numMimpmapLevels); + } + + + // 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_CUBE_MAP, handle ); + + } + else + { + glBindTexture( GL_TEXTURE_CUBE_MAP, 0 ); + } } diff --git a/src/osgPlugins/dx/DXWriter.cpp b/src/osgPlugins/dx/DXWriter.cpp index 0ec6a2067..521f3d1c9 100644 --- a/src/osgPlugins/dx/DXWriter.cpp +++ b/src/osgPlugins/dx/DXWriter.cpp @@ -2047,14 +2047,6 @@ void MyStateSet::Query( const osg::StateSet &sset ) } } - if ( texture.getSubloadMode() != osg::Texture::OFF ) { - // FIXME: When we generalize this, remove the static hack - static int been_here = 0; - if ( !been_here ) { - msg_bin.Add( "WARNING: Texture subloading not supported.\n" ); - been_here = 1; - } - } } // TEXENV diff --git a/src/osgPlugins/osg/Makefile b/src/osgPlugins/osg/Makefile index aa466d594..e160460f5 100644 --- a/src/osgPlugins/osg/Makefile +++ b/src/osgPlugins/osg/Makefile @@ -49,8 +49,10 @@ CXXFILES =\ TexGen.cpp\ TexMat.cpp\ Texture.cpp\ - Transform.cpp\ + TextureBase.cpp\ + Texture2D.cpp\ TextureCubeMap.cpp\ + Transform.cpp\ LIBS += $(OSG_LIBS) $(OTHER_LIBS) diff --git a/src/osgPlugins/osg/Texture.cpp b/src/osgPlugins/osg/Texture.cpp index 96b587756..244e2f3d9 100644 --- a/src/osgPlugins/osg/Texture.cpp +++ b/src/osgPlugins/osg/Texture.cpp @@ -1,5 +1,8 @@ #include "osg/Texture" +#ifdef TEXTURE_USE_DEPRECATED_API + + #include "osgDB/Registry" #include "osgDB/Input" #include "osgDB/Output" @@ -27,7 +30,7 @@ RegisterDotOsgWrapperProxy g_TextureProxy ( osgNew osg::Texture, "Texture", - "Object StateAttribute Texture", + "Object StateAttribute Texture TextureBase", &Texture_readLocalData, &Texture_writeLocalData ); @@ -55,70 +58,6 @@ bool Texture_readLocalData(Object& obj, Input& fr) fr += 2; iteratorAdvanced = true; } - Texture::WrapMode wrap; - if (fr[0].matchWord("wrap_s") && Texture_matchWrapStr(fr[1].getStr(),wrap)) - { - texture.setWrap(Texture::WRAP_S,wrap); - fr+=2; - iteratorAdvanced = true; - } - - if (fr[0].matchWord("wrap_t") && Texture_matchWrapStr(fr[1].getStr(),wrap)) - { - texture.setWrap(Texture::WRAP_T,wrap); - fr+=2; - iteratorAdvanced = true; - } - - if (fr[0].matchWord("wrap_r") && Texture_matchWrapStr(fr[1].getStr(),wrap)) - { - texture.setWrap(Texture::WRAP_R,wrap); - fr+=2; - iteratorAdvanced = true; - } - - Texture::FilterMode filter; - if (fr[0].matchWord("min_filter") && Texture_matchFilterStr(fr[1].getStr(),filter)) - { - texture.setFilter(Texture::MIN_FILTER,filter); - fr+=2; - iteratorAdvanced = true; - } - - if (fr[0].matchWord("mag_filter") && Texture_matchFilterStr(fr[1].getStr(),filter)) - { - texture.setFilter(Texture::MAG_FILTER,filter); - fr+=2; - iteratorAdvanced = true; - } - - if (fr.matchSequence("maxAnisotropy %f")) - { - float anis=1.0f; - fr[1].getFloat(anis); - texture.setMaxAnisotropy(anis); - fr +=2 ; - iteratorAdvanced = true; - } - - Texture::InternalFormatMode mode; - if (fr[0].matchWord("internalFormatMode") && Texture_matchInternalFormatModeStr(fr[1].getStr(),mode)) - { - texture.setInternalFormatMode(mode); - fr+=2; - iteratorAdvanced = true; - } - - if (fr[0].matchWord("internalFormatValue")) - { - int value; - if (Texture_matchInternalFormatValueStr(fr[1].getStr(),value) || fr[1].getInt(value)) - { - texture.setInternalFormatValue(value); - fr+=2; - iteratorAdvanced = true; - } - } Texture::SubloadMode submode; if (fr[0].matchWord("subloadMode") && Texture_matchSubloadModeStr(fr[1].getStr(),submode)) @@ -201,22 +140,6 @@ bool Texture_writeLocalData(const Object& obj, Output& fw) fw.indent() << "file \""<getFileName())<<"\""<< std::endl; } - fw.indent() << "wrap_s " << Texture_getWrapStr(texture.getWrap(Texture::WRAP_S)) << std::endl; - fw.indent() << "wrap_t " << Texture_getWrapStr(texture.getWrap(Texture::WRAP_T)) << std::endl; - fw.indent() << "wrap_r " << Texture_getWrapStr(texture.getWrap(Texture::WRAP_R)) << std::endl; - - fw.indent() << "min_filter " << Texture_getFilterStr(texture.getFilter(Texture::MIN_FILTER)) << std::endl; - fw.indent() << "mag_filter " << Texture_getFilterStr(texture.getFilter(Texture::MAG_FILTER)) << std::endl; - fw.indent() << "maxAnisotropy " << texture.getMaxAnisotropy() << std::endl; - - fw.indent() << "internalFormatMode " << Texture_getInternalFormatModeStr(texture.getInternalFormatMode()) << std::endl; - - if (texture.getInternalFormatMode()==Texture::USE_USER_DEFINED_FORMAT) - { - const char* str = Texture_getInternalFormatValueStr(texture.getInternalFormatValue()); - if (str) fw.indent() << "internalFormatValue " << str << std::endl; - else fw.indent() << "internalFormatValue " << texture.getInternalFormatValue() << std::endl; - } fw.indent() << "subloadMode " << Texture_getSubloadModeStr(texture.getSubloadMode()) << std::endl; if (texture.getSubloadMode()!=Texture::OFF) @@ -395,3 +318,26 @@ const char* Texture_getSubloadModeStr(Texture::SubloadMode value) } return NULL; } +#else + +#include "osg/Texture2D" + +#include "osgDB/Registry" +#include "osgDB/Input" +#include "osgDB/Output" + +using namespace osg; +using namespace osgDB; + +RegisterDotOsgWrapperProxy g_TextureProxy +( + osgNew osg::Texture2D, + "Texture", + "Object StateAttribute Texture2D TextureBase", + 0, + 0 +); + + +#endif + diff --git a/src/osgPlugins/osg/Texture2D.cpp b/src/osgPlugins/osg/Texture2D.cpp new file mode 100644 index 000000000..8a7f9e346 --- /dev/null +++ b/src/osgPlugins/osg/Texture2D.cpp @@ -0,0 +1,71 @@ +#include "osg/Texture2D" + +#include "osgDB/Registry" +#include "osgDB/Input" +#include "osgDB/Output" + +using namespace osg; +using namespace osgDB; + +// forward declare functions to use later. +bool Texture2D_readLocalData(Object& obj, Input& fr); +bool Texture2D_writeLocalData(const Object& obj, Output& fw); + +bool Texture2D_matchWrapStr(const char* str,Texture2D::WrapMode& wrap); +const char* Texture2D_getWrapStr(Texture2D::WrapMode wrap); +bool Texture2D_matchFilterStr(const char* str,Texture2D::FilterMode& filter); +const char* Texture2D_getFilterStr(Texture2D::FilterMode filter); +bool Texture2D_matchInternalFormatModeStr(const char* str,Texture2D::InternalFormatMode& mode); +const char* Texture2D_getInternalFormatModeStr(Texture2D::InternalFormatMode mode); +bool Texture2D_matchInternalFormatStr(const char* str,int& value); +const char* Texture2D_getInternalFormatStr(int value); + +// register the read and write functions with the osgDB::Registry. +RegisterDotOsgWrapperProxy g_Texture2DProxy +( + osgNew osg::Texture2D, + "Texture2D", + "Object StateAttribute Texture2D TextureBase", + &Texture2D_readLocalData, + &Texture2D_writeLocalData +); + + +bool Texture2D_readLocalData(Object& obj, Input& fr) +{ + bool iteratorAdvanced = false; + + Texture2D& texture = static_cast(obj); + + if (fr[0].matchWord("file") && fr[1].isString()) + { + std::string filename = fr[1].getStr(); + Image* image = fr.readImage(filename.c_str()); + if (image) + { + // name will have already been set by the image plugin, + // but it will have absolute path, so will override it + // here to keep the original name intact. + //image->setFileName(filename); + texture.setImage(image); + } + + fr += 2; + iteratorAdvanced = true; + } + + return iteratorAdvanced; +} + + +bool Texture2D_writeLocalData(const Object& obj, Output& fw) +{ + const Texture2D& texture = static_cast(obj); + + if (texture.getImage() && !(texture.getImage()->getFileName().empty())) + { + fw.indent() << "file \""<getFileName())<<"\""<< std::endl; + } + + return true; +} diff --git a/src/osgPlugins/osg/TextureBase.cpp b/src/osgPlugins/osg/TextureBase.cpp new file mode 100644 index 000000000..4879b49e8 --- /dev/null +++ b/src/osgPlugins/osg/TextureBase.cpp @@ -0,0 +1,263 @@ +#include + +#include +#include +#include + +using namespace osg; +using namespace osgDB; + +// forward declare functions to use later. +bool TextureBase_readLocalData(Object& obj, Input& fr); +bool TextureBase_writeLocalData(const Object& obj, Output& fw); + +bool TextureBase_matchWrapStr(const char* str,TextureBase::WrapMode& wrap); +const char* TextureBase_getWrapStr(TextureBase::WrapMode wrap); +bool TextureBase_matchFilterStr(const char* str,TextureBase::FilterMode& filter); +const char* TextureBase_getFilterStr(TextureBase::FilterMode filter); +bool TextureBase_matchInternalFormatModeStr(const char* str,TextureBase::InternalFormatMode& mode); +const char* TextureBase_getInternalFormatModeStr(TextureBase::InternalFormatMode mode); +bool TextureBase_matchInternalFormatStr(const char* str,int& value); +const char* TextureBase_getInternalFormatStr(int value); + +// register the read and write functions with the osgDB::Registry. +RegisterDotOsgWrapperProxy g_TextureBaseProxy +( + 0, + "TextureBase", + "Object StateAttribute TextureBase", + &TextureBase_readLocalData, + &TextureBase_writeLocalData +); + + +bool TextureBase_readLocalData(Object& obj, Input& fr) +{ + bool iteratorAdvanced = false; + + TextureBase& texture = static_cast(obj); + + TextureBase::WrapMode wrap; + if (fr[0].matchWord("wrap_s") && TextureBase_matchWrapStr(fr[1].getStr(),wrap)) + { + texture.setWrap(TextureBase::WRAP_S,wrap); + fr+=2; + iteratorAdvanced = true; + } + + if (fr[0].matchWord("wrap_t") && TextureBase_matchWrapStr(fr[1].getStr(),wrap)) + { + texture.setWrap(TextureBase::WRAP_T,wrap); + fr+=2; + iteratorAdvanced = true; + } + + if (fr[0].matchWord("wrap_r") && TextureBase_matchWrapStr(fr[1].getStr(),wrap)) + { + texture.setWrap(TextureBase::WRAP_R,wrap); + fr+=2; + iteratorAdvanced = true; + } + + TextureBase::FilterMode filter; + if (fr[0].matchWord("min_filter") && TextureBase_matchFilterStr(fr[1].getStr(),filter)) + { + texture.setFilter(TextureBase::MIN_FILTER,filter); + fr+=2; + iteratorAdvanced = true; + } + + if (fr[0].matchWord("mag_filter") && TextureBase_matchFilterStr(fr[1].getStr(),filter)) + { + texture.setFilter(TextureBase::MAG_FILTER,filter); + fr+=2; + iteratorAdvanced = true; + } + + if (fr.matchSequence("maxAnisotropy %f")) + { + float anis=1.0f; + fr[1].getFloat(anis); + texture.setMaxAnisotropy(anis); + fr +=2 ; + iteratorAdvanced = true; + } + + TextureBase::InternalFormatMode mode; + if (fr[0].matchWord("internalFormatMode") && TextureBase_matchInternalFormatModeStr(fr[1].getStr(),mode)) + { + texture.setInternalFormatMode(mode); + fr+=2; + iteratorAdvanced = true; + } + + if (fr[0].matchWord("internalFormatValue")) + { + int value; + if (TextureBase_matchInternalFormatStr(fr[1].getStr(),value) || fr[1].getInt(value)) + { + texture.setInternalFormat(value); + fr+=2; + iteratorAdvanced = true; + } + } + + return iteratorAdvanced; +} + + +bool TextureBase_writeLocalData(const Object& obj, Output& fw) +{ + const TextureBase& texture = static_cast(obj); + + fw.indent() << "wrap_s " << TextureBase_getWrapStr(texture.getWrap(TextureBase::WRAP_S)) << std::endl; + fw.indent() << "wrap_t " << TextureBase_getWrapStr(texture.getWrap(TextureBase::WRAP_T)) << std::endl; + fw.indent() << "wrap_r " << TextureBase_getWrapStr(texture.getWrap(TextureBase::WRAP_R)) << std::endl; + + fw.indent() << "min_filter " << TextureBase_getFilterStr(texture.getFilter(TextureBase::MIN_FILTER)) << std::endl; + fw.indent() << "mag_filter " << TextureBase_getFilterStr(texture.getFilter(TextureBase::MAG_FILTER)) << std::endl; + fw.indent() << "maxAnisotropy " << texture.getMaxAnisotropy() << std::endl; + + fw.indent() << "internalFormatMode " << TextureBase_getInternalFormatModeStr(texture.getInternalFormatMode()) << std::endl; + + if (texture.getInternalFormatMode()==TextureBase::USE_USER_DEFINED_FORMAT) + { + const char* str = TextureBase_getInternalFormatStr(texture.getInternalFormat()); + if (str) fw.indent() << "internalFormat " << str << std::endl; + else fw.indent() << "internalFormat " << texture.getInternalFormat() << std::endl; + } + + return true; +} + + +bool TextureBase_matchWrapStr(const char* str,TextureBase::WrapMode& wrap) +{ + if (strcmp(str,"CLAMP")==0) wrap = TextureBase::CLAMP; + else if (strcmp(str,"CLAMP_TO_EDGE")==0) wrap = TextureBase::CLAMP_TO_EDGE; + else if (strcmp(str,"CLAMP_TO_BORDER")==0) wrap = TextureBase::CLAMP_TO_BORDER; + else if (strcmp(str,"REPEAT")==0) wrap = TextureBase::REPEAT; + else if (strcmp(str,"MIRROR")==0) wrap = TextureBase::MIRROR; + else return false; + return true; +} + + +const char* TextureBase_getWrapStr(TextureBase::WrapMode wrap) +{ + switch(wrap) + { + case(TextureBase::CLAMP): return "CLAMP"; + case(TextureBase::CLAMP_TO_EDGE): return "CLAMP_TO_EDGE"; + case(TextureBase::CLAMP_TO_BORDER): return "CLAMP_TO_BORDER"; + case(TextureBase::REPEAT): return "REPEAT"; + case(TextureBase::MIRROR): return "MIRROR"; + } + return ""; +} + + +bool TextureBase_matchFilterStr(const char* str,TextureBase::FilterMode& filter) +{ + if (strcmp(str,"NEAREST")==0) filter = TextureBase::NEAREST; + else if (strcmp(str,"LINEAR")==0) filter = TextureBase::LINEAR; + else if (strcmp(str,"NEAREST_MIPMAP_NEAREST")==0) filter = TextureBase::NEAREST_MIPMAP_NEAREST; + else if (strcmp(str,"LINEAR_MIPMAP_NEAREST")==0) filter = TextureBase::LINEAR_MIPMAP_NEAREST; + else if (strcmp(str,"NEAREST_MIPMAP_LINEAR")==0) filter = TextureBase::NEAREST_MIPMAP_LINEAR; + else if (strcmp(str,"LINEAR_MIPMAP_LINEAR")==0) filter = TextureBase::LINEAR_MIPMAP_LINEAR; + else if (strcmp(str,"ANISOTROPIC")==0) filter = TextureBase::LINEAR; + else return false; + return true; +} + + +const char* TextureBase_getFilterStr(TextureBase::FilterMode filter) +{ + switch(filter) + { + case(TextureBase::NEAREST): return "NEAREST"; + case(TextureBase::LINEAR): return "LINEAR"; + case(TextureBase::NEAREST_MIPMAP_NEAREST): return "NEAREST_MIPMAP_NEAREST"; + case(TextureBase::LINEAR_MIPMAP_NEAREST): return "LINEAR_MIPMAP_NEAREST"; + case(TextureBase::NEAREST_MIPMAP_LINEAR): return "NEAREST_MIPMAP_LINEAR"; + case(TextureBase::LINEAR_MIPMAP_LINEAR): return "LINEAR_MIPMAP_LINEAR"; + } + return ""; +} + +bool TextureBase_matchInternalFormatModeStr(const char* str,TextureBase::InternalFormatMode& mode) +{ + if (strcmp(str,"USE_IMAGE_DATA_FORMAT")==0) mode = TextureBase::USE_IMAGE_DATA_FORMAT; + else if (strcmp(str,"USE_USER_DEFINED_FORMAT")==0) mode = TextureBase::USE_USER_DEFINED_FORMAT; + else if (strcmp(str,"USE_ARB_COMPRESSION")==0) mode = TextureBase::USE_ARB_COMPRESSION; + else if (strcmp(str,"USE_S3TC_DXT1_COMPRESSION")==0) mode = TextureBase::USE_S3TC_DXT1_COMPRESSION; + else if (strcmp(str,"USE_S3TC_DXT3_COMPRESSION")==0) mode = TextureBase::USE_S3TC_DXT3_COMPRESSION; + else if (strcmp(str,"USE_S3TC_DXT5_COMPRESSION")==0) mode = TextureBase::USE_S3TC_DXT5_COMPRESSION; + else return false; + return true; +} + + +const char* TextureBase_getInternalFormatModeStr(TextureBase::InternalFormatMode mode) +{ + switch(mode) + { + case(TextureBase::USE_IMAGE_DATA_FORMAT): return "USE_IMAGE_DATA_FORMAT"; + case(TextureBase::USE_USER_DEFINED_FORMAT): return "USE_USER_DEFINED_FORMAT"; + case(TextureBase::USE_ARB_COMPRESSION): return "USE_ARB_COMPRESSION"; + case(TextureBase::USE_S3TC_DXT1_COMPRESSION): return "USE_S3TC_DXT1_COMPRESSION"; + case(TextureBase::USE_S3TC_DXT3_COMPRESSION): return "USE_S3TC_DXT3_COMPRESSION"; + case(TextureBase::USE_S3TC_DXT5_COMPRESSION): return "USE_S3TC_DXT5_COMPRESSION"; + } + return ""; +} + + +bool TextureBase_matchInternalFormatStr(const char* str,int& value) +{ + + if ( strcmp(str,"GL_INTENSITY")==0) value = GL_INTENSITY; + else if (strcmp(str,"GL_LUMINANCE")==0) value = GL_LUMINANCE; + else if (strcmp(str,"GL_ALPHA")==0) value = GL_ALPHA; + else if (strcmp(str,"GL_LUMINANCE_ALPHA")==0) value = GL_LUMINANCE_ALPHA; + else if (strcmp(str,"GL_RGB")==0) value = GL_RGB; + else if (strcmp(str,"GL_RGBA")==0) value = GL_RGBA; + else if (strcmp(str,"GL_COMPRESSED_ALPHA_ARB")==0) value = GL_COMPRESSED_ALPHA_ARB; + else if (strcmp(str,"GL_COMPRESSED_LUMINANCE_ARB")==0) value = GL_COMPRESSED_LUMINANCE_ARB; + else if (strcmp(str,"GL_COMPRESSED_INTENSITY_ARB")==0) value = GL_COMPRESSED_INTENSITY_ARB; + else if (strcmp(str,"GL_COMPRESSED_LUMINANCE_ALPHA_ARB")==0) value = GL_COMPRESSED_LUMINANCE_ALPHA_ARB; + else if (strcmp(str,"GL_COMPRESSED_RGB_ARB")==0) value = GL_COMPRESSED_RGB_ARB; + else if (strcmp(str,"GL_COMPRESSED_RGBA_ARB")==0) value = GL_COMPRESSED_RGBA_ARB; + else if (strcmp(str,"GL_COMPRESSED_RGB_S3TC_DXT1_EXT")==0) value = GL_COMPRESSED_RGB_S3TC_DXT1_EXT; + else if (strcmp(str,"GL_COMPRESSED_RGBA_S3TC_DXT1_EXT")==0) value = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; + else if (strcmp(str,"GL_COMPRESSED_RGBA_S3TC_DXT3_EXT")==0) value = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; + else if (strcmp(str,"GL_COMPRESSED_RGBA_S3TC_DXT5_EXT")==0) value = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; + else return false; + return true; +} + + +const char* TextureBase_getInternalFormatStr(int value) +{ + switch(value) + { + case(GL_INTENSITY): return "GL_INTENSITY"; + case(GL_LUMINANCE): return "GL_LUMINANCE"; + case(GL_ALPHA): return "GL_ALPHA"; + case(GL_LUMINANCE_ALPHA): return "GL_LUMINANCE_ALPHA"; + case(GL_RGB): return "GL_RGB"; + case(GL_RGBA): return "GL_RGBA"; + case(GL_COMPRESSED_ALPHA_ARB): return "GL_COMPRESSED_ALPHA_ARB"; + case(GL_COMPRESSED_LUMINANCE_ARB): return "GL_COMPRESSED_LUMINANCE_ARB"; + case(GL_COMPRESSED_INTENSITY_ARB): return "GL_COMPRESSED_INTENSITY_ARB"; + case(GL_COMPRESSED_LUMINANCE_ALPHA_ARB): return "GL_COMPRESSED_LUMINANCE_ALPHA_ARB"; + case(GL_COMPRESSED_RGB_ARB): return "GL_COMPRESSED_RGB_ARB"; + case(GL_COMPRESSED_RGBA_ARB): return "GL_COMPRESSED_RGBA_ARB"; + case(GL_COMPRESSED_RGB_S3TC_DXT1_EXT): return "GL_COMPRESSED_RGB_S3TC_DXT1_EXT"; + case(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT): return "GL_COMPRESSED_RGBA_S3TC_DXT1_EXT"; + case(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT): return "GL_COMPRESSED_RGBA_S3TC_DXT3_EXT"; + case(GL_COMPRESSED_RGBA_S3TC_DXT5_EXT): return "GL_COMPRESSED_RGBA_S3TC_DXT5_EXT"; + } + + return NULL; +} diff --git a/src/osgPlugins/osg/TextureCubeMap.cpp b/src/osgPlugins/osg/TextureCubeMap.cpp index 158975345..ed53180b9 100644 --- a/src/osgPlugins/osg/TextureCubeMap.cpp +++ b/src/osgPlugins/osg/TextureCubeMap.cpp @@ -11,23 +11,12 @@ using namespace osgDB; bool TextureCubeMap_readLocalData(Object& obj, Input& fr); bool TextureCubeMap_writeLocalData(const Object& obj, Output& fw); -bool TextureCubeMap_matchWrapStr(const char* str,TextureCubeMap::WrapMode& wrap); -const char* TextureCubeMap_getWrapStr(TextureCubeMap::WrapMode wrap); -bool TextureCubeMap_matchFilterStr(const char* str,TextureCubeMap::FilterMode& filter); -const char* TextureCubeMap_getFilterStr(TextureCubeMap::FilterMode filter); -bool TextureCubeMap_matchInternalFormatModeStr(const char* str,TextureCubeMap::InternalFormatMode& mode); -const char* TextureCubeMap_getInternalFormatModeStr(TextureCubeMap::InternalFormatMode mode); -bool TextureCubeMap_matchInternalFormatValueStr(const char* str,int& value); -const char* TextureCubeMap_getInternalFormatValueStr(int value); -bool TextureCubeMap_matchSubloadModeStr(const char* str, TextureCubeMap::SubloadMode& value); -const char* TextureCubeMap_getSubloadModeStr(TextureCubeMap::SubloadMode value); - // register the read and write functions with the osgDB::Registry. RegisterDotOsgWrapperProxy g_TextureCubeMapProxy ( osgNew osg::TextureCubeMap, "TextureCubeMap", - "Object StateAttribute TextureCubeMap Texture", + "Object StateAttribute TextureCubeMap TextureBase", &TextureCubeMap_readLocalData, &TextureCubeMap_writeLocalData ); diff --git a/src/osgUtil/CullVisitor.cpp b/src/osgUtil/CullVisitor.cpp index 2e2032794..5ba0b4cd3 100644 --- a/src/osgUtil/CullVisitor.cpp +++ b/src/osgUtil/CullVisitor.cpp @@ -938,7 +938,7 @@ ImpostorSprite* CullVisitor::createImpostorSprite(Impostor& node) stateset->setRenderBinDetails(1,"DepthSortedBin"); } - Texture* texture = impostorSprite->getTexture(); + Texture2D* texture = impostorSprite->getTexture(); // update frame number to show that impostor is in action. impostorSprite->setLastFrameUsed(getTraversalNumber());