Logo Search packages:      
Sourcecode: passage version File versions  Download package

Color.h

// Jason Rohrer
// Color.h

/**
*
*     Color object for RadiosGL
*
*     Float components in RGB (0..1)
*     Color of emitted energy can be greater than 1
*
*
*     Created 9-5-99
*     Mods:
*           Jason Rohrer      11-6-99                 Added 32-bit composite member
*           Jason Rohrer      11-13-99          Added printing functionality
*           Jason Rohrer      11-15-99          Added rebuildComposite function
*                                                                 Added weightColor function
*                                                                 Added getMax function
*           Jason Rohrer      2004-June-12      Fixed a bug in copy function.
*           Jason Rohrer      2004-June-12      Added a linear sum function.
*
*       Jason Rohrer    2004-August-12  Optimized Color constructor.
*       Jason Rohrer    2004-August-27  Added an equality test.
*       Jason Rohrer    2005-February-4 Added weighting and setValue functions.
*       Jason Rohrer    2005-February-10  Added invert and saturate functions.
*       Jason Rohrer    2005-February-11  Added HSV conversion function.
*       Jason Rohrer    2005-April-5  Disabled default building of composite.
*       Jason Rohrer    2006-August-29  Changed alpha default to 1.
*       Jason Rohrer    2006-October-3  Disabled building composite in
*                                       default Color() constuctor.
*/

#ifndef COLOR_INCLUDED
#define COLOR_INCLUDED

#include <stdio.h>
#include <float.h>

00039 class Color {
      public :
        /**
         * Constructs a color.
         *
         * @param red, green, blue the components of the color, each in [0,1].
         * @param alpha the alpha value in [0,1].  Defaults to 1.
         * @param inBuildComposite set to true to build the composite
         *   upon construction, or false to skip building composite (faster).
         *   Defaults to false.
         */
            Color(float red, float green, float blue, float alpha=1,
              char inBuildComposite=false );


        
        /**
         * Constructs a all-zero color with no composite built.
         */
        Color();

        

        /**
         * Constructs an rgb color from HSV components.
         *
         * @param inHue, inSaturation, inValue the HSV components of the
         *   color, each in [0,1].
         * @param alpha the alpha value in [0,1].  Defaults to 1.
         * @param inBuildComposite set to true to build the composite
         *   upon construction, or false to skip building composite (faster).
         *   Defaults to true.
         *
         * @return an RGBA color equivalent to the HSV color.
         *   Must be destroyed by caller.
         */
        static Color *makeColorFromHSV(
            float inHue, float inSaturation, float inValue,
            float inAlpha=1, char inBuildComposite=false ); 


        
            float r, g, b, a;

        char mCompositeBuilt;
            unsigned long composite;            // 32-bit composite color

        
            Color *copy();    // make a copy of this color


        
        /**
         * Sets the RGBA values of this color.
         *
         * @param red, green, blue, alpha the values to set.
         *   Alpha defaults to 0.
         */
        void setValues( float red, float green, float blue, float alpha=1 );

        
        
        /**
         * Sets the RGBA values of this color using the values from
         * another color.
         *
         * @param inOtherColor the color to copy values from.
         *   Must be destroyed by caller.
         */
        void setValues( Color *inOtherColor ); 

        
        
        /**
         * Tests whether this color is equal to another color.
         *
         * @param inOtherColor the other color.
         *   Must be destroyed by caller.
         *
         * @return true if they are equal, or false otherwise.
         */
        char equals( Color *inOtherColor );

        
            void print();


            /**
             * Computes the linear weighted sum of two colors.
             *
             * @param inFirst the first color.
             * @param inSecond the second color.
             * @param inFirstWeight the weight given to the first color in the
             *   sum.  The second color is weighted (1-inFirstWeight).
             *
             * @return the sum color.  Must be destroyed by caller.
             */
            static Color *linearSum( Color *inFirst, Color *inSecond,
                  float inFirstWeight );

        
            // after adjusting the r, g, b, a values exterally
            // call this to remake the composite unsigned long
            unsigned long rebuildComposite();
            
            // get largest component of R,G,B
            float getMax();
            
            // alter color data by multiplying by weight
            void weightColor( float weight );

        
        
        /**
         * Alters color data by multiplying by a weight color.
         *
         * @param inWeightColor the color to multiply this color by.
         *   Must be destroyed by caller.
         */
            void weightColor( Color *inWeightColor );

        

        /**
         * Inverts this color.
         *
         * Ignores alpha channel.
         */
        void invert();

        

        /**
         * Saturates this color, ensuring that at most 2 components are
         * non-zero.
         *
         * Ignores alpha channel.
         */
        void saturate();

        
        
            // get component by component weighted 32-bit composite
            // (returns alpha unweighted)
            unsigned long getWeightedComposite( float weight );         // from this color
            unsigned long getWeightedComposite(unsigned long c1, float weight );    // from composite
            
            unsigned long sumComposite(unsigned long c1, unsigned long c2);
            
            // access this color as a three vector
            float &operator[](int rgbIndex);
        
      };
      
      
