From 393b5cd1dc438872af89d334ef6e5fcc59f27d47 Mon Sep 17 00:00:00 2001 From: David Walter Seikel Date: Sun, 13 Jan 2013 17:24:39 +1000 Subject: Added Irrlicht 1.8, but without all the Windows binaries. --- libraries/irrlicht-1.8/include/SColor.h | 697 ++++++++++++++++++++++++++++++++ 1 file changed, 697 insertions(+) create mode 100644 libraries/irrlicht-1.8/include/SColor.h (limited to 'libraries/irrlicht-1.8/include/SColor.h') diff --git a/libraries/irrlicht-1.8/include/SColor.h b/libraries/irrlicht-1.8/include/SColor.h new file mode 100644 index 0000000..b61bbef --- /dev/null +++ b/libraries/irrlicht-1.8/include/SColor.h @@ -0,0 +1,697 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __COLOR_H_INCLUDED__ +#define __COLOR_H_INCLUDED__ + +#include "irrTypes.h" +#include "irrMath.h" + +namespace irr +{ +namespace video +{ + //! An enum for the color format of textures used by the Irrlicht Engine. + /** A color format specifies how color information is stored. */ + enum ECOLOR_FORMAT + { + //! 16 bit color format used by the software driver. + /** It is thus preferred by all other irrlicht engine video drivers. + There are 5 bits for every color component, and a single bit is left + for alpha information. */ + ECF_A1R5G5B5 = 0, + + //! Standard 16 bit color format. + ECF_R5G6B5, + + //! 24 bit color, no alpha channel, but 8 bit for red, green and blue. + ECF_R8G8B8, + + //! Default 32 bit color format. 8 bits are used for every component: red, green, blue and alpha. + ECF_A8R8G8B8, + + /** Floating Point formats. The following formats may only be used for render target textures. */ + + //! 16 bit floating point format using 16 bits for the red channel. + ECF_R16F, + + //! 32 bit floating point format using 16 bits for the red channel and 16 bits for the green channel. + ECF_G16R16F, + + //! 64 bit floating point format 16 bits are used for the red, green, blue and alpha channels. + ECF_A16B16G16R16F, + + //! 32 bit floating point format using 32 bits for the red channel. + ECF_R32F, + + //! 64 bit floating point format using 32 bits for the red channel and 32 bits for the green channel. + ECF_G32R32F, + + //! 128 bit floating point format. 32 bits are used for the red, green, blue and alpha channels. + ECF_A32B32G32R32F, + + //! Unknown color format: + ECF_UNKNOWN + }; + + + //! Creates a 16 bit A1R5G5B5 color + inline u16 RGBA16(u32 r, u32 g, u32 b, u32 a=0xFF) + { + return (u16)((a & 0x80) << 8 | + (r & 0xF8) << 7 | + (g & 0xF8) << 2 | + (b & 0xF8) >> 3); + } + + + //! Creates a 16 bit A1R5G5B5 color + inline u16 RGB16(u32 r, u32 g, u32 b) + { + return RGBA16(r,g,b); + } + + + //! Creates a 16bit A1R5G5B5 color, based on 16bit input values + inline u16 RGB16from16(u16 r, u16 g, u16 b) + { + return (0x8000 | + (r & 0x1F) << 10 | + (g & 0x1F) << 5 | + (b & 0x1F)); + } + + + //! Converts a 32bit (X8R8G8B8) color to a 16bit A1R5G5B5 color + inline u16 X8R8G8B8toA1R5G5B5(u32 color) + { + return (u16)(0x8000 | + ( color & 0x00F80000) >> 9 | + ( color & 0x0000F800) >> 6 | + ( color & 0x000000F8) >> 3); + } + + + //! Converts a 32bit (A8R8G8B8) color to a 16bit A1R5G5B5 color + inline u16 A8R8G8B8toA1R5G5B5(u32 color) + { + return (u16)(( color & 0x80000000) >> 16| + ( color & 0x00F80000) >> 9 | + ( color & 0x0000F800) >> 6 | + ( color & 0x000000F8) >> 3); + } + + + //! Converts a 32bit (A8R8G8B8) color to a 16bit R5G6B5 color + inline u16 A8R8G8B8toR5G6B5(u32 color) + { + return (u16)(( color & 0x00F80000) >> 8 | + ( color & 0x0000FC00) >> 5 | + ( color & 0x000000F8) >> 3); + } + + + //! Convert A8R8G8B8 Color from A1R5G5B5 color + /** build a nicer 32bit Color by extending dest lower bits with source high bits. */ + inline u32 A1R5G5B5toA8R8G8B8(u16 color) + { + return ( (( -( (s32) color & 0x00008000 ) >> (s32) 31 ) & 0xFF000000 ) | + (( color & 0x00007C00 ) << 9) | (( color & 0x00007000 ) << 4) | + (( color & 0x000003E0 ) << 6) | (( color & 0x00000380 ) << 1) | + (( color & 0x0000001F ) << 3) | (( color & 0x0000001C ) >> 2) + ); + } + + + //! Returns A8R8G8B8 Color from R5G6B5 color + inline u32 R5G6B5toA8R8G8B8(u16 color) + { + return 0xFF000000 | + ((color & 0xF800) << 8)| + ((color & 0x07E0) << 5)| + ((color & 0x001F) << 3); + } + + + //! Returns A1R5G5B5 Color from R5G6B5 color + inline u16 R5G6B5toA1R5G5B5(u16 color) + { + return 0x8000 | (((color & 0xFFC0) >> 1) | (color & 0x1F)); + } + + + //! Returns R5G6B5 Color from A1R5G5B5 color + inline u16 A1R5G5B5toR5G6B5(u16 color) + { + return (((color & 0x7FE0) << 1) | (color & 0x1F)); + } + + + + //! Returns the alpha component from A1R5G5B5 color + /** In Irrlicht, alpha refers to opacity. + \return The alpha value of the color. 0 is transparent, 1 is opaque. */ + inline u32 getAlpha(u16 color) + { + return ((color >> 15)&0x1); + } + + + //! Returns the red component from A1R5G5B5 color. + /** Shift left by 3 to get 8 bit value. */ + inline u32 getRed(u16 color) + { + return ((color >> 10)&0x1F); + } + + + //! Returns the green component from A1R5G5B5 color + /** Shift left by 3 to get 8 bit value. */ + inline u32 getGreen(u16 color) + { + return ((color >> 5)&0x1F); + } + + + //! Returns the blue component from A1R5G5B5 color + /** Shift left by 3 to get 8 bit value. */ + inline u32 getBlue(u16 color) + { + return (color & 0x1F); + } + + + //! Returns the average from a 16 bit A1R5G5B5 color + inline s32 getAverage(s16 color) + { + return ((getRed(color)<<3) + (getGreen(color)<<3) + (getBlue(color)<<3)) / 3; + } + + + //! Class representing a 32 bit ARGB color. + /** The color values for alpha, red, green, and blue are + stored in a single u32. So all four values may be between 0 and 255. + Alpha in Irrlicht is opacity, so 0 is fully transparent, 255 is fully opaque (solid). + This class is used by most parts of the Irrlicht Engine + to specify a color. Another way is using the class SColorf, which + stores the color values in 4 floats. + This class must consist of only one u32 and must not use virtual functions. + */ + class SColor + { + public: + + //! Constructor of the Color. Does nothing. + /** The color value is not initialized to save time. */ + SColor() {} + + //! Constructs the color from 4 values representing the alpha, red, green and blue component. + /** Must be values between 0 and 255. */ + SColor (u32 a, u32 r, u32 g, u32 b) + : color(((a & 0xff)<<24) | ((r & 0xff)<<16) | ((g & 0xff)<<8) | (b & 0xff)) {} + + //! Constructs the color from a 32 bit value. Could be another color. + SColor(u32 clr) + : color(clr) {} + + //! Returns the alpha component of the color. + /** The alpha component defines how opaque a color is. + \return The alpha value of the color. 0 is fully transparent, 255 is fully opaque. */ + u32 getAlpha() const { return color>>24; } + + //! Returns the red component of the color. + /** \return Value between 0 and 255, specifying how red the color is. + 0 means no red, 255 means full red. */ + u32 getRed() const { return (color>>16) & 0xff; } + + //! Returns the green component of the color. + /** \return Value between 0 and 255, specifying how green the color is. + 0 means no green, 255 means full green. */ + u32 getGreen() const { return (color>>8) & 0xff; } + + //! Returns the blue component of the color. + /** \return Value between 0 and 255, specifying how blue the color is. + 0 means no blue, 255 means full blue. */ + u32 getBlue() const { return color & 0xff; } + + //! Get lightness of the color in the range [0,255] + f32 getLightness() const + { + return 0.5f*(core::max_(core::max_(getRed(),getGreen()),getBlue())+core::min_(core::min_(getRed(),getGreen()),getBlue())); + } + + //! Get luminance of the color in the range [0,255]. + f32 getLuminance() const + { + return 0.3f*getRed() + 0.59f*getGreen() + 0.11f*getBlue(); + } + + //! Get average intensity of the color in the range [0,255]. + u32 getAverage() const + { + return ( getRed() + getGreen() + getBlue() ) / 3; + } + + //! Sets the alpha component of the Color. + /** The alpha component defines how transparent a color should be. + \param a The alpha value of the color. 0 is fully transparent, 255 is fully opaque. */ + void setAlpha(u32 a) { color = ((a & 0xff)<<24) | (color & 0x00ffffff); } + + //! Sets the red component of the Color. + /** \param r: Has to be a value between 0 and 255. + 0 means no red, 255 means full red. */ + void setRed(u32 r) { color = ((r & 0xff)<<16) | (color & 0xff00ffff); } + + //! Sets the green component of the Color. + /** \param g: Has to be a value between 0 and 255. + 0 means no green, 255 means full green. */ + void setGreen(u32 g) { color = ((g & 0xff)<<8) | (color & 0xffff00ff); } + + //! Sets the blue component of the Color. + /** \param b: Has to be a value between 0 and 255. + 0 means no blue, 255 means full blue. */ + void setBlue(u32 b) { color = (b & 0xff) | (color & 0xffffff00); } + + //! Calculates a 16 bit A1R5G5B5 value of this color. + /** \return 16 bit A1R5G5B5 value of this color. */ + u16 toA1R5G5B5() const { return A8R8G8B8toA1R5G5B5(color); } + + //! Converts color to OpenGL color format + /** From ARGB to RGBA in 4 byte components for endian aware + passing to OpenGL + \param dest: address where the 4x8 bit OpenGL color is stored. */ + void toOpenGLColor(u8* dest) const + { + *dest = (u8)getRed(); + *++dest = (u8)getGreen(); + *++dest = (u8)getBlue(); + *++dest = (u8)getAlpha(); + } + + //! Sets all four components of the color at once. + /** Constructs the color from 4 values representing the alpha, + red, green and blue components of the color. Must be values + between 0 and 255. + \param a: Alpha component of the color. The alpha component + defines how transparent a color should be. Has to be a value + between 0 and 255. 255 means not transparent (opaque), 0 means + fully transparent. + \param r: Sets the red component of the Color. Has to be a + value between 0 and 255. 0 means no red, 255 means full red. + \param g: Sets the green component of the Color. Has to be a + value between 0 and 255. 0 means no green, 255 means full + green. + \param b: Sets the blue component of the Color. Has to be a + value between 0 and 255. 0 means no blue, 255 means full blue. */ + void set(u32 a, u32 r, u32 g, u32 b) + { + color = (((a & 0xff)<<24) | ((r & 0xff)<<16) | ((g & 0xff)<<8) | (b & 0xff)); + } + void set(u32 col) { color = col; } + + //! Compares the color to another color. + /** \return True if the colors are the same, and false if not. */ + bool operator==(const SColor& other) const { return other.color == color; } + + //! Compares the color to another color. + /** \return True if the colors are different, and false if they are the same. */ + bool operator!=(const SColor& other) const { return other.color != color; } + + //! comparison operator + /** \return True if this color is smaller than the other one */ + bool operator<(const SColor& other) const { return (color < other.color); } + + //! Adds two colors, result is clamped to 0..255 values + /** \param other Color to add to this color + \return Addition of the two colors, clamped to 0..255 values */ + SColor operator+(const SColor& other) const + { + return SColor(core::min_(getAlpha() + other.getAlpha(), 255u), + core::min_(getRed() + other.getRed(), 255u), + core::min_(getGreen() + other.getGreen(), 255u), + core::min_(getBlue() + other.getBlue(), 255u)); + } + + //! Interpolates the color with a f32 value to another color + /** \param other: Other color + \param d: value between 0.0f and 1.0f + \return Interpolated color. */ + SColor getInterpolated(const SColor &other, f32 d) const + { + d = core::clamp(d, 0.f, 1.f); + const f32 inv = 1.0f - d; + return SColor((u32)core::round32(other.getAlpha()*inv + getAlpha()*d), + (u32)core::round32(other.getRed()*inv + getRed()*d), + (u32)core::round32(other.getGreen()*inv + getGreen()*d), + (u32)core::round32(other.getBlue()*inv + getBlue()*d)); + } + + //! Returns interpolated color. ( quadratic ) + /** \param c1: first color to interpolate with + \param c2: second color to interpolate with + \param d: value between 0.0f and 1.0f. */ + SColor getInterpolated_quadratic(const SColor& c1, const SColor& c2, f32 d) const + { + // this*(1-d)*(1-d) + 2 * c1 * (1-d) + c2 * d * d; + d = core::clamp(d, 0.f, 1.f); + const f32 inv = 1.f - d; + const f32 mul0 = inv * inv; + const f32 mul1 = 2.f * d * inv; + const f32 mul2 = d * d; + + return SColor( + core::clamp( core::floor32( + getAlpha() * mul0 + c1.getAlpha() * mul1 + c2.getAlpha() * mul2 ), 0, 255 ), + core::clamp( core::floor32( + getRed() * mul0 + c1.getRed() * mul1 + c2.getRed() * mul2 ), 0, 255 ), + core::clamp ( core::floor32( + getGreen() * mul0 + c1.getGreen() * mul1 + c2.getGreen() * mul2 ), 0, 255 ), + core::clamp ( core::floor32( + getBlue() * mul0 + c1.getBlue() * mul1 + c2.getBlue() * mul2 ), 0, 255 )); + } + + //! set the color by expecting data in the given format + /** \param data: must point to valid memory containing color information in the given format + \param format: tells the format in which data is available + */ + void setData(const void *data, ECOLOR_FORMAT format) + { + switch (format) + { + case ECF_A1R5G5B5: + color = A1R5G5B5toA8R8G8B8(*(u16*)data); + break; + case ECF_R5G6B5: + color = R5G6B5toA8R8G8B8(*(u16*)data); + break; + case ECF_A8R8G8B8: + color = *(u32*)data; + break; + case ECF_R8G8B8: + { + u8* p = (u8*)data; + set(255, p[0],p[1],p[2]); + } + break; + default: + color = 0xffffffff; + break; + } + } + + //! Write the color to data in the defined format + /** \param data: target to write the color. Must contain sufficiently large memory to receive the number of bytes neede for format + \param format: tells the format used to write the color into data + */ + void getData(void *data, ECOLOR_FORMAT format) + { + switch(format) + { + case ECF_A1R5G5B5: + { + u16 * dest = (u16*)data; + *dest = video::A8R8G8B8toA1R5G5B5( color ); + } + break; + + case ECF_R5G6B5: + { + u16 * dest = (u16*)data; + *dest = video::A8R8G8B8toR5G6B5( color ); + } + break; + + case ECF_R8G8B8: + { + u8* dest = (u8*)data; + dest[0] = (u8)getRed(); + dest[1] = (u8)getGreen(); + dest[2] = (u8)getBlue(); + } + break; + + case ECF_A8R8G8B8: + { + u32 * dest = (u32*)data; + *dest = color; + } + break; + + default: + break; + } + } + + //! color in A8R8G8B8 Format + u32 color; + }; + + + //! Class representing a color with four floats. + /** The color values for red, green, blue + and alpha are each stored in a 32 bit floating point variable. + So all four values may be between 0.0f and 1.0f. + Another, faster way to define colors is using the class SColor, which + stores the color values in a single 32 bit integer. + */ + class SColorf + { + public: + //! Default constructor for SColorf. + /** Sets red, green and blue to 0.0f and alpha to 1.0f. */ + SColorf() : r(0.0f), g(0.0f), b(0.0f), a(1.0f) {} + + //! Constructs a color from up to four color values: red, green, blue, and alpha. + /** \param r: Red color component. Should be a value between + 0.0f meaning no red and 1.0f, meaning full red. + \param g: Green color component. Should be a value between 0.0f + meaning no green and 1.0f, meaning full green. + \param b: Blue color component. Should be a value between 0.0f + meaning no blue and 1.0f, meaning full blue. + \param a: Alpha color component of the color. The alpha + component defines how transparent a color should be. Has to be + a value between 0.0f and 1.0f, 1.0f means not transparent + (opaque), 0.0f means fully transparent. */ + SColorf(f32 r, f32 g, f32 b, f32 a = 1.0f) : r(r), g(g), b(b), a(a) {} + + //! Constructs a color from 32 bit Color. + /** \param c: 32 bit color from which this SColorf class is + constructed from. */ + SColorf(SColor c) + { + const f32 inv = 1.0f / 255.0f; + r = c.getRed() * inv; + g = c.getGreen() * inv; + b = c.getBlue() * inv; + a = c.getAlpha() * inv; + } + + //! Converts this color to a SColor without floats. + SColor toSColor() const + { + return SColor((u32)core::round32(a*255.0f), (u32)core::round32(r*255.0f), (u32)core::round32(g*255.0f), (u32)core::round32(b*255.0f)); + } + + //! Sets three color components to new values at once. + /** \param rr: Red color component. Should be a value between 0.0f meaning + no red (=black) and 1.0f, meaning full red. + \param gg: Green color component. Should be a value between 0.0f meaning + no green (=black) and 1.0f, meaning full green. + \param bb: Blue color component. Should be a value between 0.0f meaning + no blue (=black) and 1.0f, meaning full blue. */ + void set(f32 rr, f32 gg, f32 bb) {r = rr; g =gg; b = bb; } + + //! Sets all four color components to new values at once. + /** \param aa: Alpha component. Should be a value between 0.0f meaning + fully transparent and 1.0f, meaning opaque. + \param rr: Red color component. Should be a value between 0.0f meaning + no red and 1.0f, meaning full red. + \param gg: Green color component. Should be a value between 0.0f meaning + no green and 1.0f, meaning full green. + \param bb: Blue color component. Should be a value between 0.0f meaning + no blue and 1.0f, meaning full blue. */ + void set(f32 aa, f32 rr, f32 gg, f32 bb) {a = aa; r = rr; g =gg; b = bb; } + + //! Interpolates the color with a f32 value to another color + /** \param other: Other color + \param d: value between 0.0f and 1.0f + \return Interpolated color. */ + SColorf getInterpolated(const SColorf &other, f32 d) const + { + d = core::clamp(d, 0.f, 1.f); + const f32 inv = 1.0f - d; + return SColorf(other.r*inv + r*d, + other.g*inv + g*d, other.b*inv + b*d, other.a*inv + a*d); + } + + //! Returns interpolated color. ( quadratic ) + /** \param c1: first color to interpolate with + \param c2: second color to interpolate with + \param d: value between 0.0f and 1.0f. */ + inline SColorf getInterpolated_quadratic(const SColorf& c1, const SColorf& c2, + f32 d) const + { + d = core::clamp(d, 0.f, 1.f); + // this*(1-d)*(1-d) + 2 * c1 * (1-d) + c2 * d * d; + const f32 inv = 1.f - d; + const f32 mul0 = inv * inv; + const f32 mul1 = 2.f * d * inv; + const f32 mul2 = d * d; + + return SColorf (r * mul0 + c1.r * mul1 + c2.r * mul2, + g * mul0 + c1.g * mul1 + c2.g * mul2, + b * mul0 + c1.b * mul1 + c2.b * mul2, + a * mul0 + c1.a * mul1 + c2.a * mul2); + } + + + //! Sets a color component by index. R=0, G=1, B=2, A=3 + void setColorComponentValue(s32 index, f32 value) + { + switch(index) + { + case 0: r = value; break; + case 1: g = value; break; + case 2: b = value; break; + case 3: a = value; break; + } + } + + //! Returns the alpha component of the color in the range 0.0 (transparent) to 1.0 (opaque) + f32 getAlpha() const { return a; } + + //! Returns the red component of the color in the range 0.0 to 1.0 + f32 getRed() const { return r; } + + //! Returns the green component of the color in the range 0.0 to 1.0 + f32 getGreen() const { return g; } + + //! Returns the blue component of the color in the range 0.0 to 1.0 + f32 getBlue() const { return b; } + + //! red color component + f32 r; + + //! green color component + f32 g; + + //! blue component + f32 b; + + //! alpha color component + f32 a; + }; + + + //! Class representing a color in HSL format + /** The color values for hue, saturation, luminance + are stored in 32bit floating point variables. Hue is in range [0,360], + Luminance and Saturation are in percent [0,100] + */ + class SColorHSL + { + public: + SColorHSL ( f32 h = 0.f, f32 s = 0.f, f32 l = 0.f ) + : Hue ( h ), Saturation ( s ), Luminance ( l ) {} + + void fromRGB(const SColorf &color); + void toRGB(SColorf &color) const; + + f32 Hue; + f32 Saturation; + f32 Luminance; + + private: + inline f32 toRGB1(f32 rm1, f32 rm2, f32 rh) const; + + }; + + inline void SColorHSL::fromRGB(const SColorf &color) + { + const f32 maxVal = core::max_(color.getRed(), color.getGreen(), color.getBlue()); + const f32 minVal = (f32)core::min_(color.getRed(), color.getGreen(), color.getBlue()); + Luminance = (maxVal+minVal)*50; + if (core::equals(maxVal, minVal)) + { + Hue=0.f; + Saturation=0.f; + return; + } + + const f32 delta = maxVal-minVal; + if ( Luminance <= 50 ) + { + Saturation = (delta)/(maxVal+minVal); + } + else + { + Saturation = (delta)/(2-maxVal-minVal); + } + Saturation *= 100; + + if (core::equals(maxVal, color.getRed())) + Hue = (color.getGreen()-color.getBlue())/delta; + else if (core::equals(maxVal, color.getGreen())) + Hue = 2+((color.getBlue()-color.getRed())/delta); + else // blue is max + Hue = 4+((color.getRed()-color.getGreen())/delta); + + Hue *= 60.0f; + while ( Hue < 0.f ) + Hue += 360; + } + + + inline void SColorHSL::toRGB(SColorf &color) const + { + const f32 l = Luminance/100; + if (core::iszero(Saturation)) // grey + { + color.set(l, l, l); + return; + } + + f32 rm2; + + if ( Luminance <= 50 ) + { + rm2 = l + l * (Saturation/100); + } + else + { + rm2 = l + (1 - l) * (Saturation/100); + } + + const f32 rm1 = 2.0f * l - rm2; + + const f32 h = Hue / 360.0f; + color.set( toRGB1(rm1, rm2, h + 1.f/3.f), + toRGB1(rm1, rm2, h), + toRGB1(rm1, rm2, h - 1.f/3.f) + ); + } + + + // algorithm from Foley/Van-Dam + inline f32 SColorHSL::toRGB1(f32 rm1, f32 rm2, f32 rh) const + { + if (rh<0) + rh += 1; + if (rh>1) + rh -= 1; + + if (rh < 1.f/6.f) + rm1 = rm1 + (rm2 - rm1) * rh*6.f; + else if (rh < 0.5f) + rm1 = rm2; + else if (rh < 2.f/3.f) + rm1 = rm1 + (rm2 - rm1) * ((2.f/3.f)-rh)*6.f; + + return rm1; + } + +} // end namespace video +} // end namespace irr + +#endif -- cgit v1.1