//C++ header - Open Scene Graph - Copyright (C) 1998-2001 Robert Osfield //Distributed under the terms of the GNU Library General Public License (LGPL) //as published by the Free Software Foundation. // -*-c++-*- #ifndef OSG_TEXTURE #define OSG_TEXTURE 1 #include #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 state class which encapsulates OpenGl texture functionality.*/ class SG_EXPORT Texture : public StateAttribute { public : Texture(); /** Copy constructor using CopyOp to manage deep vs shallow copy.*/ Texture(const Texture& text,const CopyOp& copyop=CopyOp::SHALLOW_COPY): StateAttribute(text,copyop), _handleList(), _modifiedTag(), _image(copyop(text._image.get())), _target(text._target), _textureUnit(text._textureUnit), _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), _texParamtersDirty(false), _internalFormatMode(text._internalFormatMode), _internalFormatValue(text._internalFormatValue), _borderColor(text._borderColor), _textureWidth(text._textureWidth), _textureHeight(text._textureHeight), _subloadMode(text._subloadMode), _subloadOffsX(text._subloadOffsX), _subloadOffsY(text._subloadOffsY), _subloadWidth(text._subloadWidth), _subloadHeight(text._subloadHeight) {} META_StateAttribute(Texture,(Type)(TEXTURE_0+_textureUnit)); /** return -1 if *this < *rhs, 0 if *this==*rhs, 1 if *this>*rhs.*/ virtual int compare(const StateAttribute& rhs) const; virtual void setStateSetModes(StateSet& ds,const GLModeValue value) const { ds.setMode(_target,value); } /** 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(); } /** 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 ); /** Set the texture unit. * Valid values are 0,1,2,3. * Default value of texture unit is 0. * note, multi-texturing not fully implemented yet... April 2001. */ inline void setTextureUnit(const unsigned int textureUnit) { _textureUnit = textureUnit; } /** get the texture unit.*/ inline const unsigned int getTextureUnit() const { return _textureUnit; } 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, ANISOTROPIC = GL_TEXTURE_MAX_ANISOTROPY_EXT }; /** 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; 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. */ inline void setInternalFormatValue(const int internalFormat) { _internalFormatMode = USE_USER_DEFINED_FORMAT; _internalFormatValue = internalFormat; } /** Get the internal format to use when creating OpenGL textures.*/ inline const int getInternalFormatValue() const { return _internalFormatValue; } /** return the OpenGL texture object for specified context.*/ inline const uint getTextureObject(const uint contextID) const { if (contextID<_handleList.size()) return _handleList[contextID]; else return 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 offsets. */ inline void setSubloadOffset(const int x, const int y) { _subloadOffsX = x; _subloadOffsY = y; } /** Get the texture subload offsets. */ inline void getSubloadOffset(int& x, int& y) const { x = _subloadOffsX; y = _subloadOffsY; } /** 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 setSubloadSize(const int width, const int height) { _subloadWidth = width; _subloadHeight = height; } /** Get the texture subload width. */ inline void getSubloadSize(int& width, int& height) const { width = _subloadWidth; height = _subloadHeight; } /** Get the handle to the texture object for the current context.*/ inline GLuint& getHandle(const uint contextID) const { // pad out handle list if required. if (_handleList.size()<=contextID) _handleList.resize(contextID,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,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; /** 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); 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; // 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; GLenum _target; // defaults to GL_TEXTURE_2D unsigned int _textureUnit; WrapMode _wrap_s; WrapMode _wrap_t; WrapMode _wrap_r; FilterMode _min_filter; FilterMode _mag_filter; // true if apply tex parameters required. mutable bool _texParamtersDirty; InternalFormatMode _internalFormatMode; int _internalFormatValue; Vec4 _borderColor; // subloaded images can have different texture and image sizes. mutable GLsizei _textureWidth, _textureHeight; SubloadMode _subloadMode; GLint _subloadOffsX, _subloadOffsY; GLsizei _subloadWidth, _subloadHeight; // 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