00194 inline Color::Color() {
      r = 0;
      g = 0;
      b = 0;
      a = 0;

    mCompositeBuilt = false;
      composite = 0;
      }



00206 inline Color::Color(float red, float green, float blue, float alpha,
                    char inBuildComposite ) {
      r = red;
      g = green;
      b = blue;
      a = alpha;

    if( inBuildComposite ) {
        rebuildComposite();
        }
    else {
        composite = 0;
        mCompositeBuilt = false;
        }
      }



00224 inline Color *Color::makeColorFromHSV(
    float inHue, float inSaturation, float inValue,
    float inAlpha, char inBuildComposite ) {

    // based on pseudocode from http://www.easyrgb.com/math.php
    float r, g, b;
    
    if ( inSaturation == 0 ) {
        r = inValue;                      
        g = inValue;
        b = inValue;
        }
    else {
        float var_h = inHue * 6;
        float var_i = int( var_h );             // Or var_i = floor( var_h )
        float var_1 = inValue * ( 1 - inSaturation );
        float var_2 = inValue * ( 1 - inSaturation * ( var_h - var_i ) );
        float var_3 =
            inValue * ( 1 - inSaturation * ( 1 - ( var_h - var_i ) ) );
        
        if( var_i == 0 ) {
            r = inValue;
            g = var_3;
            b = var_1;
            }
        else if( var_i == 1 ) {
            r = var_2;
            g = inValue;
            b = var_1;
            }
        else if( var_i == 2 ) {
            r = var_1;
            g = inValue;
            b = var_3;
            }
        else if( var_i == 3 ) {
            r = var_1;
            g = var_2;
            b = inValue;
            }
        else if( var_i == 4 ) {
            r = var_3;
            g = var_1;
            b = inValue;
            }
        else {
            r = inValue;
            g = var_1;
            b = var_2;
            }
        }

    return new Color( r, g, b, inAlpha, inBuildComposite );
    }



inline Color *Color::copy() {
      Color *copyColor = new Color(r,g,b,a, mCompositeBuilt );
      return copyColor;
      }



00288 inline void Color::setValues( float red, float green,
                              float blue, float alpha ) {
    r = red;
    g = green;
    b = blue;
    a = alpha;
    
    if( mCompositeBuilt ) {
        rebuildComposite();
        }
    }



00302 inline void Color::setValues( Color *inOtherColor ) {
    setValues( inOtherColor->r,
               inOtherColor->g,
               inOtherColor->b,
               inOtherColor->a );
    }



00311 inline char Color::equals( Color *inOtherColor ) {
    if( r == inOtherColor->r &&
        g == inOtherColor->g &&
        b == inOtherColor->b &&
        a == inOtherColor->a ) {
        return true;
        }
    else {
        return false;
        }
    }

