Merged revisions 1309:1314 from 1.4 branch.
git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@1315 dfc29bdd-3216-0410-991c-e03cc46cb475master
parent
6a0d4ea7b2
commit
0e63486fbe
36
changes.txt
36
changes.txt
|
@ -47,7 +47,39 @@ Changes in version 1.5 (... 2008)
|
|||
- Finally added StarSonata patch with table element and TabControl additions. Table is based on MultiColor listbox by Acki, and has loads of changes by CuteAlien.
|
||||
|
||||
-------------------------------------------
|
||||
Changes in version 1.4.1 (??? 2008)
|
||||
Changes in version 1.4.1 (??.4.2008)
|
||||
|
||||
- New JPG image writer version by Vitek.
|
||||
|
||||
- Texture matrix fixes, all methods should now work as expected.
|
||||
|
||||
- Some container methods now return the this pointer after member functions have been called on them, in order to allow call chains.
|
||||
|
||||
- Some new methods for SColorf access, for uniform API of all colors.
|
||||
|
||||
- bug fix for SMaterialLayer equality check. Did only check the TextureMatrix pointers, instead of the matrices.
|
||||
|
||||
- New getMesh method for the SceneManager, which takes an IReadFile instead of a filename.
|
||||
|
||||
- Support for flags _WIN32 and _WIN64 in addition to WIN32 and WIN64 added, this simplifies usage of Irrlicht headers under MSVC.
|
||||
|
||||
- Fixed a crash in GUIMeshViewer
|
||||
|
||||
- new string method findLastChar by Halifax
|
||||
|
||||
- GUIEditBox got the 1 pixel shift after click fixed.
|
||||
|
||||
- Some debug visualization has been fixed for skinned meshes
|
||||
|
||||
- Undef PI symbol before declaring core::PI to avoid compilation problems
|
||||
|
||||
- SAnimatedMesh now properly returns properties of Meshes[0] if those exist, such that it should be usable in place of an SMesh again.
|
||||
|
||||
- Fixed 2d initialisation in opengl and d3d9 driver. This should fix problems with render states mixing up and distrubing, e.g. skin effects.
|
||||
|
||||
- Avoid a crash when passing setSkin the current skin
|
||||
|
||||
- Fixed current frame calculation for non-looped animations. Bug reported by greenya.
|
||||
|
||||
- Fixed bug in CBillboardSceneNode::setColor, reported by rogerborg
|
||||
|
||||
|
@ -82,7 +114,7 @@ Changes in version 1.4.1 (??? 2008)
|
|||
|
||||
- Function setbit was renamed to setbit_cond to avoid name clashes.
|
||||
|
||||
- Fixed .x animations with multiple references to the same joint from different meshes.
|
||||
- Fixed .x animations with multiple references to the same joint from different meshes. Fixed texture path problems.
|
||||
|
||||
- Support for Milkshape 1.8 files, also with multiple weights per joint.
|
||||
|
||||
|
|
227
include/SColor.h
227
include/SColor.h
|
@ -13,7 +13,7 @@ namespace irr
|
|||
namespace video
|
||||
{
|
||||
//! Creates a 16 bit A1R5G5B5 color
|
||||
inline u16 RGBA16(u32 r, u32 g, u32 b, u32 a)
|
||||
inline u16 RGBA16(u32 r, u32 g, u32 b, u32 a=0xFF)
|
||||
{
|
||||
return ((a & 0x80) << 8 |
|
||||
(r & 0xF8) << 7 |
|
||||
|
@ -25,20 +25,21 @@ namespace video
|
|||
//! Creates a 16 bit A1R5G5B5 color
|
||||
inline u16 RGB16(u32 r, u32 g, u32 b)
|
||||
{
|
||||
return RGBA16(r,g,b,0xFF);
|
||||
return RGBA16(r,g,b);
|
||||
}
|
||||
|
||||
|
||||
//! Creates a 16 bit A1R5G5B5 color, based on 16 bit input values
|
||||
//! Creates a 16bit A1R5G5B5 color, based on 16bit input values
|
||||
inline u16 RGB16from16(u16 r, u16 g, u16 b)
|
||||
{
|
||||
return (r & 0x1F) << 10 |
|
||||
(g & 0x1F) << 5 |
|
||||
(b & 0x1F);
|
||||
return (0x8000 |
|
||||
(r & 0x1F) << 10 |
|
||||
(g & 0x1F) << 5 |
|
||||
(b & 0x1F));
|
||||
}
|
||||
|
||||
|
||||
//! Converts a 32 bit (X8R8G8B8) color to a 16 A1R5G5B5 color
|
||||
//! Converts a 32bit (X8R8G8B8) color to a 16bit A1R5G5B5 color
|
||||
inline u16 X8R8G8B8toA1R5G5B5(u32 color)
|
||||
{
|
||||
return ( 0x8000 |
|
||||
|
@ -48,7 +49,7 @@ namespace video
|
|||
}
|
||||
|
||||
|
||||
//! Converts a 32 bit (A8R8G8B8) color to a 16 A1R5G5B5 color
|
||||
//! Converts a 32bit (A8R8G8B8) color to a 16bit A1R5G5B5 color
|
||||
inline u16 A8R8G8B8toA1R5G5B5(u32 color)
|
||||
{
|
||||
return (( color & 0x80000000) >> 16|
|
||||
|
@ -58,7 +59,7 @@ namespace video
|
|||
}
|
||||
|
||||
|
||||
//! Converts a 32 bit (A8R8G8B8) color to a 16 R5G6B5 color
|
||||
//! Converts a 32bit (A8R8G8B8) color to a 16bit R5G6B5 color
|
||||
inline u16 A8R8G8B8toR5G6B5(u32 color)
|
||||
{
|
||||
return (( color & 0x00F80000) >> 8 |
|
||||
|
@ -68,7 +69,7 @@ namespace video
|
|||
|
||||
|
||||
//! Returns A8R8G8B8 Color from A1R5G5B5 color
|
||||
//! build a nicer 32 Bit Color by extending dest lower bits with source high bits
|
||||
//! 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 ) |
|
||||
|
@ -164,12 +165,11 @@ namespace video
|
|||
}
|
||||
|
||||
|
||||
|
||||
//! 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.
|
||||
This class is used by most parts of the Irrlicht Engine
|
||||
to specify a color. Another way is using the class Colorf, which
|
||||
to specify a color. Another way is using the class SColorf, which
|
||||
stores the color values in 4 floats.
|
||||
*/
|
||||
class SColor
|
||||
|
@ -178,45 +178,45 @@ namespace video
|
|||
|
||||
//! Constructor of the Color. Does nothing. The color value
|
||||
//! is not initialized to save time.
|
||||
inline SColor() {}
|
||||
SColor() {}
|
||||
|
||||
//! Constructs the color from 4 values representing the alpha, red, green and
|
||||
//! blue components of the color. Must be values between 0 and 255.
|
||||
inline SColor (u32 a, u32 r, u32 g, u32 b)
|
||||
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.
|
||||
inline SColor(u32 clr)
|
||||
SColor(u32 clr)
|
||||
: color(clr) {}
|
||||
|
||||
//! Returns the alpha component of the color. The alpha component
|
||||
//! defines how transparent a color should be.
|
||||
//! 0 means not transparent (opaque), 255 means fully transparent.
|
||||
inline u32 getAlpha() const { return color>>24; }
|
||||
//! 255 means not transparent (opaque), 0 means fully transparent.
|
||||
u32 getAlpha() const { return color>>24; }
|
||||
|
||||
//! Returns the red component of the color.
|
||||
//! \return Returns a value between 0 and 255, specifying how red the color is.
|
||||
//! 0 means no red, 255 means full red.
|
||||
inline u32 getRed() const { return (color>>16) & 0xff; }
|
||||
u32 getRed() const { return (color>>16) & 0xff; }
|
||||
|
||||
//! Returns the green component of the color.
|
||||
//! \return Returns a value between 0 and 255, specifying how green the color is.
|
||||
//! 0 means no green, 255 means full green.
|
||||
inline u32 getGreen() const { return (color>>8) & 0xff; }
|
||||
u32 getGreen() const { return (color>>8) & 0xff; }
|
||||
|
||||
//! Returns the blue component of the color.
|
||||
//! \return Returns a value between 0 and 255, specifying how blue the color is.
|
||||
//! 0 means no blue, 255 means full blue.
|
||||
inline u32 getBlue() const { return color & 0xff; }
|
||||
u32 getBlue() const { return color & 0xff; }
|
||||
|
||||
//! Returns the luminance of the color.
|
||||
inline f32 getLuminance() const
|
||||
f32 getLuminance() const
|
||||
{
|
||||
return 0.3f*getRed() + 0.59f*getGreen() + 0.11f*getBlue();
|
||||
}
|
||||
|
||||
//! Returns the average intensity of the color.
|
||||
inline u32 getAverage() const
|
||||
u32 getAverage() const
|
||||
{
|
||||
return ( getRed() + getGreen() + getBlue() ) / 3;
|
||||
}
|
||||
|
@ -224,33 +224,33 @@ namespace video
|
|||
//! Sets the alpha component of the Color. The alpha component
|
||||
//! defines how transparent a color should be.
|
||||
//! \param a: Has to be a value between 0 and 255.
|
||||
//! 0 means not transparent (opaque), 255 means fully transparent.
|
||||
inline void setAlpha(u32 a) { color = ((a & 0xff)<<24) | (color & 0x00ffffff); }
|
||||
//! 255 means not transparent (opaque), 0 means fully transparent.
|
||||
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 (=black), 255 means full red.
|
||||
inline void setRed(u32 r) { color = ((r & 0xff)<<16) | (color & 0xff00ffff); }
|
||||
//! 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 (=black), 255 means full green.
|
||||
inline void setGreen(u32 g) { color = ((g & 0xff)<<8) | (color & 0xffff00ff); }
|
||||
//! 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 (=black), 255 means full blue.
|
||||
inline void setBlue(u32 b) { color = (b & 0xff) | (color & 0xffffff00); }
|
||||
//! 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 Returns the 16 bit A1R5G5B5 value of this color.
|
||||
inline u16 toA1R5G5B5() const { return A8R8G8B8toA1R5G5B5(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.
|
||||
inline void toOpenGLColor(u8* dest) const
|
||||
void toOpenGLColor(u8* dest) const
|
||||
{
|
||||
*dest = getRed();
|
||||
*++dest = getGreen();
|
||||
|
@ -264,59 +264,49 @@ namespace video
|
|||
//! \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.
|
||||
//! 0 means not transparent (opaque), 255 means fully transparent.
|
||||
//! 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 (=black), 255 means full red.
|
||||
//! 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 (=black), 255 means full green.
|
||||
//! 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 (=black), 255 means full blue.
|
||||
inline void set(u32 a, u32 r, u32 g, u32 b) { color = (((a & 0xff)<<24) | ((r & 0xff)<<16) | ((g & 0xff)<<8) | (b & 0xff)); }
|
||||
inline void set(u32 col) { color = col; }
|
||||
//! 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 Returns true if the colors are the same, and false if not.
|
||||
inline bool operator==(const SColor& other) const { return other.color == color; }
|
||||
bool operator==(const SColor& other) const { return other.color == color; }
|
||||
|
||||
//! Compares the color to another color.
|
||||
//! \return Returns true if the colors are different, and false if they are the same.
|
||||
inline bool operator!=(const SColor& other) const { return other.color != color; }
|
||||
bool operator!=(const SColor& other) const { return other.color != color; }
|
||||
|
||||
//! comparison operator
|
||||
//! \return Returns true if this color is smaller than the other one
|
||||
inline bool operator<(const SColor& other) const { return (color < other.color); }
|
||||
bool operator<(const SColor& other) const { return (color < other.color); }
|
||||
|
||||
//! Adds two colors
|
||||
inline SColor operator+(const SColor& other) const
|
||||
//! 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
|
||||
{
|
||||
s32 a = getAlpha() + other.getAlpha();
|
||||
if (a > 255)
|
||||
a = 255;
|
||||
|
||||
s32 r = getRed() + other.getRed();
|
||||
if (r > 255)
|
||||
r = 255;
|
||||
|
||||
s32 g = getGreen() + other.getGreen();
|
||||
if (g > 255)
|
||||
g = 255;
|
||||
|
||||
s32 b = getBlue() + other.getBlue();
|
||||
if (b > 255)
|
||||
b = 255;
|
||||
|
||||
return SColor(a,r,g,b);
|
||||
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 Returns interpolated color.
|
||||
inline SColor getInterpolated(const SColor &other, f32 d) const
|
||||
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)(other.getAlpha()*inv + getAlpha()*d),
|
||||
(u32)(other.getRed()*inv + getRed()*d),
|
||||
|
@ -328,9 +318,10 @@ namespace video
|
|||
/** \param c1: first color to interpolate with
|
||||
\param c2: second color to interpolate with
|
||||
\param d: value between 0.0f and 1.0f. */
|
||||
inline SColor getInterpolated_quadratic(const SColor& c1, const SColor& c2, const f32 d) const
|
||||
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;
|
||||
|
@ -351,63 +342,43 @@ namespace video
|
|||
/** 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.
|
||||
This class is rarely used by the Irrlicht Engine
|
||||
to specify a color. Another, faster way is using the class Color, which
|
||||
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:
|
||||
|
||||
//! Constructs a color. All colors are initialised with 0.0f, resulting
|
||||
//! in a black color. alpha is 1.0f for no transparency.
|
||||
SColorf() : r(0.0f), g(0.0f), b(0.0f), a(1.0f) {};
|
||||
|
||||
//! Constructs a color from three color values: red, green and blue.
|
||||
//! 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 (=black) and 1.0f, meaning full red.
|
||||
//! no red and 1.0f, meaning full red.
|
||||
//! \param g: Green color component. Should be a value between 0.0f meaning
|
||||
//! no green (=black) and 1.0f, meaning full green.
|
||||
//! no green and 1.0f, meaning full green.
|
||||
//! \param b: Blue color component. Should be a value between 0.0f meaning
|
||||
//! no blue (=black) and 1.0f, meaning full blue.
|
||||
SColorf(f32 r, f32 g, f32 b) : r(r), g(g), b(b), a(1.0f) {};
|
||||
|
||||
//! Constructs a color from four color values: red, green, blue, and alpha.
|
||||
//! \param r: Red color component. Should be a value between 0.0f meaning
|
||||
//! no red (=black) and 1.0f, meaning full red.
|
||||
//! \param g: Green color component. Should be a value between 0.0f meaning
|
||||
//! no green (=black) and 1.0f, meaning full green.
|
||||
//! \param b: Blue color component. Should be a value between 0.0f meaning
|
||||
//! no blue (=black) and 1.0f, meaning full blue.
|
||||
//! 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,
|
||||
//! 0.0f means not transparent (opaque), 1.0f means fully transparent.
|
||||
SColorf(f32 r, f32 g, f32 b, f32 a) : r(r), g(g), b(b), a(a) {};
|
||||
//! 1.0f means not transparent (opaque), 0.0f means fully transparent.
|
||||
SColorf(f32 r=0.f, f32 g=0.f, f32 b=0.f, f32 a=1.f) : r(r), g(g), b(b), a(a) {}
|
||||
|
||||
//! Constructs a color from 32 bit Color.
|
||||
//! \param c: 32 bit color value from which this Colorf class is
|
||||
//! \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; };
|
||||
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((s32)(a*255.0f), (s32)(r*255.0f), (s32)(g*255.0f), (s32)(b*255.0f));
|
||||
return SColor((u32)(a*255.0f), (u32)(r*255.0f), (u32)(g*255.0f), (u32)(b*255.0f));
|
||||
}
|
||||
|
||||
//! red color component
|
||||
f32 r;
|
||||
|
||||
//! green color component
|
||||
f32 g;
|
||||
|
||||
//! blue component
|
||||
f32 b;
|
||||
|
||||
//! alpha color component
|
||||
f32 a;
|
||||
|
||||
//! 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.
|
||||
|
@ -418,21 +389,23 @@ namespace video
|
|||
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.
|
||||
//! \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 (=black) and 1.0f, meaning full red.
|
||||
//! no red 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.
|
||||
//! no green 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.
|
||||
//! 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 Returns interpolated color.
|
||||
inline SColorf getInterpolated(const SColorf &other, f32 d) const
|
||||
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);
|
||||
|
@ -442,8 +415,9 @@ namespace video
|
|||
/** \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, const f32 d) const
|
||||
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;
|
||||
|
@ -457,9 +431,8 @@ namespace video
|
|||
}
|
||||
|
||||
|
||||
|
||||
//! Sets a color component by index. R=0, G=1, B=2, A=3
|
||||
inline void setColorComponentValue(s32 index, f32 value)
|
||||
void setColorComponentValue(s32 index, f32 value)
|
||||
{
|
||||
switch(index)
|
||||
{
|
||||
|
@ -469,8 +442,33 @@ namespace video
|
|||
case 3: a = value; break;
|
||||
}
|
||||
}
|
||||
|
||||
//! Returns the alpha component of the color in the range 0.0 to 1.0
|
||||
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 HSV format
|
||||
/** The color values for hue, saturation, value
|
||||
are stored in a 32 bit floating point variable.
|
||||
|
@ -481,15 +479,15 @@ namespace video
|
|||
SColorHSL ( f32 h = 0.f, f32 s = 0.f, f32 l = 0.f )
|
||||
: Hue ( h ), Saturation ( s ), Luminance ( l ) {}
|
||||
|
||||
void setfromRGB ( const SColor &color );
|
||||
// void setfromRGB ( const SColor &color );
|
||||
void settoRGB ( SColor &color ) const;
|
||||
|
||||
f32 Hue;
|
||||
f32 Saturation;
|
||||
f32 Luminance;
|
||||
|
||||
private:
|
||||
inline u32 toRGB1(f32 rm1, f32 rm2, f32 rh) const;
|
||||
private:
|
||||
inline u32 toRGB1(f32 rm1, f32 rm2, f32 rh) const;
|
||||
|
||||
};
|
||||
|
||||
|
@ -531,9 +529,12 @@ namespace video
|
|||
while ( rh < 0.f )
|
||||
rh += 2.f * core::PI;
|
||||
|
||||
if (rh < 60.0f * core::DEGTORAD ) rm1 = rm1 + (rm2 - rm1) * rh / (60.0f * core::DEGTORAD);
|
||||
else if (rh < 180.0f * core::DEGTORAD ) rm1 = rm2;
|
||||
else if (rh < 240.0f * core::DEGTORAD ) rm1 = rm1 + (rm2 - rm1) * ( ( 240.0f * core::DEGTORAD ) - rh) / (60.0f * core::DEGTORAD);
|
||||
if (rh < 60.0f * core::DEGTORAD )
|
||||
rm1 = rm1 + (rm2 - rm1) * rh / (60.0f * core::DEGTORAD);
|
||||
else if (rh < 180.0f * core::DEGTORAD )
|
||||
rm1 = rm2;
|
||||
else if (rh < 240.0f * core::DEGTORAD )
|
||||
rm1 = rm1 + (rm2 - rm1) * ( ( 240.0f * core::DEGTORAD ) - rh) / (60.0f * core::DEGTORAD);
|
||||
|
||||
return (u32) (rm1 * 255.f);
|
||||
}
|
||||
|
|
|
@ -154,7 +154,7 @@ namespace video
|
|||
if (different)
|
||||
return true;
|
||||
else
|
||||
different |= (TextureMatrix != b.TextureMatrix);
|
||||
different |= (TextureMatrix != b.TextureMatrix) && TextureMatrix && b.TextureMatrix && (*TextureMatrix != *(b.TextureMatrix));
|
||||
return different;
|
||||
}
|
||||
|
||||
|
|
|
@ -82,11 +82,11 @@ namespace core
|
|||
CMatrix4<T>& operator-=(const CMatrix4<T>& other);
|
||||
|
||||
//! set this matrix to the product of two matrices
|
||||
inline void setbyproduct(const CMatrix4<T>& other_a,const CMatrix4<T>& other_b );
|
||||
inline CMatrix4<T>& setbyproduct(const CMatrix4<T>& other_a,const CMatrix4<T>& other_b );
|
||||
|
||||
//! set this matrix to the product of two matrices, no logical optimation
|
||||
//! use it if you know you never have a identity matrix
|
||||
void setbyproduct_nocheck(const CMatrix4<T>& other_a,const CMatrix4<T>& other_b );
|
||||
CMatrix4<T>& setbyproduct_nocheck(const CMatrix4<T>& other_a,const CMatrix4<T>& other_b );
|
||||
|
||||
//! Multiply by another matrix.
|
||||
CMatrix4<T> operator*(const CMatrix4<T>& other) const;
|
||||
|
@ -101,7 +101,7 @@ namespace core
|
|||
CMatrix4<T>& operator*=(const T& scalar);
|
||||
|
||||
//! Set matrix to identity.
|
||||
inline void makeIdentity();
|
||||
inline CMatrix4<T>& makeIdentity();
|
||||
|
||||
//! Returns true if the matrix is the identity matrix
|
||||
inline bool isIdentity() const;
|
||||
|
@ -110,31 +110,31 @@ namespace core
|
|||
bool isIdentity_integer_base () const;
|
||||
|
||||
//! Set the translation of the current matrix. Will erase any previous values.
|
||||
void setTranslation( const vector3d<T>& translation );
|
||||
CMatrix4<T>& setTranslation( const vector3d<T>& translation );
|
||||
|
||||
//! Gets the current translation
|
||||
vector3d<T> getTranslation() const;
|
||||
|
||||
//! Set the inverse translation of the current matrix. Will erase any previous values.
|
||||
void setInverseTranslation( const vector3d<T>& translation );
|
||||
CMatrix4<T>& setInverseTranslation( const vector3d<T>& translation );
|
||||
|
||||
//! Make a rotation matrix from Euler angles. The 4th row and column are unmodified.
|
||||
inline void setRotationRadians( const vector3d<T>& rotation );
|
||||
inline CMatrix4<T>& setRotationRadians( const vector3d<T>& rotation );
|
||||
|
||||
//! Make a rotation matrix from Euler angles. The 4th row and column are unmodified.
|
||||
void setRotationDegrees( const vector3d<T>& rotation );
|
||||
CMatrix4<T>& setRotationDegrees( const vector3d<T>& rotation );
|
||||
|
||||
//! Returns the rotation, as set by setRotation(). This code was orginally written by by Chev.
|
||||
core::vector3d<T> getRotationDegrees() const;
|
||||
|
||||
//! Make an inverted rotation matrix from Euler angles. The 4th row and column are unmodified.
|
||||
inline void setInverseRotationRadians( const vector3d<T>& rotation );
|
||||
inline CMatrix4<T>& setInverseRotationRadians( const vector3d<T>& rotation );
|
||||
|
||||
//! Make an inverted rotation matrix from Euler angles. The 4th row and column are unmodified.
|
||||
void setInverseRotationDegrees( const vector3d<T>& rotation );
|
||||
CMatrix4<T>& setInverseRotationDegrees( const vector3d<T>& rotation );
|
||||
|
||||
//! Set Scale
|
||||
void setScale( const vector3d<T>& scale );
|
||||
CMatrix4<T>& setScale( const vector3d<T>& scale );
|
||||
|
||||
//! Get Scale
|
||||
core::vector3d<T> getScale() const;
|
||||
|
@ -203,39 +203,39 @@ namespace core
|
|||
bool getInverse(CMatrix4<T>& out) const;
|
||||
|
||||
//! Builds a right-handed perspective projection matrix based on a field of view
|
||||
void buildProjectionMatrixPerspectiveFovRH(f32 fieldOfViewRadians, f32 aspectRatio, f32 zNear, f32 zFar);
|
||||
CMatrix4<T>& buildProjectionMatrixPerspectiveFovRH(f32 fieldOfViewRadians, f32 aspectRatio, f32 zNear, f32 zFar);
|
||||
|
||||
//! Builds a left-handed perspective projection matrix based on a field of view
|
||||
void buildProjectionMatrixPerspectiveFovLH(f32 fieldOfViewRadians, f32 aspectRatio, f32 zNear, f32 zFar);
|
||||
CMatrix4<T>& buildProjectionMatrixPerspectiveFovLH(f32 fieldOfViewRadians, f32 aspectRatio, f32 zNear, f32 zFar);
|
||||
|
||||
//! Builds a right-handed perspective projection matrix.
|
||||
void buildProjectionMatrixPerspectiveRH(f32 widthOfViewVolume, f32 heightOfViewVolume, f32 zNear, f32 zFar);
|
||||
CMatrix4<T>& buildProjectionMatrixPerspectiveRH(f32 widthOfViewVolume, f32 heightOfViewVolume, f32 zNear, f32 zFar);
|
||||
|
||||
//! Builds a left-handed perspective projection matrix.
|
||||
void buildProjectionMatrixPerspectiveLH(f32 widthOfViewVolume, f32 heightOfViewVolume, f32 zNear, f32 zFar);
|
||||
CMatrix4<T>& buildProjectionMatrixPerspectiveLH(f32 widthOfViewVolume, f32 heightOfViewVolume, f32 zNear, f32 zFar);
|
||||
|
||||
//! Builds a left-handed orthogonal projection matrix.
|
||||
void buildProjectionMatrixOrthoLH(f32 widthOfViewVolume, f32 heightOfViewVolume, f32 zNear, f32 zFar);
|
||||
CMatrix4<T>& buildProjectionMatrixOrthoLH(f32 widthOfViewVolume, f32 heightOfViewVolume, f32 zNear, f32 zFar);
|
||||
|
||||
//! Builds a right-handed orthogonal projection matrix.
|
||||
void buildProjectionMatrixOrthoRH(f32 widthOfViewVolume, f32 heightOfViewVolume, f32 zNear, f32 zFar);
|
||||
CMatrix4<T>& buildProjectionMatrixOrthoRH(f32 widthOfViewVolume, f32 heightOfViewVolume, f32 zNear, f32 zFar);
|
||||
|
||||
//! Builds a left-handed look-at matrix.
|
||||
void buildCameraLookAtMatrixLH(const vector3df& position, const vector3df& target, const vector3df& upVector);
|
||||
CMatrix4<T>& buildCameraLookAtMatrixLH(const vector3df& position, const vector3df& target, const vector3df& upVector);
|
||||
|
||||
//! Builds a right-handed look-at matrix.
|
||||
void buildCameraLookAtMatrixRH(const vector3df& position, const vector3df& target, const vector3df& upVector);
|
||||
CMatrix4<T>& buildCameraLookAtMatrixRH(const vector3df& position, const vector3df& target, const vector3df& upVector);
|
||||
|
||||
//! Builds a matrix that flattens geometry into a plane.
|
||||
//! \param light: light source
|
||||
//! \param plane: plane into which the geometry if flattened into
|
||||
//! \param point: value between 0 and 1, describing the light source.
|
||||
//! If this is 1, it is a point light, if it is 0, it is a directional light.
|
||||
void buildShadowMatrix(const core::vector3df& light, core::plane3df plane, f32 point=1.0f);
|
||||
CMatrix4<T>& buildShadowMatrix(const core::vector3df& light, core::plane3df plane, f32 point=1.0f);
|
||||
|
||||
//! Builds a matrix which transforms a normalized Device Coordinate to Device Coordinates.
|
||||
/** Used to scale <-1,-1><1,1> to viewport, for example from von <-1,-1> <1,1> to the viewport <0,0><0,640> */
|
||||
void buildNDCToDCMatrix( const core::rect<s32>& area, f32 zScale);
|
||||
CMatrix4<T>& buildNDCToDCMatrix( const core::rect<s32>& area, f32 zScale);
|
||||
|
||||
//! creates a new matrix as interpolated matrix from two other ones.
|
||||
//! \param b: other matrix to interpolate with
|
||||
|
@ -252,21 +252,48 @@ namespace core
|
|||
construct 2D Texture transformations
|
||||
rotate about center, scale, and transform.
|
||||
*/
|
||||
void setTextureScale( f32 sx, f32 sy );
|
||||
|
||||
void setTextureRotationCenter( f32 radAngle );
|
||||
void setTextureScaleCenter( f32 sx, f32 sy );
|
||||
|
||||
void setTextureTranslate( f32 x, f32 y );
|
||||
void setTextureTranslateTransposed( f32 x, f32 y );
|
||||
|
||||
void buildTextureTransform( f32 rotateRad,
|
||||
CMatrix4<T>& buildTextureTransform( f32 rotateRad,
|
||||
const core::vector2df &rotatecenter,
|
||||
const core::vector2df &translate,
|
||||
const core::vector2df &scale);
|
||||
|
||||
//! set texture transformation rotation
|
||||
//! rotate about z axis, recenter at (0.5,0.5)
|
||||
//! doesn't clear other elements than those affected
|
||||
//! \param radAngle Angle in radians
|
||||
//! \return Altered matrix
|
||||
CMatrix4<T>& setTextureRotationCenter( f32 radAngle );
|
||||
|
||||
//! set texture transformation translation
|
||||
//! doesn't clear other elements than those affected
|
||||
//! \param x Offset on x axis
|
||||
//! \param y Offset on y axis
|
||||
//! \return Altered matrix
|
||||
CMatrix4<T>& setTextureTranslate( f32 x, f32 y );
|
||||
|
||||
//! set texture transformation translation, using a transposed representation
|
||||
//! doesn't clear other elements than those affected
|
||||
//! \param x Offset on x axis
|
||||
//! \param y Offset on y axis
|
||||
//! \return Altered matrix
|
||||
CMatrix4<T>& setTextureTranslateTransposed( f32 x, f32 y );
|
||||
|
||||
//! set texture transformation scale
|
||||
//! doesn't clear other elements than those affected
|
||||
//! \param sx Scale factor on x axis
|
||||
//! \param sy Scale factor on y axis
|
||||
//! \return Altered matrix
|
||||
CMatrix4<T>& setTextureScale( f32 sx, f32 sy );
|
||||
|
||||
//! set texture transformation scale, and recenter at (0.5,0.5)
|
||||
//! doesn't clear other elements than those affected
|
||||
//! \param sx Scale factor on x axis
|
||||
//! \param sy Scale factor on y axis
|
||||
//! \return Altered matrix
|
||||
CMatrix4<T>& setTextureScaleCenter( f32 sx, f32 sy );
|
||||
|
||||
//! sets all matrix data members at once
|
||||
void setM(const T* data);
|
||||
CMatrix4<T>& setM(const T* data);
|
||||
|
||||
//! sets if the matrix is definitely identity matrix
|
||||
void setDefinitelyIdentityMatrix( bool isDefinitelyIdentityMatrix);
|
||||
|
@ -479,17 +506,17 @@ namespace core
|
|||
template <class T>
|
||||
inline CMatrix4<T>& CMatrix4<T>::operator*=(const CMatrix4<T>& other)
|
||||
{
|
||||
// do chacks on your own in order to avoid copy creation
|
||||
// do checks on your own in order to avoid copy creation
|
||||
if ( !other.isIdentity() )
|
||||
{
|
||||
if ( this->isIdentity() )
|
||||
{
|
||||
*this = other;
|
||||
return (*this = other);
|
||||
}
|
||||
else
|
||||
{
|
||||
CMatrix4<T> temp ( *this );
|
||||
setbyproduct_nocheck( temp, other );
|
||||
return setbyproduct_nocheck( temp, other );
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
|
@ -499,7 +526,7 @@ namespace core
|
|||
// set this matrix to the product of two other matrices
|
||||
// goal is to reduce stack use and copy
|
||||
template <class T>
|
||||
inline void CMatrix4<T>::setbyproduct_nocheck(const CMatrix4<T>& other_a,const CMatrix4<T>& other_b )
|
||||
inline CMatrix4<T>& CMatrix4<T>::setbyproduct_nocheck(const CMatrix4<T>& other_a,const CMatrix4<T>& other_b )
|
||||
{
|
||||
const T *m1 = other_a.M;
|
||||
const T *m2 = other_b.M;
|
||||
|
@ -524,6 +551,7 @@ namespace core
|
|||
M[14] = m1[2]*m2[12] + m1[6]*m2[13] + m1[10]*m2[14] + m1[14]*m2[15];
|
||||
M[15] = m1[3]*m2[12] + m1[7]*m2[13] + m1[11]*m2[14] + m1[15]*m2[15];
|
||||
definitelyIdentityMatrix=false;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
|
@ -531,20 +559,15 @@ namespace core
|
|||
// set this matrix to the product of two other matrices
|
||||
// goal is to reduce stack use and copy
|
||||
template <class T>
|
||||
inline void CMatrix4<T>::setbyproduct(const CMatrix4<T>& other_a,const CMatrix4<T>& other_b )
|
||||
inline CMatrix4<T>& CMatrix4<T>::setbyproduct(const CMatrix4<T>& other_a, const CMatrix4<T>& other_b )
|
||||
{
|
||||
if ( other_a.isIdentity () )
|
||||
{
|
||||
*this = other_b;
|
||||
return;
|
||||
}
|
||||
return (*this = other_b);
|
||||
else
|
||||
if ( other_b.isIdentity () )
|
||||
{
|
||||
*this = other_a;
|
||||
return;
|
||||
}
|
||||
setbyproduct_nocheck(other_a,other_b);
|
||||
return (*this = other_a);
|
||||
else
|
||||
return setbyproduct_nocheck(other_a,other_b);
|
||||
}
|
||||
|
||||
//! multiply by another matrix
|
||||
|
@ -593,30 +616,33 @@ namespace core
|
|||
|
||||
|
||||
template <class T>
|
||||
inline void CMatrix4<T>::setTranslation( const vector3d<T>& translation )
|
||||
inline CMatrix4<T>& CMatrix4<T>::setTranslation( const vector3d<T>& translation )
|
||||
{
|
||||
M[12] = translation.X;
|
||||
M[13] = translation.Y;
|
||||
M[14] = translation.Z;
|
||||
definitelyIdentityMatrix=false;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline void CMatrix4<T>::setInverseTranslation( const vector3d<T>& translation )
|
||||
inline CMatrix4<T>& CMatrix4<T>::setInverseTranslation( const vector3d<T>& translation )
|
||||
{
|
||||
M[12] = -translation.X;
|
||||
M[13] = -translation.Y;
|
||||
M[14] = -translation.Z;
|
||||
definitelyIdentityMatrix=false;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline void CMatrix4<T>::setScale( const vector3d<T>& scale )
|
||||
inline CMatrix4<T>& CMatrix4<T>::setScale( const vector3d<T>& scale )
|
||||
{
|
||||
M[0] = scale.X;
|
||||
M[5] = scale.Y;
|
||||
M[10] = scale.Z;
|
||||
definitelyIdentityMatrix=false;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
|
@ -626,33 +652,33 @@ namespace core
|
|||
}
|
||||
|
||||
template <class T>
|
||||
inline void CMatrix4<T>::setRotationDegrees( const vector3d<T>& rotation )
|
||||
inline CMatrix4<T>& CMatrix4<T>::setRotationDegrees( const vector3d<T>& rotation )
|
||||
{
|
||||
setRotationRadians( rotation * core::DEGTORAD );
|
||||
return setRotationRadians( rotation * core::DEGTORAD );
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline void CMatrix4<T>::setInverseRotationDegrees( const vector3d<T>& rotation )
|
||||
inline CMatrix4<T>& CMatrix4<T>::setInverseRotationDegrees( const vector3d<T>& rotation )
|
||||
{
|
||||
setInverseRotationRadians( rotation * core::DEGTORAD );
|
||||
return setInverseRotationRadians( rotation * core::DEGTORAD );
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline void CMatrix4<T>::setRotationRadians( const vector3d<T>& rotation )
|
||||
inline CMatrix4<T>& CMatrix4<T>::setRotationRadians( const vector3d<T>& rotation )
|
||||
{
|
||||
f64 cr = cos( rotation.X );
|
||||
f64 sr = sin( rotation.X );
|
||||
f64 cp = cos( rotation.Y );
|
||||
f64 sp = sin( rotation.Y );
|
||||
f64 cy = cos( rotation.Z );
|
||||
f64 sy = sin( rotation.Z );
|
||||
const f64 cr = cos( rotation.X );
|
||||
const f64 sr = sin( rotation.X );
|
||||
const f64 cp = cos( rotation.Y );
|
||||
const f64 sp = sin( rotation.Y );
|
||||
const f64 cy = cos( rotation.Z );
|
||||
const f64 sy = sin( rotation.Z );
|
||||
|
||||
M[0] = (T)( cp*cy );
|
||||
M[1] = (T)( cp*sy );
|
||||
M[2] = (T)( -sp );
|
||||
|
||||
f64 srsp = sr*sp;
|
||||
f64 crsp = cr*sp;
|
||||
const f64 srsp = sr*sp;
|
||||
const f64 crsp = cr*sp;
|
||||
|
||||
M[4] = (T)( srsp*cy-cr*sy );
|
||||
M[5] = (T)( srsp*sy+cr*cy );
|
||||
|
@ -662,10 +688,10 @@ namespace core
|
|||
M[9] = (T)( crsp*sy-sr*cy );
|
||||
M[10] = (T)( cr*cp );
|
||||
definitelyIdentityMatrix=false;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//! Returns the rotation, as set by setRotation(). This code was sent
|
||||
//! in by Chev.
|
||||
template <class T>
|
||||
|
@ -674,18 +700,19 @@ namespace core
|
|||
const CMatrix4<T> &mat = *this;
|
||||
|
||||
f64 Y = -asin(mat(0,2));
|
||||
f64 C = cos(Y);
|
||||
const f64 C = cos(Y);
|
||||
Y *= RADTODEG64;
|
||||
|
||||
f64 rotx, roty, X, Z;
|
||||
|
||||
if (fabs(C)>0.0005f)
|
||||
{
|
||||
rotx = mat(2,2) / C;
|
||||
roty = mat(1,2) / C;
|
||||
const T invC = 1.0/C;
|
||||
rotx = mat(2,2) * invC;
|
||||
roty = mat(1,2) * invC;
|
||||
X = atan2( roty, rotx ) * RADTODEG64;
|
||||
rotx = mat(0,0) / C;
|
||||
roty = mat(0,1) / C;
|
||||
rotx = mat(0,0) * invC;
|
||||
roty = mat(0,1) * invC;
|
||||
Z = atan2( roty, rotx ) * RADTODEG64;
|
||||
}
|
||||
else
|
||||
|
@ -703,11 +730,12 @@ namespace core
|
|||
if (Y < 0.0) Y += 360.0;
|
||||
if (Z < 0.0) Z += 360.0;
|
||||
|
||||
return vector3d<T>((f32)X,(f32)Y,(f32)Z);
|
||||
return vector3d<T>((T)X,(T)Y,(T)Z);
|
||||
}
|
||||
|
||||
|
||||
template <class T>
|
||||
inline void CMatrix4<T>::setInverseRotationRadians( const vector3d<T>& rotation )
|
||||
inline CMatrix4<T>& CMatrix4<T>::setInverseRotationRadians( const vector3d<T>& rotation )
|
||||
{
|
||||
f64 cr = cos( rotation.X );
|
||||
f64 sr = sin( rotation.X );
|
||||
|
@ -731,17 +759,19 @@ namespace core
|
|||
M[6] = (T)( crsp*sy-sr*cy );
|
||||
M[10] = (T)( cr*cp );
|
||||
definitelyIdentityMatrix=false;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
*/
|
||||
template <class T>
|
||||
inline void CMatrix4<T>::makeIdentity()
|
||||
inline CMatrix4<T>& CMatrix4<T>::makeIdentity()
|
||||
{
|
||||
memset(M, 0, 16*sizeof(T));
|
||||
M[0] = M[5] = M[10] = M[15] = (T)1;
|
||||
definitelyIdentityMatrix=true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
|
@ -806,7 +836,6 @@ namespace core
|
|||
}
|
||||
|
||||
|
||||
|
||||
template <class T>
|
||||
inline void CMatrix4<T>::rotateVect( vector3df& vect ) const
|
||||
{
|
||||
|
@ -1166,10 +1195,10 @@ namespace core
|
|||
|
||||
//! Builds a right-handed perspective projection matrix based on a field of view
|
||||
template <class T>
|
||||
inline void CMatrix4<T>::buildProjectionMatrixPerspectiveFovRH(f32 fieldOfViewRadians, f32 aspectRatio, f32 zNear, f32 zFar)
|
||||
inline CMatrix4<T>& CMatrix4<T>::buildProjectionMatrixPerspectiveFovRH(f32 fieldOfViewRadians, f32 aspectRatio, f32 zNear, f32 zFar)
|
||||
{
|
||||
f64 h = 1.0/tan(fieldOfViewRadians/2.0);
|
||||
T w = h / aspectRatio;
|
||||
const f64 h = 1.0/tan(fieldOfViewRadians/2.0);
|
||||
const T w = h / aspectRatio;
|
||||
|
||||
M[0] = w;
|
||||
M[1] = 0;
|
||||
|
@ -1193,16 +1222,17 @@ namespace core
|
|||
// M[14] = (T)(2.0f*zNear*zFar/(zNear-zFar)); // OpenGL version
|
||||
M[15] = 0;
|
||||
definitelyIdentityMatrix=false;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//! Builds a left-handed perspective projection matrix based on a field of view
|
||||
template <class T>
|
||||
inline void CMatrix4<T>::buildProjectionMatrixPerspectiveFovLH(f32 fieldOfViewRadians, f32 aspectRatio, f32 zNear, f32 zFar)
|
||||
inline CMatrix4<T>& CMatrix4<T>::buildProjectionMatrixPerspectiveFovLH(f32 fieldOfViewRadians, f32 aspectRatio, f32 zNear, f32 zFar)
|
||||
{
|
||||
f64 h = 1.0/tan(fieldOfViewRadians/2.0);
|
||||
T w = (T)(h / aspectRatio);
|
||||
const f64 h = 1.0/tan(fieldOfViewRadians/2.0);
|
||||
const T w = (T)(h / aspectRatio);
|
||||
|
||||
M[0] = w;
|
||||
M[1] = 0;
|
||||
|
@ -1224,13 +1254,13 @@ namespace core
|
|||
M[14] = (T)(-zNear*zFar/(zFar-zNear));
|
||||
M[15] = 0;
|
||||
definitelyIdentityMatrix=false;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//! Builds a left-handed orthogonal projection matrix.
|
||||
template <class T>
|
||||
inline void CMatrix4<T>::buildProjectionMatrixOrthoLH(f32 widthOfViewVolume, f32 heightOfViewVolume, f32 zNear, f32 zFar)
|
||||
inline CMatrix4<T>& CMatrix4<T>::buildProjectionMatrixOrthoLH(f32 widthOfViewVolume, f32 heightOfViewVolume, f32 zNear, f32 zFar)
|
||||
{
|
||||
M[0] = (T)(2/widthOfViewVolume);
|
||||
M[1] = 0;
|
||||
|
@ -1252,13 +1282,14 @@ namespace core
|
|||
M[14] = (T)(zNear/(zNear-zFar));
|
||||
M[15] = 1;
|
||||
definitelyIdentityMatrix=false;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//! Builds a right-handed orthogonal projection matrix.
|
||||
template <class T>
|
||||
inline void CMatrix4<T>::buildProjectionMatrixOrthoRH(f32 widthOfViewVolume, f32 heightOfViewVolume, f32 zNear, f32 zFar)
|
||||
inline CMatrix4<T>& CMatrix4<T>::buildProjectionMatrixOrthoRH(f32 widthOfViewVolume, f32 heightOfViewVolume, f32 zNear, f32 zFar)
|
||||
{
|
||||
M[0] = (T)(2/widthOfViewVolume);
|
||||
M[1] = 0;
|
||||
|
@ -1280,12 +1311,13 @@ namespace core
|
|||
M[14] = (T)(zNear/(zNear-zFar));
|
||||
M[15] = -1;
|
||||
definitelyIdentityMatrix=false;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
//! Builds a right-handed perspective projection matrix.
|
||||
template <class T>
|
||||
inline void CMatrix4<T>::buildProjectionMatrixPerspectiveRH(f32 widthOfViewVolume, f32 heightOfViewVolume, f32 zNear, f32 zFar)
|
||||
inline CMatrix4<T>& CMatrix4<T>::buildProjectionMatrixPerspectiveRH(f32 widthOfViewVolume, f32 heightOfViewVolume, f32 zNear, f32 zFar)
|
||||
{
|
||||
M[0] = (T)(2*zNear/widthOfViewVolume);
|
||||
M[1] = 0;
|
||||
|
@ -1307,12 +1339,13 @@ namespace core
|
|||
M[14] = (T)(zNear*zFar/(zNear-zFar));
|
||||
M[15] = 0;
|
||||
definitelyIdentityMatrix=false;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
//! Builds a left-handed perspective projection matrix.
|
||||
template <class T>
|
||||
inline void CMatrix4<T>::buildProjectionMatrixPerspectiveLH(f32 widthOfViewVolume, f32 heightOfViewVolume, f32 zNear, f32 zFar)
|
||||
inline CMatrix4<T>& CMatrix4<T>::buildProjectionMatrixPerspectiveLH(f32 widthOfViewVolume, f32 heightOfViewVolume, f32 zNear, f32 zFar)
|
||||
{
|
||||
M[0] = (T)(2*zNear/widthOfViewVolume);
|
||||
M[1] = 0;
|
||||
|
@ -1334,15 +1367,16 @@ namespace core
|
|||
M[14] = (T)(zNear*zFar/(zNear-zFar));
|
||||
M[15] = 0;
|
||||
definitelyIdentityMatrix=false;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
//! Builds a matrix that flattens geometry into a plane.
|
||||
template <class T>
|
||||
inline void CMatrix4<T>::buildShadowMatrix(const core::vector3df& light, core::plane3df plane, f32 point)
|
||||
inline CMatrix4<T>& CMatrix4<T>::buildShadowMatrix(const core::vector3df& light, core::plane3df plane, f32 point)
|
||||
{
|
||||
plane.Normal.normalize();
|
||||
f32 d = plane.Normal.dotProduct(light);
|
||||
const f32 d = plane.Normal.dotProduct(light);
|
||||
|
||||
M[ 0] = (T)(-plane.Normal.X * light.X + d);
|
||||
M[ 1] = (T)(-plane.Normal.X * light.Y);
|
||||
|
@ -1364,11 +1398,12 @@ namespace core
|
|||
M[14] = (T)(-plane.D * light.Z);
|
||||
M[15] = (T)(-plane.D * point + d);
|
||||
definitelyIdentityMatrix=false;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! Builds a left-handed look-at matrix.
|
||||
template <class T>
|
||||
inline void CMatrix4<T>::buildCameraLookAtMatrixLH(
|
||||
inline CMatrix4<T>& CMatrix4<T>::buildCameraLookAtMatrixLH(
|
||||
const vector3df& position,
|
||||
const vector3df& target,
|
||||
const vector3df& upVector)
|
||||
|
@ -1401,13 +1436,14 @@ namespace core
|
|||
M[14] = (T)-zaxis.dotProduct(position);
|
||||
M[15] = 1;
|
||||
definitelyIdentityMatrix=false;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//! Builds a right-handed look-at matrix.
|
||||
template <class T>
|
||||
inline void CMatrix4<T>::buildCameraLookAtMatrixRH(
|
||||
inline CMatrix4<T>& CMatrix4<T>::buildCameraLookAtMatrixRH(
|
||||
const vector3df& position,
|
||||
const vector3df& target,
|
||||
const vector3df& upVector)
|
||||
|
@ -1440,10 +1476,12 @@ namespace core
|
|||
M[14] = (T)-zaxis.dotProduct(position);
|
||||
M[15] = 1;
|
||||
definitelyIdentityMatrix=false;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
//! creates a new matrix as interpolated matrix from to other ones.
|
||||
//! creates a new matrix as interpolated matrix from this and the passed one.
|
||||
//! \param b: Second matrix to interpolate with
|
||||
//! \param time: Must be a value between 0 and 1.
|
||||
template <class T>
|
||||
inline CMatrix4<T> CMatrix4<T>::interpolate(const core::CMatrix4<T>& b, f32 time) const
|
||||
|
@ -1498,21 +1536,18 @@ namespace core
|
|||
|
||||
// used to scale <-1,-1><1,1> to viewport
|
||||
template <class T>
|
||||
inline void CMatrix4<T>::buildNDCToDCMatrix( const core::rect<s32>& viewport, f32 zScale)
|
||||
inline CMatrix4<T>& CMatrix4<T>::buildNDCToDCMatrix( const core::rect<s32>& viewport, f32 zScale)
|
||||
{
|
||||
f32 scaleX = (viewport.getWidth() - 0.75f ) / 2.0f;
|
||||
f32 scaleY = -(viewport.getHeight() - 0.75f ) / 2.0f;
|
||||
const f32 scaleX = (viewport.getWidth() - 0.75f ) / 2.0f;
|
||||
const f32 scaleY = -(viewport.getHeight() - 0.75f ) / 2.0f;
|
||||
|
||||
f32 dx = -0.5f + ( (viewport.UpperLeftCorner.X + viewport.LowerRightCorner.X ) / 2.0f );
|
||||
f32 dy = -0.5f + ( (viewport.UpperLeftCorner.Y + viewport.LowerRightCorner.Y ) / 2.0f );
|
||||
const f32 dx = -0.5f + ( (viewport.UpperLeftCorner.X + viewport.LowerRightCorner.X ) / 2.0f );
|
||||
const f32 dy = -0.5f + ( (viewport.UpperLeftCorner.Y + viewport.LowerRightCorner.Y ) / 2.0f );
|
||||
|
||||
makeIdentity();
|
||||
M[0] = (T)scaleX;
|
||||
M[5] = (T)scaleY;
|
||||
M[10] = (T)zScale;
|
||||
M[12] = (T)dx;
|
||||
M[13] = (T)dy;
|
||||
definitelyIdentityMatrix=false;
|
||||
return setScale(core::vector3d<T>((T)scaleX, (T)scaleY, (T)zScale));
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -1527,7 +1562,7 @@ namespace core
|
|||
*/
|
||||
|
||||
template <class T>
|
||||
inline void CMatrix4<T>::buildTextureTransform( f32 rotateRad,
|
||||
inline CMatrix4<T>& CMatrix4<T>::buildTextureTransform( f32 rotateRad,
|
||||
const core::vector2df &rotatecenter,
|
||||
const core::vector2df &translate,
|
||||
const core::vector2df &scale)
|
||||
|
@ -1555,66 +1590,73 @@ namespace core
|
|||
M[14] = 0;
|
||||
M[15] = 1;
|
||||
definitelyIdentityMatrix=false;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! rotate about z axis, center ( 0.5, 0.5 )
|
||||
template <class T>
|
||||
inline void CMatrix4<T>::setTextureRotationCenter( f32 rotateRad )
|
||||
inline CMatrix4<T>& CMatrix4<T>::setTextureRotationCenter( f32 rotateRad )
|
||||
{
|
||||
const f32 c = cosf(rotateRad);
|
||||
const f32 s = sinf(rotateRad);
|
||||
M[0] = (T)c;
|
||||
M[1] = (T)s;
|
||||
M[2] = (T)(-0.5f * ( c + s) + 0.5f);
|
||||
|
||||
M[4] = (T)-s;
|
||||
M[5] = (T)c;
|
||||
M[6] = (T)(-0.5f * (-s + c) + 0.5f);
|
||||
definitelyIdentityMatrix=false;
|
||||
|
||||
M[8] = (T)(0.5f * ( s - c) + 0.5f);
|
||||
M[9] = (T)(-0.5f * ( s + c) + 0.5f);
|
||||
definitelyIdentityMatrix = definitelyIdentityMatrix && (rotateRad==0.0f);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline void CMatrix4<T>::setTextureTranslate ( f32 x, f32 y )
|
||||
inline CMatrix4<T>& CMatrix4<T>::setTextureTranslate ( f32 x, f32 y )
|
||||
{
|
||||
M[8] = (T)x;
|
||||
M[9] = (T)y;
|
||||
definitelyIdentityMatrix = definitelyIdentityMatrix && (x==0.0f) && (y==0.0f) ;
|
||||
definitelyIdentityMatrix = definitelyIdentityMatrix && (x==0.0f) && (y==0.0f);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline void CMatrix4<T>::setTextureTranslateTransposed ( f32 x, f32 y )
|
||||
inline CMatrix4<T>& CMatrix4<T>::setTextureTranslateTransposed ( f32 x, f32 y )
|
||||
{
|
||||
M[2] = (T)x;
|
||||
M[6] = (T)y;
|
||||
definitelyIdentityMatrix = definitelyIdentityMatrix && (x==0.0f) && (y==0.0f) ;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline void CMatrix4<T>::setTextureScale ( f32 sx, f32 sy )
|
||||
inline CMatrix4<T>& CMatrix4<T>::setTextureScale ( f32 sx, f32 sy )
|
||||
{
|
||||
M[0] = (T)sx;
|
||||
M[5] = (T)sy;
|
||||
definitelyIdentityMatrix = definitelyIdentityMatrix && (sx==1.0f) && (sy==1.0f) ;
|
||||
definitelyIdentityMatrix = definitelyIdentityMatrix && (sx==1.0f) && (sy==1.0f);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline void CMatrix4<T>::setTextureScaleCenter( f32 sx, f32 sy )
|
||||
inline CMatrix4<T>& CMatrix4<T>::setTextureScaleCenter( f32 sx, f32 sy )
|
||||
{
|
||||
M[0] = (T)sx;
|
||||
M[2] = (T)(-0.5f * sx + 0.5f);
|
||||
M[5] = (T)sy;
|
||||
M[6] = (T)(-0.5f * sy + 0.5f);
|
||||
definitelyIdentityMatrix = definitelyIdentityMatrix && (sx==1.0f) && (sy==1.0f) ;
|
||||
M[8] = (T)(0.5f - 0.5f * sx);
|
||||
M[9] = (T)(0.5f - 0.5f * sy);
|
||||
definitelyIdentityMatrix = definitelyIdentityMatrix && (sx==1.0f) && (sy==1.0f);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! sets all matrix data members at once
|
||||
template <class T>
|
||||
inline void CMatrix4<T>::setM(const T* data)
|
||||
inline CMatrix4<T>& CMatrix4<T>::setM(const T* data)
|
||||
{
|
||||
for (u32 i = 0; i < 16; ++i)
|
||||
M[i] = data[i];
|
||||
memcpy(M,data, 16*sizeof(T));
|
||||
|
||||
definitelyIdentityMatrix = false;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! sets if the matrix is definitely identity matrix
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
#include "CColorConverter.h"
|
||||
#include "IWriteFile.h"
|
||||
#include "CImage.h"
|
||||
#include "CColorConverter.h"
|
||||
#include "irrString.h"
|
||||
|
||||
#ifdef _IRR_COMPILE_WITH_LIBJPEG_
|
||||
|
@ -23,7 +22,6 @@ extern "C"
|
|||
#include "jpeglib/jpeglib.h"
|
||||
#include "jpeglib/jerror.h"
|
||||
#endif
|
||||
#include <setjmp.h>
|
||||
}
|
||||
|
||||
|
||||
|
@ -32,118 +30,156 @@ namespace irr
|
|||
namespace video
|
||||
{
|
||||
|
||||
|
||||
// The writer uses a 4k buffer and flushes to disk each time it's filled
|
||||
#define OUTPUT_BUF_SIZE 4096
|
||||
typedef struct
|
||||
{
|
||||
struct jpeg_destination_mgr pub; /* public fields */
|
||||
struct jpeg_destination_mgr pub;/* public fields */
|
||||
|
||||
JOCTET * buffer; /* image buffer */
|
||||
u32 buffer_size; /* image buffer size */
|
||||
io::IWriteFile* file; /* target file */
|
||||
JOCTET buffer[OUTPUT_BUF_SIZE]; /* image buffer */
|
||||
} mem_destination_mgr;
|
||||
|
||||
|
||||
typedef mem_destination_mgr * mem_dest_ptr;
|
||||
|
||||
void init_destination (j_compress_ptr cinfo)
|
||||
|
||||
// init
|
||||
static void jpeg_init_destination(j_compress_ptr cinfo)
|
||||
{
|
||||
mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest;
|
||||
dest->pub.next_output_byte = dest->buffer;
|
||||
dest->pub.free_in_buffer = OUTPUT_BUF_SIZE;
|
||||
}
|
||||
|
||||
|
||||
// flush to disk and reset buffer
|
||||
static boolean jpeg_empty_output_buffer(j_compress_ptr cinfo)
|
||||
{
|
||||
mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest;
|
||||
|
||||
/* image buffer must be allocated before mem_dest routines are called. */
|
||||
if(dest->buffer == NULL) {
|
||||
//fprintf(stderr, "jmem_dest: init_destination: buffer not allocated\n");
|
||||
}
|
||||
// for now just exit upon file error
|
||||
if (dest->file->write(dest->buffer, OUTPUT_BUF_SIZE) != OUTPUT_BUF_SIZE)
|
||||
ERREXIT (cinfo, JERR_FILE_WRITE);
|
||||
|
||||
dest->pub.next_output_byte = dest->buffer;
|
||||
dest->pub.free_in_buffer = dest->buffer_size;
|
||||
dest->pub.free_in_buffer = OUTPUT_BUF_SIZE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
boolean empty_output_buffer (j_compress_ptr cinfo)
|
||||
{
|
||||
/*
|
||||
mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest;
|
||||
*/
|
||||
// empty_output_buffer: buffer should not ever be full\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
void term_destination (j_compress_ptr cinfo)
|
||||
static void jpeg_term_destination(j_compress_ptr cinfo)
|
||||
{
|
||||
mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest;
|
||||
size_t datacount = dest->buffer_size - dest->pub.free_in_buffer;
|
||||
const s32 datacount = OUTPUT_BUF_SIZE - dest->pub.free_in_buffer;
|
||||
// for now just exit upon file error
|
||||
if (dest->file->write(dest->buffer, datacount) != datacount)
|
||||
ERREXIT (cinfo, JERR_FILE_WRITE);
|
||||
}
|
||||
|
||||
void jpeg_memory_dest (j_compress_ptr cinfo, u8 *jfif_buffer,
|
||||
s32 buf_size)
|
||||
|
||||
// set up buffer data
|
||||
static void jpeg_file_dest(j_compress_ptr cinfo, io::IWriteFile* file)
|
||||
{
|
||||
mem_dest_ptr dest;
|
||||
if (cinfo->dest == NULL)
|
||||
{ /* first time for this JPEG object? */
|
||||
cinfo->dest = (struct jpeg_destination_mgr *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo,
|
||||
JPOOL_PERMANENT,
|
||||
sizeof(mem_destination_mgr));
|
||||
}
|
||||
|
||||
if(jfif_buffer == NULL) {
|
||||
//fprintf(stderr, "jpeg_memory_dest: memory buffer needs to be allocated\n");
|
||||
//ERREXIT(cinfo, JERR_BUFFER_SIZE);
|
||||
return;
|
||||
}
|
||||
mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest; /* for casting */
|
||||
|
||||
if (cinfo->dest == NULL) { /* first time for this JPEG object? */
|
||||
cinfo->dest = (struct jpeg_destination_mgr *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
|
||||
(size_t) sizeof(mem_destination_mgr));
|
||||
}
|
||||
/* Initialize method pointers */
|
||||
dest->pub.init_destination = jpeg_init_destination;
|
||||
dest->pub.empty_output_buffer = jpeg_empty_output_buffer;
|
||||
dest->pub.term_destination = jpeg_term_destination;
|
||||
|
||||
dest = (mem_dest_ptr) cinfo->dest; /* for casting */
|
||||
|
||||
/* Initialize method pointers */
|
||||
dest->pub.init_destination = init_destination;
|
||||
dest->pub.empty_output_buffer = empty_output_buffer;
|
||||
dest->pub.term_destination = term_destination;
|
||||
|
||||
/* Initialize private member */
|
||||
dest->buffer = (JOCTET*)jfif_buffer;
|
||||
dest->buffer_size = buf_size;
|
||||
/* Initialize private member */
|
||||
dest->file = file;
|
||||
}
|
||||
|
||||
|
||||
/* write_JPEG_memory: store JPEG compressed image into memory.
|
||||
*/
|
||||
void write_JPEG_memory (void *img_buf, s32 width, s32 height, u32 bpp, u32 pitch,
|
||||
u8 *jpeg_buffer, u32 jpeg_buffer_size,
|
||||
s32 quality, u32 *jpeg_comp_size)
|
||||
static bool writeJPEGFile(io::IWriteFile* file, IImage* image, u32 quality)
|
||||
{
|
||||
void (*format)(const void*, s32, void*) = 0;
|
||||
switch( image->getColorFormat () )
|
||||
{
|
||||
case ECF_R8G8B8:
|
||||
format = CColorConverter::convert_R8G8B8toR8G8B8;
|
||||
break;
|
||||
case ECF_A8R8G8B8:
|
||||
format = CColorConverter::convert_A8R8G8B8toR8G8B8;
|
||||
break;
|
||||
case ECF_A1R5G5B5:
|
||||
format = CColorConverter::convert_A1R5G5B5toB8G8R8;
|
||||
break;
|
||||
case ECF_R5G6B5:
|
||||
format = CColorConverter::convert_R5G6B5toR8G8B8;
|
||||
break;
|
||||
}
|
||||
|
||||
// couldn't find a color converter
|
||||
if ( 0 == format )
|
||||
return false;
|
||||
|
||||
const core::dimension2di dim = image->getDimension();
|
||||
|
||||
struct jpeg_compress_struct cinfo;
|
||||
struct jpeg_error_mgr jerr;
|
||||
|
||||
/* More stuff */
|
||||
JSAMPROW row_pointer[1]; /* pointer to JSAMPLE row[s] */
|
||||
|
||||
cinfo.err = jpeg_std_error(&jerr);
|
||||
|
||||
jpeg_create_compress(&cinfo);
|
||||
jpeg_memory_dest(&cinfo, jpeg_buffer, jpeg_buffer_size);
|
||||
cinfo.image_width = width;
|
||||
cinfo.image_height = height;
|
||||
cinfo.input_components = bpp;
|
||||
jpeg_file_dest(&cinfo, file);
|
||||
cinfo.image_width = dim.Width;
|
||||
cinfo.image_height = dim.Height;
|
||||
cinfo.input_components = 3;
|
||||
cinfo.in_color_space = JCS_RGB;
|
||||
|
||||
jpeg_set_defaults(&cinfo);
|
||||
|
||||
if ( 0 == quality )
|
||||
quality = 75;
|
||||
|
||||
jpeg_set_quality(&cinfo, quality, TRUE);
|
||||
jpeg_start_compress(&cinfo, TRUE);
|
||||
|
||||
while (cinfo.next_scanline < cinfo.image_height)
|
||||
u8 * dest = new u8[dim.Width*3];
|
||||
|
||||
if (dest)
|
||||
{
|
||||
row_pointer[0] = (u8*) img_buf + (cinfo.next_scanline * pitch );
|
||||
jpeg_write_scanlines(&cinfo, row_pointer, 1);
|
||||
}
|
||||
|
||||
/* Step 6: Finish compression */
|
||||
jpeg_finish_compress(&cinfo);
|
||||
|
||||
{
|
||||
mem_dest_ptr dest = (mem_dest_ptr) cinfo.dest;
|
||||
*jpeg_comp_size = dest->buffer_size - dest->pub.free_in_buffer;
|
||||
const u32 pitch = image->getPitch();
|
||||
JSAMPROW row_pointer[1]; /* pointer to JSAMPLE row[s] */
|
||||
row_pointer[0] = dest;
|
||||
|
||||
u8* src = (u8*)image->lock();
|
||||
|
||||
while (cinfo.next_scanline < cinfo.image_height)
|
||||
{
|
||||
// convert next line
|
||||
format( src, dim.Width, dest );
|
||||
src += pitch;
|
||||
jpeg_write_scanlines(&cinfo, row_pointer, 1);
|
||||
}
|
||||
image->unlock();
|
||||
|
||||
delete [] dest;
|
||||
|
||||
/* Step 6: Finish compression */
|
||||
jpeg_finish_compress(&cinfo);
|
||||
}
|
||||
|
||||
/* Step 7: Destroy */
|
||||
jpeg_destroy_compress(&cinfo);
|
||||
|
||||
return (dest != 0);
|
||||
}
|
||||
|
||||
|
||||
} // namespace video
|
||||
} // namespace irr
|
||||
|
||||
|
@ -169,63 +205,17 @@ CImageWriterJPG::CImageWriterJPG()
|
|||
|
||||
bool CImageWriterJPG::isAWriteableFileExtension(const c8* fileName) const
|
||||
{
|
||||
return strstr(fileName, ".jpg") != 0 || strstr(fileName, ".jpeg") != 0;
|
||||
const char* dot = strrchr (fileName, '.');
|
||||
return dot && (!strcmp (dot, ".jpg") || !strcmp (dot, ".jpeg"));
|
||||
}
|
||||
|
||||
|
||||
bool CImageWriterJPG::writeImage(io::IWriteFile *file, IImage *input,u32 quality) const
|
||||
bool CImageWriterJPG::writeImage(io::IWriteFile *file, IImage *image, u32 quality) const
|
||||
{
|
||||
#ifndef _IRR_COMPILE_WITH_LIBJPEG_
|
||||
return false;
|
||||
#else
|
||||
|
||||
core::dimension2di dim = input->getDimension();
|
||||
IImage * image = new CImage(ECF_R8G8B8, dim );
|
||||
|
||||
void (*format)(const void*, s32, void*) = 0;
|
||||
switch( input->getColorFormat () )
|
||||
{
|
||||
case ECF_R8G8B8: format = CColorConverter::convert_R8G8B8toR8G8B8; break;
|
||||
case ECF_A8R8G8B8: format = CColorConverter::convert_A8R8G8B8toR8G8B8; break;
|
||||
case ECF_A1R5G5B5: format = CColorConverter::convert_A1R5G5B5toB8G8R8; break;
|
||||
case ECF_R5G6B5: format = CColorConverter::convert_R5G6B5toR8G8B8; break;
|
||||
}
|
||||
|
||||
// couldn't find a color converter
|
||||
if ( 0 == format )
|
||||
return false;
|
||||
|
||||
s32 y;
|
||||
void *src = input->lock();
|
||||
void *dst = image->lock();
|
||||
for ( y = 0; y!= dim.Height; ++y )
|
||||
{
|
||||
format( src, dim.Width, dst );
|
||||
src = (void*) ( (u8*) src + input->getPitch () );
|
||||
dst = (void*) ( (u8*) dst + image->getPitch () );
|
||||
}
|
||||
input->unlock ();
|
||||
image->unlock ();
|
||||
|
||||
// temp buffer
|
||||
u32 destSize = image->getImageDataSizeInBytes ();
|
||||
u8 * dest = new u8 [ destSize ];
|
||||
|
||||
if ( 0 == quality )
|
||||
quality = 75;
|
||||
|
||||
write_JPEG_memory ( image->lock (), dim.Width, dim.Height,
|
||||
image->getBytesPerPixel(), image->getPitch(),
|
||||
dest, destSize,
|
||||
quality,
|
||||
&destSize);
|
||||
|
||||
file->write ( dest, destSize );
|
||||
|
||||
image->drop ();
|
||||
delete [] dest;
|
||||
|
||||
return true;
|
||||
return writeJPEGFile(file, image, quality);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -78,7 +78,7 @@ bool CImageWriterPNG::writeImage(io::IWriteFile* file, IImage* image,u32 param)
|
|||
NULL, (png_error_ptr)png_cpexcept_error, NULL);
|
||||
if (!png_ptr)
|
||||
{
|
||||
os::Printer::log("LOAD PNG: Internal PNG create write struct failure\n", file->getFileName(), ELL_ERROR);
|
||||
os::Printer::log("PNGWriter: Internal PNG create write struct failure\n", file->getFileName(), ELL_ERROR);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -86,7 +86,7 @@ bool CImageWriterPNG::writeImage(io::IWriteFile* file, IImage* image,u32 param)
|
|||
png_infop info_ptr = png_create_info_struct(png_ptr);
|
||||
if (!info_ptr)
|
||||
{
|
||||
os::Printer::log("LOAD PNG: Internal PNG create info struct failure\n", file->getFileName(), ELL_ERROR);
|
||||
os::Printer::log("PNGWriter: Internal PNG create info struct failure\n", file->getFileName(), ELL_ERROR);
|
||||
png_destroy_write_struct(&png_ptr, NULL);
|
||||
return false;
|
||||
}
|
||||
|
@ -132,7 +132,7 @@ bool CImageWriterPNG::writeImage(io::IWriteFile* file, IImage* image,u32 param)
|
|||
u8* tmpImage = new u8[image->getDimension().Height*lineWidth];
|
||||
if (!tmpImage)
|
||||
{
|
||||
os::Printer::log("LOAD PNG: Internal PNG create image failure\n", file->getFileName(), ELL_ERROR);
|
||||
os::Printer::log("PNGWriter: Internal PNG create image failure\n", file->getFileName(), ELL_ERROR);
|
||||
png_destroy_write_struct(&png_ptr, &info_ptr);
|
||||
return false;
|
||||
}
|
||||
|
@ -161,7 +161,7 @@ bool CImageWriterPNG::writeImage(io::IWriteFile* file, IImage* image,u32 param)
|
|||
u8** RowPointers = new png_bytep[image->getDimension().Height];
|
||||
if (!RowPointers)
|
||||
{
|
||||
os::Printer::log("LOAD PNG: Internal PNG create row pointers failure\n", file->getFileName(), ELL_ERROR);
|
||||
os::Printer::log("PNGWriter: Internal PNG create row pointers failure\n", file->getFileName(), ELL_ERROR);
|
||||
png_destroy_write_struct(&png_ptr, &info_ptr);
|
||||
delete [] tmpImage;
|
||||
return false;
|
||||
|
|
|
@ -2272,7 +2272,7 @@ void COpenGLDriver::setFog(SColor c, bool linearFog, f32 start,
|
|||
{
|
||||
CNullDriver::setFog(c, linearFog, start, end, density, pixelFog, rangeFog);
|
||||
|
||||
glFogf(GL_FOG_MODE, linearFog ? GL_LINEAR : GL_EXP);
|
||||
glFogf(GL_FOG_MODE, GLfloat(linearFog ? GL_LINEAR : GL_EXP));
|
||||
#ifdef GL_EXT_fog_coord
|
||||
if (FeatureAvailable[IRR_EXT_fog_coord])
|
||||
glFogi(GL_FOG_COORDINATE_SOURCE, GL_FRAGMENT_DEPTH);
|
||||
|
|
Loading…
Reference in New Issue