538 lines
13 KiB
C++
538 lines
13 KiB
C++
// Copyright (C) 2007 Id Software, Inc.
|
|
//
|
|
|
|
#ifndef __COLOR_H__
|
|
#define __COLOR_H__
|
|
|
|
class sdColor3 {
|
|
public:
|
|
float r;
|
|
float g;
|
|
float b;
|
|
|
|
sdColor3();
|
|
explicit sdColor3( const float r, const float g, const float b );
|
|
explicit sdColor3( const idVec3& rhs );
|
|
|
|
void Set( const float r, const float g, const float b );
|
|
void Zero();
|
|
|
|
void Normalize( float scaleFactor = 1.0f );
|
|
|
|
void ToBytes( byte* bytes ) const;
|
|
void FromBytes( byte* bytes );
|
|
|
|
idVec3& ToVec3();
|
|
const idVec3& ToVec3() const;
|
|
|
|
|
|
int GetDimension() const;
|
|
|
|
float operator[]( const int index ) const;
|
|
float& operator[]( const int index );
|
|
sdColor3 operator-() const;
|
|
sdColor3 operator*( const float rhs ) const;
|
|
sdColor3 operator/( const float rhs ) const;
|
|
sdColor3 operator+( const sdColor3& rhs ) const;
|
|
sdColor3 operator-( const sdColor3& rhs ) const;
|
|
sdColor3& operator+=( const sdColor3& rhs );
|
|
sdColor3& operator-=( const sdColor3& rhs );
|
|
sdColor3& operator/=( const sdColor3& rhs );
|
|
sdColor3& operator/=( const float rhs );
|
|
sdColor3& operator*=( const float rhs );
|
|
|
|
sdColor3& operator=( const idVec3& rhs );
|
|
|
|
friend sdColor3 operator*( const float a1, const sdColor3 b1 );
|
|
|
|
bool Compare( const sdColor3& rhs ) const; // exact compare, no epsilon
|
|
bool Compare( const sdColor3& rhs, const float epsilon ) const; // compare with epsilon
|
|
bool operator==( const sdColor3& rhs ) const; // exact compare, no epsilon
|
|
bool operator!=( const sdColor3& rhs ) const; // exact compare, no epsilon
|
|
|
|
const float* ToFloatPtr() const;
|
|
float* ToFloatPtr();
|
|
const char* ToString( int precision = 2 ) const;
|
|
|
|
void Lerp( const sdColor3& v1, const sdColor3& v2, const float l );
|
|
|
|
// packs color floats in the range [0,1] into an integer
|
|
static dword PackColor( const idVec3& color );
|
|
static void UnpackColor( const dword color, idVec3& unpackedColor );
|
|
|
|
static const sdColor3 black;
|
|
static const sdColor3 white;
|
|
static const sdColor3 red;
|
|
static const sdColor3 green;
|
|
static const sdColor3 blue;
|
|
static const sdColor3 yellow;
|
|
static const sdColor3 magenta;
|
|
static const sdColor3 cyan;
|
|
static const sdColor3 orange;
|
|
static const sdColor3 purple;
|
|
static const sdColor3 pink;
|
|
static const sdColor3 brown;
|
|
static const sdColor3 ltGrey;
|
|
static const sdColor3 mdGrey;
|
|
static const sdColor3 dkGrey;
|
|
|
|
static const sdColor3 ltBlue;
|
|
static const sdColor3 dkRed;
|
|
};
|
|
|
|
ID_INLINE sdColor3::sdColor3() {
|
|
}
|
|
|
|
ID_INLINE sdColor3::sdColor3( const float r, const float g, const float b ) {
|
|
this->r = r;
|
|
this->g = g;
|
|
this->b = b;
|
|
}
|
|
|
|
ID_INLINE sdColor3::sdColor3( const idVec3& rhs ) {
|
|
this->r = rhs.x;
|
|
this->g = rhs.y;
|
|
this->b = rhs.z;
|
|
}
|
|
|
|
ID_INLINE void sdColor3::ToBytes( byte* bytes ) const {
|
|
for( int i = 0; i < GetDimension(); i++ ) {
|
|
bytes[ i ] = idMath::Ftob( (*this)[ i ] * 255.0f );
|
|
}
|
|
}
|
|
|
|
ID_INLINE void sdColor3::FromBytes( byte* bytes ) {
|
|
for( int i = 0; i < GetDimension(); i++ ) {
|
|
(*this)[ i ] = bytes[ i ] / 255.0f;
|
|
}
|
|
}
|
|
|
|
ID_INLINE void sdColor3::Set( const float r, const float g, const float b ) {
|
|
this->r = r;
|
|
this->g = g;
|
|
this->b = b;
|
|
}
|
|
|
|
ID_INLINE void sdColor3::Normalize( float scaleFactor ) {
|
|
r = idMath::ClampFloat( 0.0f, 1.0f, r * scaleFactor );
|
|
g = idMath::ClampFloat( 0.0f, 1.0f, g * scaleFactor );
|
|
b = idMath::ClampFloat( 0.0f, 1.0f, b * scaleFactor );
|
|
}
|
|
|
|
ID_INLINE void sdColor3::Zero() {
|
|
r = g = b = 0.0f;
|
|
}
|
|
|
|
ID_INLINE int sdColor3::GetDimension() const {
|
|
return 3;
|
|
}
|
|
|
|
ID_INLINE float sdColor3::operator[]( int index ) const {
|
|
assert( index >= 0 && index < 3 );
|
|
return ( &r )[ index ];
|
|
}
|
|
|
|
ID_INLINE float& sdColor3::operator[]( int index ) {
|
|
assert( index >= 0 && index < 3 );
|
|
return ( &r )[ index ];
|
|
}
|
|
|
|
ID_INLINE sdColor3 sdColor3::operator-() const {
|
|
return sdColor3( -r, -g, -b );
|
|
}
|
|
|
|
ID_INLINE sdColor3 sdColor3::operator-( const sdColor3& rhs ) const {
|
|
return sdColor3( r - rhs.r, g - rhs.g, b - rhs.b );
|
|
}
|
|
|
|
ID_INLINE sdColor3 sdColor3::operator*( const float rhs ) const {
|
|
return sdColor3( r * rhs, g * rhs, b * rhs );
|
|
}
|
|
|
|
ID_INLINE sdColor3 sdColor3::operator/( const float rhs ) const {
|
|
float inva = 1.0f / rhs;
|
|
return sdColor3( r * inva, g * inva, b * inva );
|
|
}
|
|
|
|
ID_INLINE sdColor3 operator*( const float a1, const sdColor3 b1 ) {
|
|
return sdColor3( b1.r * a1, b1.g * a1, b1.b * a1 );
|
|
}
|
|
|
|
ID_INLINE sdColor3 sdColor3::operator+( const sdColor3& rhs ) const {
|
|
return sdColor3( r + rhs.r, g + rhs.g, b + rhs.b );
|
|
}
|
|
|
|
ID_INLINE sdColor3& sdColor3::operator+=( const sdColor3& rhs ) {
|
|
r += rhs.r;
|
|
g += rhs.g;
|
|
b += rhs.b;
|
|
|
|
return *this;
|
|
}
|
|
|
|
ID_INLINE sdColor3& sdColor3::operator/=( const sdColor3& rhs ) {
|
|
r /= rhs.r;
|
|
g /= rhs.g;
|
|
b /= rhs.b;
|
|
|
|
return *this;
|
|
}
|
|
|
|
ID_INLINE sdColor3& sdColor3::operator/=( const float rhs ) {
|
|
float inva = 1.0f / rhs;
|
|
r *= inva;
|
|
g *= inva;
|
|
b *= inva;
|
|
|
|
return *this;
|
|
}
|
|
|
|
ID_INLINE sdColor3& sdColor3::operator-=( const sdColor3& rhs ) {
|
|
r -= rhs.r;
|
|
g -= rhs.g;
|
|
b -= rhs.b;
|
|
|
|
return *this;
|
|
}
|
|
|
|
ID_INLINE sdColor3& sdColor3::operator*=( const float rhs ) {
|
|
r *= rhs;
|
|
g *= rhs;
|
|
b *= rhs;
|
|
|
|
return *this;
|
|
}
|
|
|
|
ID_INLINE bool sdColor3::Compare( const sdColor3& rhs ) const {
|
|
return ( ( r == rhs.r ) && ( g == rhs.g ) && ( b == rhs.b ) );
|
|
}
|
|
|
|
ID_INLINE bool sdColor3::Compare( const sdColor3& rhs, const float epsilon ) const {
|
|
if ( idMath::Fabs( r - rhs.r ) > epsilon ) {
|
|
return false;
|
|
}
|
|
|
|
if ( idMath::Fabs( g - rhs.g ) > epsilon ) {
|
|
return false;
|
|
}
|
|
|
|
if ( idMath::Fabs( b - rhs.b ) > epsilon ) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
ID_INLINE bool sdColor3::operator==( const sdColor3& rhs ) const {
|
|
return Compare( rhs );
|
|
}
|
|
|
|
ID_INLINE bool sdColor3::operator!=( const sdColor3& rhs ) const {
|
|
return !Compare( rhs );
|
|
}
|
|
|
|
ID_INLINE const float* sdColor3::ToFloatPtr() const {
|
|
return &r;
|
|
}
|
|
|
|
ID_INLINE float* sdColor3::ToFloatPtr() {
|
|
return &r;
|
|
}
|
|
|
|
ID_INLINE sdColor3& sdColor3::operator=( const idVec3& rhs ) {
|
|
r = rhs.x;
|
|
g = rhs.y;
|
|
b = rhs.z;
|
|
return *this;
|
|
}
|
|
|
|
ID_INLINE const idVec3& sdColor3::ToVec3() const {
|
|
return *reinterpret_cast< const idVec3 * >( this );
|
|
}
|
|
|
|
ID_INLINE idVec3& sdColor3::ToVec3() {
|
|
return *reinterpret_cast< idVec3 * >( this );
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
class sdColor4 {
|
|
public:
|
|
float r;
|
|
float g;
|
|
float b;
|
|
float a;
|
|
|
|
sdColor4();
|
|
explicit sdColor4( const float r, const float g, const float b, const float a );
|
|
explicit sdColor4( const idVec4& rhs );
|
|
|
|
void Set( const float r, const float g, const float b, const float a );
|
|
void Zero();
|
|
|
|
void Normalize( float scaleFactor = 1.0f );
|
|
|
|
int GetDimension() const;
|
|
|
|
void ToBytes( byte* bytes ) const;
|
|
void FromBytes( byte* bytes );
|
|
|
|
idVec4& ToVec4();
|
|
const idVec4& ToVec4() const;
|
|
|
|
float operator[]( const int index ) const;
|
|
float& operator[]( const int index );
|
|
sdColor4 operator-() const;
|
|
sdColor4 operator*( const float rhs ) const;
|
|
sdColor4 operator/( const float rhs ) const;
|
|
sdColor4 operator+( const sdColor4& rhs ) const;
|
|
sdColor4 operator-( const sdColor4& rhs ) const;
|
|
sdColor4& operator+=( const sdColor4& rhs );
|
|
sdColor4& operator-=( const sdColor4& rhs );
|
|
sdColor4& operator/=( const sdColor4& rhs );
|
|
sdColor4& operator/=( const float rhs );
|
|
sdColor4& operator*=( const float rhs );
|
|
|
|
sdColor4& operator=( const idVec4& rhs );
|
|
|
|
friend sdColor4 operator*( const float a1, const sdColor4 b1 );
|
|
|
|
bool Compare( const sdColor4& rhs ) const; // exact compare, no epsilon
|
|
bool Compare( const sdColor4& rhs, const float epsilon ) const; // compare with epsilon
|
|
bool operator==( const sdColor4& rhs ) const; // exact compare, no epsilon
|
|
bool operator!=( const sdColor4& rhs ) const; // exact compare, no epsilon
|
|
|
|
const float* ToFloatPtr() const;
|
|
float* ToFloatPtr();
|
|
const char* ToString( int precision = 2 ) const;
|
|
|
|
void Lerp( const sdColor4& v1, const sdColor4& v2, const float l );
|
|
|
|
static dword PackColor( const idVec3& color, float alpha );
|
|
static dword PackColor( const idVec4& color );
|
|
static void UnpackColor( const dword color, idVec4& unpackedColor );
|
|
|
|
const sdColor3& ToColor3() const;
|
|
sdColor3& ToColor3();
|
|
|
|
static const sdColor4 black;
|
|
static const sdColor4 white;
|
|
static const sdColor4 red;
|
|
static const sdColor4 green;
|
|
static const sdColor4 blue;
|
|
static const sdColor4 yellow;
|
|
static const sdColor4 magenta;
|
|
static const sdColor4 cyan;
|
|
static const sdColor4 orange;
|
|
static const sdColor4 purple;
|
|
static const sdColor4 pink;
|
|
static const sdColor4 brown;
|
|
static const sdColor4 ltGrey;
|
|
static const sdColor4 mdGrey;
|
|
static const sdColor4 dkGrey;
|
|
|
|
static const sdColor4 ltBlue;
|
|
static const sdColor4 dkRed;
|
|
};
|
|
|
|
ID_INLINE sdColor4::sdColor4() {
|
|
}
|
|
|
|
ID_INLINE sdColor4::sdColor4( const float r, const float g, const float b, const float a ) {
|
|
this->r = r;
|
|
this->g = g;
|
|
this->b = b;
|
|
this->a = a;
|
|
}
|
|
|
|
ID_INLINE sdColor4::sdColor4( const idVec4& rhs ) {
|
|
this->r = rhs.x;
|
|
this->g = rhs.y;
|
|
this->b = rhs.z;
|
|
this->a = rhs.w;
|
|
}
|
|
|
|
ID_INLINE void sdColor4::ToBytes( byte* bytes ) const {
|
|
for( int i = 0; i < GetDimension(); i++ ) {
|
|
bytes[ i ] = idMath::Ftob( (*this)[ i ] * 255.0f );
|
|
}
|
|
}
|
|
|
|
ID_INLINE void sdColor4::FromBytes( byte* bytes ) {
|
|
for( int i = 0; i < GetDimension(); i++ ) {
|
|
(*this)[ i ] = bytes[ i ] / 255.0f;
|
|
}
|
|
}
|
|
|
|
ID_INLINE void sdColor4::Set( const float r, const float g, const float b, const float a ) {
|
|
this->r = r;
|
|
this->g = g;
|
|
this->b = b;
|
|
this->a = a;
|
|
}
|
|
|
|
ID_INLINE void sdColor4::Normalize( float scaleFactor ) {
|
|
r = idMath::ClampFloat( 0.0f, 1.0f, r * scaleFactor );
|
|
g = idMath::ClampFloat( 0.0f, 1.0f, g * scaleFactor );
|
|
b = idMath::ClampFloat( 0.0f, 1.0f, b * scaleFactor );
|
|
a = idMath::ClampFloat( 0.0f, 1.0f, a * scaleFactor );
|
|
}
|
|
|
|
ID_INLINE void sdColor4::Zero() {
|
|
r = g = b = a = 0.0f;
|
|
}
|
|
|
|
ID_INLINE int sdColor4::GetDimension() const {
|
|
return 4;
|
|
}
|
|
|
|
ID_INLINE float sdColor4::operator[]( int index ) const {
|
|
assert( index >= 0 && index < 4 );
|
|
return ( &r )[ index ];
|
|
}
|
|
|
|
ID_INLINE float& sdColor4::operator[]( int index ) {
|
|
assert( index >= 0 && index < 4 );
|
|
return ( &r )[ index ];
|
|
}
|
|
|
|
ID_INLINE sdColor4 sdColor4::operator-() const {
|
|
return sdColor4( -r, -g, -b, -a );
|
|
}
|
|
|
|
ID_INLINE sdColor4 sdColor4::operator-( const sdColor4& rhs ) const {
|
|
return sdColor4( r - rhs.r, g - rhs.g, b - rhs.b, a - rhs.a );
|
|
}
|
|
|
|
ID_INLINE sdColor4 sdColor4::operator*( const float rhs ) const {
|
|
return sdColor4( r * rhs, g * rhs, b * rhs, a * rhs );
|
|
}
|
|
|
|
ID_INLINE sdColor4 sdColor4::operator/( const float rhs ) const {
|
|
float inva = 1.0f / rhs;
|
|
return sdColor4( r * inva, g * inva, b * inva, a * inva );
|
|
}
|
|
|
|
ID_INLINE sdColor4 operator*( const float a1, const sdColor4 b1 ) {
|
|
return sdColor4( b1.r * a1, b1.g * a1, b1.b * a1, b1.a * a1 );
|
|
}
|
|
|
|
ID_INLINE sdColor4 sdColor4::operator+( const sdColor4& rhs ) const {
|
|
return sdColor4( r + rhs.r, g + rhs.g, b + rhs.b, a + rhs.a );
|
|
}
|
|
|
|
ID_INLINE sdColor4& sdColor4::operator+=( const sdColor4& rhs ) {
|
|
r += rhs.r;
|
|
g += rhs.g;
|
|
b += rhs.b;
|
|
a += rhs.a;
|
|
|
|
return *this;
|
|
}
|
|
|
|
ID_INLINE sdColor4& sdColor4::operator/=( const sdColor4& rhs ) {
|
|
r /= rhs.r;
|
|
g /= rhs.g;
|
|
b /= rhs.b;
|
|
a /= rhs.a;
|
|
|
|
return *this;
|
|
}
|
|
|
|
ID_INLINE sdColor4& sdColor4::operator/=( const float rhs ) {
|
|
float inva = 1.0f / rhs;
|
|
r *= inva;
|
|
g *= inva;
|
|
b *= inva;
|
|
a *= inva;
|
|
|
|
return *this;
|
|
}
|
|
|
|
ID_INLINE sdColor4& sdColor4::operator-=( const sdColor4& rhs ) {
|
|
r -= rhs.r;
|
|
g -= rhs.g;
|
|
b -= rhs.b;
|
|
a -= rhs.a;
|
|
|
|
return *this;
|
|
}
|
|
|
|
ID_INLINE sdColor4& sdColor4::operator*=( const float rhs ) {
|
|
r *= rhs;
|
|
g *= rhs;
|
|
b *= rhs;
|
|
a *= rhs;
|
|
|
|
return *this;
|
|
}
|
|
|
|
ID_INLINE bool sdColor4::Compare( const sdColor4& rhs ) const {
|
|
return ( ( r == rhs.r ) && ( g == rhs.g ) && ( b == rhs.b ) && a == rhs.a );
|
|
}
|
|
|
|
ID_INLINE bool sdColor4::Compare( const sdColor4& rhs, const float epsilon ) const {
|
|
if ( idMath::Fabs( r - rhs.r ) > epsilon ) {
|
|
return false;
|
|
}
|
|
|
|
if ( idMath::Fabs( g - rhs.g ) > epsilon ) {
|
|
return false;
|
|
}
|
|
|
|
if ( idMath::Fabs( b - rhs.b ) > epsilon ) {
|
|
return false;
|
|
}
|
|
|
|
if ( idMath::Fabs( a - rhs.a ) > epsilon ) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
ID_INLINE bool sdColor4::operator==( const sdColor4& rhs ) const {
|
|
return Compare( rhs );
|
|
}
|
|
|
|
ID_INLINE bool sdColor4::operator!=( const sdColor4& rhs ) const {
|
|
return !Compare( rhs );
|
|
}
|
|
|
|
ID_INLINE const float* sdColor4::ToFloatPtr() const {
|
|
return &r;
|
|
}
|
|
|
|
ID_INLINE float* sdColor4::ToFloatPtr() {
|
|
return &r;
|
|
}
|
|
|
|
ID_INLINE sdColor4& sdColor4::operator=( const idVec4& rhs ) {
|
|
r = rhs.x;
|
|
g = rhs.y;
|
|
b = rhs.z;
|
|
a = rhs.w;
|
|
return *this;
|
|
}
|
|
|
|
ID_INLINE const sdColor3 &sdColor4::ToColor3() const {
|
|
return *reinterpret_cast< const sdColor3 * >( this );
|
|
}
|
|
|
|
ID_INLINE sdColor3 &sdColor4::ToColor3() {
|
|
return *reinterpret_cast< sdColor3 * >( this );
|
|
}
|
|
|
|
ID_INLINE const idVec4& sdColor4::ToVec4() const {
|
|
return *reinterpret_cast< const idVec4 * >( this );
|
|
}
|
|
|
|
ID_INLINE idVec4& sdColor4::ToVec4() {
|
|
return *reinterpret_cast< idVec4 * >( this );
|
|
}
|
|
|
|
|
|
#endif // __COLOR_H__
|