inline void Color::print() {
      printf( "(%f, %f, %f)", r, g, b );
      }



00329 inline Color *Color::linearSum( Color *inFirst, Color *inSecond,
      float inFirstWeight ) {
      
      float secondWeight = 1 - inFirstWeight;
      float r = inFirstWeight * inFirst->r + secondWeight * inSecond->r;
      float g = inFirstWeight * inFirst->g + secondWeight * inSecond->g;
      float b = inFirstWeight * inFirst->b + secondWeight * inSecond->b;
    float a = inFirstWeight * inFirst->a + secondWeight * inSecond->a;
      
      return new Color( r, g, b, a,
                      inFirst->mCompositeBuilt || inSecond->mCompositeBuilt );
      }



inline unsigned long Color::rebuildComposite() {
      composite = ((int)(b*255)) | ((int)(g*255)) << 8 | ((int)(r*255)) << 16 |
        ((int)(a*255)) << 24;
    mCompositeBuilt = true;
      return composite;
      }

inline float Color::getMax() {
      float max = -FLT_MAX;
      if( r > max ) max = r;
      if( g > max ) max = g;
      if( b > max ) max = b;
      return max;
      }



inline void Color::weightColor( float weight ) {
      r = r * weight;
      g = g * weight;
      b = b * weight;
      // for now, don't touch alpha

    if( mCompositeBuilt ) {
        rebuildComposite();
        }
      }     



00374 inline void Color::invert() {
    r = 1 - r;
    g = 1 - g;
    b = 1 - b;
    }



00382 inline void Color::saturate() {
    if( r < g && r < b ) {
        r = 0;
        }
    else if( g < r && g < b ) {
        g = 0;
        }
    else if( b < r && b < g ) {
        b = 0;
        }
    else if( r != 0 ) {
        // they are all equal, but non-zero

        // default to dropping red
        r = 0;
        }
    //else
    // they are all 0
    // leave as black
    }



00405 inline void Color::weightColor( Color *inWeightColor ) {
    r *= inWeightColor->r;
    g *= inWeightColor->g;
    b *= inWeightColor->b;
    a *= inWeightColor->a;

    if( mCompositeBuilt ) {
        rebuildComposite();
        }
    }



inline float &Color::operator[](int rgbIndex) {
      if( rgbIndex == 0) return r;
      else if( rgbIndex == 1) return g;
      else if( rgbIndex == 2) return b;
      else if( rgbIndex == 3) return a;
      return r;         // default, return r reference
      }
      
      
inline unsigned long Color::getWeightedComposite( float weight ) {
      return ((int)(b*255*weight)) | ((int)(g*255*weight)) << 8 | ((int)(r*255*weight)) << 16 | ((int)(a*255)) << 24;
      }


inline unsigned long Color::getWeightedComposite( unsigned long c1, float weight ) {
      int b = c1 & 0xFF;
      
      int g = (c1 >> 8) & 0xFF;
      
      int r = (c1 >> 16) & 0xFF;

      int a = c1 >> 24;
      
      return ((int)(b*weight)) | (((int)(g*weight)) << 8) | (((int)(r*weight)) << 16) | (((int)(a*weight)) << 24);
      }

inline unsigned long Color::sumComposite(unsigned long c1, unsigned long c2) {
      int b = (c1 & 0xFF) + (c2 & 0xFF);
      if( b > 255) b = 255;
      
      int g = ((c1 >> 8) & 0xFF) + ((c2 >> 8) & 0xFF);
      if( g > 255) g = 255;
      
      int r = ((c1 >> 16) & 0xFF) + ((c2 >> 16) & 0xFF);
      if( r > 255) r = 255;

      int a = (c1 >> 24) + (c2 >> 24);
      if( a > 255) a = 255;

      return b | (g << 8) | (r << 16) | (a << 24);
      }
#endif

Generated by  Doxygen 1.6.0   Back to index