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 <volume> tag

This commit is contained in:
Robert Osfield 2012-11-13 13:16:10 +00:00
parent e72af02c2b
commit 92975a01fd
8 changed files with 150 additions and 91 deletions

View File

@ -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"<<std::endl;
osg::modifyImage(image,ModulateAlphaByLuminanceOperator());
return image;
}
case (MODULATE_ALPHA_BY_COLOUR):
{
std::cout<<"doing conversion MODULATE_ALPHA_BY_COLOUR"<<std::endl;
osg::modifyImage(image,ModulateAlphaByColourOperator(colour));
return image;
}
case (REPLACE_ALPHA_WITH_LUMINANCE):
{
std::cout<<"doing conversion REPLACE_ALPHA_WITH_LUMINANCE"<<std::endl;
osg::modifyImage(image,ReplaceAlphaWithLuminanceOperator());
return image;
}
case (REPLACE_RGB_WITH_LUMINANCE):
{
std::cout<<"doing conversion REPLACE_ALPHA_WITH_LUMINANCE"<<std::endl;
osg::Image* newImage = new osg::Image;
newImage->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);
}
}

View File

@ -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;

View File

@ -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);
}

View File

@ -15,6 +15,7 @@
#include <osg/Vec3>
#include <osg/Vec4>
#include <osg/ImageUtils>
#include <osg/Group>
#include <osg/ClearNode>
#include <osg/Switch>
@ -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;
};

View File

@ -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;

View File

@ -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"<<std::endl;
osg::modifyImage(image, ModulateAlphaByLuminanceOperator());
return image;
}
case (MODULATE_ALPHA_BY_COLOUR):
{
OSG_NOTICE<<"doing conversion MODULATE_ALPHA_BY_COLOUR"<<std::endl;
osg::modifyImage(image, ModulateAlphaByColourOperator(colour));
return image;
}
case (REPLACE_ALPHA_WITH_LUMINANCE):
{
OSG_NOTICE<<"doing conversion REPLACE_ALPHA_WITH_LUMINANCE"<<std::endl;
osg::modifyImage(image, ReplaceAlphaWithLuminanceOperator());
return image;
}
case (REPLACE_RGB_WITH_LUMINANCE):
{
OSG_NOTICE<<"doing conversion REPLACE_ALPHA_WITH_LUMINANCE"<<std::endl;
osg::Image* newImage = new osg::Image;
newImage->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;
}
}
}

View File

@ -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))

View File

@ -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"<<std::endl;
osg::ref_ptr<osg::Image> 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();