From e67466a74fd6f9f25149859b10d2c9f6e9ee1ef3 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 21 Nov 2014 16:27:29 +0000 Subject: [PATCH] From Sebastian Messerschmidt, "Added setColor function to modify an image based on texture coordinates, parallel to the getColor functionality." git-svn-id: http://svn.openscenegraph.org/osg/OpenSceneGraph/trunk@14517 16af8721-9629-0410-8352-f15c8da7e697 --- include/osg/Image | 20 ++++++++++++++------ src/osg/Image.cpp | 45 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 6 deletions(-) diff --git a/include/osg/Image b/include/osg/Image index 4e01e3af1..cd3ea7d30 100644 --- a/include/osg/Image +++ b/include/osg/Image @@ -373,6 +373,14 @@ class OSG_EXPORT Image : public BufferData /** Get the color value for specified texcoord.*/ Vec4 getColor(const Vec3& texcoord) const; + /** Set the color value for specified texcoord.*/ + void setColor(const osg::Vec4& color, unsigned int s, unsigned int t=0, unsigned int r=0); + + /** Set the color value for specified texcoord.*/ + void setColor(const osg::Vec4& color, const osg::Vec2& texcoord ) { setColor(color, osg::Vec3(texcoord, 0.0f)); } + + /** Set the color value for specified texcoord.*/ + void setColor(const osg::Vec4& color, const osg::Vec3& texcoord ); /** Flip the image horizontally, around s dimension. */ void flipHorizontal(); @@ -476,15 +484,15 @@ class OSG_EXPORT Image : public BufferData /** Pass frame information to the custom Image classes, to be called only when objects associated with imagery are not culled.*/ virtual void setFrameLastRendered(const osg::FrameStamp* /*frameStamp*/) {} - + class DimensionsChangedCallback : public osg::Referenced { public: DimensionsChangedCallback() : osg::Referenced() {} virtual void operator()(osg::Image* image) = 0; }; - + typedef std::vector< osg::ref_ptr > DimensionsChangedCallbackVector; - + void addDimensionsChangedCallback(DimensionsChangedCallback* cb); void removeDimensionsChangedCallback(DimensionsChangedCallback* cb); @@ -493,8 +501,8 @@ class OSG_EXPORT Image : public BufferData virtual ~Image(); Image& operator = (const Image&) { return *this; } - - void handleDimensionsChangedCallbacks() + + void handleDimensionsChangedCallbacks() { for(DimensionsChangedCallbackVector::iterator i = _dimensionsChangedCallbacks.begin(); i != _dimensionsChangedCallbacks.end(); ++i) { @@ -523,7 +531,7 @@ class OSG_EXPORT Image : public BufferData void setData(unsigned char* data,AllocationMode allocationMode); MipmapDataType _mipmapData; - + DimensionsChangedCallbackVector _dimensionsChangedCallbacks; }; diff --git a/src/osg/Image.cpp b/src/osg/Image.cpp index 20144a931..6e21a7991 100644 --- a/src/osg/Image.cpp +++ b/src/osg/Image.cpp @@ -1926,6 +1926,51 @@ Vec4 Image::getColor(const Vec3& texcoord) const return getColor(s,t,r); } + +template +void _writeColor(GLenum pixelFormat, T* data, float scale, const Vec4& c) +{ + switch(pixelFormat) + { + case(GL_DEPTH_COMPONENT): //intentionally fall through and execute the code for GL_LUMINANCE + case(GL_LUMINANCE): { (*data++) = c[0] * scale; } break; + case(GL_ALPHA): { (*data++) = c[3] * scale; } break; + case(GL_LUMINANCE_ALPHA): { (*data++) = c[0] * scale; (*data++) = c[3] * scale; } break; + case(GL_RGB): { (*data++) = c[0] *scale; (*data++) = c[1] *scale; (*data++) = c[2] *scale;} break; + case(GL_RGBA): { (*data++) = c[0] *scale; (*data++) = c[1] *scale; (*data++) = c[2] *scale; (*data++) = c[3] *scale;} break; + case(GL_BGR): { (*data++) = c[2] *scale; (*data++) = c[1] *scale; (*data++) = c[0] *scale;} break; + case(GL_BGRA): { (*data++) = c[2] *scale; (*data++) = c[1] *scale; (*data++) = c[0] *scale; (*data++) = c[3] *scale;} break; + } + +} + + +void Image::setColor( const Vec4& color, unsigned int s, unsigned int t/*=0*/, unsigned int r/*=0*/ ) +{ + unsigned char* ptr = data(s,t,r); + + switch(getDataType()) + { + case(GL_BYTE): return _writeColor(getPixelFormat(), (char*)ptr, 128.0f, color); + case(GL_UNSIGNED_BYTE): return _writeColor(getPixelFormat(), (unsigned char*)ptr, 255.0f, color); + case(GL_SHORT): return _writeColor(getPixelFormat(), (short*)ptr, 32768.0f, color); + case(GL_UNSIGNED_SHORT): return _writeColor(getPixelFormat(), (unsigned short*)ptr, 65535.0f, color); + case(GL_INT): return _writeColor(getPixelFormat(), (int*)ptr, 2147483648.0f, color); + case(GL_UNSIGNED_INT): return _writeColor(getPixelFormat(), (unsigned int*)ptr, 4294967295.0f, color); + case(GL_FLOAT): return _writeColor(getPixelFormat(), (float*)ptr, 1.0f, color); + case(GL_DOUBLE): return _writeColor(getPixelFormat(), (double*)ptr, 1.0f, color); + } +} + +void Image::setColor( const Vec4& color, const Vec3& texcoord ) +{ + int s = int(texcoord.x()*float(_s - 1 )) % _s; + int t = int(texcoord.y()*float(_t - 1)) % _t; + int r = int(texcoord.z()*float(_r - 1)) % _r; + + return setColor(color, s,t,r); +} + void Image::addDimensionsChangedCallback(DimensionsChangedCallback* cb) { _dimensionsChangedCallbacks.push_back(cb);