From 2dc53ceabb55c4a213031c9f5684386e5c2f87d7 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 3 Jun 2013 15:10:53 +0000 Subject: [PATCH] From Aurelien Albert, Added support for texture swizzle. --- include/osg/Texture | 19 +++- src/osg/Texture.cpp | 12 +++ src/osgWrappers/serializers/osg/Texture.cpp | 97 +++++++++++++++++++++ 3 files changed, 127 insertions(+), 1 deletion(-) diff --git a/include/osg/Texture b/include/osg/Texture index 9961dcf5a..72d0c7068 100644 --- a/include/osg/Texture +++ b/include/osg/Texture @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -33,6 +34,12 @@ #define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE #endif +// If not defined, use the definition found in: +// http://www.opengl.org/registry/specs/ARB/texture_swizzle.txt +#ifndef GL_TEXTURE_SWIZZLE_RGBA + #define GL_TEXTURE_SWIZZLE_RGBA 0x8E46 +#endif + #ifndef GL_ARB_texture_compression #define GL_COMPRESSED_ALPHA_ARB 0x84E9 #define GL_COMPRESSED_LUMINANCE_ARB 0x84EA @@ -481,7 +488,6 @@ class OSG_EXPORT Texture : public osg::StateAttribute NEAREST_MIPMAP_NEAREST = GL_NEAREST_MIPMAP_NEAREST }; - /** Sets the texture filter mode. */ void setFilter(FilterParameter which, FilterMode filter); @@ -498,6 +504,12 @@ class OSG_EXPORT Texture : public osg::StateAttribute /** Gets the maximum anisotropy value. */ inline float getMaxAnisotropy() const { return _maxAnisotropy; } + /** Configure the source of texture swizzling for all channels */ + inline void setSwizzle(const Vec4i& swizzle) { _swizzle = swizzle; dirtyTextureParameters(); }; + + /** Gets the source of texture swizzling for all channels */ + inline const Vec4i& getSwizzle() const { return _swizzle; } + /** Sets the hardware mipmap generation hint. If enabled, it will * only be used if supported in the graphics system. */ inline void setUseHardwareMipMapGeneration(bool useHardwareMipMapGeneration) { _useHardwareMipMapGeneration = useHardwareMipMapGeneration; } @@ -764,6 +776,9 @@ class OSG_EXPORT Texture : public osg::StateAttribute void setTextureFilterAnisotropicSupported(bool flag) { _isTextureFilterAnisotropicSupported=flag; } bool isTextureFilterAnisotropicSupported() const { return _isTextureFilterAnisotropicSupported; } + void setTextureSwizzleSupported(bool flag) { _isTextureSwizzleSupported=flag; } + bool isTextureSwizzleSupported() const { return _isTextureSwizzleSupported; } + void setTextureCompressionARBSupported(bool flag) { _isTextureCompressionARBSupported=flag; } bool isTextureCompressionARBSupported() const { return _isTextureCompressionARBSupported; } @@ -895,6 +910,7 @@ class OSG_EXPORT Texture : public osg::StateAttribute bool _isMultiTexturingSupported; bool _isTextureFilterAnisotropicSupported; + bool _isTextureSwizzleSupported; bool _isTextureCompressionARBSupported; bool _isTextureCompressionS3TCSupported; bool _isTextureCompressionPVRTC2BPPSupported; @@ -1017,6 +1033,7 @@ class OSG_EXPORT Texture : public osg::StateAttribute FilterMode _min_filter; FilterMode _mag_filter; float _maxAnisotropy; + Vec4i _swizzle; bool _useHardwareMipMapGeneration; bool _unrefImageDataAfterApply; bool _clientStorageHint; diff --git a/src/osg/Texture.cpp b/src/osg/Texture.cpp index 8de09b85f..0a31700e4 100644 --- a/src/osg/Texture.cpp +++ b/src/osg/Texture.cpp @@ -1075,6 +1075,7 @@ Texture::Texture(): _min_filter(LINEAR_MIPMAP_LINEAR), // trilinear _mag_filter(LINEAR), _maxAnisotropy(1.0f), + _swizzle(GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA), _useHardwareMipMapGeneration(true), _unrefImageDataAfterApply(false), _clientStorageHint(false), @@ -1101,6 +1102,7 @@ Texture::Texture(const Texture& text,const CopyOp& copyop): _min_filter(text._min_filter), _mag_filter(text._mag_filter), _maxAnisotropy(text._maxAnisotropy), + _swizzle(text._swizzle), _useHardwareMipMapGeneration(text._useHardwareMipMapGeneration), _unrefImageDataAfterApply(text._unrefImageDataAfterApply), _clientStorageHint(text._clientStorageHint), @@ -1133,6 +1135,7 @@ int Texture::compareTexture(const Texture& rhs) const COMPARE_StateAttribute_Parameter(_min_filter) COMPARE_StateAttribute_Parameter(_mag_filter) COMPARE_StateAttribute_Parameter(_maxAnisotropy) + COMPARE_StateAttribute_Parameter(_swizzle) COMPARE_StateAttribute_Parameter(_useHardwareMipMapGeneration) COMPARE_StateAttribute_Parameter(_internalFormatMode) @@ -1704,6 +1707,13 @@ void Texture::applyTexParameters(GLenum target, State& state) const glTexParameterf(target, GL_TEXTURE_MAX_ANISOTROPY_EXT, _maxAnisotropy); } + if (extensions->isTextureSwizzleSupported()) + { + // note, GL_TEXTURE_SWIZZLE_RGBA will either be defined + // by gl.h (or via glext.h) or by include/osg/Texture. + glTexParameteriv(target, GL_TEXTURE_SWIZZLE_RGBA, _swizzle.ptr()); + } + if (extensions->isTextureBorderClampSupported()) { @@ -2506,6 +2516,8 @@ Texture::Extensions::Extensions(unsigned int contextID) _isTextureFilterAnisotropicSupported = isGLExtensionSupported(contextID,"GL_EXT_texture_filter_anisotropic"); + _isTextureSwizzleSupported = isGLExtensionSupported(contextID,"GL_ARB_texture_swizzle"); + _isTextureCompressionARBSupported = builtInSupport || isGLExtensionOrVersionSupported(contextID,"GL_ARB_texture_compression", 1.3f); _isTextureCompressionS3TCSupported = isGLExtensionSupported(contextID,"GL_EXT_texture_compression_s3tc"); diff --git a/src/osgWrappers/serializers/osg/Texture.cpp b/src/osgWrappers/serializers/osg/Texture.cpp index bd1b9b9ca..bb8f1a7bd 100644 --- a/src/osgWrappers/serializers/osg/Texture.cpp +++ b/src/osgWrappers/serializers/osg/Texture.cpp @@ -94,6 +94,98 @@ static bool writeImageAttachment( osgDB::OutputStream& os, const osg::Texture& a return true; } +// _swizzle +static bool checkSwizzle( const osg::Texture& attr ) +{ + return true; +} + +static unsigned char swizzleToCharacter(GLint swizzle, unsigned char defaultCharacter) +{ + switch (swizzle) + { + case GL_RED: + return 'R'; + case GL_GREEN: + return 'G'; + case GL_BLUE: + return 'B'; + case GL_ALPHA: + return 'A'; + case GL_ZERO: + return '0'; + case GL_ONE: + return '1'; + default: + break; + } + + return defaultCharacter; +} + +static GLint characterToSwizzle(unsigned char character, GLint defaultSwizzle) +{ + switch (character) + { + case 'R': + return GL_RED; + case 'G': + return GL_GREEN; + case 'B': + return GL_BLUE; + case 'A': + return GL_ALPHA; + case '0': + return GL_ZERO; + case '1': + return GL_ONE; + default: + break; + } + + return defaultSwizzle; +} + +static std::string swizzleToString(const osg::Vec4i& swizzle) +{ + std::string result; + + result.push_back(swizzleToCharacter(swizzle.r(), 'R')); + result.push_back(swizzleToCharacter(swizzle.g(), 'G')); + result.push_back(swizzleToCharacter(swizzle.b(), 'B')); + result.push_back(swizzleToCharacter(swizzle.a(), 'A')); + + return result; +} + +static osg::Vec4i stringToSwizzle(const std::string& swizzleString) +{ + osg::Vec4i swizzle; + + swizzle.r() = characterToSwizzle(swizzleString[0], GL_RED); + swizzle.g() = characterToSwizzle(swizzleString[1], GL_GREEN); + swizzle.b() = characterToSwizzle(swizzleString[2], GL_BLUE); + swizzle.a() = characterToSwizzle(swizzleString[3], GL_ALPHA); + + return swizzle; +} + +static bool readSwizzle( osgDB::InputStream& is, osg::Texture& attr ) +{ + std::string swizzleString; + is >> swizzleString; + attr.setSwizzle(stringToSwizzle(swizzleString)); + + return true; +} + +static bool writeSwizzle( osgDB::OutputStream& os, const osg::Texture& attr ) +{ + os << swizzleToString(attr.getSwizzle()) << std::endl; + + return true; +} + REGISTER_OBJECT_WRAPPER( Texture, /*new osg::Texture*/NULL, osg::Texture, @@ -156,4 +248,9 @@ REGISTER_OBJECT_WRAPPER( Texture, UPDATE_TO_VERSION_SCOPED( 95 ) ADD_USER_SERIALIZER( ImageAttachment ); // _imageAttachment } + + { + UPDATE_TO_VERSION_SCOPED( 98 ) + ADD_USER_SERIALIZER( Swizzle ); // _swizzle + } }