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-e03cc46cb475
master
hybrid 2008-04-12 23:02:15 +00:00
parent 6a0d4ea7b2
commit 0e63486fbe
7 changed files with 417 additions and 352 deletions

View File

@ -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.

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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

View File

@ -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
}

View File

@ -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;

View File

@ -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);