From 6d3e7f83e261d173fdd7bd5c8e4f7c7d4ac13911 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 24 Nov 2009 14:12:54 +0000 Subject: [PATCH] From Terry Welsh, "As I mentioned here http://www.mail-archive.com/osg-users@lists.openscenegraph.org/msg33967.html , interpolating through HSV space gives a rainbow color effect which does not mimic the simple RGB color interpolation that OpenGL does. It's overkill and causes unexpected visual artifacts. In the attached files I've removed the conversion to HSV so that interpolation happens in RGB space." --- include/osgText/Text | 4 +- src/osgText/Text.cpp | 263 +++---------------------------------------- 2 files changed, 17 insertions(+), 250 deletions(-) diff --git a/include/osgText/Text b/include/osgText/Text index 420b44e75..c93ad59c4 100644 --- a/include/osgText/Text +++ b/include/osgText/Text @@ -397,10 +397,8 @@ protected: osg::Vec4 _colorGradientBottomRight; osg::Vec4 _colorGradientTopRight; - // Helper functions for color interpolation + // Helper function for color interpolation float bilinearInterpolate(float x1, float x2, float y1, float y2, float x, float y, float q11, float q12, float q21, float q22) const; - void convertHsvToRgb( float hsv[], float rgb[] ) const; - void convertRgbToHsv( float rgb[], float hsv[] ) const; }; } diff --git a/src/osgText/Text.cpp b/src/osgText/Text.cpp index c730397d2..3bdd4e9f2 100644 --- a/src/osgText/Text.cpp +++ b/src/osgText/Text.cpp @@ -1064,17 +1064,6 @@ void Text::computeColorGradientsOverall() const float max_x = FLT_MIN; float max_y = FLT_MIN; - float rgb_q11[3]; - float hsv_q11[3]; - float rgb_q12[3]; - float hsv_q12[3]; - float rgb_q21[3]; - float hsv_q21[3]; - float rgb_q22[3]; - float hsv_q22[3]; - - float rgb[3]; - float hsv[3]; unsigned int i; for(TextureGlyphQuadMap::const_iterator const_titr=_textureGlyphQuadMap.begin(); @@ -1107,36 +1096,6 @@ void Text::computeColorGradientsOverall() const } } - rgb_q11[0] = _colorGradientBottomLeft[0]; - rgb_q11[1] = _colorGradientBottomLeft[1]; - rgb_q11[2] = _colorGradientBottomLeft[2]; - - rgb_q12[0] = _colorGradientTopLeft[0]; - rgb_q12[1] = _colorGradientTopLeft[1]; - rgb_q12[2] = _colorGradientTopLeft[2]; - - rgb_q21[0] = _colorGradientBottomRight[0]; - rgb_q21[1] = _colorGradientBottomRight[1]; - rgb_q21[2] = _colorGradientBottomRight[2]; - - rgb_q22[0] = _colorGradientTopRight[0]; - rgb_q22[1] = _colorGradientTopRight[1]; - rgb_q22[2] = _colorGradientTopRight[2]; - - // for linear interpolation to look correct - // for colors and imitate what OpenGL does, - // we need to convert over to Hue-Saturation-Value - // and linear interpolate in that space. - // HSV will interpolate through the color spectrum. - // Now that I think about this, perhaps we could - // extend this to use function pointers or something - // so users may specify their own color interpolation - // scales such as Intensity, or Heated Metal, etc. - convertRgbToHsv(rgb_q11, hsv_q11); - convertRgbToHsv(rgb_q12, hsv_q12); - convertRgbToHsv(rgb_q21, hsv_q21); - convertRgbToHsv(rgb_q22, hsv_q22); - for(TextureGlyphQuadMap::iterator titr=_textureGlyphQuadMap.begin(); titr!=_textureGlyphQuadMap.end(); ++titr) @@ -1153,43 +1112,43 @@ void Text::computeColorGradientsOverall() const for(i=0;i= 6.f ) h -= 6.f; - while( h < 0.f ) h += 6.f; - - s = hsv[1]; - if( s < 0.f ) - s = 0.f; - if( s > 1.f ) - s = 1.f; - - v = hsv[2]; - if( v < 0.f ) - v = 0.f; - if( v > 1.f ) - v = 1.f; - - - /* if sat==0, then is a gray: */ - - if( s == 0.0f ) - { - rgb[0] = rgb[1] = rgb[2] = v; - return; - } - - - /* get an rgb from the hue itself: */ - - i = floor( h ); - f = h - i; - p = v * ( 1.f - s ); - q = v * ( 1.f - s*f ); - t = v * ( 1.f - ( s * (1.f-f) ) ); - - switch( (int) i ) - { - case 0: - r = v; g = t; b = p; - break; - - case 1: - r = q; g = v; b = p; - break; - - case 2: - r = p; g = v; b = t; - break; - - case 3: - r = p; g = q; b = v; - break; - - case 4: - r = t; g = p; b = v; - break; - - case 5: - r = v; g = p; b = q; - break; - - default: - /* never happens? */ - r = 0; g = 0; b = 0; - break; - } - - - rgb[0] = r; - rgb[1] = g; - rgb[2] = b; - -} - -/* - * FUNCTION - * RgbHsv - * - * DESCRIPTION - * convert a red-green-blue value into hue-saturation-value - * - * NOTE - * Array sizes are 3 - * Values are between 0.0 and 1.0 - */ - -void Text::convertRgbToHsv( float rgb[], float hsv[] ) const -{ - float r, g, b; /* red, green, blue */ - float min, max; /* min and max rgb values */ - float fmin, fmax, diff; /* min, max, and range of rgb vals */ - float hue, sat, value; /* h s v */ - float cr, cg, cb; /* coefficients for computing hue */ - - - /* determine min and max color primary values: */ - - r = rgb[0]; g = rgb[1]; b = rgb[2]; - min = r; max = r; - if( g < min ) min = g; - if( g > max ) max = g; - if( b < min ) min = b; - if( b > max ) max = b; - - fmin = min; - fmax = max; - diff = fmax - fmin; - - - /* get value and saturation: */ - - value = fmax; - if( max == 0.f ) - sat = 0.0f; - else - sat = diff/fmax; - - - - /* compute hue: */ - - if( sat == 0.0f ) - hue = 0.0f; - else - { - float inv_diff = 1.0f / diff; - cr = ( fmax-r ) * inv_diff; - cg = ( fmax-g ) * inv_diff; - cb = ( fmax-b ) * inv_diff; - - if( max == r ) - hue = (g-b) * inv_diff; - else if( max == g ) - hue = 2.f + (b-r) * inv_diff; - else if( max == b ) - hue = 4.f + (r-g) * inv_diff; - else - hue = 0.0f; - } - - - hue *= 60.0f; - if( hue < 0.0f ) - hue += 360.0f; - if( hue > 360.0f ) - hue -= 360.0f; - - - /* store output values: */ - - hsv[0] = hue; - hsv[1] = sat; - hsv[2] = value; - -} - void Text::drawForegroundText(osg::State& state, const GlyphQuads& glyphquad, const osg::Vec4& colorMultiplier) const { unsigned int contextID = state.getContextID();