From 86439123b44732c2e23046e7ddadf0966c1e3434 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 8 Jun 2011 16:10:46 +0000 Subject: [PATCH] Added support for creating a 3D Image from an image list. Added support for reading a list of images in the Present3D tag. --- examples/osgvolume/osgvolume.cpp | 123 +++++++---- include/osg/ImageUtils | 22 ++ src/osg/ImageUtils.cpp | 205 ++++++++++++++++++- src/osgPresentation/SlideShowConstructor.cpp | 5 +- 4 files changed, 313 insertions(+), 42 deletions(-) diff --git a/examples/osgvolume/osgvolume.cpp b/examples/osgvolume/osgvolume.cpp index 2bb6f9bc4..d0d1efe0f 100644 --- a/examples/osgvolume/osgvolume.cpp +++ b/examples/osgvolume/osgvolume.cpp @@ -70,8 +70,6 @@ #include #include -typedef std::vector< osg::ref_ptr > ImageList; - enum ShadingModel { Standard, @@ -86,6 +84,86 @@ struct PassThroughTransformFunction }; +void clampToNearestValidPowerOfTwo(int& sizeX, int& sizeY, int& sizeZ, int s_maximumTextureSize, int t_maximumTextureSize, int r_maximumTextureSize) +{ + // compute nearest powers of two for each axis. + int s_nearestPowerOfTwo = 1; + while(s_nearestPowerOfTwo image = osg::createImage3D(imageList, + desiredPixelFormat, + s_maximumTextureSize, + t_maximumTextureSize, + r_maximumTextureSize, + resizeToPowerOfTwo); + if (image.valid()) + { + if (modulateAlphaByLuminance) + { + osg::modifyImage(image.get(), ModulateAlphaByLuminanceOperator()); + } + return image.release(); + } + else + { + return 0; + } +} +#else + struct ProcessRow { virtual ~ProcessRow() {} @@ -435,36 +513,19 @@ struct ProcessRow }; - -void clampToNearestValidPowerOfTwo(int& sizeX, int& sizeY, int& sizeZ, int s_maximumTextureSize, int t_maximumTextureSize, int r_maximumTextureSize) -{ - // compute nearest powers of two for each axis. - int s_nearestPowerOfTwo = 1; - while(s_nearestPowerOfTwo=0) { - ImageList imageList; + osg::ImageList imageList; int pos=images_pos+1; for(;pos > ImageList; + +/** Search through the list of Images and find the maximum number of components used amoung the images.*/ +extern OSG_EXPORT unsigned int maximimNumOfComponents(const ImageList& imageList); + +/** create a 3D osg::Image from a list of osg::Image.*/ +extern OSG_EXPORT osg::Image* createImage3D(const ImageList& imageList, + GLenum desiredPixelFormat, + int s_maximumImageSize = 1024, + int t_maximumImageSize = 1024, + int r_maximumImageSize = 1024, + bool resizeToPowerOfTwo = false); + +/** create a 3D osg::Image from a list of osg::Image.*/ +extern OSG_EXPORT osg::Image* createImage3DWithAlpha(const ImageList& imageList, + int s_maximumImageSize = 1024, + int t_maximumImageSize = 1024, + int r_maximumImageSize = 1024, + bool resizeToPowerOfTwo = false); + + } diff --git a/src/osg/ImageUtils.cpp b/src/osg/ImageUtils.cpp index 63727e919..cbd54c50b 100644 --- a/src/osg/ImageUtils.cpp +++ b/src/osg/ImageUtils.cpp @@ -197,7 +197,7 @@ struct WriteRowOperator }; bool copyImage(const osg::Image* srcImage, int src_s, int src_t, int src_r, int width, int height, int depth, - osg::Image* destImage, int dest_s, int dest_t, int dest_r, bool doRescale) + osg::Image* destImage, int dest_s, int dest_t, int dest_r, bool doRescale) { if ((src_s+width) > (dest_s + destImage->s())) { @@ -287,8 +287,8 @@ bool copyImage(const osg::Image* srcImage, int src_s, int src_t, int src_r, int } else { - OSG_NOTICE<<"copyImage("<get(); + GLenum pixelFormat = image->getPixelFormat(); + if (pixelFormat==GL_ALPHA || + pixelFormat==GL_INTENSITY || + pixelFormat==GL_LUMINANCE || + pixelFormat==GL_LUMINANCE_ALPHA || + pixelFormat==GL_RGB || + pixelFormat==GL_RGBA || + pixelFormat==GL_BGR || + pixelFormat==GL_BGRA) + { + max_components = osg::maximum(osg::Image::computeNumComponents(pixelFormat), max_components); + } + } + return max_components; +} + +osg::Image* createImage3D(const ImageList& imageList, + GLenum desiredPixelFormat, + int s_maximumImageSize, + int t_maximumImageSize, + int r_maximumImageSize, + bool resizeToPowerOfTwo) +{ + OSG_INFO<<"createImage3D(..)"<get(); + GLenum pixelFormat = image->getPixelFormat(); + if (pixelFormat==GL_ALPHA || + pixelFormat==GL_INTENSITY || + pixelFormat==GL_LUMINANCE || + pixelFormat==GL_LUMINANCE_ALPHA || + pixelFormat==GL_RGB || + pixelFormat==GL_RGBA || + pixelFormat==GL_BGR || + pixelFormat==GL_BGRA) + { + max_s = osg::maximum(image->s(), max_s); + max_t = osg::maximum(image->t(), max_t); + total_r += image->r(); + } + else + { + OSG_INFO<<"Image "<getFileName()<<" has unsuitable pixel format 0x"<< std::hex<< pixelFormat << std::dec << std::endl; + } + } + + //bool remapRGBtoLuminance; + //bool remapRGBtoRGBA; + + if (desiredPixelFormat==0) + { + unsigned int max_components = maximimNumOfComponents(imageList); + switch(max_components) + { + case(1): + OSG_INFO<<"desiredPixelFormat = GL_LUMINANCE" << std::endl; + desiredPixelFormat = GL_LUMINANCE; + break; + case(2): + OSG_INFO<<"desiredPixelFormat = GL_LUMINANCE_ALPHA" << std::endl; + desiredPixelFormat = GL_LUMINANCE_ALPHA; + break; + case(3): + OSG_INFO<<"desiredPixelFormat = GL_RGB" << std::endl; + desiredPixelFormat = GL_RGB; + break; + case(4): + OSG_INFO<<"desiredPixelFormat = GL_RGBA" << std::endl; + desiredPixelFormat = GL_RGBA; + break; + } + } + if (desiredPixelFormat==0) return 0; + + // compute nearest powers of two for each axis. + + int size_s = 1; + int size_t = 1; + int size_r = 1; + + if (resizeToPowerOfTwo) + { + while(size_s image_3d = new osg::Image; + image_3d->allocateImage(size_s,size_t,size_r, + desiredPixelFormat,GL_UNSIGNED_BYTE); + + unsigned int r_offset = (total_rget(); + GLenum pixelFormat = image->getPixelFormat(); + if (pixelFormat==GL_ALPHA || + pixelFormat==GL_LUMINANCE || + pixelFormat==GL_INTENSITY || + pixelFormat==GL_LUMINANCE_ALPHA || + pixelFormat==GL_RGB || + pixelFormat==GL_RGBA || + pixelFormat==GL_BGR || + pixelFormat==GL_BGRA) + { + + int num_s = osg::minimum(image->s(), image_3d->s()); + int num_t = osg::minimum(image->t(), image_3d->t()); + int num_r = osg::minimum(image->r(), (image_3d->r() - curr_dest_r)); + + unsigned int s_offset_dest = (image->s()s())/2 : 0; + unsigned int t_offset_dest = (image->t()t())/2 : 0; + + copyImage(image, 0, 0, 0, num_s, num_t, num_r, + image_3d.get(), s_offset_dest, t_offset_dest, curr_dest_r, false); + + curr_dest_r += num_r; + } + } + + return image_3d.release(); +} + +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;} +}; + +osg::Image* createImage3DWithAlpha(const ImageList& imageList, + int s_maximumImageSize, + int t_maximumImageSize, + int r_maximumImageSize, + bool resizeToPowerOfTwo) +{ + GLenum desiredPixelFormat = 0; + bool modulateAlphaByLuminance = false; + + unsigned int maxNumComponents = osg::maximimNumOfComponents(imageList); + if (maxNumComponents==3) + { + desiredPixelFormat = GL_RGBA; + modulateAlphaByLuminance = true; + } + + osg::ref_ptr image = createImage3D(imageList, + desiredPixelFormat, + s_maximumImageSize, + t_maximumImageSize, + r_maximumImageSize, + resizeToPowerOfTwo); + if (image.valid()) + { + if (modulateAlphaByLuminance) + { + osg::modifyImage(image.get(), ModulateAlphaByLuminanceOperator()); + } + return image.release(); + } + else + { + return 0; + } +} + + } diff --git a/src/osgPresentation/SlideShowConstructor.cpp b/src/osgPresentation/SlideShowConstructor.cpp index ca35f4100..5ff0a4be8 100644 --- a/src/osgPresentation/SlideShowConstructor.cpp +++ b/src/osgPresentation/SlideShowConstructor.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -1776,11 +1777,11 @@ void SlideShowConstructor::addVolume(const std::string& filename, const Position osg::ref_ptr loadedImage = osgDB::readImageFile(*itr); if (loadedImage.valid()) { - OSG_NOTICE<<"Image loaded "<<*itr<