336 lines
13 KiB
C++
336 lines
13 KiB
C++
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield
|
|
*
|
|
* This library is open source and may be redistributed and/or modified under
|
|
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
|
* (at your option) any later version. The full license is in LICENSE file
|
|
* included with this distribution, and on the openscenegraph.org website.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* OpenSceneGraph Public License for more details.
|
|
*/
|
|
|
|
#ifndef OSG_TEXTURE
|
|
#define OSG_TEXTURE 1
|
|
|
|
#include <osg/GL>
|
|
#include <osg/Types>
|
|
#include <osg/Image>
|
|
#include <osg/StateAttribute>
|
|
#include <osg/ref_ptr>
|
|
#include <osg/Vec4>
|
|
#include <osg/buffered_value>
|
|
|
|
|
|
// 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 Texture : public osg::StateAttribute
|
|
{
|
|
|
|
public :
|
|
|
|
|
|
Texture();
|
|
|
|
/** Copy constructor using CopyOp to manage deep vs shallow copy.*/
|
|
Texture(const Texture& 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<const Texture *>(obj)!=NULL; }
|
|
virtual const char* libraryName() const { return "osg"; }
|
|
virtual const char* className() const { return "Texture"; }
|
|
virtual 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(WrapParameter which, WrapMode wrap);
|
|
/** Get the texture wrap mode.*/
|
|
WrapMode getWrap(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; dirtyTextureParameters(); }
|
|
|
|
const Vec4& getBorderColor() 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(FilterParameter which, FilterMode filter);
|
|
|
|
/** Get the texture filter mode.*/
|
|
FilterMode getFilter(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(InternalFormatMode mode) { _internalFormatMode = mode; }
|
|
|
|
/** Get the internal format mode.*/
|
|
inline 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(GLint internalFormat)
|
|
{
|
|
_internalFormatMode = USE_USER_DEFINED_FORMAT;
|
|
_internalFormat = internalFormat;
|
|
}
|
|
|
|
/** Get the internal format to use when creating OpenGL textures.*/
|
|
inline GLint 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(uint contextID) const
|
|
{
|
|
// get the globj for the current contextID.
|
|
return _handleList[contextID];
|
|
}
|
|
|
|
inline uint& getModifiedTag(uint contextID) const
|
|
{
|
|
// get the modified tag for the current contextID.
|
|
return _modifiedTag[contextID];
|
|
}
|
|
|
|
inline uint& getTextureParameterDirty(uint contextID) const
|
|
{
|
|
// get the dirty flag for the current contextID.
|
|
return _texParametersDirtyList[contextID];
|
|
}
|
|
|
|
/** Force a recompile on next apply() of associated OpenGL texture objects.*/
|
|
void dirtyTextureObject();
|
|
|
|
/** Force a resetting on next apply() of associated OpenGL texture parameters.*/
|
|
void dirtyTextureParameters();
|
|
|
|
|
|
/** use deleteTextureObject instead of glDeleteTextures to allow
|
|
* OpenGL texture objects to cached until they can be deleted
|
|
* by the OpenGL context in which they were created, specified
|
|
* by contextID.*/
|
|
static void deleteTextureObject(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);
|
|
|
|
/** Texture 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;
|
|
|
|
/** Extensions class which encapsulates the querring of extensions and
|
|
* associated function pointers, and provide convinience wrappers to
|
|
* check for the extensions or use the associated functions.*/
|
|
class Extensions : public osg::Referenced
|
|
{
|
|
public:
|
|
Extensions();
|
|
|
|
Extensions(const Extensions& rhs);
|
|
|
|
void lowestCommonDenominator(const Extensions& rhs);
|
|
|
|
void setupGLExtenions();
|
|
|
|
bool isTextureFilterAnisotropicSupported() const { return _isTextureFilterAnisotropicSupported; }
|
|
bool isTextureCompressionARBSupported() const { return _isTextureCompressionARBSupported; }
|
|
bool isTextureCompressionS3TCSupported() const { return _isTextureCompressionS3TCSupported; }
|
|
bool isTextureMirroredRepeatSupported() const { return _isTextureMirroredRepeatSupported; }
|
|
bool isTextureEdgeClampSupported() const { return _isTextureEdgeClampSupported; }
|
|
bool isTextureBorderClampSupported() const { return _isTextureBorderClampSupported; }
|
|
|
|
GLint maxTextureSize() const { return _maxTextureSize; }
|
|
|
|
bool isCompressedTexImage2DSupported() const { return _glCompressedTexImage2D!=0; }
|
|
|
|
void glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data) const;
|
|
|
|
protected:
|
|
|
|
~Extensions() {}
|
|
|
|
bool _isTextureFilterAnisotropicSupported;
|
|
bool _isTextureCompressionARBSupported;
|
|
bool _isTextureCompressionS3TCSupported;
|
|
bool _isTextureMirroredRepeatSupported;
|
|
bool _isTextureEdgeClampSupported;
|
|
bool _isTextureBorderClampSupported;
|
|
|
|
GLint _maxTextureSize;
|
|
|
|
void* _glCompressedTexImage2D;
|
|
|
|
};
|
|
|
|
/** Function to call to get the extension of a specified context.
|
|
* If the Exentsion object for that context has not yet been created then
|
|
* and the 'createIfNotInitalized' flag been set to false then returns NULL.
|
|
* If 'createIfNotInitalized' is true then the Extensions object is
|
|
* automatically created. However, in this case the extension object
|
|
* only be created with the graphics context associated with ContextID..*/
|
|
static const Extensions* getExtensions(uint contextID,bool createIfNotInitalized);
|
|
|
|
/** setExtensions allows users to override the extensions across graphics contexts.
|
|
* typically used when you have different extensions supported across graphics pipes
|
|
* but need to ensure that they all use the same low common denominator extensions.*/
|
|
static void setExtensions(uint contextID,Extensions* extensions);
|
|
|
|
protected :
|
|
|
|
virtual ~Texture();
|
|
|
|
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 compareTexture(const Texture& rhs) const;
|
|
|
|
typedef buffered_value<GLuint> TextureNameList;
|
|
mutable TextureNameList _handleList;
|
|
|
|
typedef buffered_value<uint> ImageModifiedTag;
|
|
mutable ImageModifiedTag _modifiedTag;
|
|
|
|
typedef buffered_value<uint> TexParameterDirtyList;
|
|
mutable TexParameterDirtyList _texParametersDirtyList;
|
|
|
|
WrapMode _wrap_s;
|
|
WrapMode _wrap_t;
|
|
WrapMode _wrap_r;
|
|
|
|
FilterMode _min_filter;
|
|
FilterMode _mag_filter;
|
|
float _maxAnisotropy;
|
|
|
|
Vec4 _borderColor;
|
|
|
|
InternalFormatMode _internalFormatMode;
|
|
mutable GLint _internalFormat;
|
|
|
|
};
|
|
|
|
}
|
|
|
|
#endif
|