From 92975a01fde796b0a166a8057f8dee9d81644da4 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 13 Nov 2012 13:16:10 +0000 Subject: [PATCH] Moved colour space conversion of volumes from the osgvolume example into osg/ImageUtils and added support for colorSpaceConversion="MODULATE_ALPHA_BY_LUMINANCE","MODULATE_ALPHA_BY_COLOUR","REPLACE_ALPHA_WITH_LUMINANCE" and "REPLACE_RGB_WITH_LUMINANCE" to .p3d tag --- examples/osgvolume/osgvolume.cpp | 96 ++------------------ include/osg/Image | 3 +- include/osg/ImageUtils | 17 ++++ include/osgPresentation/SlideShowConstructor | 8 +- src/osg/Image.cpp | 26 ++++++ src/osg/ImageUtils.cpp | 63 +++++++++++++ src/osgPlugins/p3d/ReaderWriterP3D.cpp | 17 ++++ src/osgPresentation/SlideShowConstructor.cpp | 11 +++ 8 files changed, 150 insertions(+), 91 deletions(-) diff --git a/examples/osgvolume/osgvolume.cpp b/examples/osgvolume/osgvolume.cpp index abbe04a46..0891db9a8 100644 --- a/examples/osgvolume/osgvolume.cpp +++ b/examples/osgvolume/osgvolume.cpp @@ -115,18 +115,6 @@ osg::Image* createTexture3D(osg::ImageList& imageList, } } -struct ModulateAlphaByLuminanceOperator -{ - ModulateAlphaByLuminanceOperator() {} - - inline void luminance(float&) const {} - inline void alpha(float&) const {} - inline void luminance_alpha(float& l,float& a) const { a*= l; } - inline void rgb(float&,float&,float&) const {} - inline void rgba(float& r,float& g,float& b,float& a) const { float l = (r+g+b)*0.3333333; a *= l;} -}; - - struct ScaleOperator { ScaleOperator():_scale(1.0f) {} @@ -310,76 +298,6 @@ osg::Image* readRaw(int sizeX, int sizeY, int sizeZ, int numberBytesPerComponent } -enum ColourSpaceOperation -{ - NO_COLOUR_SPACE_OPERATION, - MODULATE_ALPHA_BY_LUMINANCE, - MODULATE_ALPHA_BY_COLOUR, - REPLACE_ALPHA_WITH_LUMINANCE, - REPLACE_RGB_WITH_LUMINANCE -}; - -struct ModulateAlphaByColourOperator -{ - ModulateAlphaByColourOperator(const osg::Vec4& colour):_colour(colour) { _lum = _colour.length(); } - - osg::Vec4 _colour; - float _lum; - - inline void luminance(float&) const {} - inline void alpha(float&) const {} - inline void luminance_alpha(float& l,float& a) const { a*= l*_lum; } - inline void rgb(float&,float&,float&) const {} - inline void rgba(float& r,float& g,float& b,float& a) const { a = (r*_colour.r()+g*_colour.g()+b*_colour.b()+a*_colour.a()); } -}; - -struct ReplaceAlphaWithLuminanceOperator -{ - ReplaceAlphaWithLuminanceOperator() {} - - inline void luminance(float&) const {} - inline void alpha(float&) const {} - inline void luminance_alpha(float& l,float& a) const { a= l; } - inline void rgb(float&,float&,float&) const { } - inline void rgba(float& r,float& g,float& b,float& a) const { float l = (r+g+b)*0.3333333; a = l; } -}; - -osg::Image* doColourSpaceConversion(ColourSpaceOperation op, osg::Image* image, osg::Vec4& colour) -{ - switch(op) - { - case (MODULATE_ALPHA_BY_LUMINANCE): - { - std::cout<<"doing conversion MODULATE_ALPHA_BY_LUMINANCE"<allocateImage(image->s(), image->t(), image->r(), GL_LUMINANCE, image->getDataType()); - osg::copyImage(image, 0, 0, 0, image->s(), image->t(), image->r(), - newImage, 0, 0, 0, false); - return newImage; - } - default: - return image; - } -} - osg::TransferFunction1D* readTransferFunctionFile(const std::string& filename, float colorScale=1.0f) { @@ -671,12 +589,12 @@ int main( int argc, char **argv ) while(arguments.read("--r_maxTextureSize",r_maximumTextureSize)) {} // set up colour space operation. - ColourSpaceOperation colourSpaceOperation = NO_COLOUR_SPACE_OPERATION; + osg::ColorSpaceOperation colourSpaceOperation = osg::NO_COLOUR_SPACE_OPERATION; osg::Vec4 colourModulate(0.25f,0.25f,0.25f,0.25f); - while(arguments.read("--modulate-alpha-by-luminance")) { colourSpaceOperation = MODULATE_ALPHA_BY_LUMINANCE; } - while(arguments.read("--modulate-alpha-by-colour", colourModulate.x(),colourModulate.y(),colourModulate.z(),colourModulate.w() )) { colourSpaceOperation = MODULATE_ALPHA_BY_COLOUR; } - while(arguments.read("--replace-alpha-with-luminance")) { colourSpaceOperation = REPLACE_ALPHA_WITH_LUMINANCE; } - while(arguments.read("--replace-rgb-with-luminance")) { colourSpaceOperation = REPLACE_RGB_WITH_LUMINANCE; } + while(arguments.read("--modulate-alpha-by-luminance")) { colourSpaceOperation = osg::MODULATE_ALPHA_BY_LUMINANCE; } + while(arguments.read("--modulate-alpha-by-colour", colourModulate.x(),colourModulate.y(),colourModulate.z(),colourModulate.w() )) { colourSpaceOperation = osg::MODULATE_ALPHA_BY_COLOUR; } + while(arguments.read("--replace-alpha-with-luminance")) { colourSpaceOperation = osg::REPLACE_ALPHA_WITH_LUMINANCE; } + while(arguments.read("--replace-rgb-with-luminance")) { colourSpaceOperation = osg::REPLACE_RGB_WITH_LUMINANCE; } enum RescaleOperation @@ -1018,13 +936,13 @@ int main( int argc, char **argv ) } - if (colourSpaceOperation!=NO_COLOUR_SPACE_OPERATION) + if (colourSpaceOperation!=osg::NO_COLOUR_SPACE_OPERATION) { for(Images::iterator itr = images.begin(); itr != images.end(); ++itr) { - (*itr) = doColourSpaceConversion(colourSpaceOperation, itr->get(), colourModulate); + (*itr) = osg::colorSpaceConversion(colourSpaceOperation, itr->get(), colourModulate); } } diff --git a/include/osg/Image b/include/osg/Image index 1facfcaaa..67e524248 100644 --- a/include/osg/Image +++ b/include/osg/Image @@ -179,6 +179,8 @@ class OSG_EXPORT Image : public BufferData */ virtual void readImageFromCurrentTexture(unsigned int contextID, bool copyMipMapsIfAvailable, GLenum type = GL_UNSIGNED_BYTE, unsigned int face = 0); + /** swap the data and settings between two image objects.*/ + void swap(osg::Image& rhs); /** Scale image to specified size. */ void scaleImage(int s,int t,int r) { scaleImage(s,t,r, getDataType()); } @@ -471,7 +473,6 @@ class OSG_EXPORT Image : public BufferData std::string _fileName; WriteHint _writeHint; - Origin _origin; int _s, _t, _r; diff --git a/include/osg/ImageUtils b/include/osg/ImageUtils index 782019533..55d763ea0 100644 --- a/include/osg/ImageUtils +++ b/include/osg/ImageUtils @@ -153,10 +153,27 @@ extern OSG_EXPORT osg::Image* createImage3DWithAlpha(const ImageList& imageList, int r_maximumImageSize = 1024, bool resizeToPowerOfTwo = false); + + + /** create a 2D osg::Image that provides a point at the center of the image. * The colour across th image is computed from a balance between the center color and the background color controlled by the power of the radius from the center.*/ extern OSG_EXPORT osg::Image* createSpotLightImage(const osg::Vec4& centerColour, const osg::Vec4& backgroudColour, unsigned int size, float power); + +enum ColorSpaceOperation +{ + NO_COLOUR_SPACE_OPERATION, + MODULATE_ALPHA_BY_LUMINANCE, + MODULATE_ALPHA_BY_COLOUR, + REPLACE_ALPHA_WITH_LUMINANCE, + REPLACE_RGB_WITH_LUMINANCE +}; + +/** Convert the RGBA values in a Image based on a ColorSpaceOperation defined scheme.*/ +extern osg::Image* colorSpaceConversion(ColorSpaceOperation op, osg::Image* image, const osg::Vec4& colour); + + } diff --git a/include/osgPresentation/SlideShowConstructor b/include/osgPresentation/SlideShowConstructor index 897060ab1..247b5389e 100644 --- a/include/osgPresentation/SlideShowConstructor +++ b/include/osgPresentation/SlideShowConstructor @@ -15,6 +15,7 @@ #include #include +#include #include #include #include @@ -291,7 +292,9 @@ public: alphaValue(1.0), cutoffValue(0.1), sampleDensityValue(0.005), - sampleDensityWhenMovingValue(0.0) + sampleDensityWhenMovingValue(0.0), + colorSpaceOperation(osg::NO_COLOUR_SPACE_OPERATION), + colorModulate(1.0f,1.0f,1.0f,1.0f) { region[0] = region[1] = region[2] = 0.0f; region[3] = region[4] = region[5] = 1.0f; @@ -308,6 +311,9 @@ public: float cutoffValue; float sampleDensityValue; float sampleDensityWhenMovingValue; + + osg::ColorSpaceOperation colorSpaceOperation; + osg::Vec4 colorModulate; }; diff --git a/src/osg/Image.cpp b/src/osg/Image.cpp index bc6846029..15f76ba33 100644 --- a/src/osg/Image.cpp +++ b/src/osg/Image.cpp @@ -1183,6 +1183,32 @@ void Image::readImageFromCurrentTexture(unsigned int contextID, bool copyMipMaps #endif } +void Image::swap(osg::Image& rhs) +{ + std::swap(_fileName, rhs._fileName); + std::swap(_writeHint, rhs._writeHint); + + std::swap(_origin, rhs._origin); + + std::swap(_s, rhs._s); std::swap(_t, rhs._t); std::swap(_r, rhs._r); + std::swap(_rowLength, rhs._rowLength); + std::swap(_internalTextureFormat, rhs._internalTextureFormat); + std::swap(_pixelFormat, rhs._pixelFormat); + std::swap(_dataType, rhs._dataType); + std::swap(_packing, rhs._packing); + std::swap(_pixelAspectRatio, rhs._pixelAspectRatio); + + std::swap(_allocationMode, rhs._allocationMode); + std::swap(_data, rhs._data); + + std::swap(_mipmapData, rhs._mipmapData); + + std::swap(_bufferObject, rhs._bufferObject); + + std::swap(_dimensionsChangedCallbacks, rhs._dimensionsChangedCallbacks); +} + + void Image::scaleImage(int s,int t,int r, GLenum newDataType) { if (_s==s && _t==t && _r==r) return; diff --git a/src/osg/ImageUtils.cpp b/src/osg/ImageUtils.cpp index 8f45a2f8f..f88cb11ef 100644 --- a/src/osg/ImageUtils.cpp +++ b/src/osg/ImageUtils.cpp @@ -615,5 +615,68 @@ osg::Image* createSpotLightImage(const osg::Vec4& centerColour, const osg::Vec4& } +struct ModulateAlphaByColourOperator +{ + ModulateAlphaByColourOperator(const osg::Vec4& colour):_colour(colour) { _lum = _colour.length(); } + + osg::Vec4 _colour; + float _lum; + + inline void luminance(float&) const {} + inline void alpha(float&) const {} + inline void luminance_alpha(float& l,float& a) const { a*= l*_lum; } + inline void rgb(float&,float&,float&) const {} + inline void rgba(float& r,float& g,float& b,float& a) const { a = (r*_colour.r()+g*_colour.g()+b*_colour.b()+a*_colour.a()); } +}; + +struct ReplaceAlphaWithLuminanceOperator +{ + ReplaceAlphaWithLuminanceOperator() {} + + inline void luminance(float&) const {} + inline void alpha(float&) const {} + inline void luminance_alpha(float& l,float& a) const { a= l; } + inline void rgb(float&,float&,float&) const { } + inline void rgba(float& r,float& g,float& b,float& a) const { float l = (r+g+b)*0.3333333; a = l; } +}; + +osg::Image* colorSpaceConversion(ColorSpaceOperation op, osg::Image* image, const osg::Vec4& colour) +{ + switch(op) + { + case (MODULATE_ALPHA_BY_LUMINANCE): + { + OSG_NOTICE<<"doing conversion MODULATE_ALPHA_BY_LUMINANCE"<allocateImage(image->s(), image->t(), image->r(), GL_LUMINANCE, image->getDataType()); + osg::copyImage(image, 0, 0, 0, image->s(), image->t(), image->r(), + newImage, 0, 0, 0, false); + return newImage; + } + default: + return image; + } +} + + + } diff --git a/src/osgPlugins/p3d/ReaderWriterP3D.cpp b/src/osgPlugins/p3d/ReaderWriterP3D.cpp index 76c769abb..ebfe130a5 100644 --- a/src/osgPlugins/p3d/ReaderWriterP3D.cpp +++ b/src/osgPlugins/p3d/ReaderWriterP3D.cpp @@ -1098,6 +1098,23 @@ void ReaderWriterP3DXML::parseVolume(osgPresentation::SlideShowConstructor& cons if (getProperty(cur, "sampleDensity", volumeData.sampleDensityValue)) {} if (getProperty(cur, "sampleDensityWhenMoving", volumeData.sampleDensityWhenMovingValue)) {} + + if (getProperty(cur, "colourModulate", volumeData.colorModulate)) {} + if (getProperty(cur, "colorModulate", volumeData.colorModulate)) {} + + std::string operation; + if (getProperty(cur, "colorSpaceOperation", operation) || getProperty(cur, "colourSpaceOperation", operation)) + { + osg::ColorSpaceOperation colorOp = osg::NO_COLOUR_SPACE_OPERATION; + if (operation=="NO_COLOUR_SPACE_OPERATION") volumeData.colorSpaceOperation = osg::NO_COLOUR_SPACE_OPERATION; + else if (operation=="MODULATE_ALPHA_BY_LUMINANCE") volumeData.colorSpaceOperation = osg::MODULATE_ALPHA_BY_LUMINANCE; + else if (operation=="MODULATE_ALPHA_BY_COLOUR") volumeData.colorSpaceOperation = osg::MODULATE_ALPHA_BY_COLOUR; + else if (operation=="REPLACE_ALPHA_WITH_LUMINANCE") volumeData.colorSpaceOperation = osg::REPLACE_ALPHA_WITH_LUMINANCE; + else if (operation=="REPLACE_RGB_WITH_LUMINANCE") volumeData.colorSpaceOperation = osg::REPLACE_RGB_WITH_LUMINANCE; + } + + + // check for any transfer function required std::string transferFunctionFile; if (getTrimmedProperty(cur, "tf", transferFunctionFile)) diff --git a/src/osgPresentation/SlideShowConstructor.cpp b/src/osgPresentation/SlideShowConstructor.cpp index e4bf86c5f..1f319731a 100644 --- a/src/osgPresentation/SlideShowConstructor.cpp +++ b/src/osgPresentation/SlideShowConstructor.cpp @@ -2081,6 +2081,17 @@ void SlideShowConstructor::addVolume(const std::string& filename, const Position if (!image && !volume) return; + + if (volumeData.colorSpaceOperation!=osg::NO_COLOUR_SPACE_OPERATION) + { + OSG_NOTICE<<"Doing colour space conversion"< converted_image = osg::colorSpaceConversion(volumeData.colorSpaceOperation, image.get(), volumeData.colorModulate); + if (converted_image!=image) + { + image->swap(*converted_image); + } + } + if (positionData.scale.x()<0.0) { image->flipHorizontal();