osgEarth 2.1.1
|
00001 /* -*-c++-*- */ 00002 /* osgEarth - Dynamic map generation toolkit for OpenSceneGraph 00003 * Copyright 2008-2010 Pelican Mapping 00004 * http://osgearth.org 00005 * 00006 * osgEarth is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU Lesser General Public License as published by 00008 * the Free Software Foundation; either version 2 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU Lesser General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public License 00017 * along with this program. If not, see <http://www.gnu.org/licenses/> 00018 */ 00019 #include <osgEarthSymbology/Color> 00020 #include <algorithm> 00021 #include <osg/Vec4ub> 00022 #include <sstream> 00023 #include <iomanip> 00024 00025 using namespace osgEarth::Symbology; 00026 00027 namespace 00028 { 00029 void rgb2hsv( osg::Vec4f& c ) 00030 { 00031 float minval = std::min( c.r(), std::min( c.g(), c.b() ) ); 00032 float maxval = std::max( c.r(), std::max( c.g(), c.b() ) ); 00033 float delta = maxval - minval; 00034 float h = 0.0f, s = 0.0, v = maxval; 00035 if ( delta != 0.0f ) 00036 { 00037 s = delta / maxval; 00038 float dr = (((maxval-c.r())/6.0f)+(delta/2.0f))/delta; 00039 float dg = (((maxval-c.g())/6.0f)+(delta/2.0f))/delta; 00040 float db = (((maxval-c.b())/6.0f)+(delta/2.0f))/delta; 00041 if ( c.r() == maxval ) h = db - dg; 00042 else if ( c.g() == maxval ) h = (1.0f/3.0f)+dr-db; 00043 else if ( c.b() == maxval ) h = (2.0f/3.0f)+dg-dr; 00044 if ( h < 0.0f ) h += 1.0f; 00045 if ( h > 1.0f ) h -= 1.0f; 00046 } 00047 c.set( h, s, v, c.a() ); 00048 } 00049 00050 void hsv2rgb( osg::Vec4f& c ) 00051 { 00052 float h = c[0], s = c[1], v = c[2]; 00053 if ( s == 0.0f ) { 00054 c.r() = c.g() = c.b() = 1.0f; 00055 } 00056 else { 00057 float vh = h*6.0f; 00058 float vi = floor(vh); 00059 float v1 = v * (1.0f - s); 00060 float v2 = v * (1.0f - s * (vh-vi)); 00061 float v3 = v * (1.0f - s * (1.0f - (vh-vi))); 00062 float vr, vg, vb; 00063 if ( vi == 0.0f ) { vr = v, vg = v3, vb = v1; } 00064 else if ( vi == 1.0f ) { vr = v2, vg = v, vb = v1; } 00065 else if ( vi == 2.0f ) { vr = v1, vg = v, vb = v3; } 00066 else if ( vi == 3.0f ) { vr = v1, vb = v2, vb = v; } 00067 else if ( vi == 4.0f ) { vr = v3, vg = v1, vb = v; } 00068 else { vr = v, vg = v1, vb = v2; } 00069 c.set( vr, vg, vb, c.a() ); 00070 } 00071 } 00072 } 00073 00074 Color Color::White ( 0xffffffff ); 00075 Color Color::Silver ( 0xc0c0c0ff ); 00076 Color Color::Gray ( 0x808080ff ); 00077 Color Color::Black ( 0x000000ff ); 00078 Color Color::Red ( 0xff0000ff ); 00079 Color Color::Maroon ( 0x800000ff ); 00080 Color Color::Yellow ( 0xffff00ff ); 00081 Color Color::Olive ( 0x808000ff ); 00082 Color Color::Lime ( 0x00ff00ff ); 00083 Color Color::Green ( 0x008000ff ); 00084 Color Color::Aqua ( 0x00ffffff ); 00085 Color Color::Teal ( 0x008080ff ); 00086 Color Color::Blue ( 0x0000ffff ); 00087 Color Color::Navy ( 0x000080ff ); 00088 Color Color::Fuchsia ( 0xff00ffff ); 00089 Color Color::Purple ( 0x800080ff ); 00090 Color Color::Orange ( 0xffa500ff ); 00091 00092 Color Color::DarkGray ( 0x404040ff ); 00093 Color Color::Cyan ( 0x00ffffff ); 00094 00095 Color::Color( unsigned rgba ) 00096 { 00097 set( 00098 (float)(rgba>>24)/255.0f, 00099 (float)((rgba&0xFF0000)>>16)/255.0f, 00100 (float)((rgba&0xFF00)>>8)/255.0f, 00101 (float)(rgba&0xFF)/255.0f ); 00102 } 00103 00104 Color::Color( const Color& rhs, float a ) : 00105 osg::Vec4f( rhs ) 00106 { 00107 (*this)[3] = a; 00108 } 00109 00111 Color::Color( const std::string& html, Format format ) 00112 { 00113 std::string t = html; 00114 std::transform( t.begin(), t.end(), t.begin(), ::tolower ); 00115 osg::Vec4ub c(0,0,0,255); 00116 if ( t.length() >= 7 ) { 00117 c.r() |= t[1]<='9' ? (t[1]-'0')<<4 : (10+(t[1]-'a'))<<4; 00118 c.r() |= t[2]<='9' ? (t[2]-'0') : (10+(t[2]-'a')); 00119 c.g() |= t[3]<='9' ? (t[3]-'0')<<4 : (10+(t[3]-'a'))<<4; 00120 c.g() |= t[4]<='9' ? (t[4]-'0') : (10+(t[4]-'a')); 00121 c.b() |= t[5]<='9' ? (t[5]-'0')<<4 : (10+(t[5]-'a'))<<4; 00122 c.b() |= t[6]<='9' ? (t[6]-'0') : (10+(t[6]-'a')); 00123 if ( t.length() == 9 ) { 00124 c.a() = 0; 00125 c.a() |= t[7]<='9' ? (t[7]-'0')<<4 : (10+(t[7]-'a'))<<4; 00126 c.a() |= t[8]<='9' ? (t[8]-'0') : (10+(t[8]-'a')); 00127 } 00128 } 00129 float w = ((float)c.r())/255.0f; 00130 float x = ((float)c.g())/255.0f; 00131 float y = ((float)c.b())/255.0f; 00132 float z = ((float)c.a())/255.0f; 00133 00134 if ( format == RGBA ) 00135 set( w, x, y, z ); 00136 else // ABGR 00137 set( z, y, x, w ); 00138 } 00139 00141 std::string 00142 Color::toHTML( Format format ) const 00143 { 00144 float w, x, y, z; 00145 if ( format == RGBA ) { 00146 w = r(), x = g(), y = b(), z = a(); 00147 } 00148 else { // ABGR 00149 w = a(), x = b(), y = g(), z = r(); 00150 } 00151 00152 std::stringstream buf; 00153 buf << "#"; 00154 buf << std::hex << std::setw(2) << std::setfill('0') << (int)(w*255.0f); 00155 buf << std::hex << std::setw(2) << std::setfill('0') << (int)(x*255.0f); 00156 buf << std::hex << std::setw(2) << std::setfill('0') << (int)(y*255.0f); 00157 buf << std::hex << std::setw(2) << std::setfill('0') << (int)(z*255.0f); 00158 std::string ssStr = buf.str(); 00159 return ssStr; 00160 } 00161 00162 Color 00163 Color::brightness( float perc ) const 00164 { 00165 Color c( *this ); 00166 rgb2hsv( c ); 00167 c.b() = osg::clampBetween( perc * c.b(), 0.0f, 1.0f ); 00168 hsv2rgb( c ); 00169 return c; 00170 }