//===========================================================================// // File: color.hpp // // Title: Declaration of Color classes. // // Purpose: Stores color information. // //---------------------------------------------------------------------------// // Copyright (C) Microsoft Corporation. All rights reserved. // //===========================================================================// #pragma once #include "Stuff.hpp" #include "MemoryStream.hpp" #include "Scalar.hpp" #include "Vector3D.hpp" namespace Stuff { class RGBColor; class RGBAColor; class HSVColor; class HSVAColor; } #if !defined(Spew) void Spew( const char* group, const Stuff::RGBColor &color ); void Spew( const char* group, const Stuff::RGBAColor &color ); void Spew( const char* group, const Stuff::HSVColor &color ); void Spew( const char* group, const Stuff::HSVAColor &color ); #endif namespace Stuff { //########################################################################## //############## RGBColor ############################################ //########################################################################## class RGBColor { friend class RGBAColor; public: static const RGBColor Unassigned; Scalar red, green, blue; RGBColor() {red = green = blue = -1.0f;} RGBColor( Scalar r, Scalar g, Scalar b ) {red = r; green = g; blue = b;} friend bool Close_Enough( const RGBColor &c1, const RGBColor &c2, Scalar e = SMALL ); bool operator==(const RGBColor &color) const {Check_Object(this); return Close_Enough(*this, color, SMALL);} bool operator!=(const RGBColor &color) const {Check_Object(this); return !Close_Enough(*this, color, SMALL);} RGBColor& operator=(const RGBColor &color) { Check_Object(this); Check_Object(&color); red = color.red; green = color.green; blue = color.blue; return *this; } RGBColor& operator=(const HSVColor &color); void TestInstance() const {} Scalar Infrared() const {Check_Object(this); return 0.3f*red + 0.5f*green + 0.2f*blue;} RGBColor& Combine( const RGBColor& c1, Scalar t1, const RGBColor& c2, Scalar t2 ) { Check_Pointer(this); Check_Object(&c1); Check_Object(&c2); red = c1.red*t1 + c2.red*t2; green = c1.green*t1 + c2.green*t2; blue = c1.blue*t1 + c2.blue*t2; return *this; } RGBColor& Lerp( const RGBColor& c1, const RGBColor& c2, Scalar t ) { Check_Pointer(this); Check_Object(&c1); Check_Object(&c2); red = c1.red + t*(c2.red-c1.red); green = c1.green + t*(c2.green-c1.green); blue = c1.blue + t*(c2.blue-c1.blue); return *this; } // // Support functions // #if !defined(Spew) friend void ::Spew( const char* group, const RGBColor &color ); #endif }; //~~~~~~~~~~~~~~~~~~~~~~~~~~ RGBColor functions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ void Convert_From_Ascii( const char *str, RGBColor *color ); //########################################################################## //############## RGBAColor ########################################### //########################################################################## class RGBAColor: public RGBColor { public: static const RGBAColor Unassigned; Scalar alpha; RGBAColor(): RGBColor() {alpha = -1.0f;} RGBAColor( Scalar r, Scalar g, Scalar b, Scalar a ): RGBColor(r, g, b) {alpha = a;} friend bool Close_Enough( const RGBAColor &c1, const RGBAColor &c2, Scalar e = SMALL ); bool operator==(const RGBAColor &color) const {return Close_Enough(*this, color, SMALL);} bool operator!=(const RGBAColor &color) const {return !Close_Enough(*this, color, SMALL);} RGBAColor& operator=(const RGBAColor &color) { Check_Object(this); Check_Object(&color); red = color.red; green = color.green; blue = color.blue; alpha = color.alpha; return *this; } RGBAColor& operator=(const HSVAColor &color); RGBAColor& Combine( const RGBAColor& c1, Scalar t1, const RGBAColor& c2, Scalar t2 ) { Check_Pointer(this); Check_Object(&c1); Check_Object(&c2); red = c1.red*t1 + c2.red*t2; green = c1.green*t1 + c2.green*t2; blue = c1.blue*t1 + c2.blue*t2; alpha = c1.alpha*t1 + c2.alpha*t2; return *this; } RGBAColor& Lerp( const RGBAColor& c1, const RGBAColor& c2, Scalar t ) { Check_Pointer(this); Check_Object(&c1); Check_Object(&c2); red = c1.red + t*(c2.red-c1.red); green = c1.green + t*(c2.green-c1.green); blue = c1.blue + t*(c2.blue-c1.blue); alpha = c1.alpha + t*(c2.alpha-c1.alpha); return *this; } // // Support functions // #if !defined(Spew) friend void ::Spew( const char* group, const RGBAColor &color ); #endif }; //~~~~~~~~~~~~~~~~~~~~~~~~~~ RGBAColor functions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ void Convert_From_Ascii( const char *str, RGBAColor *color ); //########################################################################## //############## HSVColor ############################################ //########################################################################## class HSVColor { friend class HSVAColor; public: static const HSVColor Unassigned; Scalar hue, saturation, value; HSVColor() {hue = saturation = value = -1.0f;} HSVColor( Scalar h, Scalar s, Scalar v ) {hue = h; saturation = s; value = v;} friend bool Close_Enough( const HSVColor &c1, const HSVColor &c2, Scalar e = SMALL ); bool operator==(const HSVColor &color) const {Check_Object(this); return Close_Enough(*this, color, SMALL);} bool operator!=(const HSVColor &color) const {Check_Object(this); return !Close_Enough(*this, color, SMALL);} HSVColor& operator=(const RGBColor &color); HSVColor& operator=(const HSVColor &color) { Check_Object(this); Check_Object(&color); hue = color.hue; saturation = color.saturation; value = color.value; return *this; } void TestInstance() const {} HSVColor& Combine( const HSVColor& c1, Scalar t1, const HSVColor& c2, Scalar t2 ) { Check_Pointer(this); Check_Object(&c1); Check_Object(&c2); hue = c1.hue*t1 + c2.hue*t2; saturation = c1.saturation*t1 + c2.saturation*t2; value = c1.value*t1 + c2.value*t2; return *this; } HSVColor& Lerp( const HSVColor& c1, const HSVColor& c2, Scalar t ) { Check_Pointer(this); Check_Object(&c1); Check_Object(&c2); hue = c1.hue + t*(c2.hue-c1.hue); saturation = c1.saturation + t*(c2.saturation-c1.saturation); value = c1.value + t*(c2.value-c1.value); return *this; } // // Support functions // #if !defined(Spew) friend void ::Spew( const char* group, const HSVColor &color ); #endif }; //~~~~~~~~~~~~~~~~~~~~~~~~~~ HSVColor functions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ void Convert_From_Ascii( const char *str, HSVColor *color ); //########################################################################## //############## HSVAColor ########################################### //########################################################################## class HSVAColor: public HSVColor { public: static const HSVAColor Unassigned; Scalar alpha; HSVAColor(): HSVColor() {alpha = -1.0f;} HSVAColor( Scalar h, Scalar s, Scalar v, Scalar a ): HSVColor(h, s, v) {alpha = a;} friend bool Close_Enough( const HSVAColor &c1, const HSVAColor &c2, Scalar e = SMALL ); bool operator==(const HSVAColor &color) const {return Close_Enough(*this, color, SMALL);} bool operator!=(const HSVAColor &color) const {return !Close_Enough(*this, color, SMALL);} HSVAColor& operator=(const RGBAColor &color) { Check_Object(this); Check_Object(&color); HSVColor::operator=(color); alpha = color.alpha; return *this; } HSVAColor& operator=(const HSVAColor &color) { Check_Object(this); Check_Object(&color); hue = color.hue; saturation = color.saturation; value = color.value; alpha = color.alpha; return *this; } HSVAColor& Combine( const HSVAColor& c1, Scalar t1, const HSVAColor& c2, Scalar t2 ) { Check_Pointer(this); Check_Object(&c1); Check_Object(&c2); hue = c1.hue*t1 + c2.hue*t2; saturation = c1.saturation*t1 + c2.saturation*t2; value = c1.value*t1 + c2.value*t2; alpha = c1.alpha*t1 + c2.alpha*t2; return *this; } HSVAColor& Lerp( const HSVAColor& c1, const HSVAColor& c2, Scalar t ) { Check_Pointer(this); Check_Object(&c1); Check_Object(&c2); hue = c1.hue + t*(c2.hue-c1.hue); saturation = c1.saturation + t*(c2.saturation-c1.saturation); value = c1.value + t*(c2.value-c1.value); alpha = c1.alpha + t*(c2.alpha-c1.alpha); return *this; } // // Support functions // #if !defined(Spew) friend void ::Spew( const char* group, const HSVAColor &color ); #endif }; //~~~~~~~~~~~~~~~~~~~~~~~~~~ HSVAColor functions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ void Convert_From_Ascii( const char *str, HSVAColor *color ); inline RGBAColor& RGBAColor::operator=(const HSVAColor &color) { Check_Object(this); Check_Object(&color); RGBColor::operator=(color); alpha = color.alpha; return *this; } } namespace MemoryStreamIO { inline Stuff::MemoryStream& Read( Stuff::MemoryStream* stream, Stuff::RGBColor *output ) {return stream->ReadBytes(output, sizeof(*output));} inline Stuff::MemoryStream& Write( Stuff::MemoryStream* stream, const Stuff::RGBColor *input ) {return stream->WriteBytes(input, sizeof(*input));} inline Stuff::MemoryStream& Read( Stuff::MemoryStream* stream, Stuff::RGBAColor *output ) {return stream->ReadBytes(output, sizeof(*output));} inline Stuff::MemoryStream& Write( Stuff::MemoryStream* stream, const Stuff::RGBAColor *input ) {return stream->WriteBytes(input, sizeof(*input));} inline Stuff::MemoryStream& Read( Stuff::MemoryStream* stream, Stuff::HSVColor *output ) {return stream->ReadBytes(output, sizeof(*output));} inline Stuff::MemoryStream& Write( Stuff::MemoryStream* stream, const Stuff::HSVColor *input ) {return stream->WriteBytes(input, sizeof(*input));} inline Stuff::MemoryStream& Read( Stuff::MemoryStream* stream, Stuff::HSVAColor *output ) {return stream->ReadBytes(output, sizeof(*output));} inline Stuff::MemoryStream& Write( Stuff::MemoryStream* stream, const Stuff::HSVAColor *input ) {return stream->WriteBytes(input, sizeof(*input));} }