Mass code cleanup
This commit is contained in:
parent
6b79ef2f3f
commit
82ad4fb5c8
|
@ -1,10 +0,0 @@
|
||||||
#include "CTimer.h"
|
|
||||||
#include <cmath>
|
|
||||||
|
|
||||||
namespace AnimUtil
|
|
||||||
{
|
|
||||||
float SecondsMod900()
|
|
||||||
{
|
|
||||||
return fmod((float) CTimer::GlobalTime(), 900.f);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
#ifndef ANIMUTIL_H
|
|
||||||
#define ANIMUTIL_H
|
|
||||||
|
|
||||||
namespace AnimUtil
|
|
||||||
{
|
|
||||||
float SecondsMod900();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // ANIMUTIL_H
|
|
|
@ -1,7 +1,7 @@
|
||||||
#include "CColor.h"
|
#include "CColor.h"
|
||||||
|
|
||||||
CColor::CColor()
|
CColor::CColor()
|
||||||
: r(0.f), g(0.f), b(0.f), a(0.f)
|
: R(0.f), G(0.f), B(0.f), A(0.f)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,42 +9,42 @@ CColor::CColor(IInputStream& rInput, bool Integral /*= false*/)
|
||||||
{
|
{
|
||||||
if (Integral)
|
if (Integral)
|
||||||
{
|
{
|
||||||
r = (u8) rInput.ReadByte() / 255.f;
|
R = (u8) rInput.ReadByte() / 255.f;
|
||||||
g = (u8) rInput.ReadByte() / 255.f;
|
G = (u8) rInput.ReadByte() / 255.f;
|
||||||
b = (u8) rInput.ReadByte() / 255.f;
|
B = (u8) rInput.ReadByte() / 255.f;
|
||||||
a = (u8) rInput.ReadByte() / 255.f;
|
A = (u8) rInput.ReadByte() / 255.f;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
r = rInput.ReadFloat();
|
R = rInput.ReadFloat();
|
||||||
g = rInput.ReadFloat();
|
G = rInput.ReadFloat();
|
||||||
b = rInput.ReadFloat();
|
B = rInput.ReadFloat();
|
||||||
a = rInput.ReadFloat();
|
A = rInput.ReadFloat();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CColor::CColor(float rgba)
|
CColor::CColor(float RGBA)
|
||||||
: r(rgba), g(rgba), b(rgba), a(rgba)
|
: R(RGBA), G(RGBA), B(RGBA), A(RGBA)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
CColor::CColor(float _r, float _g, float _b, float _a /*= 1.f*/)
|
CColor::CColor(float _R, float _G, float _B, float _A /*= 1.f*/)
|
||||||
: r(_r), g(_g), b(_b), a(_a)
|
: R(_R), G(_G), B(_B), A(_A)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void CColor::SetIntegral(u8 rgba)
|
void CColor::SetIntegral(u8 RGBA)
|
||||||
{
|
{
|
||||||
float f = rgba / 255.f;
|
float f = RGBA / 255.f;
|
||||||
r = g = b = a = f;
|
R = G = B = A = f;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CColor::SetIntegral(u8 _r, u8 _g, u8 _b, u8 _a /*= 255*/)
|
void CColor::SetIntegral(u8 _R, u8 _G, u8 _B, u8 _A /*= 255*/)
|
||||||
{
|
{
|
||||||
r = _r / 255.f;
|
R = _R / 255.f;
|
||||||
g = _g / 255.f;
|
G = _G / 255.f;
|
||||||
b = _b / 255.f;
|
B = _B / 255.f;
|
||||||
a = _a / 255.f;
|
A = _A / 255.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CColor::Write(IOutputStream &rOutput, bool Integral /*= false*/)
|
void CColor::Write(IOutputStream &rOutput, bool Integral /*= false*/)
|
||||||
|
@ -56,37 +56,37 @@ void CColor::Write(IOutputStream &rOutput, bool Integral /*= false*/)
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rOutput.WriteFloat(r);
|
rOutput.WriteFloat(R);
|
||||||
rOutput.WriteFloat(g);
|
rOutput.WriteFloat(G);
|
||||||
rOutput.WriteFloat(b);
|
rOutput.WriteFloat(B);
|
||||||
rOutput.WriteFloat(a);
|
rOutput.WriteFloat(A);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
long CColor::ToLongRGBA() const
|
long CColor::ToLongRGBA() const
|
||||||
{
|
{
|
||||||
u8 _r = (u8) (r * 255);
|
u8 _R = (u8) (R * 255);
|
||||||
u8 _g = (u8) (g * 255);
|
u8 _G = (u8) (G * 255);
|
||||||
u8 _b = (u8) (b * 255);
|
u8 _B = (u8) (B * 255);
|
||||||
u8 _a = (u8) (a * 255);
|
u8 _A = (u8) (A * 255);
|
||||||
return (_r << 24) | (_g << 16) | (_b << 8) | _a;
|
return (_R << 24) | (_G << 16) | (_B << 8) | _A;
|
||||||
}
|
}
|
||||||
|
|
||||||
long CColor::ToLongARGB() const
|
long CColor::ToLongARGB() const
|
||||||
{
|
{
|
||||||
u8 _r = (u8) (r * 255);
|
u8 _R = (u8) (R * 255);
|
||||||
u8 _g = (u8) (g * 255);
|
u8 _G = (u8) (G * 255);
|
||||||
u8 _b = (u8) (b * 255);
|
u8 _B = (u8) (B * 255);
|
||||||
u8 _a = (u8) (a * 255);
|
u8 _A = (u8) (A * 255);
|
||||||
return (_a << 24) | (_r << 16) | (_g << 8) | _b;
|
return (_A << 24) | (_R << 16) | (_G << 8) | _B;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CColor::operator==(const CColor& rkOther) const
|
bool CColor::operator==(const CColor& rkOther) const
|
||||||
{
|
{
|
||||||
return ((r == rkOther.r) &&
|
return ((R == rkOther.R) &&
|
||||||
(g == rkOther.g) &&
|
(G == rkOther.G) &&
|
||||||
(b == rkOther.b) &&
|
(B == rkOther.B) &&
|
||||||
(a == rkOther.a));
|
(A == rkOther.A));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CColor::operator!=(const CColor& rkOther) const
|
bool CColor::operator!=(const CColor& rkOther) const
|
||||||
|
@ -96,10 +96,10 @@ bool CColor::operator!=(const CColor& rkOther) const
|
||||||
|
|
||||||
CColor CColor::operator+(const CColor& rkOther) const
|
CColor CColor::operator+(const CColor& rkOther) const
|
||||||
{
|
{
|
||||||
float NewR = fmin(r + rkOther.r, 1.f);
|
float NewR = fmin(R + rkOther.R, 1.f);
|
||||||
float NewG = fmin(g + rkOther.g, 1.f);
|
float NewG = fmin(G + rkOther.G, 1.f);
|
||||||
float NewB = fmin(b + rkOther.b, 1.f);
|
float NewB = fmin(B + rkOther.B, 1.f);
|
||||||
float NewA = fmin(a + rkOther.a, 1.f);
|
float NewA = fmin(A + rkOther.A, 1.f);
|
||||||
return CColor(NewR, NewG, NewB, NewA);
|
return CColor(NewR, NewG, NewB, NewA);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,10 +110,10 @@ void CColor::operator+=(const CColor& rkOther)
|
||||||
|
|
||||||
CColor CColor::operator-(const CColor& rkOther) const
|
CColor CColor::operator-(const CColor& rkOther) const
|
||||||
{
|
{
|
||||||
float NewR = fmax(r - rkOther.r, 0.f);
|
float NewR = fmax(R - rkOther.R, 0.f);
|
||||||
float NewG = fmax(g - rkOther.g, 0.f);
|
float NewG = fmax(G - rkOther.G, 0.f);
|
||||||
float NewB = fmax(b - rkOther.b, 0.f);
|
float NewB = fmax(B - rkOther.B, 0.f);
|
||||||
float NewA = fmax(a - rkOther.a, 0.f);
|
float NewA = fmax(A - rkOther.A, 0.f);
|
||||||
return CColor(NewR, NewG, NewB, NewA);
|
return CColor(NewR, NewG, NewB, NewA);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,10 +124,10 @@ void CColor::operator-=(const CColor& other)
|
||||||
|
|
||||||
CColor CColor::operator*(const CColor& rkOther) const
|
CColor CColor::operator*(const CColor& rkOther) const
|
||||||
{
|
{
|
||||||
float NewR = r * rkOther.r;
|
float NewR = R * rkOther.R;
|
||||||
float NewG = g * rkOther.g;
|
float NewG = G * rkOther.G;
|
||||||
float NewB = b * rkOther.b;
|
float NewB = B * rkOther.B;
|
||||||
float NewA = a * rkOther.a;
|
float NewA = A * rkOther.A;
|
||||||
return CColor(NewR, NewG, NewB, NewA);
|
return CColor(NewR, NewG, NewB, NewA);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,26 +136,26 @@ void CColor::operator*=(const CColor& rkOther)
|
||||||
*this = (*this * rkOther);
|
*this = (*this * rkOther);
|
||||||
}
|
}
|
||||||
|
|
||||||
CColor CColor::operator*(float other) const
|
CColor CColor::operator*(float Other) const
|
||||||
{
|
{
|
||||||
float NewR = fmin( fmax(r * other, 0.f), 1.f);
|
float NewR = fmin( fmax(R * Other, 0.f), 1.f);
|
||||||
float NewG = fmin( fmax(g * other, 0.f), 1.f);
|
float NewG = fmin( fmax(G * Other, 0.f), 1.f);
|
||||||
float NewB = fmin( fmax(b * other, 0.f), 1.f);
|
float NewB = fmin( fmax(B * Other, 0.f), 1.f);
|
||||||
float NewA = fmin( fmax(a * other, 0.f), 1.f);
|
float NewA = fmin( fmax(A * Other, 0.f), 1.f);
|
||||||
return CColor(NewR, NewG, NewB, NewA);
|
return CColor(NewR, NewG, NewB, NewA);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CColor::operator*=(float other)
|
void CColor::operator*=(float Other)
|
||||||
{
|
{
|
||||||
*this = (*this * other);
|
*this = (*this * Other);
|
||||||
}
|
}
|
||||||
|
|
||||||
CColor CColor::operator/(const CColor& rkOther) const
|
CColor CColor::operator/(const CColor& rkOther) const
|
||||||
{
|
{
|
||||||
float NewR = (rkOther.r == 0.f) ? 0.f : r / rkOther.r;
|
float NewR = (rkOther.R == 0.f) ? 0.f : R / rkOther.R;
|
||||||
float NewG = (rkOther.g == 0.f) ? 0.f : g / rkOther.g;
|
float NewG = (rkOther.G == 0.f) ? 0.f : G / rkOther.G;
|
||||||
float NewB = (rkOther.b == 0.f) ? 0.f : b / rkOther.b;
|
float NewB = (rkOther.B == 0.f) ? 0.f : B / rkOther.B;
|
||||||
float NewA = (rkOther.a == 0.f) ? 0.f : a / rkOther.a;
|
float NewA = (rkOther.A == 0.f) ? 0.f : A / rkOther.A;
|
||||||
return CColor(NewR, NewG, NewB, NewA);
|
return CColor(NewR, NewG, NewB, NewA);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -165,45 +165,45 @@ void CColor::operator/=(const CColor& rkOther)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ************ STATIC ************
|
// ************ STATIC ************
|
||||||
CColor CColor::Integral(u8 rgba)
|
CColor CColor::Integral(u8 RGBA)
|
||||||
{
|
{
|
||||||
CColor out;
|
CColor Out;
|
||||||
out.SetIntegral(rgba);
|
Out.SetIntegral(RGBA);
|
||||||
return out;
|
return Out;
|
||||||
}
|
}
|
||||||
|
|
||||||
CColor CColor::Integral(u8 _r, u8 _g, u8 _b, u8 _a /*= 255*/)
|
CColor CColor::Integral(u8 _R, u8 _G, u8 _B, u8 _A /*= 255*/)
|
||||||
{
|
{
|
||||||
CColor out;
|
CColor Out;
|
||||||
out.SetIntegral(_r, _g, _b, _a);
|
Out.SetIntegral(_R, _G, _B, _A);
|
||||||
return out;
|
return Out;
|
||||||
}
|
}
|
||||||
|
|
||||||
CColor CColor::RandomColor(bool transparent)
|
CColor CColor::RandomColor(bool Transparent)
|
||||||
{
|
{
|
||||||
float _r = (rand() % 255) / 255.f;
|
float _R = (rand() % 255) / 255.f;
|
||||||
float _g = (rand() % 255) / 255.f;
|
float _G = (rand() % 255) / 255.f;
|
||||||
float _b = (rand() % 255) / 255.f;
|
float _B = (rand() % 255) / 255.f;
|
||||||
float _a = (transparent ? (rand() % 255) / 255.f : 0);
|
float _A = (Transparent ? (rand() % 255) / 255.f : 0);
|
||||||
return CColor(_r, _g, _b, _a);
|
return CColor(_R, _G, _B, _A);
|
||||||
}
|
}
|
||||||
|
|
||||||
CColor CColor::RandomLightColor(bool transparent)
|
CColor CColor::RandomLightColor(bool Transparent)
|
||||||
{
|
{
|
||||||
float _r = 0.5f + (rand() % 128) / 255.f;
|
float _R = 0.5f + (rand() % 128) / 255.f;
|
||||||
float _g = 0.5f + (rand() % 128) / 255.f;
|
float _G = 0.5f + (rand() % 128) / 255.f;
|
||||||
float _b = 0.5f + (rand() % 128) / 255.f;
|
float _B = 0.5f + (rand() % 128) / 255.f;
|
||||||
float _a = (transparent ? 0.5f + ((rand() % 128) / 255.f) : 0);
|
float _A = (Transparent ? 0.5f + ((rand() % 128) / 255.f) : 0);
|
||||||
return CColor(_r, _g, _b, _a);
|
return CColor(_R, _G, _B, _A);
|
||||||
}
|
}
|
||||||
|
|
||||||
CColor CColor::RandomDarkColor(bool transparent)
|
CColor CColor::RandomDarkColor(bool Transparent)
|
||||||
{
|
{
|
||||||
float _r = (rand() % 128) / 255.f;
|
float _R = (rand() % 128) / 255.f;
|
||||||
float _g = (rand() % 128) / 255.f;
|
float _G = (rand() % 128) / 255.f;
|
||||||
float _b = (rand() % 128) / 255.f;
|
float _B = (rand() % 128) / 255.f;
|
||||||
float _a = (transparent ? (rand() % 128) / 255.f : 0);
|
float _A = (Transparent ? (rand() % 128) / 255.f : 0);
|
||||||
return CColor(_r, _g, _b, _a);
|
return CColor(_R, _G, _B, _A);
|
||||||
}
|
}
|
||||||
|
|
||||||
// defining predefined colors
|
// defining predefined colors
|
||||||
|
|
|
@ -8,14 +8,14 @@
|
||||||
class CColor
|
class CColor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
float r, g, b, a;
|
float R, G, B, A;
|
||||||
|
|
||||||
CColor();
|
CColor();
|
||||||
CColor(IInputStream& rSrc, bool Integral = false);
|
CColor(IInputStream& rInput, bool Integral = false);
|
||||||
CColor(float rgba);
|
CColor(float RGBA);
|
||||||
CColor(float _r, float _g, float _b, float _a = 1.f);
|
CColor(float _R, float _G, float _B, float A = 1.f);
|
||||||
void SetIntegral(u8 rgba);
|
void SetIntegral(u8 RGBA);
|
||||||
void SetIntegral(u8 _r, u8 _g, u8 _b, u8 _a = 255);
|
void SetIntegral(u8 _R, u8 _G, u8 _B, u8 _A = 255);
|
||||||
void Write(IOutputStream& rOutput, bool Integral = false);
|
void Write(IOutputStream& rOutput, bool Integral = false);
|
||||||
|
|
||||||
long ToLongRGBA() const;
|
long ToLongRGBA() const;
|
||||||
|
@ -28,17 +28,17 @@ public:
|
||||||
void operator-=(const CColor& rkOther);
|
void operator-=(const CColor& rkOther);
|
||||||
CColor operator*(const CColor& rkOther) const;
|
CColor operator*(const CColor& rkOther) const;
|
||||||
void operator*=(const CColor& rkOther);
|
void operator*=(const CColor& rkOther);
|
||||||
CColor operator*(float other) const;
|
CColor operator*(float Other) const;
|
||||||
void operator*=(float other);
|
void operator*=(float Other);
|
||||||
CColor operator/(const CColor& rkOther) const;
|
CColor operator/(const CColor& rkOther) const;
|
||||||
void operator/=(const CColor& rkOther);
|
void operator/=(const CColor& rkOther);
|
||||||
|
|
||||||
// Static
|
// Static
|
||||||
static CColor Integral(u8 rgba);
|
static CColor Integral(u8 RGBA);
|
||||||
static CColor Integral(u8 _r, u8 _g, u8 _b, u8 _a = 255);
|
static CColor Integral(u8 _R, u8 _G, u8 _B, u8 _A = 255);
|
||||||
static CColor RandomColor(bool transparent);
|
static CColor RandomColor(bool Transparent);
|
||||||
static CColor RandomLightColor(bool transparent);
|
static CColor RandomLightColor(bool Transparent);
|
||||||
static CColor RandomDarkColor(bool transparent);
|
static CColor RandomDarkColor(bool Transparent);
|
||||||
|
|
||||||
// some predefined colors below for ease of use
|
// some predefined colors below for ease of use
|
||||||
static const CColor skRed;
|
static const CColor skRed;
|
||||||
|
|
|
@ -1,120 +0,0 @@
|
||||||
#include "CFourCC.h"
|
|
||||||
|
|
||||||
// ************ CONSTRUCTORS ************
|
|
||||||
CFourCC::CFourCC()
|
|
||||||
{
|
|
||||||
memset(mFourCC, 0, 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
CFourCC::CFourCC(const char *src)
|
|
||||||
{
|
|
||||||
*this = src;
|
|
||||||
}
|
|
||||||
|
|
||||||
CFourCC::CFourCC(const TString& src)
|
|
||||||
{
|
|
||||||
*this = src;
|
|
||||||
}
|
|
||||||
|
|
||||||
CFourCC::CFourCC(u32 src)
|
|
||||||
{
|
|
||||||
*this = src;
|
|
||||||
}
|
|
||||||
|
|
||||||
CFourCC::CFourCC(IInputStream& src)
|
|
||||||
{
|
|
||||||
src.ReadBytes(&mFourCC[0], 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ************ FUNCTIONALITY ************
|
|
||||||
void CFourCC::Write(IOutputStream &Output)
|
|
||||||
{
|
|
||||||
Output.WriteBytes(mFourCC, 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 CFourCC::ToLong() const
|
|
||||||
{
|
|
||||||
return mFourCC[0] << 24 | mFourCC[1] << 16 | mFourCC[2] << 8 | mFourCC[3];
|
|
||||||
}
|
|
||||||
|
|
||||||
TString CFourCC::ToString() const
|
|
||||||
{
|
|
||||||
return TString(mFourCC, 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
CFourCC CFourCC::ToUpper() const
|
|
||||||
{
|
|
||||||
CFourCC Out;
|
|
||||||
|
|
||||||
for (int c = 0; c < 4; c++)
|
|
||||||
{
|
|
||||||
if ((mFourCC[c] >= 0x61) && (mFourCC[c] <= 0x7A))
|
|
||||||
Out.mFourCC[c] = mFourCC[c] - 0x20;
|
|
||||||
else
|
|
||||||
Out.mFourCC[c] = mFourCC[c];
|
|
||||||
}
|
|
||||||
|
|
||||||
return Out;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ************ OPERATORS ************
|
|
||||||
CFourCC& CFourCC::operator=(const char *src)
|
|
||||||
{
|
|
||||||
memcpy(&mFourCC[0], src, 4);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
CFourCC& CFourCC::operator=(const TString& src)
|
|
||||||
{
|
|
||||||
memcpy(&mFourCC[0], src.CString(), 4);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
CFourCC& CFourCC::operator=(u32 src)
|
|
||||||
{
|
|
||||||
mFourCC[0] = (src >> 24) & 0xFF;
|
|
||||||
mFourCC[1] = (src >> 16) & 0xFF;
|
|
||||||
mFourCC[2] = (src >> 8) & 0xFF;
|
|
||||||
mFourCC[3] = (src >> 0) & 0xFF;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CFourCC::operator==(const CFourCC& other) const
|
|
||||||
{
|
|
||||||
return ((mFourCC[0] == other.mFourCC[0]) && (mFourCC[1] == other.mFourCC[1]) && (mFourCC[2] == other.mFourCC[2]) && (mFourCC[3] == other.mFourCC[3]));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CFourCC::operator!=(const CFourCC& other) const
|
|
||||||
{
|
|
||||||
return (!(*this == other));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CFourCC::operator>(const CFourCC& other) const
|
|
||||||
{
|
|
||||||
return (ToLong() > other.ToLong());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CFourCC::operator>=(const CFourCC& other) const
|
|
||||||
{
|
|
||||||
return (ToLong() >= other.ToLong());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CFourCC::operator<(const CFourCC& other) const
|
|
||||||
{
|
|
||||||
return (ToLong() < other.ToLong());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CFourCC::operator<=(const CFourCC& other) const
|
|
||||||
{
|
|
||||||
return (ToLong() <= other.ToLong());
|
|
||||||
}
|
|
||||||
|
|
||||||
char CFourCC::operator[](int index)
|
|
||||||
{
|
|
||||||
return mFourCC[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
const char CFourCC::operator[](int index) const
|
|
||||||
{
|
|
||||||
return mFourCC[index];
|
|
||||||
}
|
|
|
@ -11,30 +11,73 @@ class CFourCC
|
||||||
char mFourCC[4];
|
char mFourCC[4];
|
||||||
public:
|
public:
|
||||||
// Constructors
|
// Constructors
|
||||||
CFourCC();
|
CFourCC() { memset(mFourCC, 0, 4); }
|
||||||
CFourCC(const char *src);
|
CFourCC(const char *pkSrc) { *this = pkSrc; }
|
||||||
CFourCC(const TString& src);
|
CFourCC(const TString& rkSrc) { *this = rkSrc; }
|
||||||
CFourCC(u32 src);
|
CFourCC(u32 Src) { *this = Src; }
|
||||||
CFourCC(IInputStream& src);
|
CFourCC(IInputStream& rSrc) { rSrc.ReadBytes(&mFourCC[0], 4); }
|
||||||
|
|
||||||
// Functionality
|
// Functionality
|
||||||
void Write(IOutputStream& Output);
|
inline void Write(IOutputStream& rOutput)
|
||||||
u32 ToLong() const;
|
{
|
||||||
TString ToString() const;
|
rOutput.WriteBytes(&mFourCC[0], 4);
|
||||||
CFourCC ToUpper() const;
|
}
|
||||||
|
|
||||||
|
inline u32 ToLong() const
|
||||||
|
{
|
||||||
|
return mFourCC[0] << 24 | mFourCC[1] << 16 | mFourCC[2] << 8 | mFourCC[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
inline TString ToString() const
|
||||||
|
{
|
||||||
|
return TString(mFourCC, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline CFourCC ToUpper() const
|
||||||
|
{
|
||||||
|
CFourCC Out;
|
||||||
|
|
||||||
|
for (int iChr = 0; iChr < 4; iChr++)
|
||||||
|
{
|
||||||
|
if ((mFourCC[iChr] >= 0x61) && (mFourCC[iChr] <= 0x7A))
|
||||||
|
Out.mFourCC[iChr] = mFourCC[iChr] - 0x20;
|
||||||
|
else
|
||||||
|
Out.mFourCC[iChr] = mFourCC[iChr];
|
||||||
|
}
|
||||||
|
|
||||||
|
return Out;
|
||||||
|
}
|
||||||
|
|
||||||
// Operators
|
// Operators
|
||||||
CFourCC& operator=(const char *src);
|
inline CFourCC& operator=(const char *pkSrc)
|
||||||
CFourCC& operator=(const TString& src);
|
{
|
||||||
CFourCC& operator=(u32 src);
|
memcpy(&mFourCC[0], pkSrc, 4);
|
||||||
bool operator==(const CFourCC& other) const;
|
return *this;
|
||||||
bool operator!=(const CFourCC& other) const;
|
}
|
||||||
bool operator>(const CFourCC& other) const;
|
|
||||||
bool operator>=(const CFourCC& other) const;
|
inline CFourCC& operator=(const TString& rkSrc)
|
||||||
bool operator<(const CFourCC& other) const;
|
{
|
||||||
bool operator<=(const CFourCC& other) const;
|
memcpy(&mFourCC[0], rkSrc.CString(), 4);
|
||||||
char operator[](int index);
|
return *this;
|
||||||
const char operator[](int index) const;
|
}
|
||||||
|
|
||||||
|
inline CFourCC& operator=(u32 Src)
|
||||||
|
{
|
||||||
|
mFourCC[0] = (Src >> 24) & 0xFF;
|
||||||
|
mFourCC[1] = (Src >> 16) & 0xFF;
|
||||||
|
mFourCC[2] = (Src >> 8) & 0xFF;
|
||||||
|
mFourCC[3] = (Src >> 0) & 0xFF;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator==(const CFourCC& rkOther) const { return ((mFourCC[0] == rkOther.mFourCC[0]) && (mFourCC[1] == rkOther.mFourCC[1]) && (mFourCC[2] == rkOther.mFourCC[2]) && (mFourCC[3] == rkOther.mFourCC[3])); }
|
||||||
|
inline bool operator!=(const CFourCC& rkOther) const { return (!(*this == rkOther)); }
|
||||||
|
inline bool operator>(const CFourCC& rkOther) const { return (ToLong() > rkOther.ToLong()); }
|
||||||
|
inline bool operator>=(const CFourCC& rkOther) const { return (ToLong() >= rkOther.ToLong()); }
|
||||||
|
inline bool operator<(const CFourCC& rkOther) const { return (ToLong() < rkOther.ToLong()); }
|
||||||
|
inline bool operator<=(const CFourCC& rkOther) const { return (ToLong() <= rkOther.ToLong()); }
|
||||||
|
inline char operator[](int Index) { return mFourCC[Index]; }
|
||||||
|
inline const char operator[](int Index) const { return mFourCC[Index]; }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CFOURCC_H
|
#endif // CFOURCC_H
|
||||||
|
|
|
@ -1,72 +0,0 @@
|
||||||
#include "CHashFNV1A.h"
|
|
||||||
|
|
||||||
const u64 CHashFNV1A::skFNVOffsetBasis32 = 0x811C9DC5;
|
|
||||||
const u64 CHashFNV1A::skFNVOffsetBasis64 = 0xCBF29CE484222325;
|
|
||||||
const u64 CHashFNV1A::skFNVPrime32 = 0x1000193;
|
|
||||||
const u64 CHashFNV1A::skFNVPrime64 = 0x100000001B3;
|
|
||||||
|
|
||||||
CHashFNV1A::CHashFNV1A()
|
|
||||||
{
|
|
||||||
Init32();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CHashFNV1A::Init32()
|
|
||||||
{
|
|
||||||
mHashLength = e32Bit;
|
|
||||||
mHash = skFNVOffsetBasis32;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CHashFNV1A::Init64()
|
|
||||||
{
|
|
||||||
mHashLength = e64Bit;
|
|
||||||
mHash = skFNVOffsetBasis64;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CHashFNV1A::HashData(const void *pData, u32 Size)
|
|
||||||
{
|
|
||||||
const char *pCharData = (const char*) pData;
|
|
||||||
u64 FNVPrime = (mHashLength == e32Bit) ? skFNVPrime32 : skFNVPrime64;
|
|
||||||
|
|
||||||
for (u32 i = 0; i < Size; i++)
|
|
||||||
{
|
|
||||||
mHash ^= *pCharData;
|
|
||||||
mHash *= FNVPrime;
|
|
||||||
pCharData++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 CHashFNV1A::GetHash32()
|
|
||||||
{
|
|
||||||
return (u32) mHash;
|
|
||||||
}
|
|
||||||
|
|
||||||
u64 CHashFNV1A::GetHash64()
|
|
||||||
{
|
|
||||||
return mHash;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ************ CONVENIENCE FUNCTIONS ************
|
|
||||||
void CHashFNV1A::HashByte(const u8& v)
|
|
||||||
{
|
|
||||||
HashData(&v, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CHashFNV1A::HashShort(const u16& v)
|
|
||||||
{
|
|
||||||
HashData(&v, 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CHashFNV1A::HashLong(const u32& v)
|
|
||||||
{
|
|
||||||
HashData(&v, 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CHashFNV1A::HashFloat(const float& v)
|
|
||||||
{
|
|
||||||
HashData(&v, 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CHashFNV1A::HashString(const TString& v)
|
|
||||||
{
|
|
||||||
HashData(v.Data(), v.Size());
|
|
||||||
}
|
|
|
@ -12,25 +12,51 @@ class CHashFNV1A
|
||||||
e32Bit, e64Bit
|
e32Bit, e64Bit
|
||||||
} mHashLength;
|
} mHashLength;
|
||||||
|
|
||||||
static const u64 skFNVOffsetBasis32;
|
static const u64 skFNVOffsetBasis32 = 0x811C9DC5;
|
||||||
static const u64 skFNVOffsetBasis64;
|
static const u64 skFNVOffsetBasis64 = 0xCBF29CE484222325;
|
||||||
static const u64 skFNVPrime32;
|
static const u64 skFNVPrime32 = 0x1000193;
|
||||||
static const u64 skFNVPrime64;
|
static const u64 skFNVPrime64 = 0x100000001B3;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CHashFNV1A();
|
CHashFNV1A()
|
||||||
void Init32();
|
{
|
||||||
void Init64();
|
Init32();
|
||||||
void HashData(const void *pData, u32 Size);
|
}
|
||||||
u32 GetHash32();
|
|
||||||
u64 GetHash64();
|
void Init32()
|
||||||
|
{
|
||||||
|
mHashLength = e32Bit;
|
||||||
|
mHash = skFNVOffsetBasis32;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Init64()
|
||||||
|
{
|
||||||
|
mHashLength = e64Bit;
|
||||||
|
mHash = skFNVOffsetBasis64;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HashData(const void *pkData, u32 Size)
|
||||||
|
{
|
||||||
|
const char *pkCharData = (const char*) pkData;
|
||||||
|
u64 FNVPrime = (mHashLength == e32Bit) ? skFNVPrime32 : skFNVPrime64;
|
||||||
|
|
||||||
|
for (u32 iByte = 0; iByte < Size; iByte++)
|
||||||
|
{
|
||||||
|
mHash ^= *pkCharData;
|
||||||
|
mHash *= FNVPrime;
|
||||||
|
pkCharData++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline u32 GetHash32() { return (u32) mHash; }
|
||||||
|
inline u64 GetHash64() { return mHash; }
|
||||||
|
|
||||||
// Convenience functions
|
// Convenience functions
|
||||||
void HashByte(const u8& v);
|
inline void HashByte(const u8& rkVal) { HashData(&rkVal, 1); }
|
||||||
void HashShort(const u16& v);
|
inline void HashShort(const u16& rkVal) { HashData(&rkVal, 2); }
|
||||||
void HashLong(const u32& v);
|
inline void HashLong(const u32& rkVal) { HashData(&rkVal, 4); }
|
||||||
void HashFloat(const float& v);
|
inline void HashFloat(const float& rkVal) { HashData(&rkVal, 4); }
|
||||||
void HashString(const TString& v);
|
inline void HashString(const TString& rkVal) { HashData(rkVal.Data(), rkVal.Size()); }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CHASHFNV1A_H
|
#endif // CHASHFNV1A_H
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
#include "CTimer.h"
|
#include "CTimer.h"
|
||||||
|
#include <cmath>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
|
||||||
CTimer::CTimer()
|
CTimer::CTimer()
|
||||||
|
: mStartTime(0)
|
||||||
|
, mStopTime(0)
|
||||||
|
, mStarted(false)
|
||||||
|
, mPaused(false)
|
||||||
{
|
{
|
||||||
mStartTime = 0;
|
|
||||||
mStopTime = 0;
|
|
||||||
mStarted = false;
|
|
||||||
mPaused = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CTimer::Start()
|
void CTimer::Start()
|
||||||
|
@ -83,7 +84,13 @@ double CTimer::Time()
|
||||||
return mStopTime;
|
return mStopTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ************ STATIC ************
|
||||||
double CTimer::GlobalTime()
|
double CTimer::GlobalTime()
|
||||||
{
|
{
|
||||||
return (double) clock() / CLOCKS_PER_SEC;
|
return (double) clock() / CLOCKS_PER_SEC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float CTimer::SecondsMod900()
|
||||||
|
{
|
||||||
|
return fmodf((float) GlobalTime(), 900.f);
|
||||||
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@ public:
|
||||||
|
|
||||||
// Static
|
// Static
|
||||||
static double GlobalTime();
|
static double GlobalTime();
|
||||||
|
static float SecondsMod900();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CTIMER_H
|
#endif // CTIMER_H
|
||||||
|
|
|
@ -11,9 +11,9 @@ using IOUtil::eLittleEndian;
|
||||||
using IOUtil::eBigEndian;
|
using IOUtil::eBigEndian;
|
||||||
|
|
||||||
CUniqueID::CUniqueID()
|
CUniqueID::CUniqueID()
|
||||||
|
: mLength(eInvalidUIDLength)
|
||||||
{
|
{
|
||||||
memset(mID, 0xFF, 16);
|
memset(mID, 0xFF, 16);
|
||||||
mLength = eInvalidUIDLength;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CUniqueID::CUniqueID(u64 ID)
|
CUniqueID::CUniqueID(u64 ID)
|
||||||
|
@ -72,15 +72,15 @@ CUniqueID::CUniqueID(u64 Part1, u64 Part2)
|
||||||
mLength = e128Bit;
|
mLength = e128Bit;
|
||||||
}
|
}
|
||||||
|
|
||||||
CUniqueID::CUniqueID(const char* ID)
|
CUniqueID::CUniqueID(const char* pkID)
|
||||||
{
|
{
|
||||||
*this = CUniqueID::FromString(ID);
|
*this = CUniqueID::FromString(pkID);
|
||||||
}
|
}
|
||||||
|
|
||||||
CUniqueID::CUniqueID(IInputStream& Input, EUIDLength Length)
|
CUniqueID::CUniqueID(IInputStream& rInput, EUIDLength Length)
|
||||||
{
|
{
|
||||||
memset(mID, 0, 16);
|
memset(mID, 0, 16);
|
||||||
Input.ReadBytes(&mID[16 - Length], Length);
|
rInput.ReadBytes(&mID[16 - Length], Length);
|
||||||
|
|
||||||
if (Length != e128Bit)
|
if (Length != e128Bit)
|
||||||
if (kSystemEndianness == eLittleEndian)
|
if (kSystemEndianness == eLittleEndian)
|
||||||
|
@ -120,8 +120,8 @@ TString CUniqueID::ToString() const
|
||||||
std::stringstream Ret;
|
std::stringstream Ret;
|
||||||
Ret << std::hex << std::setfill('0');
|
Ret << std::hex << std::setfill('0');
|
||||||
|
|
||||||
for (u32 i = 0; i < 16; i++)
|
for (u32 iByte = 0; iByte < 16; iByte++)
|
||||||
Ret << std::setw(2) << (u32) mID[i];
|
Ret << std::setw(2) << (u32) mID[iByte];
|
||||||
|
|
||||||
return Ret.str();
|
return Ret.str();
|
||||||
}
|
}
|
||||||
|
@ -159,44 +159,44 @@ bool CUniqueID::IsValid() const
|
||||||
}
|
}
|
||||||
|
|
||||||
// ************ OPERATORS ************
|
// ************ OPERATORS ************
|
||||||
void CUniqueID::operator=(const u64& Input)
|
void CUniqueID::operator=(const u64& rkInput)
|
||||||
{
|
{
|
||||||
*this = CUniqueID(Input);
|
*this = CUniqueID(rkInput);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CUniqueID::operator=(const char* Input)
|
void CUniqueID::operator=(const char* pkInput)
|
||||||
{
|
{
|
||||||
*this = CUniqueID(Input);
|
*this = CUniqueID(pkInput);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CUniqueID::operator==(const CUniqueID& Other) const
|
bool CUniqueID::operator==(const CUniqueID& rkOther) const
|
||||||
{
|
{
|
||||||
return ((mLength == Other.mLength) &&
|
return ((mLength == rkOther.mLength) &&
|
||||||
(memcmp(mID, Other.mID, 16) == 0));
|
(memcmp(mID, rkOther.mID, 16) == 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CUniqueID::operator!=(const CUniqueID& Other) const
|
bool CUniqueID::operator!=(const CUniqueID& rkOther) const
|
||||||
{
|
{
|
||||||
return (!(*this == Other));
|
return (!(*this == rkOther));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CUniqueID::operator>(const CUniqueID& Other) const
|
bool CUniqueID::operator>(const CUniqueID& rkOther) const
|
||||||
{
|
{
|
||||||
if (mLength != Other.mLength)
|
if (mLength != rkOther.mLength)
|
||||||
return mLength > Other.mLength;
|
return mLength > rkOther.mLength;
|
||||||
|
|
||||||
switch (mLength)
|
switch (mLength)
|
||||||
{
|
{
|
||||||
case e32Bit:
|
case e32Bit:
|
||||||
return (ToLong() > Other.ToLong());
|
return (ToLong() > rkOther.ToLong());
|
||||||
|
|
||||||
case e64Bit:
|
case e64Bit:
|
||||||
return (ToLongLong() > Other.ToLongLong());
|
return (ToLongLong() > rkOther.ToLongLong());
|
||||||
|
|
||||||
case e128Bit:
|
case e128Bit:
|
||||||
for (u32 i = 0; i < 16; i++)
|
for (u32 iByte = 0; iByte < 16; iByte++)
|
||||||
if (mID[i] != Other.mID[i])
|
if (mID[iByte] != rkOther.mID[iByte])
|
||||||
return (mID[i] > Other.mID[i]);
|
return (mID[iByte] > rkOther.mID[iByte]);
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -204,28 +204,28 @@ bool CUniqueID::operator>(const CUniqueID& Other) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CUniqueID::operator>=(const CUniqueID& Other) const
|
bool CUniqueID::operator>=(const CUniqueID& rkOther) const
|
||||||
{
|
{
|
||||||
return ((*this == Other) || (*this > Other));
|
return ((*this == rkOther) || (*this > rkOther));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CUniqueID::operator<(const CUniqueID& Other) const
|
bool CUniqueID::operator<(const CUniqueID& rkOther) const
|
||||||
{
|
{
|
||||||
if (mLength != Other.mLength)
|
if (mLength != rkOther.mLength)
|
||||||
return mLength < Other.mLength;
|
return mLength < rkOther.mLength;
|
||||||
|
|
||||||
switch (mLength)
|
switch (mLength)
|
||||||
{
|
{
|
||||||
case e32Bit:
|
case e32Bit:
|
||||||
return (ToLong() < Other.ToLong());
|
return (ToLong() < rkOther.ToLong());
|
||||||
|
|
||||||
case e64Bit:
|
case e64Bit:
|
||||||
return (ToLongLong() < Other.ToLongLong());
|
return (ToLongLong() < rkOther.ToLongLong());
|
||||||
|
|
||||||
case e128Bit:
|
case e128Bit:
|
||||||
for (u32 i = 0; i < 16; i++)
|
for (u32 iByte = 0; iByte < 16; iByte++)
|
||||||
if (mID[i] != Other.mID[i])
|
if (mID[iByte] != rkOther.mID[iByte])
|
||||||
return (mID[i] < Other.mID[i]);
|
return (mID[iByte] < rkOther.mID[iByte]);
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -233,9 +233,9 @@ bool CUniqueID::operator<(const CUniqueID& Other) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CUniqueID::operator<=(const CUniqueID& Other) const
|
bool CUniqueID::operator<=(const CUniqueID& rkOther) const
|
||||||
{
|
{
|
||||||
return ((*this == Other) || (*this < Other));
|
return ((*this == rkOther) || (*this < rkOther));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CUniqueID::operator==(u64 Other) const
|
bool CUniqueID::operator==(u64 Other) const
|
||||||
|
@ -249,10 +249,10 @@ bool CUniqueID::operator!=(u64 Other) const
|
||||||
}
|
}
|
||||||
|
|
||||||
// ************ STATIC ************
|
// ************ STATIC ************
|
||||||
CUniqueID CUniqueID::FromString(const TString& String)
|
CUniqueID CUniqueID::FromString(const TString& rkString)
|
||||||
{
|
{
|
||||||
// If the input is a hex ID in string form, then preserve it... otherwise, generate an ID by hashing the string
|
// If the input is a hex ID in string form, then preserve it... otherwise, generate an ID by hashing the string
|
||||||
TString Name = String.GetFileName(false);
|
TString Name = rkString.GetFileName(false);
|
||||||
u32 NameLength = Name.Length();
|
u32 NameLength = Name.Length();
|
||||||
|
|
||||||
if (Name.IsHexString())
|
if (Name.IsHexString())
|
||||||
|
@ -296,7 +296,7 @@ CUniqueID CUniqueID::FromString(const TString& String)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return CUniqueID(String.Hash64());
|
return CUniqueID(rkString.Hash64());
|
||||||
}
|
}
|
||||||
|
|
||||||
CUniqueID CUniqueID::FromData(void *pData, EUIDLength Length)
|
CUniqueID CUniqueID::FromData(void *pData, EUIDLength Length)
|
||||||
|
@ -312,8 +312,8 @@ CUniqueID CUniqueID::RandomID()
|
||||||
CUniqueID ID;
|
CUniqueID ID;
|
||||||
ID.mLength = e128Bit;
|
ID.mLength = e128Bit;
|
||||||
|
|
||||||
for (u32 i = 0; i < 16; i++)
|
for (u32 iByte = 0; iByte < 16; iByte++)
|
||||||
ID.mID[i] = rand() & 0xFF;
|
ID.mID[iByte] = rand() & 0xFF;
|
||||||
|
|
||||||
return ID;
|
return ID;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
#ifndef CUNIQUEID_H
|
#ifndef CUNIQUEID_H
|
||||||
#define CUNIQUEID_H
|
#define CUNIQUEID_H
|
||||||
|
|
||||||
#include "types.h"
|
|
||||||
#include "TString.h"
|
#include "TString.h"
|
||||||
|
#include "types.h"
|
||||||
#include <FileIO/FileIO.h>
|
#include <FileIO/FileIO.h>
|
||||||
|
|
||||||
enum EUIDLength
|
enum EUIDLength
|
||||||
|
@ -23,7 +23,7 @@ public:
|
||||||
CUniqueID(u64 ID);
|
CUniqueID(u64 ID);
|
||||||
CUniqueID(u64 ID, EUIDLength Length);
|
CUniqueID(u64 ID, EUIDLength Length);
|
||||||
CUniqueID(u64 Part1, u64 Part2);
|
CUniqueID(u64 Part1, u64 Part2);
|
||||||
CUniqueID(const char* ID);
|
CUniqueID(const char* pkID);
|
||||||
CUniqueID(IInputStream& Input, EUIDLength Length);
|
CUniqueID(IInputStream& Input, EUIDLength Length);
|
||||||
u32 ToLong() const;
|
u32 ToLong() const;
|
||||||
u64 ToLongLong() const;
|
u64 ToLongLong() const;
|
||||||
|
@ -34,20 +34,20 @@ public:
|
||||||
bool IsValid() const;
|
bool IsValid() const;
|
||||||
|
|
||||||
// Operators
|
// Operators
|
||||||
void operator=(const u64& Input);
|
void operator=(const u64& rkInput);
|
||||||
void operator=(const char *Input);
|
void operator=(const char *pkInput);
|
||||||
bool operator==(const CUniqueID& Other) const;
|
bool operator==(const CUniqueID& rkOther) const;
|
||||||
bool operator!=(const CUniqueID& Other) const;
|
bool operator!=(const CUniqueID& rkOther) const;
|
||||||
bool operator>(const CUniqueID& Other) const;
|
bool operator>(const CUniqueID& rkOther) const;
|
||||||
bool operator>=(const CUniqueID& Other) const;
|
bool operator>=(const CUniqueID& rkOther) const;
|
||||||
bool operator<(const CUniqueID& Other) const;
|
bool operator<(const CUniqueID& rkOther) const;
|
||||||
bool operator<=(const CUniqueID& Other) const;
|
bool operator<=(const CUniqueID& rkOther) const;
|
||||||
bool operator==(u64 Other) const;
|
bool operator==(u64 Other) const;
|
||||||
bool operator!=(u64 Other) const;
|
bool operator!=(u64 Other) const;
|
||||||
|
|
||||||
// Static
|
// Static
|
||||||
static CUniqueID FromString(const TString& String);
|
static CUniqueID FromString(const TString& rkString);
|
||||||
static CUniqueID FromData(void *pData, EUIDLength Length);
|
static CUniqueID FromData(void *pkData, EUIDLength Length);
|
||||||
static CUniqueID RandomID();
|
static CUniqueID RandomID();
|
||||||
|
|
||||||
static CUniqueID skInvalidID32;
|
static CUniqueID skInvalidID32;
|
||||||
|
|
|
@ -56,7 +56,6 @@ INCLUDEPATH += $$PWD/.. \
|
||||||
|
|
||||||
# Header Files
|
# Header Files
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
AnimUtil.h \
|
|
||||||
CColor.h \
|
CColor.h \
|
||||||
CFourCC.h \
|
CFourCC.h \
|
||||||
CHashFNV1A.h \
|
CHashFNV1A.h \
|
||||||
|
@ -73,10 +72,7 @@ HEADERS += \
|
||||||
|
|
||||||
# Source Files
|
# Source Files
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
AnimUtil.cpp \
|
|
||||||
CColor.cpp \
|
CColor.cpp \
|
||||||
CFourCC.cpp \
|
|
||||||
CHashFNV1A.cpp \
|
|
||||||
CompressionUtil.cpp \
|
CompressionUtil.cpp \
|
||||||
CTimer.cpp \
|
CTimer.cpp \
|
||||||
CUniqueID.cpp \
|
CUniqueID.cpp \
|
||||||
|
|
|
@ -10,9 +10,9 @@ class TFlags
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TFlags() : mValue(0) {}
|
TFlags() : mValue(0) {}
|
||||||
TFlags(int v) : mValue(v) {}
|
TFlags(int Val) : mValue(Val) {}
|
||||||
TFlags(u32 v) : mValue(v) {}
|
TFlags(u32 Val) : mValue(Val) {}
|
||||||
TFlags(FlagEnum v) : mValue(v) {}
|
TFlags(FlagEnum Val) : mValue(Val) {}
|
||||||
|
|
||||||
inline operator int() const { return mValue; }
|
inline operator int() const { return mValue; }
|
||||||
inline bool operator!() const { return !mValue; }
|
inline bool operator!() const { return !mValue; }
|
||||||
|
|
|
@ -100,7 +100,7 @@ void FileWrite(const TString& rkFilename, const TString& rkMessage)
|
||||||
|
|
||||||
void FileWrite(const TString& rkFilename, u32 Offset, const TString& rkMessage)
|
void FileWrite(const TString& rkFilename, u32 Offset, const TString& rkMessage)
|
||||||
{
|
{
|
||||||
Write(rkFilename + " : " + TString::HexString(Offset) + " - " + rkMessage);
|
Write(rkFilename + " : " + TString::HexString(Offset, 0) + " - " + rkMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileError(const TString& rkFilename, const TString& rkMessage)
|
void FileError(const TString& rkFilename, const TString& rkMessage)
|
||||||
|
@ -110,7 +110,7 @@ void FileError(const TString& rkFilename, const TString& rkMessage)
|
||||||
|
|
||||||
void FileError(const TString& rkFilename, u32 Offset, const TString& rkMessage)
|
void FileError(const TString& rkFilename, u32 Offset, const TString& rkMessage)
|
||||||
{
|
{
|
||||||
Error(rkFilename + " : " + TString::HexString(Offset) + " - " + rkMessage);
|
Error(rkFilename + " : " + TString::HexString(Offset, 0) + " - " + rkMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileWarning(const TString& rkFilename, const TString& rkMessage)
|
void FileWarning(const TString& rkFilename, const TString& rkMessage)
|
||||||
|
@ -120,7 +120,7 @@ void FileWarning(const TString& rkFilename, const TString& rkMessage)
|
||||||
|
|
||||||
void FileWarning(const TString& rkFilename, u32 Offset, const TString& rkMessage)
|
void FileWarning(const TString& rkFilename, u32 Offset, const TString& rkMessage)
|
||||||
{
|
{
|
||||||
Warning(rkFilename + " : " + TString::HexString(Offset) + " - " + rkMessage);
|
Warning(rkFilename + " : " + TString::HexString(Offset, 0) + " - " + rkMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
const TStringList& GetErrorLog()
|
const TStringList& GetErrorLog()
|
||||||
|
|
|
@ -47,13 +47,13 @@ public:
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
TBasicString(u32 size)
|
TBasicString(u32 Size)
|
||||||
: mInternalString(size, 0)
|
: mInternalString(Size, 0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
TBasicString(u32 size, CharType fill)
|
TBasicString(u32 Size, CharType Fill)
|
||||||
: mInternalString(size, fill)
|
: mInternalString(Size, Fill)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,8 +63,8 @@ public:
|
||||||
mInternalString = pkText;
|
mInternalString = pkText;
|
||||||
}
|
}
|
||||||
|
|
||||||
TBasicString(const CharType* pkText, u32 length)
|
TBasicString(const CharType* pkText, u32 Length)
|
||||||
: mInternalString(pkText, length)
|
: mInternalString(pkText, Length)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,13 +84,13 @@ public:
|
||||||
return mInternalString.data();
|
return mInternalString.data();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline CharType At(u32 pos) const
|
inline CharType At(u32 Pos) const
|
||||||
{
|
{
|
||||||
#if _DEBUG
|
#if _DEBUG
|
||||||
if (Size() <= pos)
|
if (Size() <= Pos)
|
||||||
throw std::out_of_range("Invalid position passed to TBasicString::At()");
|
throw std::out_of_range("Invalid position passed to TBasicString::At()");
|
||||||
#endif
|
#endif
|
||||||
return mInternalString.at(pos);
|
return mInternalString.at(Pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline CharType Front() const
|
inline CharType Front() const
|
||||||
|
@ -115,56 +115,56 @@ public:
|
||||||
|
|
||||||
inline u32 IndexOf(const CharType* pkCharacters) const
|
inline u32 IndexOf(const CharType* pkCharacters) const
|
||||||
{
|
{
|
||||||
size_t pos = mInternalString.find_first_of(pkCharacters);
|
size_t Pos = mInternalString.find_first_of(pkCharacters);
|
||||||
|
|
||||||
if (pos == _TStdString::npos)
|
if (Pos == _TStdString::npos)
|
||||||
return -1;
|
return -1;
|
||||||
else
|
else
|
||||||
return (u32) pos;
|
return (u32) Pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline u32 LastIndexOf(const CharType* pkCharacters) const
|
inline u32 LastIndexOf(const CharType* pkCharacters) const
|
||||||
{
|
{
|
||||||
size_t pos = mInternalString.find_last_of(pkCharacters);
|
size_t Pos = mInternalString.find_last_of(pkCharacters);
|
||||||
|
|
||||||
if (pos == _TStdString::npos)
|
if (Pos == _TStdString::npos)
|
||||||
return -1;
|
return -1;
|
||||||
else
|
else
|
||||||
return (u32) pos;
|
return (u32) Pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Modify String
|
// Modify String
|
||||||
inline _TString SubString(int startPos, int length) const
|
inline _TString SubString(int StartPos, int Length) const
|
||||||
{
|
{
|
||||||
return mInternalString.substr(startPos, length);
|
return mInternalString.substr(StartPos, Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Insert(u32 pos, CharType c)
|
inline void Insert(u32 Pos, CharType Chr)
|
||||||
{
|
{
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
if (Size() < pos)
|
if (Size() < Pos)
|
||||||
throw std::out_of_range("Invalid pos passed to TBasicString::Insert(CharType)");
|
throw std::out_of_range("Invalid pos passed to TBasicString::Insert(CharType)");
|
||||||
#endif
|
#endif
|
||||||
mInternalString.insert(pos, 1, c);
|
mInternalString.insert(Pos, 1, Chr);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Insert(u32 pos, const CharType* pkStr)
|
inline void Insert(u32 Pos, const CharType* pkStr)
|
||||||
{
|
{
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
if (Size() < pos)
|
if (Size() < Pos)
|
||||||
throw std::out_of_range("Invalid pos passed to TBasicString::Insert(const CharType*)");
|
throw std::out_of_range("Invalid pos passed to TBasicString::Insert(const CharType*)");
|
||||||
#endif
|
#endif
|
||||||
mInternalString.insert(pos, pkStr);
|
mInternalString.insert(Pos, pkStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Insert(u32 pos, const _TString& rkStr)
|
inline void Insert(u32 Pos, const _TString& rkStr)
|
||||||
{
|
{
|
||||||
Insert(pos, rkStr.CString());
|
Insert(Pos, rkStr.CString());
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Append(CharType c)
|
inline void Append(CharType Chr)
|
||||||
{
|
{
|
||||||
mInternalString.append(1, c);
|
mInternalString.append(1, Chr);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Append(const CharType* pkText)
|
inline void Append(const CharType* pkText)
|
||||||
|
@ -177,9 +177,9 @@ public:
|
||||||
mInternalString.append(rkStr.CString());
|
mInternalString.append(rkStr.CString());
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Prepend(CharType c)
|
inline void Prepend(CharType Chr)
|
||||||
{
|
{
|
||||||
Insert(0, c);
|
Insert(0, Chr);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Prepend(const CharType* pkText)
|
inline void Prepend(const CharType* pkText)
|
||||||
|
@ -195,134 +195,134 @@ public:
|
||||||
_TString ToUpper() const
|
_TString ToUpper() const
|
||||||
{
|
{
|
||||||
// todo: doesn't handle accented characters
|
// todo: doesn't handle accented characters
|
||||||
_TString out(Size());
|
_TString Out(Size());
|
||||||
|
|
||||||
for (u32 iChar = 0; iChar < Size(); iChar++)
|
for (u32 iChar = 0; iChar < Size(); iChar++)
|
||||||
{
|
{
|
||||||
CharType c = At(iChar);
|
CharType Chr = At(iChar);
|
||||||
|
|
||||||
if (c >= 'a' && c <= 'z')
|
if (Chr >= 'a' && Chr <= 'z')
|
||||||
out[iChar] = c - 0x20;
|
Out[iChar] = Chr - 0x20;
|
||||||
else
|
else
|
||||||
out[iChar] = c;
|
Out[iChar] = Chr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return out;
|
return Out;
|
||||||
}
|
}
|
||||||
|
|
||||||
_TString ToLower() const
|
_TString ToLower() const
|
||||||
{
|
{
|
||||||
// todo: doesn't handle accented characters
|
// todo: doesn't handle accented characters
|
||||||
_TString out(Size());
|
_TString Out(Size());
|
||||||
|
|
||||||
for (u32 iChar = 0; iChar < Size(); iChar++)
|
for (u32 iChar = 0; iChar < Size(); iChar++)
|
||||||
{
|
{
|
||||||
CharType c = At(iChar);
|
CharType Chr = At(iChar);
|
||||||
|
|
||||||
if (c >= 'A' && c <= 'Z')
|
if (Chr >= 'A' && Chr <= 'Z')
|
||||||
out[iChar] = c + 0x20;
|
Out[iChar] = Chr + 0x20;
|
||||||
else
|
else
|
||||||
out[iChar] = c;
|
Out[iChar] = Chr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return out;
|
return Out;
|
||||||
}
|
}
|
||||||
|
|
||||||
_TString Trimmed() const
|
_TString Trimmed() const
|
||||||
{
|
{
|
||||||
int start = -1, end = -1;
|
int Start = -1, End = -1;
|
||||||
|
|
||||||
for (u32 iChar = 0; iChar < Size(); iChar++)
|
for (u32 iChar = 0; iChar < Size(); iChar++)
|
||||||
{
|
{
|
||||||
if (!IsWhitespace(mInternalString[iChar]))
|
if (!IsWhitespace(mInternalString[iChar]))
|
||||||
{
|
{
|
||||||
start = iChar;
|
Start = iChar;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If start is still -1 then there are no non-whitespace characters in this string. Return early.
|
// If start is still -1 then there are no non-whitespace characters in this string. Return early.
|
||||||
if (start == -1) return "";
|
if (Start == -1) return "";
|
||||||
|
|
||||||
for (int iChar = Size() - 1; iChar >= 0; iChar--)
|
for (int iChar = Size() - 1; iChar >= 0; iChar--)
|
||||||
{
|
{
|
||||||
if (!IsWhitespace(mInternalString[iChar]))
|
if (!IsWhitespace(mInternalString[iChar]))
|
||||||
{
|
{
|
||||||
end = iChar + 1;
|
End = iChar + 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return SubString(start, end - start);
|
return SubString(Start, End - Start);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline _TString Truncate(u32 amount) const
|
inline _TString Truncate(u32 Amount) const
|
||||||
{
|
{
|
||||||
return SubString(0, amount);
|
return SubString(0, Amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline _TString ChopFront(u32 amount) const
|
inline _TString ChopFront(u32 Amount) const
|
||||||
{
|
{
|
||||||
if (Size() <= amount) return "";
|
if (Size() <= Amount) return "";
|
||||||
return SubString(amount, Size() - amount);
|
return SubString(Amount, Size() - Amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline _TString ChopBack(u32 amount) const
|
inline _TString ChopBack(u32 Amount) const
|
||||||
{
|
{
|
||||||
if (Size() <= amount) return "";
|
if (Size() <= Amount) return "";
|
||||||
return SubString(0, Size() - amount);
|
return SubString(0, Size() - Amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 Hash32() const
|
u32 Hash32() const
|
||||||
{
|
{
|
||||||
u32 hash = 0;
|
u32 Hash = 0;
|
||||||
|
|
||||||
for (u32 iChar = 0; iChar < Size(); iChar++)
|
for (u32 iChar = 0; iChar < Size(); iChar++)
|
||||||
{
|
{
|
||||||
hash += At(iChar);
|
Hash += At(iChar);
|
||||||
hash *= 101;
|
Hash *= 101;
|
||||||
}
|
}
|
||||||
|
|
||||||
return hash;
|
return Hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 Hash64() const
|
u64 Hash64() const
|
||||||
{
|
{
|
||||||
u64 hash = 0;
|
u64 Hash = 0;
|
||||||
|
|
||||||
for (u32 iChar = 0; iChar < Size(); iChar++)
|
for (u32 iChar = 0; iChar < Size(); iChar++)
|
||||||
{
|
{
|
||||||
hash += At(iChar);
|
Hash += At(iChar);
|
||||||
hash *= 101;
|
Hash *= 101;
|
||||||
}
|
}
|
||||||
|
|
||||||
return hash;
|
return Hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline u32 ToInt32(int base = 16) const
|
inline u32 ToInt32(int Base = 16) const
|
||||||
{
|
{
|
||||||
return std::stoul(mInternalString, nullptr, base);
|
return std::stoul(mInternalString, nullptr, Base);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline u64 ToInt64(int base = 16) const
|
inline u64 ToInt64(int Base = 16) const
|
||||||
{
|
{
|
||||||
return std::stoull(mInternalString, nullptr, base);
|
return std::stoull(mInternalString, nullptr, Base);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ToInt128(CharType* pOut, int base = 16) const
|
void ToInt128(CharType* pOut, int Base = 16) const
|
||||||
{
|
{
|
||||||
// TODO: only works in base 16
|
// TODO: only works in base 16
|
||||||
u64 part1 = std::stoull(mInternalString.substr(0, 16), nullptr, base);
|
u64 Part1 = std::stoull(mInternalString.substr(0, 16), nullptr, Base);
|
||||||
u64 part2 = std::stoull(mInternalString.substr(16, 16), nullptr, base);
|
u64 Part2 = std::stoull(mInternalString.substr(16, 16), nullptr, Base);
|
||||||
|
|
||||||
if (IOUtil::kSystemEndianness == IOUtil::eLittleEndian)
|
if (IOUtil::kSystemEndianness == IOUtil::eLittleEndian)
|
||||||
{
|
{
|
||||||
IOUtil::SwapBytes(part1);
|
IOUtil::SwapBytes(Part1);
|
||||||
IOUtil::SwapBytes(part2);
|
IOUtil::SwapBytes(Part2);
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(pOut, &part1, 8);
|
memcpy(pOut, &Part1, 8);
|
||||||
memcpy(pOut + 8, &part2, 8);
|
memcpy(pOut + 8, &Part2, 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline float ToFloat() const
|
inline float ToFloat() const
|
||||||
|
@ -337,8 +337,8 @@ public:
|
||||||
|
|
||||||
_TStringList Split(const CharType* pkTokens) const
|
_TStringList Split(const CharType* pkTokens) const
|
||||||
{
|
{
|
||||||
_TStringList out;
|
_TStringList Out;
|
||||||
u32 lastSplit = 0;
|
u32 LastSplit = 0;
|
||||||
|
|
||||||
// Iterate over all characters in the input string
|
// Iterate over all characters in the input string
|
||||||
for (u32 iChr = 0; iChr < Length(); iChr++)
|
for (u32 iChr = 0; iChr < Length(); iChr++)
|
||||||
|
@ -351,26 +351,26 @@ public:
|
||||||
if (mInternalString[iChr] == pkTokens[iTok])
|
if (mInternalString[iChr] == pkTokens[iTok])
|
||||||
{
|
{
|
||||||
// Token found - split string
|
// Token found - split string
|
||||||
if (iChr > lastSplit)
|
if (iChr > LastSplit)
|
||||||
out.push_back(SubString(lastSplit, iChr - lastSplit));
|
Out.push_back(SubString(LastSplit, iChr - LastSplit));
|
||||||
|
|
||||||
lastSplit = iChr + 1;
|
LastSplit = iChr + 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add final string
|
// Add final string
|
||||||
if (lastSplit != Length())
|
if (LastSplit != Length())
|
||||||
out.push_back(SubString(lastSplit, Length() - lastSplit));
|
Out.push_back(SubString(LastSplit, Length() - LastSplit));
|
||||||
|
|
||||||
return out;
|
return Out;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EnsureEndsWith(CharType chr)
|
void EnsureEndsWith(CharType Chr)
|
||||||
{
|
{
|
||||||
if (Back() != chr)
|
if (Back() != Chr)
|
||||||
Append(chr);
|
Append(Chr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EnsureEndsWith(const CharType* pkText)
|
void EnsureEndsWith(const CharType* pkText)
|
||||||
|
@ -385,92 +385,92 @@ public:
|
||||||
return (Size() == 0);
|
return (Size() == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool StartsWith(const _TString& str) const
|
bool StartsWith(const _TString& rkStr) const
|
||||||
{
|
{
|
||||||
if (Size() < str.Size())
|
if (Size() < rkStr.Size())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return (SubString(0, str.Size()) == str);
|
return (SubString(0, rkStr.Size()) == rkStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EndsWith(const _TString& str) const
|
bool EndsWith(const _TString& rkStr) const
|
||||||
{
|
{
|
||||||
if (Size() < str.Size())
|
if (Size() < rkStr.Size())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return (SubString(Size() - str.Size(), str.Size()) == str);
|
return (SubString(Size() - rkStr.Size(), rkStr.Size()) == rkStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Contains(_TString str, bool caseSensitive = true) const
|
bool Contains(_TString Str, bool CaseSensitive = true) const
|
||||||
{
|
{
|
||||||
if (Size() < str.Size()) return false;
|
if (Size() < Str.Size()) return false;
|
||||||
|
|
||||||
_TString checkStr(caseSensitive ? *this : ToUpper());
|
_TString CheckStr(CaseSensitive ? *this : ToUpper());
|
||||||
if (caseSensitive) str = str.ToUpper();
|
if (CaseSensitive) Str = Str.ToUpper();
|
||||||
|
|
||||||
u32 latestPossibleStart = Size() - str.Size();
|
u32 LatestPossibleStart = Size() - Str.Size();
|
||||||
u32 match = 0;
|
u32 Match = 0;
|
||||||
|
|
||||||
for (u32 iChr = 0; iChr < Size() && iChr < str.Size(); iChr++)
|
for (u32 iChr = 0; iChr < Size() && iChr < Str.Size(); iChr++)
|
||||||
{
|
{
|
||||||
// If the current character matches, increment match
|
// If the current character matches, increment match
|
||||||
if (checkStr.At(iChr) == str.At(match))
|
if (CheckStr.At(iChr) == Str.At(Match))
|
||||||
match++;
|
Match++;
|
||||||
|
|
||||||
// Otherwise...
|
// Otherwise...
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// We need to also compare this character to the first
|
// We need to also compare this character to the first
|
||||||
// character of the string (unless we just did that)
|
// character of the string (unless we just did that)
|
||||||
if (match > 0)
|
if (Match > 0)
|
||||||
iChr--;
|
iChr--;
|
||||||
|
|
||||||
match = 0;
|
Match = 0;
|
||||||
|
|
||||||
if (iChr > latestPossibleStart)
|
if (iChr > LatestPossibleStart)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we've matched the entire string, then we can return true
|
// If we've matched the entire string, then we can return true
|
||||||
if (match == str.Size()) return true;
|
if (Match == Str.Size()) return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsHexString(bool requirePrefix = false, u32 width = -1) const
|
bool IsHexString(bool RequirePrefix = false, u32 Width = -1) const
|
||||||
{
|
{
|
||||||
_TString str(*this);
|
_TString Str(*this);
|
||||||
bool hasPrefix = str.StartsWith("0x");
|
bool HasPrefix = Str.StartsWith("0x");
|
||||||
|
|
||||||
// If we're required to match the prefix and prefix is missing, return false
|
// If we're required to match the prefix and prefix is missing, return false
|
||||||
if (requirePrefix && !hasPrefix)
|
if (RequirePrefix && !HasPrefix)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (width == -1)
|
if (Width == -1)
|
||||||
{
|
{
|
||||||
// If the string has the 0x prefix, remove it
|
// If the string has the 0x prefix, remove it
|
||||||
if (hasPrefix)
|
if (HasPrefix)
|
||||||
str = str.ChopFront(2);
|
Str = Str.ChopFront(2);
|
||||||
|
|
||||||
// If we have a variable width then assign the width value to the string size
|
// If we have a variable width then assign the width value to the string size
|
||||||
width = str.Size();
|
Width = Str.Size();
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the string starts with the prefix and the length matches the string, remove the prefix
|
// If the string starts with the prefix and the length matches the string, remove the prefix
|
||||||
else if ((str.Size() == width + 2) && (hasPrefix))
|
else if ((Str.Size() == Width + 2) && (HasPrefix))
|
||||||
str = str.ChopFront(2);
|
Str = Str.ChopFront(2);
|
||||||
|
|
||||||
// By this point, the string size and the width should match. If they don't, return false.
|
// By this point, the string size and the width should match. If they don't, return false.
|
||||||
if (str.Size() != width) return false;
|
if (Str.Size() != Width) return false;
|
||||||
|
|
||||||
// Now we can finally check the actual string and make sure all the characters are valid hex characters.
|
// Now we can finally check the actual string and make sure all the characters are valid hex characters.
|
||||||
for (u32 c = 0; c < width; c++)
|
for (u32 iChr = 0; iChr < Width; iChr++)
|
||||||
{
|
{
|
||||||
char chr = str[c];
|
char Chr = Str[iChr];
|
||||||
if (!((chr >= '0') && (chr <= '9')) &&
|
if (!((Chr >= '0') && (Chr <= '9')) &&
|
||||||
!((chr >= 'a') && (chr <= 'f')) &&
|
!((Chr >= 'a') && (Chr <= 'f')) &&
|
||||||
!((chr >= 'A') && (chr <= 'F')))
|
!((Chr >= 'A') && (Chr <= 'F')))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -485,36 +485,36 @@ public:
|
||||||
// Get Filename Components
|
// Get Filename Components
|
||||||
_TString GetFileDirectory() const
|
_TString GetFileDirectory() const
|
||||||
{
|
{
|
||||||
size_t endPath = mInternalString.find_last_of("\\/");
|
size_t EndPath = mInternalString.find_last_of("\\/");
|
||||||
return SubString(0, endPath + 1);
|
return SubString(0, EndPath + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
_TString GetFileName(bool withExtension = true) const
|
_TString GetFileName(bool WithExtension = true) const
|
||||||
{
|
{
|
||||||
size_t endPath = mInternalString.find_last_of("\\/") + 1;
|
size_t EndPath = mInternalString.find_last_of("\\/") + 1;
|
||||||
|
|
||||||
if (withExtension)
|
if (WithExtension)
|
||||||
{
|
{
|
||||||
return SubString(endPath, Size() - endPath);
|
return SubString(EndPath, Size() - EndPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
size_t endName = mInternalString.find_last_of(".");
|
size_t EndName = mInternalString.find_last_of(".");
|
||||||
return SubString(endPath, endName - endPath);
|
return SubString(EndPath, EndName - EndPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_TString GetFileExtension() const
|
_TString GetFileExtension() const
|
||||||
{
|
{
|
||||||
size_t endName = mInternalString.find_last_of(".");
|
size_t EndName = mInternalString.find_last_of(".");
|
||||||
return SubString(endName + 1, Size() - endName);
|
return SubString(EndName + 1, Size() - EndName);
|
||||||
}
|
}
|
||||||
|
|
||||||
_TString GetFilePathWithoutExtension() const
|
_TString GetFilePathWithoutExtension() const
|
||||||
{
|
{
|
||||||
size_t endName = mInternalString.find_last_of(".");
|
size_t EndName = mInternalString.find_last_of(".");
|
||||||
return SubString(0, endName);
|
return SubString(0, EndName);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Operators
|
// Operators
|
||||||
|
@ -530,14 +530,14 @@ public:
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline CharType& operator[](int pos)
|
inline CharType& operator[](int Pos)
|
||||||
{
|
{
|
||||||
return mInternalString[pos];
|
return mInternalString[Pos];
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const CharType& operator[](int pos) const
|
inline const CharType& operator[](int Pos) const
|
||||||
{
|
{
|
||||||
return mInternalString[pos];
|
return mInternalString[Pos];
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const CharType* operator*() const
|
inline const CharType* operator*() const
|
||||||
|
@ -547,17 +547,17 @@ public:
|
||||||
|
|
||||||
_TString operator+(const CharType* pkOther) const
|
_TString operator+(const CharType* pkOther) const
|
||||||
{
|
{
|
||||||
u32 len = CStringLength(pkOther);
|
u32 Len = CStringLength(pkOther);
|
||||||
|
|
||||||
_TString out(len + Size());
|
_TString Out(Len + Size());
|
||||||
memcpy(&out[0], mInternalString.data(), Size() * sizeof(CharType));
|
memcpy(&Out[0], mInternalString.data(), Size() * sizeof(CharType));
|
||||||
memcpy(&out[Size()], pkOther, len * sizeof(CharType));
|
memcpy(&Out[Size()], pkOther, Len * sizeof(CharType));
|
||||||
return out;
|
return Out;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline _TString operator+(const _TString& other) const
|
inline _TString operator+(const _TString& rkOther) const
|
||||||
{
|
{
|
||||||
return (*this + other.CString());
|
return (*this + rkOther.CString());
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void operator+=(const CharType* pkOther)
|
inline void operator+=(const CharType* pkOther)
|
||||||
|
@ -572,20 +572,20 @@ public:
|
||||||
|
|
||||||
inline friend _TString operator+(const CharType* pkLeft, const _TString& rkRight)
|
inline friend _TString operator+(const CharType* pkLeft, const _TString& rkRight)
|
||||||
{
|
{
|
||||||
u32 len = CStringLength(pkLeft);
|
u32 Len = CStringLength(pkLeft);
|
||||||
|
|
||||||
_TString out(len + rkRight.Size());
|
_TString Out(Len + rkRight.Size());
|
||||||
memcpy(&out[0], pkLeft, len * sizeof(CharType));
|
memcpy(&Out[0], pkLeft, Len * sizeof(CharType));
|
||||||
memcpy(&out[len], rkRight.CString(), rkRight.Size() * sizeof(CharType));
|
memcpy(&Out[Len], rkRight.CString(), rkRight.Size() * sizeof(CharType));
|
||||||
return out;
|
return Out;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline friend _TString operator+(const _TStdString& rkLeft, const _TString& rkRight)
|
inline friend _TString operator+(const _TStdString& rkLeft, const _TString& rkRight)
|
||||||
{
|
{
|
||||||
_TString out(rkLeft.size() + rkRight.Size());
|
_TString Out(rkLeft.size() + rkRight.Size());
|
||||||
memcpy(&out[0], rkLeft.data(), rkLeft.size() * sizeof(CharType));
|
memcpy(&Out[0], rkLeft.data(), rkLeft.size() * sizeof(CharType));
|
||||||
memcpy(&out[rkLeft.size()], rkRight.Data(), rkRight.Size() * sizeof(CharType));
|
memcpy(&Out[rkLeft.size()], rkRight.Data(), rkRight.Size() * sizeof(CharType));
|
||||||
return out;
|
return Out;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool operator==(const CharType *pkText) const
|
inline bool operator==(const CharType *pkText) const
|
||||||
|
@ -721,23 +721,23 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// Static
|
// Static
|
||||||
static TBasicString<CharType> FromInt32(s32 value, int width = 0, int base = 16)
|
static TBasicString<CharType> FromInt32(s32 Value, int Width = 0, int Base = 16)
|
||||||
{
|
{
|
||||||
std::basic_stringstream<CharType> sstream;
|
std::basic_stringstream<CharType> sstream;
|
||||||
sstream << std::setbase(base) << std::setw(width) << std::setfill('0') << value;
|
sstream << std::setbase(Base) << std::setw(Width) << std::setfill('0') << Value;
|
||||||
return sstream.str();
|
return sstream.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
static TBasicString<CharType> FromInt64(s64 value, int width = 0, int base = 16)
|
static TBasicString<CharType> FromInt64(s64 Value, int Width = 0, int Base = 16)
|
||||||
{
|
{
|
||||||
std::basic_stringstream<CharType> sstream;
|
std::basic_stringstream<CharType> sstream;
|
||||||
sstream << std::setbase(base) << std::setw(width) << std::setfill('0') << value;
|
sstream << std::setbase(Base) << std::setw(Width) << std::setfill('0') << Value;
|
||||||
return sstream.str();
|
return sstream.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
static TBasicString<CharType> FromFloat(float value, int MinDecimals = 1)
|
static TBasicString<CharType> FromFloat(float Value, int MinDecimals = 1)
|
||||||
{
|
{
|
||||||
TString Out = std::to_string(value);
|
TString Out = std::to_string(Value);
|
||||||
int NumZeroes = Out.Size() - (Out.IndexOf(".") + 1);
|
int NumZeroes = Out.Size() - (Out.IndexOf(".") + 1);
|
||||||
|
|
||||||
while (Out.Back() == '0' && NumZeroes > MinDecimals)
|
while (Out.Back() == '0' && NumZeroes > MinDecimals)
|
||||||
|
@ -749,24 +749,24 @@ public:
|
||||||
return Out;
|
return Out;
|
||||||
}
|
}
|
||||||
|
|
||||||
static TBasicString<CharType> HexString(unsigned char num, bool addPrefix = true, bool uppercase = false, int width = 0)
|
static TBasicString<CharType> HexString(unsigned char Num, int Width = 8, bool AddPrefix = true, bool Uppercase = true)
|
||||||
{
|
{
|
||||||
return HexString((unsigned long) num, addPrefix, uppercase, width);
|
return HexString((unsigned long) Num, Width, AddPrefix, Uppercase);
|
||||||
}
|
}
|
||||||
|
|
||||||
static TBasicString<CharType> HexString(unsigned short num, bool addPrefix = true, bool uppercase = false, int width = 0)
|
static TBasicString<CharType> HexString(unsigned short Num, int Width = 8, bool AddPrefix = true, bool Uppercase = true)
|
||||||
{
|
{
|
||||||
return HexString((unsigned long) num, addPrefix, uppercase, width);
|
return HexString((unsigned long) Num, Width, AddPrefix, Uppercase);
|
||||||
}
|
}
|
||||||
|
|
||||||
static TBasicString<CharType> HexString(unsigned long num, bool addPrefix = true, bool uppercase = false, int width = 0)
|
static TBasicString<CharType> HexString(unsigned long Num, int Width = 8, bool AddPrefix = true, bool Uppercase = true)
|
||||||
{
|
{
|
||||||
std::basic_stringstream<CharType> sstream;
|
std::basic_stringstream<CharType> sstream;
|
||||||
sstream << std::hex << std::setw(width) << std::setfill('0') << num;
|
sstream << std::hex << std::setw(Width) << std::setfill('0') << Num;
|
||||||
|
|
||||||
_TString str = sstream.str();
|
_TString str = sstream.str();
|
||||||
if (uppercase) str = str.ToUpper();
|
if (Uppercase) str = str.ToUpper();
|
||||||
if (addPrefix) str.Prepend("0x");
|
if (AddPrefix) str.Prepend("0x");
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ CAreaAttributes::~CAreaAttributes()
|
||||||
void CAreaAttributes::SetObject(CScriptObject *pObj)
|
void CAreaAttributes::SetObject(CScriptObject *pObj)
|
||||||
{
|
{
|
||||||
mpObj = pObj;
|
mpObj = pObj;
|
||||||
mGame = pObj->Template()->MasterTemplate()->GetGame();
|
mGame = pObj->Template()->MasterTemplate()->Game();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CAreaAttributes::IsLayerEnabled() const
|
bool CAreaAttributes::IsLayerEnabled() const
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
#include "CRayCollisionTester.h"
|
#include "CRayCollisionTester.h"
|
||||||
#include "Core/Scene/CSceneNode.h"
|
#include "Core/Scene/CSceneNode.h"
|
||||||
|
|
||||||
CRayCollisionTester::CRayCollisionTester(const CRay& Ray)
|
CRayCollisionTester::CRayCollisionTester(const CRay& rkRay)
|
||||||
: mRay(Ray)
|
: mRay(rkRay)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,10 +13,10 @@ CRayCollisionTester::~CRayCollisionTester()
|
||||||
void CRayCollisionTester::AddNode(CSceneNode *pNode, u32 ComponentIndex, float Distance)
|
void CRayCollisionTester::AddNode(CSceneNode *pNode, u32 ComponentIndex, float Distance)
|
||||||
{
|
{
|
||||||
mBoxIntersectList.emplace_back(SRayIntersection());
|
mBoxIntersectList.emplace_back(SRayIntersection());
|
||||||
SRayIntersection& Intersection = mBoxIntersectList.back();
|
SRayIntersection& rIntersection = mBoxIntersectList.back();
|
||||||
Intersection.pNode = pNode;
|
rIntersection.pNode = pNode;
|
||||||
Intersection.ComponentIndex = ComponentIndex;
|
rIntersection.ComponentIndex = ComponentIndex;
|
||||||
Intersection.Distance = Distance;
|
rIntersection.Distance = Distance;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CRayCollisionTester::AddNodeModel(CSceneNode *pNode, CBasicModel *pModel)
|
void CRayCollisionTester::AddNodeModel(CSceneNode *pNode, CBasicModel *pModel)
|
||||||
|
@ -31,13 +31,13 @@ void CRayCollisionTester::AddNodeModel(CSceneNode *pNode, CBasicModel *pModel)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SRayIntersection CRayCollisionTester::TestNodes(const SViewInfo& ViewInfo)
|
SRayIntersection CRayCollisionTester::TestNodes(const SViewInfo& rkViewInfo)
|
||||||
{
|
{
|
||||||
// Sort nodes by distance from ray
|
// Sort nodes by distance from ray
|
||||||
mBoxIntersectList.sort(
|
mBoxIntersectList.sort(
|
||||||
[](const SRayIntersection& A, SRayIntersection& B) -> bool
|
[](const SRayIntersection& rkLeft, const SRayIntersection& rkRight) -> bool
|
||||||
{
|
{
|
||||||
return (A.Distance < B.Distance);
|
return (rkLeft.Distance < rkRight.Distance);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Now do more precise intersection tests on geometry
|
// Now do more precise intersection tests on geometry
|
||||||
|
@ -46,16 +46,16 @@ SRayIntersection CRayCollisionTester::TestNodes(const SViewInfo& ViewInfo)
|
||||||
|
|
||||||
for (auto iNode = mBoxIntersectList.begin(); iNode != mBoxIntersectList.end(); iNode++)
|
for (auto iNode = mBoxIntersectList.begin(); iNode != mBoxIntersectList.end(); iNode++)
|
||||||
{
|
{
|
||||||
SRayIntersection& Intersection = *iNode;
|
SRayIntersection& rIntersection = *iNode;
|
||||||
|
|
||||||
// If we have a result, and the distance for the bounding box hit is further than the current result distance
|
// If we have a result, and the distance for the bounding box hit is further than the current result distance
|
||||||
// then we know that every remaining node is further away and there is no chance of finding a closer hit.
|
// then we know that every remaining node is further away and there is no chance of finding a closer hit.
|
||||||
if ((Result.Hit) && (Result.Distance < Intersection.Distance))
|
if ((Result.Hit) && (Result.Distance < rIntersection.Distance))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Otherwise, more intersection tests...
|
// Otherwise, more intersection tests...
|
||||||
CSceneNode *pNode = Intersection.pNode;
|
CSceneNode *pNode = rIntersection.pNode;
|
||||||
SRayIntersection MidResult = pNode->RayNodeIntersectTest(mRay, Intersection.ComponentIndex, ViewInfo);
|
SRayIntersection MidResult = pNode->RayNodeIntersectTest(mRay, rIntersection.ComponentIndex, rkViewInfo);
|
||||||
|
|
||||||
if (MidResult.Hit)
|
if (MidResult.Hit)
|
||||||
{
|
{
|
||||||
|
|
|
@ -19,17 +19,13 @@ class CRayCollisionTester
|
||||||
std::list<SRayIntersection> mBoxIntersectList;
|
std::list<SRayIntersection> mBoxIntersectList;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CRayCollisionTester(const CRay& Ray);
|
CRayCollisionTester(const CRay& rkRay);
|
||||||
~CRayCollisionTester();
|
~CRayCollisionTester();
|
||||||
const CRay& Ray() const;
|
const CRay& Ray() const { return mRay; }
|
||||||
|
|
||||||
void AddNode(CSceneNode *pNode, u32 AssetIndex, float Distance);
|
void AddNode(CSceneNode *pNode, u32 AssetIndex, float Distance);
|
||||||
void AddNodeModel(CSceneNode *pNode, CBasicModel *pModel);
|
void AddNodeModel(CSceneNode *pNode, CBasicModel *pModel);
|
||||||
SRayIntersection TestNodes(const SViewInfo& ViewInfo);
|
SRayIntersection TestNodes(const SViewInfo& rkViewInfo);
|
||||||
};
|
};
|
||||||
|
|
||||||
inline const CRay& CRayCollisionTester::Ray() const
|
|
||||||
{
|
|
||||||
return mRay;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // CRAYCOLLISIONHELPER_H
|
#endif // CRAYCOLLISIONHELPER_H
|
||||||
|
|
|
@ -159,7 +159,6 @@ HEADERS += \
|
||||||
SRayIntersection.h \
|
SRayIntersection.h \
|
||||||
OpenGL/CDynamicVertexBuffer.h \
|
OpenGL/CDynamicVertexBuffer.h \
|
||||||
OpenGL/CFramebuffer.h \
|
OpenGL/CFramebuffer.h \
|
||||||
OpenGL/CGL.h \
|
|
||||||
OpenGL/CIndexBuffer.h \
|
OpenGL/CIndexBuffer.h \
|
||||||
OpenGL/CRenderbuffer.h \
|
OpenGL/CRenderbuffer.h \
|
||||||
OpenGL/CShader.h \
|
OpenGL/CShader.h \
|
||||||
|
@ -193,11 +192,10 @@ SOURCES += \
|
||||||
Render/CCamera.cpp \
|
Render/CCamera.cpp \
|
||||||
Render/CDrawUtil.cpp \
|
Render/CDrawUtil.cpp \
|
||||||
Render/CGraphics.cpp \
|
Render/CGraphics.cpp \
|
||||||
Render/CRenderBucket.cpp \
|
|
||||||
Render/CRenderer.cpp \
|
Render/CRenderer.cpp \
|
||||||
|
Render/CRenderBucket.cpp \
|
||||||
Resource/Cooker/CMaterialCooker.cpp \
|
Resource/Cooker/CMaterialCooker.cpp \
|
||||||
Resource/Cooker/CModelCooker.cpp \
|
Resource/Cooker/CModelCooker.cpp \
|
||||||
Resource/Cooker/CSectionMgrOut.cpp \
|
|
||||||
Resource/Cooker/CTemplateWriter.cpp \
|
Resource/Cooker/CTemplateWriter.cpp \
|
||||||
Resource/Cooker/CTextureEncoder.cpp \
|
Resource/Cooker/CTextureEncoder.cpp \
|
||||||
Resource/Cooker/CWorldCooker.cpp \
|
Resource/Cooker/CWorldCooker.cpp \
|
||||||
|
@ -221,20 +219,15 @@ SOURCES += \
|
||||||
Resource/Script/CScriptObject.cpp \
|
Resource/Script/CScriptObject.cpp \
|
||||||
Resource/Script/CScriptTemplate.cpp \
|
Resource/Script/CScriptTemplate.cpp \
|
||||||
Resource/CAnimationParameters.cpp \
|
Resource/CAnimationParameters.cpp \
|
||||||
Resource/CAnimSet.cpp \
|
|
||||||
Resource/CCollisionMesh.cpp \
|
Resource/CCollisionMesh.cpp \
|
||||||
Resource/CCollisionMeshGroup.cpp \
|
|
||||||
Resource/CFont.cpp \
|
Resource/CFont.cpp \
|
||||||
Resource/CGameArea.cpp \
|
Resource/CGameArea.cpp \
|
||||||
Resource/CLight.cpp \
|
Resource/CLight.cpp \
|
||||||
Resource/CMaterial.cpp \
|
Resource/CMaterial.cpp \
|
||||||
Resource/CMaterialPass.cpp \
|
Resource/CMaterialPass.cpp \
|
||||||
Resource/CMaterialSet.cpp \
|
|
||||||
Resource/CPakFile.cpp \
|
Resource/CPakFile.cpp \
|
||||||
Resource/CResCache.cpp \
|
Resource/CResCache.cpp \
|
||||||
Resource/CResource.cpp \
|
Resource/CResource.cpp \
|
||||||
Resource/CScan.cpp \
|
|
||||||
Resource/CStringTable.cpp \
|
|
||||||
Resource/CTexture.cpp \
|
Resource/CTexture.cpp \
|
||||||
Resource/CWorld.cpp \
|
Resource/CWorld.cpp \
|
||||||
Scene/CCollisionNode.cpp \
|
Scene/CCollisionNode.cpp \
|
||||||
|
@ -253,12 +246,9 @@ SOURCES += \
|
||||||
CRayCollisionTester.cpp \
|
CRayCollisionTester.cpp \
|
||||||
OpenGL/CDynamicVertexBuffer.cpp \
|
OpenGL/CDynamicVertexBuffer.cpp \
|
||||||
OpenGL/CFramebuffer.cpp \
|
OpenGL/CFramebuffer.cpp \
|
||||||
OpenGL/CGL.cpp \
|
|
||||||
OpenGL/CIndexBuffer.cpp \
|
OpenGL/CIndexBuffer.cpp \
|
||||||
OpenGL/CRenderbuffer.cpp \
|
|
||||||
OpenGL/CShader.cpp \
|
OpenGL/CShader.cpp \
|
||||||
OpenGL/CShaderGenerator.cpp \
|
OpenGL/CShaderGenerator.cpp \
|
||||||
OpenGL/CUniformBuffer.cpp \
|
|
||||||
OpenGL/CVertexArrayManager.cpp \
|
OpenGL/CVertexArrayManager.cpp \
|
||||||
OpenGL/CVertexBuffer.cpp \
|
OpenGL/CVertexBuffer.cpp \
|
||||||
OpenGL/GLCommon.cpp \
|
OpenGL/GLCommon.cpp \
|
||||||
|
|
|
@ -6,10 +6,10 @@ static const u32 gskAttribSize[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
CDynamicVertexBuffer::CDynamicVertexBuffer()
|
CDynamicVertexBuffer::CDynamicVertexBuffer()
|
||||||
|
: mAttribFlags(eNoAttributes)
|
||||||
|
, mBufferedFlags(eNoAttributes)
|
||||||
|
, mNumVertices(0)
|
||||||
{
|
{
|
||||||
mAttribFlags = eNoAttributes;
|
|
||||||
mBufferedFlags = eNoAttributes;
|
|
||||||
mNumVertices = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CDynamicVertexBuffer::~CDynamicVertexBuffer()
|
CDynamicVertexBuffer::~CDynamicVertexBuffer()
|
||||||
|
@ -42,7 +42,7 @@ void CDynamicVertexBuffer::SetActiveAttribs(FVertexDescription AttribFlags)
|
||||||
InitBuffers();
|
InitBuffers();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDynamicVertexBuffer::BufferAttrib(EVertexAttribute Attrib, const void *pData)
|
void CDynamicVertexBuffer::BufferAttrib(EVertexAttribute Attrib, const void *pkData)
|
||||||
{
|
{
|
||||||
u32 Index;
|
u32 Index;
|
||||||
|
|
||||||
|
@ -64,16 +64,16 @@ void CDynamicVertexBuffer::BufferAttrib(EVertexAttribute Attrib, const void *pDa
|
||||||
}
|
}
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, mAttribBuffers[Index]);
|
glBindBuffer(GL_ARRAY_BUFFER, mAttribBuffers[Index]);
|
||||||
glBufferSubData(GL_ARRAY_BUFFER, 0, gskAttribSize[Index] * mNumVertices, pData);
|
glBufferSubData(GL_ARRAY_BUFFER, 0, gskAttribSize[Index] * mNumVertices, pkData);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDynamicVertexBuffer::ClearBuffers()
|
void CDynamicVertexBuffer::ClearBuffers()
|
||||||
{
|
{
|
||||||
for (u32 iAttrib = 0; iAttrib < 12; iAttrib++)
|
for (u32 iAttrib = 0; iAttrib < 12; iAttrib++)
|
||||||
{
|
{
|
||||||
int bit = 1 << iAttrib;
|
int Bit = 1 << iAttrib;
|
||||||
|
|
||||||
if (mBufferedFlags & bit)
|
if (mBufferedFlags & Bit)
|
||||||
glDeleteBuffers(1, &mAttribBuffers[iAttrib]);
|
glDeleteBuffers(1, &mAttribBuffers[iAttrib]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,8 +3,6 @@
|
||||||
|
|
||||||
#include "Core/Resource/Model/EVertexAttribute.h"
|
#include "Core/Resource/Model/EVertexAttribute.h"
|
||||||
#include <Common/types.h>
|
#include <Common/types.h>
|
||||||
#include <Math/CVector2f.h>
|
|
||||||
#include <Math/CVector3f.h>
|
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
|
@ -23,7 +21,7 @@ public:
|
||||||
void Bind();
|
void Bind();
|
||||||
void Unbind();
|
void Unbind();
|
||||||
void SetActiveAttribs(FVertexDescription AttribFlags);
|
void SetActiveAttribs(FVertexDescription AttribFlags);
|
||||||
void BufferAttrib(EVertexAttribute Attrib, const void *pData);
|
void BufferAttrib(EVertexAttribute Attrib, const void *pkData);
|
||||||
void ClearBuffers();
|
void ClearBuffers();
|
||||||
GLuint CreateVAO();
|
GLuint CreateVAO();
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -2,21 +2,21 @@
|
||||||
#include <Common/Log.h>
|
#include <Common/Log.h>
|
||||||
|
|
||||||
CFramebuffer::CFramebuffer()
|
CFramebuffer::CFramebuffer()
|
||||||
|
: mInitialized(false)
|
||||||
|
, mWidth(0)
|
||||||
|
, mHeight(0)
|
||||||
|
, mpRenderbuffer(nullptr)
|
||||||
|
, mpTexture(nullptr)
|
||||||
{
|
{
|
||||||
mInitialized = false;
|
|
||||||
mWidth = 0;
|
|
||||||
mHeight = 0;
|
|
||||||
mpRenderbuffer = nullptr;
|
|
||||||
mpTexture = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CFramebuffer::CFramebuffer(u32 Width, u32 Height)
|
CFramebuffer::CFramebuffer(u32 Width, u32 Height)
|
||||||
|
: mInitialized(false)
|
||||||
|
, mWidth(0)
|
||||||
|
, mHeight(0)
|
||||||
|
, mpRenderbuffer(nullptr)
|
||||||
|
, mpTexture(nullptr)
|
||||||
{
|
{
|
||||||
mInitialized = false;
|
|
||||||
mWidth = 0;
|
|
||||||
mHeight = 0;
|
|
||||||
mpRenderbuffer = nullptr;
|
|
||||||
mpTexture = nullptr;
|
|
||||||
Resize(Width, Height);
|
Resize(Width, Height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,41 +0,0 @@
|
||||||
#include "CGL.h"
|
|
||||||
|
|
||||||
// ************ PUBLIC ************
|
|
||||||
void CGL::SetBlendMode(EBlendFactor Source, EBlendFactor Dest)
|
|
||||||
{
|
|
||||||
glBlendFuncSeparate(Source, Dest, eBlendZero, eBlendZero);
|
|
||||||
mBlendSrcFac = Source;
|
|
||||||
mBlendDstFac = Dest;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CGL::SetOpaqueBlend()
|
|
||||||
{
|
|
||||||
SetBlendMode(eBlendOne, eBlendZero);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CGL::SetAlphaBlend()
|
|
||||||
{
|
|
||||||
SetBlendMode(eBlendSrcAlpha, eBlendInvSrcAlpha);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CGL::SetAdditiveBlend()
|
|
||||||
{
|
|
||||||
SetBlendMode(eBlendOne, eBlendOne);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ************ PRIVATE ************
|
|
||||||
void CGL::Init()
|
|
||||||
{
|
|
||||||
if (!mInitialized)
|
|
||||||
{
|
|
||||||
glBlendFuncSeparate(GL_ONE, GL_ZERO, GL_ZERO, GL_ZERO);
|
|
||||||
mBlendSrcFac = eBlendOne;
|
|
||||||
mBlendDstFac = eBlendZero;
|
|
||||||
mInitialized = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ************ STATIC MEMBER INITIALIZATION ************
|
|
||||||
bool CGL::mInitialized;
|
|
||||||
EBlendFactor CGL::mBlendSrcFac;
|
|
||||||
EBlendFactor CGL::mBlendDstFac;
|
|
|
@ -1,26 +0,0 @@
|
||||||
#ifndef CGL_H
|
|
||||||
#define CGL_H
|
|
||||||
|
|
||||||
#include "GLCommon.h"
|
|
||||||
#include <Common/types.h>
|
|
||||||
#include <GL/glew.h>
|
|
||||||
|
|
||||||
class CGL
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
void SetBlendMode(EBlendFactor Source, EBlendFactor Dest);
|
|
||||||
void SetOpaqueBlend();
|
|
||||||
void SetAlphaBlend();
|
|
||||||
void SetAdditiveBlend();
|
|
||||||
|
|
||||||
private:
|
|
||||||
static void Init();
|
|
||||||
|
|
||||||
static bool mInitialized;
|
|
||||||
static EBlendFactor mBlendSrcFac, mBlendDstFac;
|
|
||||||
static u8 mColorMask;
|
|
||||||
static bool mDepthMask;
|
|
||||||
static bool mStencilMask;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // CGL_H
|
|
|
@ -1,14 +1,14 @@
|
||||||
#include "CIndexBuffer.h"
|
#include "CIndexBuffer.h"
|
||||||
|
|
||||||
CIndexBuffer::CIndexBuffer()
|
CIndexBuffer::CIndexBuffer()
|
||||||
|
: mBuffered(false)
|
||||||
{
|
{
|
||||||
mBuffered = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CIndexBuffer::CIndexBuffer(GLenum type)
|
CIndexBuffer::CIndexBuffer(GLenum Type)
|
||||||
|
: mPrimitiveType(Type)
|
||||||
|
, mBuffered(false)
|
||||||
{
|
{
|
||||||
mPrimitiveType = type;
|
|
||||||
mBuffered = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CIndexBuffer::~CIndexBuffer()
|
CIndexBuffer::~CIndexBuffer()
|
||||||
|
@ -17,21 +17,21 @@ CIndexBuffer::~CIndexBuffer()
|
||||||
glDeleteBuffers(1, &mIndexBuffer);
|
glDeleteBuffers(1, &mIndexBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CIndexBuffer::AddIndex(u16 idx)
|
void CIndexBuffer::AddIndex(u16 Index)
|
||||||
{
|
{
|
||||||
mIndices.push_back(idx);
|
mIndices.push_back(Index);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CIndexBuffer::AddIndices(u16 *indicesPtr, u32 count)
|
void CIndexBuffer::AddIndices(u16 *pIndices, u32 Count)
|
||||||
{
|
{
|
||||||
Reserve(count);
|
Reserve(Count);
|
||||||
for (u32 i = 0; i < count; i++)
|
for (u32 iIdx = 0; iIdx < Count; iIdx++)
|
||||||
mIndices.push_back(*indicesPtr++);
|
mIndices.push_back(*pIndices++);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CIndexBuffer::Reserve(u32 size)
|
void CIndexBuffer::Reserve(u32 Size)
|
||||||
{
|
{
|
||||||
mIndices.reserve(mIndices.size() + size);
|
mIndices.reserve(mIndices.size() + Size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CIndexBuffer::Clear()
|
void CIndexBuffer::Clear()
|
||||||
|
@ -94,62 +94,62 @@ GLenum CIndexBuffer::GetPrimitiveType()
|
||||||
return mPrimitiveType;
|
return mPrimitiveType;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CIndexBuffer::SetPrimitiveType(GLenum type)
|
void CIndexBuffer::SetPrimitiveType(GLenum Type)
|
||||||
{
|
{
|
||||||
mPrimitiveType = type;
|
mPrimitiveType = Type;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CIndexBuffer::TrianglesToStrips(u16 *indicesPtr, u32 count)
|
void CIndexBuffer::TrianglesToStrips(u16 *pIndices, u32 Count)
|
||||||
{
|
{
|
||||||
Reserve(count + (count / 3));
|
Reserve(Count + (Count / 3));
|
||||||
|
|
||||||
for (u32 i = 0; i < count; i += 3)
|
for (u32 iIdx = 0; iIdx < Count; iIdx += 3)
|
||||||
{
|
{
|
||||||
mIndices.push_back(*indicesPtr++);
|
mIndices.push_back(*pIndices++);
|
||||||
mIndices.push_back(*indicesPtr++);
|
mIndices.push_back(*pIndices++);
|
||||||
mIndices.push_back(*indicesPtr++);
|
mIndices.push_back(*pIndices++);
|
||||||
mIndices.push_back(0xFFFF);
|
mIndices.push_back(0xFFFF);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CIndexBuffer::FansToStrips(u16 *indicesPtr, u32 count)
|
void CIndexBuffer::FansToStrips(u16 *pIndices, u32 Count)
|
||||||
{
|
{
|
||||||
Reserve(count);
|
Reserve(Count);
|
||||||
u16 FirstIndex = *indicesPtr;
|
u16 FirstIndex = *pIndices;
|
||||||
|
|
||||||
for (u32 i = 2; i < count; i += 3)
|
for (u32 iIdx = 2; iIdx < Count; iIdx += 3)
|
||||||
{
|
{
|
||||||
mIndices.push_back(indicesPtr[i - 1]);
|
mIndices.push_back(pIndices[iIdx - 1]);
|
||||||
mIndices.push_back(indicesPtr[i]);
|
mIndices.push_back(pIndices[iIdx]);
|
||||||
mIndices.push_back(FirstIndex);
|
mIndices.push_back(FirstIndex);
|
||||||
if (i + 1 < count)
|
if (iIdx + 1 < Count)
|
||||||
mIndices.push_back(indicesPtr[i + 1]);
|
mIndices.push_back(pIndices[iIdx + 1]);
|
||||||
if (i + 2 < count)
|
if (iIdx + 2 < Count)
|
||||||
mIndices.push_back(indicesPtr[i + 2]);
|
mIndices.push_back(pIndices[iIdx + 2]);
|
||||||
mIndices.push_back(0xFFFF);
|
mIndices.push_back(0xFFFF);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CIndexBuffer::QuadsToStrips(u16 *indicesPtr, u32 count)
|
void CIndexBuffer::QuadsToStrips(u16 *pIndices, u32 Count)
|
||||||
{
|
{
|
||||||
Reserve((u32) (count * 1.25));
|
Reserve((u32) (Count * 1.25));
|
||||||
|
|
||||||
u32 i = 3;
|
u32 iIdx = 3;
|
||||||
for (; i < count; i += 4)
|
for (; iIdx < Count; iIdx += 4)
|
||||||
{
|
{
|
||||||
mIndices.push_back(indicesPtr[i - 2]);
|
mIndices.push_back(pIndices[iIdx - 2]);
|
||||||
mIndices.push_back(indicesPtr[i - 1]);
|
mIndices.push_back(pIndices[iIdx - 1]);
|
||||||
mIndices.push_back(indicesPtr[i - 3]);
|
mIndices.push_back(pIndices[iIdx - 3]);
|
||||||
mIndices.push_back(indicesPtr[i]);
|
mIndices.push_back(pIndices[iIdx]);
|
||||||
mIndices.push_back(0xFFFF);
|
mIndices.push_back(0xFFFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
// if there's three indices present that indicates a single triangle
|
// if there's three indices present that indicates a single triangle
|
||||||
if (i == count)
|
if (iIdx == Count)
|
||||||
{
|
{
|
||||||
mIndices.push_back(indicesPtr[i - 3]);
|
mIndices.push_back(pIndices[iIdx - 3]);
|
||||||
mIndices.push_back(indicesPtr[i - 2]);
|
mIndices.push_back(pIndices[iIdx - 2]);
|
||||||
mIndices.push_back(indicesPtr[i - 1]);
|
mIndices.push_back(pIndices[iIdx - 1]);
|
||||||
mIndices.push_back(0xFFFF);
|
mIndices.push_back(0xFFFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,11 +14,11 @@ class CIndexBuffer
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CIndexBuffer();
|
CIndexBuffer();
|
||||||
CIndexBuffer(GLenum type);
|
CIndexBuffer(GLenum Type);
|
||||||
~CIndexBuffer();
|
~CIndexBuffer();
|
||||||
void AddIndex(u16 idx);
|
void AddIndex(u16 Index);
|
||||||
void AddIndices(u16 *indicesPtr, u32 count);
|
void AddIndices(u16 *pIndices, u32 Count);
|
||||||
void Reserve(u32 size);
|
void Reserve(u32 Size);
|
||||||
void Clear();
|
void Clear();
|
||||||
void Buffer();
|
void Buffer();
|
||||||
void Bind();
|
void Bind();
|
||||||
|
@ -29,11 +29,11 @@ public:
|
||||||
|
|
||||||
u32 GetSize();
|
u32 GetSize();
|
||||||
GLenum GetPrimitiveType();
|
GLenum GetPrimitiveType();
|
||||||
void SetPrimitiveType(GLenum type);
|
void SetPrimitiveType(GLenum Type);
|
||||||
|
|
||||||
void TrianglesToStrips(u16 *indicesPtr, u32 count);
|
void TrianglesToStrips(u16 *pIndices, u32 Count);
|
||||||
void FansToStrips(u16 *indicesPtr, u32 count);
|
void FansToStrips(u16 *pIndices, u32 Count);
|
||||||
void QuadsToStrips(u16 *indicesPtr, u32 count);
|
void QuadsToStrips(u16 *pIndices, u32 Count);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CINDEXBUFFER_H
|
#endif // CINDEXBUFFER_H
|
||||||
|
|
|
@ -1,52 +0,0 @@
|
||||||
#include "CRenderbuffer.h"
|
|
||||||
|
|
||||||
CRenderbuffer::CRenderbuffer()
|
|
||||||
{
|
|
||||||
mInitialized = false;
|
|
||||||
mWidth = 0;
|
|
||||||
mHeight = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
CRenderbuffer::CRenderbuffer(u32 Width, u32 Height)
|
|
||||||
{
|
|
||||||
mInitialized = false;
|
|
||||||
mWidth = Width;
|
|
||||||
mHeight = Height;
|
|
||||||
}
|
|
||||||
|
|
||||||
CRenderbuffer::~CRenderbuffer()
|
|
||||||
{
|
|
||||||
if (mInitialized)
|
|
||||||
glDeleteRenderbuffers(1, &mRenderbuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CRenderbuffer::Init()
|
|
||||||
{
|
|
||||||
glGenRenderbuffers(1, &mRenderbuffer);
|
|
||||||
glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer);
|
|
||||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, mWidth, mHeight);
|
|
||||||
mInitialized = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CRenderbuffer::Resize(u32 Width, u32 Height)
|
|
||||||
{
|
|
||||||
mWidth = Width;
|
|
||||||
mHeight = Height;
|
|
||||||
|
|
||||||
if (mInitialized)
|
|
||||||
{
|
|
||||||
Bind();
|
|
||||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, mWidth, mHeight);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CRenderbuffer::Bind()
|
|
||||||
{
|
|
||||||
if (!mInitialized) Init();
|
|
||||||
glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CRenderbuffer::Unbind()
|
|
||||||
{
|
|
||||||
glBindRenderbuffer(GL_RENDERBUFFER, 0);
|
|
||||||
}
|
|
|
@ -11,21 +11,61 @@ class CRenderbuffer
|
||||||
bool mInitialized;
|
bool mInitialized;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CRenderbuffer();
|
CRenderbuffer::CRenderbuffer()
|
||||||
CRenderbuffer(u32 Width, u32 Height);
|
: mInitialized(false)
|
||||||
~CRenderbuffer();
|
, mWidth(0)
|
||||||
void Init();
|
, mHeight(0)
|
||||||
void Resize(u32 Width, u32 Height);
|
{
|
||||||
void Bind();
|
}
|
||||||
void Unbind();
|
|
||||||
|
|
||||||
// Getters
|
CRenderbuffer::CRenderbuffer(u32 Width, u32 Height)
|
||||||
GLuint BufferID();
|
: mInitialized(false)
|
||||||
|
, mWidth(Width)
|
||||||
|
, mHeight(Height)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
CRenderbuffer::~CRenderbuffer()
|
||||||
|
{
|
||||||
|
if (mInitialized)
|
||||||
|
glDeleteRenderbuffers(1, &mRenderbuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CRenderbuffer::Init()
|
||||||
|
{
|
||||||
|
glGenRenderbuffers(1, &mRenderbuffer);
|
||||||
|
glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer);
|
||||||
|
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, mWidth, mHeight);
|
||||||
|
mInitialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void CRenderbuffer::Resize(u32 Width, u32 Height)
|
||||||
|
{
|
||||||
|
mWidth = Width;
|
||||||
|
mHeight = Height;
|
||||||
|
|
||||||
|
if (mInitialized)
|
||||||
|
{
|
||||||
|
Bind();
|
||||||
|
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, mWidth, mHeight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void CRenderbuffer::Bind()
|
||||||
|
{
|
||||||
|
if (!mInitialized) Init();
|
||||||
|
glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void CRenderbuffer::Unbind()
|
||||||
|
{
|
||||||
|
glBindRenderbuffer(GL_RENDERBUFFER, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline GLuint BufferID()
|
||||||
|
{
|
||||||
|
return mRenderbuffer;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
inline GLuint CRenderbuffer::BufferID()
|
|
||||||
{
|
|
||||||
return mRenderbuffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // CRENDERBUFFER_H
|
#endif // CRENDERBUFFER_H
|
||||||
|
|
|
@ -21,14 +21,14 @@ CShader::CShader()
|
||||||
mProgramExists = false;
|
mProgramExists = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
CShader::CShader(const char *kpVertexSource, const char *kpPixelSource)
|
CShader::CShader(const char *pkVertexSource, const char *pkPixelSource)
|
||||||
{
|
{
|
||||||
mVertexShaderExists = false;
|
mVertexShaderExists = false;
|
||||||
mPixelShaderExists = false;
|
mPixelShaderExists = false;
|
||||||
mProgramExists = false;
|
mProgramExists = false;
|
||||||
|
|
||||||
CompileVertexSource(kpVertexSource);
|
CompileVertexSource(pkVertexSource);
|
||||||
CompilePixelSource(kpPixelSource);
|
CompilePixelSource(pkPixelSource);
|
||||||
LinkShaders();
|
LinkShaders();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,10 +41,10 @@ CShader::~CShader()
|
||||||
if (spCurrentShader == this) spCurrentShader = 0;
|
if (spCurrentShader == this) spCurrentShader = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CShader::CompileVertexSource(const char* kpSource)
|
bool CShader::CompileVertexSource(const char* pkSource)
|
||||||
{
|
{
|
||||||
mVertexShader = glCreateShader(GL_VERTEX_SHADER);
|
mVertexShader = glCreateShader(GL_VERTEX_SHADER);
|
||||||
glShaderSource(mVertexShader, 1, (const GLchar**) &kpSource, NULL);
|
glShaderSource(mVertexShader, 1, (const GLchar**) &pkSource, NULL);
|
||||||
glCompileShader(mVertexShader);
|
glCompileShader(mVertexShader);
|
||||||
|
|
||||||
// Shader should be compiled - check for errors
|
// Shader should be compiled - check for errors
|
||||||
|
@ -76,10 +76,10 @@ bool CShader::CompileVertexSource(const char* kpSource)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CShader::CompilePixelSource(const char* kpSource)
|
bool CShader::CompilePixelSource(const char* pkSource)
|
||||||
{
|
{
|
||||||
mPixelShader = glCreateShader(GL_FRAGMENT_SHADER);
|
mPixelShader = glCreateShader(GL_FRAGMENT_SHADER);
|
||||||
glShaderSource(mPixelShader, 1, (const GLchar**) &kpSource, NULL);
|
glShaderSource(mPixelShader, 1, (const GLchar**) &pkSource, NULL);
|
||||||
glCompileShader(mPixelShader);
|
glCompileShader(mPixelShader);
|
||||||
|
|
||||||
// Shader should be compiled - check for errors
|
// Shader should be compiled - check for errors
|
||||||
|
@ -136,17 +136,17 @@ bool CShader::LinkShaders()
|
||||||
|
|
||||||
GLint LogLen;
|
GLint LogLen;
|
||||||
glGetProgramiv(mProgram, GL_INFO_LOG_LENGTH, &LogLen);
|
glGetProgramiv(mProgram, GL_INFO_LOG_LENGTH, &LogLen);
|
||||||
GLchar *InfoLog = new GLchar[LogLen];
|
GLchar *pInfoLog = new GLchar[LogLen];
|
||||||
glGetProgramInfoLog(mProgram, LogLen, NULL, InfoLog);
|
glGetProgramInfoLog(mProgram, LogLen, NULL, pInfoLog);
|
||||||
|
|
||||||
std::ofstream LinkOut;
|
std::ofstream LinkOut;
|
||||||
LinkOut.open(*Out);
|
LinkOut.open(*Out);
|
||||||
|
|
||||||
if (LogLen > 0)
|
if (LogLen > 0)
|
||||||
LinkOut << InfoLog;
|
LinkOut << pInfoLog;
|
||||||
|
|
||||||
LinkOut.close();
|
LinkOut.close();
|
||||||
delete[] InfoLog;
|
delete[] pInfoLog;
|
||||||
|
|
||||||
gFailedCompileCount++;
|
gFailedCompileCount++;
|
||||||
glDeleteProgram(mProgram);
|
glDeleteProgram(mProgram);
|
||||||
|
@ -172,14 +172,14 @@ GLuint CShader::GetProgramID()
|
||||||
return mProgram;
|
return mProgram;
|
||||||
}
|
}
|
||||||
|
|
||||||
GLuint CShader::GetUniformLocation(const char* Uniform)
|
GLuint CShader::GetUniformLocation(const char* pkUniform)
|
||||||
{
|
{
|
||||||
return glGetUniformLocation(mProgram, Uniform);
|
return glGetUniformLocation(mProgram, pkUniform);
|
||||||
}
|
}
|
||||||
|
|
||||||
GLuint CShader::GetUniformBlockIndex(const char* UniformBlock)
|
GLuint CShader::GetUniformBlockIndex(const char* pkUniformBlock)
|
||||||
{
|
{
|
||||||
return glGetUniformBlockIndex(mProgram, UniformBlock);
|
return glGetUniformBlockIndex(mProgram, pkUniformBlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CShader::SetCurrent()
|
void CShader::SetCurrent()
|
||||||
|
@ -197,17 +197,17 @@ void CShader::SetCurrent()
|
||||||
}
|
}
|
||||||
|
|
||||||
// ************ STATIC ************
|
// ************ STATIC ************
|
||||||
CShader* CShader::FromResourceFile(const TString& ShaderName)
|
CShader* CShader::FromResourceFile(const TString& rkShaderName)
|
||||||
{
|
{
|
||||||
TString VertexShaderFilename = "../resources/shaders/" + ShaderName + ".vs";
|
TString VertexShaderFilename = "../resources/shaders/" + rkShaderName + ".vs";
|
||||||
TString PixelShaderFilename = "../resources/shaders/" + ShaderName + ".ps";
|
TString PixelShaderFilename = "../resources/shaders/" + rkShaderName + ".ps";
|
||||||
CTextInStream VertexShaderFile(VertexShaderFilename.ToStdString());
|
CTextInStream VertexShaderFile(VertexShaderFilename.ToStdString());
|
||||||
CTextInStream PixelShaderFile(PixelShaderFilename.ToStdString());
|
CTextInStream PixelShaderFile(PixelShaderFilename.ToStdString());
|
||||||
|
|
||||||
if (!VertexShaderFile.IsValid())
|
if (!VertexShaderFile.IsValid())
|
||||||
Log::Error("Couldn't load vertex shader file for " + ShaderName);
|
Log::Error("Couldn't load vertex shader file for " + rkShaderName);
|
||||||
if (!PixelShaderFile.IsValid())
|
if (!PixelShaderFile.IsValid())
|
||||||
Log::Error("Error: Couldn't load pixel shader file for " + ShaderName);
|
Log::Error("Error: Couldn't load pixel shader file for " + rkShaderName);
|
||||||
if ((!VertexShaderFile.IsValid()) || (!PixelShaderFile.IsValid())) return nullptr;
|
if ((!VertexShaderFile.IsValid()) || (!PixelShaderFile.IsValid())) return nullptr;
|
||||||
|
|
||||||
std::stringstream VertexShader;
|
std::stringstream VertexShader;
|
||||||
|
@ -236,7 +236,7 @@ void CShader::KillCachedShader()
|
||||||
}
|
}
|
||||||
|
|
||||||
// ************ PRIVATE ************
|
// ************ PRIVATE ************
|
||||||
void CShader::DumpShaderSource(GLuint Shader, const TString& Out)
|
void CShader::DumpShaderSource(GLuint Shader, const TString& rkOut)
|
||||||
{
|
{
|
||||||
GLint SourceLen;
|
GLint SourceLen;
|
||||||
glGetShaderiv(Shader, GL_SHADER_SOURCE_LENGTH, &SourceLen);
|
glGetShaderiv(Shader, GL_SHADER_SOURCE_LENGTH, &SourceLen);
|
||||||
|
@ -245,19 +245,19 @@ void CShader::DumpShaderSource(GLuint Shader, const TString& Out)
|
||||||
|
|
||||||
GLint LogLen;
|
GLint LogLen;
|
||||||
glGetShaderiv(Shader, GL_INFO_LOG_LENGTH, &LogLen);
|
glGetShaderiv(Shader, GL_INFO_LOG_LENGTH, &LogLen);
|
||||||
GLchar *InfoLog = new GLchar[LogLen];
|
GLchar *pInfoLog = new GLchar[LogLen];
|
||||||
glGetShaderInfoLog(Shader, LogLen, NULL, InfoLog);
|
glGetShaderInfoLog(Shader, LogLen, NULL, pInfoLog);
|
||||||
|
|
||||||
std::ofstream ShaderOut;
|
std::ofstream ShaderOut;
|
||||||
ShaderOut.open(*Out);
|
ShaderOut.open(*rkOut);
|
||||||
|
|
||||||
if (SourceLen > 0)
|
if (SourceLen > 0)
|
||||||
ShaderOut << Source;
|
ShaderOut << Source;
|
||||||
if (LogLen > 0)
|
if (LogLen > 0)
|
||||||
ShaderOut << InfoLog;
|
ShaderOut << pInfoLog;
|
||||||
|
|
||||||
ShaderOut.close();
|
ShaderOut.close();
|
||||||
|
|
||||||
delete[] Source;
|
delete[] Source;
|
||||||
delete[] InfoLog;
|
delete[] pInfoLog;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,24 +22,24 @@ class CShader
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CShader();
|
CShader();
|
||||||
CShader(const char* kpVertexSource, const char* kpPixelSource);
|
CShader(const char* pkVertexSource, const char* pkPixelSource);
|
||||||
~CShader();
|
~CShader();
|
||||||
bool CompileVertexSource(const char* kpSource);
|
bool CompileVertexSource(const char* pkSource);
|
||||||
bool CompilePixelSource(const char* kpSource);
|
bool CompilePixelSource(const char* pkSource);
|
||||||
bool LinkShaders();
|
bool LinkShaders();
|
||||||
bool IsValidProgram();
|
bool IsValidProgram();
|
||||||
GLuint GetProgramID();
|
GLuint GetProgramID();
|
||||||
GLuint GetUniformLocation(const char* kpUniform);
|
GLuint GetUniformLocation(const char* pkUniform);
|
||||||
GLuint GetUniformBlockIndex(const char* kpUniformBlock);
|
GLuint GetUniformBlockIndex(const char* pkUniformBlock);
|
||||||
void SetCurrent();
|
void SetCurrent();
|
||||||
|
|
||||||
// Static
|
// Static
|
||||||
static CShader* FromResourceFile(const TString& ShaderName);
|
static CShader* FromResourceFile(const TString& rkShaderName);
|
||||||
static CShader* CurrentShader();
|
static CShader* CurrentShader();
|
||||||
static void KillCachedShader();
|
static void KillCachedShader();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void DumpShaderSource(GLuint Shader, const TString& Out);
|
void DumpShaderSource(GLuint Shader, const TString& rkOut);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CSHADER_H
|
#endif // CSHADER_H
|
||||||
|
|
|
@ -299,7 +299,7 @@ bool CShaderGenerator::CreateVertexShader(const CMaterial& Mat)
|
||||||
|
|
||||||
|
|
||||||
// Done!
|
// Done!
|
||||||
return mShader->CompileVertexSource(ShaderCode.str().c_str());
|
return mpShader->CompileVertexSource(ShaderCode.str().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CShaderGenerator::CreatePixelShader(const CMaterial& Mat)
|
bool CShaderGenerator::CreatePixelShader(const CMaterial& Mat)
|
||||||
|
@ -433,17 +433,17 @@ bool CShaderGenerator::CreatePixelShader(const CMaterial& Mat)
|
||||||
<< "}\n\n";
|
<< "}\n\n";
|
||||||
|
|
||||||
// Done!
|
// Done!
|
||||||
return mShader->CompilePixelSource(ShaderCode.str().c_str());
|
return mpShader->CompilePixelSource(ShaderCode.str().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
CShader* CShaderGenerator::GenerateShader(const CMaterial& Mat)
|
CShader* CShaderGenerator::GenerateShader(const CMaterial& rkMat)
|
||||||
{
|
{
|
||||||
CShaderGenerator Generator;
|
CShaderGenerator Generator;
|
||||||
Generator.mShader = new CShader();
|
Generator.mpShader = new CShader();
|
||||||
|
|
||||||
bool Success = Generator.CreateVertexShader(Mat);
|
bool Success = Generator.CreateVertexShader(rkMat);
|
||||||
if (Success) Success = Generator.CreatePixelShader(Mat);
|
if (Success) Success = Generator.CreatePixelShader(rkMat);
|
||||||
|
|
||||||
Generator.mShader->LinkShaders();
|
Generator.mpShader->LinkShaders();
|
||||||
return Generator.mShader;
|
return Generator.mpShader;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,15 +7,15 @@
|
||||||
|
|
||||||
class CShaderGenerator
|
class CShaderGenerator
|
||||||
{
|
{
|
||||||
CShader *mShader;
|
CShader *mpShader;
|
||||||
|
|
||||||
CShaderGenerator();
|
CShaderGenerator();
|
||||||
~CShaderGenerator();
|
~CShaderGenerator();
|
||||||
bool CreateVertexShader(const CMaterial& Mat);
|
bool CreateVertexShader(const CMaterial& rkMat);
|
||||||
bool CreatePixelShader(const CMaterial& Mat);
|
bool CreatePixelShader(const CMaterial& rkMat);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static CShader* GenerateShader(const CMaterial& Mat);
|
static CShader* GenerateShader(const CMaterial& rkMat);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SHADERGEN_H
|
#endif // SHADERGEN_H
|
||||||
|
|
|
@ -1,60 +0,0 @@
|
||||||
#include "CUniformBuffer.h"
|
|
||||||
|
|
||||||
CUniformBuffer::CUniformBuffer()
|
|
||||||
{
|
|
||||||
glGenBuffers(1, &mUniformBuffer);
|
|
||||||
SetBufferSize(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
CUniformBuffer::CUniformBuffer(u32 Size)
|
|
||||||
{
|
|
||||||
glGenBuffers(1, &mUniformBuffer);
|
|
||||||
SetBufferSize(Size);
|
|
||||||
}
|
|
||||||
|
|
||||||
CUniformBuffer::~CUniformBuffer()
|
|
||||||
{
|
|
||||||
glDeleteBuffers(1, &mUniformBuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CUniformBuffer::InitializeBuffer()
|
|
||||||
{
|
|
||||||
Bind();
|
|
||||||
glBufferData(GL_UNIFORM_BUFFER, mBufferSize, 0, GL_DYNAMIC_DRAW);
|
|
||||||
Unbind();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CUniformBuffer::Bind()
|
|
||||||
{
|
|
||||||
glBindBuffer(GL_UNIFORM_BUFFER, mUniformBuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CUniformBuffer::Unbind()
|
|
||||||
{
|
|
||||||
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CUniformBuffer::BindBase(GLuint index)
|
|
||||||
{
|
|
||||||
Bind();
|
|
||||||
glBindBufferBase(GL_UNIFORM_BUFFER, index, mUniformBuffer);
|
|
||||||
Unbind();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CUniformBuffer::Buffer(void *pData)
|
|
||||||
{
|
|
||||||
Bind();
|
|
||||||
glBufferSubData(GL_UNIFORM_BUFFER, 0, mBufferSize, pData);
|
|
||||||
Unbind();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CUniformBuffer::SetBufferSize(u32 Size)
|
|
||||||
{
|
|
||||||
mBufferSize = Size;
|
|
||||||
InitializeBuffer();
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 CUniformBuffer::GetBufferSize()
|
|
||||||
{
|
|
||||||
return mBufferSize;
|
|
||||||
}
|
|
|
@ -10,19 +10,66 @@ class CUniformBuffer
|
||||||
u32 mBufferSize;
|
u32 mBufferSize;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CUniformBuffer();
|
|
||||||
CUniformBuffer(u32 Size);
|
|
||||||
~CUniformBuffer();
|
|
||||||
void Bind();
|
|
||||||
void Unbind();
|
|
||||||
void BindBase(GLuint index);
|
|
||||||
void Buffer(void *pData);
|
|
||||||
|
|
||||||
void SetBufferSize(u32 Size);
|
CUniformBuffer()
|
||||||
u32 GetBufferSize();
|
{
|
||||||
|
glGenBuffers(1, &mUniformBuffer);
|
||||||
|
SetBufferSize(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
CUniformBuffer(u32 Size)
|
||||||
|
{
|
||||||
|
glGenBuffers(1, &mUniformBuffer);
|
||||||
|
SetBufferSize(Size);
|
||||||
|
}
|
||||||
|
|
||||||
|
~CUniformBuffer()
|
||||||
|
{
|
||||||
|
glDeleteBuffers(1, &mUniformBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Bind()
|
||||||
|
{
|
||||||
|
glBindBuffer(GL_UNIFORM_BUFFER, mUniformBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Unbind()
|
||||||
|
{
|
||||||
|
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BindBase(GLuint Index)
|
||||||
|
{
|
||||||
|
Bind();
|
||||||
|
glBindBufferBase(GL_UNIFORM_BUFFER, Index, mUniformBuffer);
|
||||||
|
Unbind();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Buffer(void *pData)
|
||||||
|
{
|
||||||
|
Bind();
|
||||||
|
glBufferSubData(GL_UNIFORM_BUFFER, 0, mBufferSize, pData);
|
||||||
|
Unbind();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetBufferSize(u32 Size)
|
||||||
|
{
|
||||||
|
mBufferSize = Size;
|
||||||
|
InitializeBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 GetBufferSize()
|
||||||
|
{
|
||||||
|
return mBufferSize;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void InitializeBuffer();
|
void InitializeBuffer()
|
||||||
|
{
|
||||||
|
Bind();
|
||||||
|
glBufferData(GL_UNIFORM_BUFFER, mBufferSize, 0, GL_DYNAMIC_DRAW);
|
||||||
|
Unbind();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CUNIFORMBUFFER_H
|
#endif // CUNIFORMBUFFER_H
|
||||||
|
|
|
@ -21,25 +21,25 @@ CVertexBuffer::~CVertexBuffer()
|
||||||
glDeleteBuffers(12, mAttribBuffers);
|
glDeleteBuffers(12, mAttribBuffers);
|
||||||
}
|
}
|
||||||
|
|
||||||
u16 CVertexBuffer::AddVertex(const CVertex& Vert)
|
u16 CVertexBuffer::AddVertex(const CVertex& rkVtx)
|
||||||
{
|
{
|
||||||
if (mPositions.size() == 0xFFFF) throw std::overflow_error("VBO contains too many vertices");
|
if (mPositions.size() == 0xFFFF) throw std::overflow_error("VBO contains too many vertices");
|
||||||
|
|
||||||
if (mVtxDesc & ePosition) mPositions.push_back(Vert.Position);
|
if (mVtxDesc & ePosition) mPositions.push_back(rkVtx.Position);
|
||||||
if (mVtxDesc & eNormal) mNormals.push_back(Vert.Normal);
|
if (mVtxDesc & eNormal) mNormals.push_back(rkVtx.Normal);
|
||||||
if (mVtxDesc & eColor0) mColors[0].push_back(Vert.Color[0]);
|
if (mVtxDesc & eColor0) mColors[0].push_back(rkVtx.Color[0]);
|
||||||
if (mVtxDesc & eColor1) mColors[1].push_back(Vert.Color[1]);
|
if (mVtxDesc & eColor1) mColors[1].push_back(rkVtx.Color[1]);
|
||||||
|
|
||||||
for (u32 iTex = 0; iTex < 8; iTex++)
|
for (u32 iTex = 0; iTex < 8; iTex++)
|
||||||
if (mVtxDesc & (eTex0 << (iTex * 2))) mTexCoords[iTex].push_back(Vert.Tex[iTex]);
|
if (mVtxDesc & (eTex0 << (iTex * 2))) mTexCoords[iTex].push_back(rkVtx.Tex[iTex]);
|
||||||
|
|
||||||
for (u32 iMtx = 0; iMtx < 8; iMtx++)
|
for (u32 iMtx = 0; iMtx < 8; iMtx++)
|
||||||
if (mVtxDesc & (ePosMtx << iMtx)) mTexCoords[iMtx].push_back(Vert.MatrixIndices[iMtx]);
|
if (mVtxDesc & (ePosMtx << iMtx)) mTexCoords[iMtx].push_back(rkVtx.MatrixIndices[iMtx]);
|
||||||
|
|
||||||
return (mPositions.size() - 1);
|
return (mPositions.size() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
u16 CVertexBuffer::AddIfUnique(const CVertex& Vert, u16 Start)
|
u16 CVertexBuffer::AddIfUnique(const CVertex& rkVtx, u16 Start)
|
||||||
{
|
{
|
||||||
if (Start < mPositions.size())
|
if (Start < mPositions.size())
|
||||||
{
|
{
|
||||||
|
@ -49,21 +49,21 @@ u16 CVertexBuffer::AddIfUnique(const CVertex& Vert, u16 Start)
|
||||||
bool Unique = false;
|
bool Unique = false;
|
||||||
|
|
||||||
if (mVtxDesc & ePosition)
|
if (mVtxDesc & ePosition)
|
||||||
if (Vert.Position != mPositions[iVert]) Unique = true;
|
if (rkVtx.Position != mPositions[iVert]) Unique = true;
|
||||||
|
|
||||||
if ((!Unique) && (mVtxDesc & eNormal))
|
if ((!Unique) && (mVtxDesc & eNormal))
|
||||||
if (Vert.Normal != mNormals[iVert]) Unique = true;
|
if (rkVtx.Normal != mNormals[iVert]) Unique = true;
|
||||||
|
|
||||||
if ((!Unique) && (mVtxDesc & eColor0))
|
if ((!Unique) && (mVtxDesc & eColor0))
|
||||||
if (Vert.Color[0] != mColors[0][iVert]) Unique = true;
|
if (rkVtx.Color[0] != mColors[0][iVert]) Unique = true;
|
||||||
|
|
||||||
if ((!Unique) && (mVtxDesc & eColor1))
|
if ((!Unique) && (mVtxDesc & eColor1))
|
||||||
if (Vert.Color[1] != mColors[1][iVert]) Unique = true;
|
if (rkVtx.Color[1] != mColors[1][iVert]) Unique = true;
|
||||||
|
|
||||||
if (!Unique)
|
if (!Unique)
|
||||||
for (u32 iTex = 0; iTex < 8; iTex++)
|
for (u32 iTex = 0; iTex < 8; iTex++)
|
||||||
if ((mVtxDesc & (eTex0 << (iTex * 2))))
|
if ((mVtxDesc & (eTex0 << (iTex * 2))))
|
||||||
if (Vert.Tex[iTex] != mTexCoords[iTex][iVert])
|
if (rkVtx.Tex[iTex] != mTexCoords[iTex][iVert])
|
||||||
{
|
{
|
||||||
Unique = true;
|
Unique = true;
|
||||||
break;
|
break;
|
||||||
|
@ -73,12 +73,12 @@ u16 CVertexBuffer::AddIfUnique(const CVertex& Vert, u16 Start)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return AddVertex(Vert);
|
return AddVertex(rkVtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CVertexBuffer::Reserve(u16 size)
|
void CVertexBuffer::Reserve(u16 Size)
|
||||||
{
|
{
|
||||||
u32 ReserveSize = mPositions.size() + size;
|
u32 ReserveSize = mPositions.size() + Size;
|
||||||
|
|
||||||
if (mVtxDesc & ePosition)
|
if (mVtxDesc & ePosition)
|
||||||
mPositions.reserve(ReserveSize);
|
mPositions.reserve(ReserveSize);
|
||||||
|
@ -140,18 +140,18 @@ void CVertexBuffer::Buffer()
|
||||||
|
|
||||||
else if (iAttrib < 4)
|
else if (iAttrib < 4)
|
||||||
{
|
{
|
||||||
u8 idx = (u8) (iAttrib - 2);
|
u8 Index = (u8) (iAttrib - 2);
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, mAttribBuffers[iAttrib]);
|
glBindBuffer(GL_ARRAY_BUFFER, mAttribBuffers[iAttrib]);
|
||||||
glBufferData(GL_ARRAY_BUFFER, mColors[idx].size() * sizeof(CColor), mColors[idx].data(), GL_STATIC_DRAW);
|
glBufferData(GL_ARRAY_BUFFER, mColors[Index].size() * sizeof(CColor), mColors[Index].data(), GL_STATIC_DRAW);
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
u8 idx = (u8) (iAttrib - 4);
|
u8 Index = (u8) (iAttrib - 4);
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, mAttribBuffers[iAttrib]);
|
glBindBuffer(GL_ARRAY_BUFFER, mAttribBuffers[iAttrib]);
|
||||||
glBufferData(GL_ARRAY_BUFFER, mTexCoords[idx].size() * sizeof(CVector2f), mTexCoords[idx].data(), GL_STATIC_DRAW);
|
glBufferData(GL_ARRAY_BUFFER, mTexCoords[Index].size() * sizeof(CVector2f), mTexCoords[Index].data(), GL_STATIC_DRAW);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,9 +20,9 @@ public:
|
||||||
CVertexBuffer();
|
CVertexBuffer();
|
||||||
CVertexBuffer(FVertexDescription Desc);
|
CVertexBuffer(FVertexDescription Desc);
|
||||||
~CVertexBuffer();
|
~CVertexBuffer();
|
||||||
u16 AddVertex(const CVertex& vtx);
|
u16 AddVertex(const CVertex& rkVtx);
|
||||||
u16 AddIfUnique(const CVertex& vtx, u16 start);
|
u16 AddIfUnique(const CVertex& rkVtx, u16 Start);
|
||||||
void Reserve(u16 size);
|
void Reserve(u16 Size);
|
||||||
void Clear();
|
void Clear();
|
||||||
void Buffer();
|
void Buffer();
|
||||||
void Bind();
|
void Bind();
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
#include "GLCommon.h"
|
#include "GLCommon.h"
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
GLenum glBlendFactor[] = {
|
GLenum gBlendFactor[] =
|
||||||
|
{
|
||||||
GL_ZERO, // GX_BL_ZERO
|
GL_ZERO, // GX_BL_ZERO
|
||||||
GL_ONE, // GX_BL_ONE
|
GL_ONE, // GX_BL_ONE
|
||||||
GL_SRC_COLOR, // GX_BL_SRCCLR / GX_BL_DSTCLR
|
GL_SRC_COLOR, // GX_BL_SRCCLR / GX_BL_DSTCLR
|
||||||
|
@ -13,7 +14,8 @@ GLenum glBlendFactor[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
GLenum glZMode[] = {
|
GLenum gZMode[] =
|
||||||
|
{
|
||||||
GL_NEVER, // GX_NEVER
|
GL_NEVER, // GX_NEVER
|
||||||
GL_LESS, // GX_LESS
|
GL_LESS, // GX_LESS
|
||||||
GL_EQUAL, // GX_EQUAL
|
GL_EQUAL, // GX_EQUAL
|
||||||
|
@ -23,8 +25,9 @@ GLenum glZMode[] = {
|
||||||
GL_ALWAYS // GX_ALWAYS
|
GL_ALWAYS // GX_ALWAYS
|
||||||
};
|
};
|
||||||
|
|
||||||
GLenum GXPrimToGLPrim(EGXPrimitiveType t) {
|
GLenum GXPrimToGLPrim(EGXPrimitiveType Type)
|
||||||
switch (t) {
|
{
|
||||||
|
switch (Type) {
|
||||||
case eGX_Quads: return GL_TRIANGLE_STRIP; // Quads are converted to strips
|
case eGX_Quads: return GL_TRIANGLE_STRIP; // Quads are converted to strips
|
||||||
case eGX_Triangles: return GL_TRIANGLE_STRIP; // Triangles are converted to strips
|
case eGX_Triangles: return GL_TRIANGLE_STRIP; // Triangles are converted to strips
|
||||||
case eGX_TriangleStrip: return GL_TRIANGLE_STRIP;
|
case eGX_TriangleStrip: return GL_TRIANGLE_STRIP;
|
||||||
|
|
|
@ -27,8 +27,8 @@ enum EGXPrimitiveType
|
||||||
eGX_Points = 0xB8
|
eGX_Points = 0xB8
|
||||||
};
|
};
|
||||||
|
|
||||||
extern GLenum glBlendFactor[];
|
extern GLenum gBlendFactor[];
|
||||||
extern GLenum glZMode[];
|
extern GLenum gZMode[];
|
||||||
GLenum GXPrimToGLPrim(EGXPrimitiveType t);
|
GLenum GXPrimToGLPrim(EGXPrimitiveType Type);
|
||||||
|
|
||||||
#endif // GLCOMMON_H
|
#endif // GLCOMMON_H
|
||||||
|
|
|
@ -5,33 +5,31 @@
|
||||||
#include <gtc/matrix_transform.hpp>
|
#include <gtc/matrix_transform.hpp>
|
||||||
|
|
||||||
CCamera::CCamera()
|
CCamera::CCamera()
|
||||||
|
: mMode(eFreeCamera)
|
||||||
|
, mPosition(0)
|
||||||
|
, mAspectRatio(1.7777777f)
|
||||||
|
, mYaw(-Math::skHalfPi)
|
||||||
|
, mPitch(0.f)
|
||||||
|
, mMoveSpeed(1.f)
|
||||||
|
, mLookSpeed(1.f)
|
||||||
|
, mTransformDirty(true)
|
||||||
|
, mViewDirty(true)
|
||||||
|
, mProjectionDirty(true)
|
||||||
|
, mFrustumPlanesDirty(true)
|
||||||
{
|
{
|
||||||
mMode = eFreeCamera;
|
|
||||||
mPosition = CVector3f(0);
|
|
||||||
mAspectRatio = 1.7777777f;
|
|
||||||
|
|
||||||
mYaw = -Math::skHalfPi;
|
|
||||||
mPitch = 0.0f;
|
|
||||||
SetOrbit(CVector3f(0), 5.f);
|
SetOrbit(CVector3f(0), 5.f);
|
||||||
|
|
||||||
mMoveSpeed = 1.f;
|
|
||||||
mLookSpeed = 1.f;
|
|
||||||
mTransformDirty = true;
|
|
||||||
mViewDirty = true;
|
|
||||||
mProjectionDirty = true;
|
|
||||||
mFrustumPlanesDirty = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// todo: make it actually look at the target!
|
||||||
|
// don't actually use this constructor, it's unfinished and won't work properly
|
||||||
CCamera::CCamera(CVector3f Position, CVector3f /*Target*/)
|
CCamera::CCamera(CVector3f Position, CVector3f /*Target*/)
|
||||||
|
: mMode(eFreeCamera)
|
||||||
|
, mMoveSpeed(1.f)
|
||||||
|
, mLookSpeed(1.f)
|
||||||
|
, mPosition(Position)
|
||||||
|
, mYaw(-Math::skHalfPi)
|
||||||
|
, mPitch(0.f)
|
||||||
{
|
{
|
||||||
// todo: make it actually look at the target!
|
|
||||||
// don't actually use this constructor, it's unfinished and won't work properly
|
|
||||||
mMode = eFreeCamera;
|
|
||||||
mMoveSpeed = 1.f;
|
|
||||||
mLookSpeed = 1.f;
|
|
||||||
mPosition = Position;
|
|
||||||
mYaw = -Math::skHalfPi;
|
|
||||||
mPitch = 0.0f;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCamera::Pan(float XAmount, float YAmount)
|
void CCamera::Pan(float XAmount, float YAmount)
|
||||||
|
@ -123,8 +121,8 @@ CRay CCamera::CastRay(CVector2f DeviceCoords) const
|
||||||
{
|
{
|
||||||
CMatrix4f InverseVP = (ViewMatrix().Transpose() * ProjectionMatrix().Transpose()).Inverse();
|
CMatrix4f InverseVP = (ViewMatrix().Transpose() * ProjectionMatrix().Transpose()).Inverse();
|
||||||
|
|
||||||
CVector3f RayOrigin = CVector3f(DeviceCoords.x, DeviceCoords.y, -1.f) * InverseVP;
|
CVector3f RayOrigin = CVector3f(DeviceCoords.X, DeviceCoords.Y, -1.f) * InverseVP;
|
||||||
CVector3f RayTarget = CVector3f(DeviceCoords.x, DeviceCoords.y, 0.f) * InverseVP;
|
CVector3f RayTarget = CVector3f(DeviceCoords.X, DeviceCoords.Y, 0.f) * InverseVP;
|
||||||
CVector3f RayDir = (RayTarget - RayOrigin).Normalized();
|
CVector3f RayDir = (RayTarget - RayOrigin).Normalized();
|
||||||
|
|
||||||
CRay Ray;
|
CRay Ray;
|
||||||
|
@ -167,9 +165,9 @@ void CCamera::SetOrbit(const CAABox& OrbitTarget, float DistScale /*= 4.f*/)
|
||||||
CVector3f Extent = (Max - Min) / 2.f;
|
CVector3f Extent = (Max - Min) / 2.f;
|
||||||
float Dist = 0.f;
|
float Dist = 0.f;
|
||||||
|
|
||||||
if (Extent.x >= Extent.y && Extent.x >= Extent.z) Dist = Extent.x;
|
if (Extent.X >= Extent.Y && Extent.X >= Extent.Z) Dist = Extent.X;
|
||||||
else if (Extent.y >= Extent.x && Extent.y >= Extent.z) Dist = Extent.y;
|
else if (Extent.Y >= Extent.X && Extent.Y >= Extent.Z) Dist = Extent.Y;
|
||||||
else Dist = Extent.z;
|
else Dist = Extent.Z;
|
||||||
|
|
||||||
mOrbitDistance = Dist * DistScale;
|
mOrbitDistance = Dist * DistScale;
|
||||||
|
|
||||||
|
@ -200,100 +198,6 @@ void CCamera::LoadMatrices() const
|
||||||
CGraphics::UpdateMVPBlock();
|
CGraphics::UpdateMVPBlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ************ GETTERS ************
|
|
||||||
CVector3f CCamera::Position() const
|
|
||||||
{
|
|
||||||
UpdateTransform();
|
|
||||||
return mPosition;
|
|
||||||
}
|
|
||||||
|
|
||||||
CVector3f CCamera::Direction() const
|
|
||||||
{
|
|
||||||
UpdateTransform();
|
|
||||||
return mDirection;
|
|
||||||
}
|
|
||||||
|
|
||||||
CVector3f CCamera::UpVector() const
|
|
||||||
{
|
|
||||||
UpdateTransform();
|
|
||||||
return mUpVector;
|
|
||||||
}
|
|
||||||
|
|
||||||
CVector3f CCamera::RightVector() const
|
|
||||||
{
|
|
||||||
UpdateTransform();
|
|
||||||
return mRightVector;
|
|
||||||
}
|
|
||||||
|
|
||||||
float CCamera::Yaw() const
|
|
||||||
{
|
|
||||||
return mYaw;
|
|
||||||
}
|
|
||||||
|
|
||||||
float CCamera::Pitch() const
|
|
||||||
{
|
|
||||||
return mPitch;
|
|
||||||
}
|
|
||||||
|
|
||||||
float CCamera::FieldOfView() const
|
|
||||||
{
|
|
||||||
return 55.f;
|
|
||||||
}
|
|
||||||
|
|
||||||
ECameraMoveMode CCamera::MoveMode() const
|
|
||||||
{
|
|
||||||
return mMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
const CMatrix4f& CCamera::ViewMatrix() const
|
|
||||||
{
|
|
||||||
UpdateView();
|
|
||||||
return mViewMatrix;
|
|
||||||
}
|
|
||||||
|
|
||||||
const CMatrix4f& CCamera::ProjectionMatrix() const
|
|
||||||
{
|
|
||||||
UpdateProjection();
|
|
||||||
return mProjectionMatrix;
|
|
||||||
}
|
|
||||||
|
|
||||||
const CFrustumPlanes& CCamera::FrustumPlanes() const
|
|
||||||
{
|
|
||||||
UpdateFrustum();
|
|
||||||
return mFrustumPlanes;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ************ SETTERS ************
|
|
||||||
void CCamera::SetYaw(float Yaw)
|
|
||||||
{
|
|
||||||
mYaw = Yaw;
|
|
||||||
mTransformDirty = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CCamera::SetPitch(float Pitch)
|
|
||||||
{
|
|
||||||
mPitch = Pitch;
|
|
||||||
ValidatePitch();
|
|
||||||
mTransformDirty = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CCamera::SetMoveSpeed(float MoveSpeed)
|
|
||||||
{
|
|
||||||
mMoveSpeed = MoveSpeed;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CCamera::SetLookSpeed(float LookSpeed)
|
|
||||||
{
|
|
||||||
mLookSpeed = LookSpeed;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CCamera::SetAspectRatio(float AspectRatio)
|
|
||||||
{
|
|
||||||
mAspectRatio = AspectRatio;
|
|
||||||
mProjectionDirty = true;
|
|
||||||
mFrustumPlanesDirty = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ************ PRIVATE ************
|
// ************ PRIVATE ************
|
||||||
void CCamera::ValidatePitch()
|
void CCamera::ValidatePitch()
|
||||||
{
|
{
|
||||||
|
@ -341,9 +245,9 @@ void CCamera::UpdateView() const
|
||||||
|
|
||||||
if (mViewDirty)
|
if (mViewDirty)
|
||||||
{
|
{
|
||||||
glm::vec3 glmpos(mPosition.x, mPosition.y, mPosition.z);
|
glm::vec3 glmpos(mPosition.X, mPosition.Y, mPosition.Z);
|
||||||
glm::vec3 glmdir(mDirection.x, mDirection.y, mDirection.z);
|
glm::vec3 glmdir(mDirection.X, mDirection.Y, mDirection.Z);
|
||||||
glm::vec3 glmup(mUpVector.x, mUpVector.y, mUpVector.z);
|
glm::vec3 glmup(mUpVector.X, mUpVector.Y, mUpVector.Z);
|
||||||
mViewMatrix = CMatrix4f::FromGlmMat4(glm::lookAt(glmpos, glmpos + glmdir, glmup)).Transpose();
|
mViewMatrix = CMatrix4f::FromGlmMat4(glm::lookAt(glmpos, glmpos + glmdir, glmup)).Transpose();
|
||||||
mViewDirty = false;
|
mViewDirty = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,29 +63,28 @@ public:
|
||||||
void LoadMatrices() const;
|
void LoadMatrices() const;
|
||||||
|
|
||||||
void SetMoveMode(ECameraMoveMode Mode);
|
void SetMoveMode(ECameraMoveMode Mode);
|
||||||
void SetOrbit(const CVector3f& OrbitTarget, float Distance);
|
void SetOrbit(const CVector3f& rkOrbitTarget, float Distance);
|
||||||
void SetOrbit(const CAABox& OrbitTarget, float DistScale = 4.f);
|
void SetOrbit(const CAABox& rkOrbitTarget, float DistScale = 4.f);
|
||||||
void SetOrbitDistance(float Distance);
|
void SetOrbitDistance(float Distance);
|
||||||
|
|
||||||
// Getters
|
// Inline Accessors
|
||||||
CVector3f Position() const;
|
inline CVector3f Position() const { UpdateTransform(); return mPosition; }
|
||||||
CVector3f Direction() const;
|
inline CVector3f Direction() const { UpdateTransform(); return mDirection; }
|
||||||
CVector3f UpVector() const;
|
inline CVector3f UpVector() const { UpdateTransform(); return mUpVector; }
|
||||||
CVector3f RightVector() const;
|
inline CVector3f RightVector() const { UpdateTransform(); return mRightVector; }
|
||||||
float Yaw() const;
|
inline float Yaw() const { return mYaw; }
|
||||||
float Pitch() const;
|
inline float Pitch() const { return mPitch; }
|
||||||
float FieldOfView() const;
|
inline float FieldOfView() const { return 55.f; }
|
||||||
ECameraMoveMode MoveMode() const;
|
inline ECameraMoveMode MoveMode() const { return mMode; }
|
||||||
const CMatrix4f& ViewMatrix() const;
|
inline const CMatrix4f& ViewMatrix() const { UpdateView(); return mViewMatrix; }
|
||||||
const CMatrix4f& ProjectionMatrix() const;
|
inline const CMatrix4f& ProjectionMatrix() const { UpdateProjection(); return mProjectionMatrix; }
|
||||||
const CFrustumPlanes& FrustumPlanes() const;
|
inline const CFrustumPlanes& FrustumPlanes() const { UpdateFrustum(); return mFrustumPlanes; }
|
||||||
|
|
||||||
// Setters
|
inline void SetYaw(float Yaw) { mYaw = Yaw; mTransformDirty = true; }
|
||||||
void SetYaw(float Yaw);
|
inline void SetPitch(float Pitch) { mPitch = Pitch; ValidatePitch(); mTransformDirty = true; }
|
||||||
void SetPitch(float Pitch);
|
inline void SetMoveSpeed(float MoveSpeed) { mMoveSpeed = MoveSpeed; }
|
||||||
void SetMoveSpeed(float MoveSpeed);
|
inline void SetLookSpeed(float LookSpeed) { mLookSpeed = LookSpeed; }
|
||||||
void SetLookSpeed(float LookSpeed);
|
inline void SetAspectRatio(float AspectRatio) { mAspectRatio = AspectRatio; mProjectionDirty = true; mFrustumPlanesDirty = true; }
|
||||||
void SetAspectRatio(float AspectRatio);
|
|
||||||
|
|
||||||
// Private
|
// Private
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -67,7 +67,7 @@ void CDrawUtil::DrawSquare()
|
||||||
{
|
{
|
||||||
// Overload with default tex coords
|
// Overload with default tex coords
|
||||||
CVector2f TexCoords[4] = { CVector2f(0.f, 1.f), CVector2f(1.f, 1.f), CVector2f(1.f, 0.f), CVector2f(0.f, 0.f) };
|
CVector2f TexCoords[4] = { CVector2f(0.f, 1.f), CVector2f(1.f, 1.f), CVector2f(1.f, 0.f), CVector2f(0.f, 0.f) };
|
||||||
DrawSquare(&TexCoords[0].x);
|
DrawSquare(&TexCoords[0].X);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDrawUtil::DrawSquare(const CVector2f& TexUL, const CVector2f& TexUR, const CVector2f& TexBR, const CVector2f& TexBL)
|
void CDrawUtil::DrawSquare(const CVector2f& TexUL, const CVector2f& TexUR, const CVector2f& TexBR, const CVector2f& TexBL)
|
||||||
|
@ -75,7 +75,7 @@ void CDrawUtil::DrawSquare(const CVector2f& TexUL, const CVector2f& TexUR, const
|
||||||
// Overload with tex coords specified via parameters
|
// Overload with tex coords specified via parameters
|
||||||
// I don't think that parameters are guaranteed to be contiguous in memory, so:
|
// I don't think that parameters are guaranteed to be contiguous in memory, so:
|
||||||
CVector2f TexCoords[4] = { TexUL, TexUR, TexBR, TexBL };
|
CVector2f TexCoords[4] = { TexUL, TexUR, TexBR, TexBL };
|
||||||
DrawSquare(&TexCoords[0].x);
|
DrawSquare(&TexCoords[0].X);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDrawUtil::DrawSquare(const float *pTexCoords)
|
void CDrawUtil::DrawSquare(const float *pTexCoords)
|
||||||
|
@ -103,7 +103,7 @@ void CDrawUtil::DrawLine(const CVector3f& PointA, const CVector3f& PointB)
|
||||||
void CDrawUtil::DrawLine(const CVector2f& PointA, const CVector2f& PointB)
|
void CDrawUtil::DrawLine(const CVector2f& PointA, const CVector2f& PointB)
|
||||||
{
|
{
|
||||||
// Overload for 2D lines
|
// Overload for 2D lines
|
||||||
DrawLine(CVector3f(PointA.x, PointA.y, 0.f), CVector3f(PointB.x, PointB.y, 0.f), CColor::skWhite);
|
DrawLine(CVector3f(PointA.X, PointA.Y, 0.f), CVector3f(PointB.X, PointB.Y, 0.f), CColor::skWhite);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDrawUtil::DrawLine(const CVector3f& PointA, const CVector3f& PointB, const CColor& LineColor)
|
void CDrawUtil::DrawLine(const CVector3f& PointA, const CVector3f& PointB, const CColor& LineColor)
|
||||||
|
@ -124,7 +124,7 @@ void CDrawUtil::DrawLine(const CVector3f& PointA, const CVector3f& PointB, const
|
||||||
void CDrawUtil::DrawLine(const CVector2f& PointA, const CVector2f& PointB, const CColor& LineColor)
|
void CDrawUtil::DrawLine(const CVector2f& PointA, const CVector2f& PointB, const CColor& LineColor)
|
||||||
{
|
{
|
||||||
// Overload for 2D lines
|
// Overload for 2D lines
|
||||||
DrawLine(CVector3f(PointA.x, PointA.y, 0.f), CVector3f(PointB.x, PointB.y, 0.f), LineColor);
|
DrawLine(CVector3f(PointA.X, PointA.Y, 0.f), CVector3f(PointB.X, PointB.Y, 0.f), LineColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDrawUtil::DrawCube()
|
void CDrawUtil::DrawCube()
|
||||||
|
@ -230,10 +230,10 @@ void CDrawUtil::DrawBillboard(CTexture* pTexture, const CVector3f& Position, con
|
||||||
mpBillboardShader->SetCurrent();
|
mpBillboardShader->SetCurrent();
|
||||||
|
|
||||||
GLuint ScaleLoc = mpBillboardShader->GetUniformLocation("BillboardScale");
|
GLuint ScaleLoc = mpBillboardShader->GetUniformLocation("BillboardScale");
|
||||||
glUniform2f(ScaleLoc, Scale.x, Scale.y);
|
glUniform2f(ScaleLoc, Scale.X, Scale.Y);
|
||||||
|
|
||||||
GLuint TintLoc = mpBillboardShader->GetUniformLocation("TintColor");
|
GLuint TintLoc = mpBillboardShader->GetUniformLocation("TintColor");
|
||||||
glUniform4f(TintLoc, Tint.r, Tint.g, Tint.b, Tint.a);
|
glUniform4f(TintLoc, Tint.R, Tint.G, Tint.B, Tint.A);
|
||||||
|
|
||||||
pTexture->Bind(0);
|
pTexture->Bind(0);
|
||||||
|
|
||||||
|
@ -259,13 +259,13 @@ void CDrawUtil::DrawLightBillboard(ELightType Type, const CColor& LightColor, co
|
||||||
mpLightBillboardShader->SetCurrent();
|
mpLightBillboardShader->SetCurrent();
|
||||||
|
|
||||||
GLuint ScaleLoc = mpLightBillboardShader->GetUniformLocation("BillboardScale");
|
GLuint ScaleLoc = mpLightBillboardShader->GetUniformLocation("BillboardScale");
|
||||||
glUniform2f(ScaleLoc, Scale.x, Scale.y);
|
glUniform2f(ScaleLoc, Scale.X, Scale.Y);
|
||||||
|
|
||||||
GLuint ColorLoc = mpLightBillboardShader->GetUniformLocation("LightColor");
|
GLuint ColorLoc = mpLightBillboardShader->GetUniformLocation("LightColor");
|
||||||
glUniform4f(ColorLoc, LightColor.r, LightColor.g, LightColor.b, LightColor.a);
|
glUniform4f(ColorLoc, LightColor.R, LightColor.G, LightColor.B, LightColor.A);
|
||||||
|
|
||||||
GLuint TintLoc = mpLightBillboardShader->GetUniformLocation("TintColor");
|
GLuint TintLoc = mpLightBillboardShader->GetUniformLocation("TintColor");
|
||||||
glUniform4f(TintLoc, Tint.r, Tint.g, Tint.b, Tint.a);
|
glUniform4f(TintLoc, Tint.R, Tint.G, Tint.B, Tint.A);
|
||||||
|
|
||||||
CTexture *pTexA = GetLightTexture(Type);
|
CTexture *pTexA = GetLightTexture(Type);
|
||||||
CTexture *pTexB = GetLightMask(Type);
|
CTexture *pTexB = GetLightMask(Type);
|
||||||
|
@ -294,7 +294,7 @@ void CDrawUtil::UseColorShader(const CColor& kColor)
|
||||||
mpColorShader->SetCurrent();
|
mpColorShader->SetCurrent();
|
||||||
|
|
||||||
GLuint ColorLoc = mpColorShader->GetUniformLocation("ColorIn");
|
GLuint ColorLoc = mpColorShader->GetUniformLocation("ColorIn");
|
||||||
glUniform4f(ColorLoc, kColor.r, kColor.g, kColor.b, kColor.a);
|
glUniform4f(ColorLoc, kColor.R, kColor.G, kColor.B, kColor.A);
|
||||||
|
|
||||||
CMaterial::KillCachedMaterial();
|
CMaterial::KillCachedMaterial();
|
||||||
}
|
}
|
||||||
|
@ -308,7 +308,7 @@ void CDrawUtil::UseColorShaderLighting(const CColor& kColor)
|
||||||
glUniform1i(NumLightsLoc, CGraphics::sNumLights);
|
glUniform1i(NumLightsLoc, CGraphics::sNumLights);
|
||||||
|
|
||||||
GLuint ColorLoc = mpColorShaderLighting->GetUniformLocation("ColorIn");
|
GLuint ColorLoc = mpColorShaderLighting->GetUniformLocation("ColorIn");
|
||||||
glUniform4f(ColorLoc, kColor.r, kColor.g, kColor.b, kColor.a);
|
glUniform4f(ColorLoc, kColor.R, kColor.G, kColor.B, kColor.A);
|
||||||
|
|
||||||
CMaterial::KillCachedMaterial();
|
CMaterial::KillCachedMaterial();
|
||||||
}
|
}
|
||||||
|
@ -324,7 +324,7 @@ void CDrawUtil::UseTextureShader(const CColor& TintColor)
|
||||||
mpTextureShader->SetCurrent();
|
mpTextureShader->SetCurrent();
|
||||||
|
|
||||||
GLuint TintColorLoc = mpTextureShader->GetUniformLocation("TintColor");
|
GLuint TintColorLoc = mpTextureShader->GetUniformLocation("TintColor");
|
||||||
glUniform4f(TintColorLoc, TintColor.r, TintColor.g, TintColor.b, TintColor.a);
|
glUniform4f(TintColorLoc, TintColor.R, TintColor.G, TintColor.B, TintColor.A);
|
||||||
|
|
||||||
CMaterial::KillCachedMaterial();
|
CMaterial::KillCachedMaterial();
|
||||||
}
|
}
|
||||||
|
@ -336,7 +336,7 @@ void CDrawUtil::UseCollisionShader(const CColor& TintColor /*= CColor::skWhite*/
|
||||||
LoadCheckerboardTexture(0);
|
LoadCheckerboardTexture(0);
|
||||||
|
|
||||||
GLuint TintColorLoc = mpCollisionShader->GetUniformLocation("TintColor");
|
GLuint TintColorLoc = mpCollisionShader->GetUniformLocation("TintColor");
|
||||||
glUniform4f(TintColorLoc, TintColor.r, TintColor.g, TintColor.b, TintColor.a);
|
glUniform4f(TintColorLoc, TintColor.R, TintColor.G, TintColor.B, TintColor.A);
|
||||||
|
|
||||||
CMaterial::KillCachedMaterial();
|
CMaterial::KillCachedMaterial();
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,65 +4,54 @@
|
||||||
#include "CRenderer.h"
|
#include "CRenderer.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
CRenderBucket::CRenderBucket()
|
void CRenderBucket::Add(const SRenderablePtr& rkPtr)
|
||||||
{
|
|
||||||
mEstSize = 0;
|
|
||||||
mSize = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CRenderBucket::SetSortType(ESortType Type)
|
|
||||||
{
|
|
||||||
mSortType = Type;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CRenderBucket::Add(const SRenderablePtr& ptr)
|
|
||||||
{
|
{
|
||||||
if (mSize >= mEstSize)
|
if (mSize >= mEstSize)
|
||||||
mRenderables.push_back(ptr);
|
mRenderables.push_back(rkPtr);
|
||||||
else
|
else
|
||||||
mRenderables[mSize] = ptr;
|
mRenderables[mSize] = rkPtr;
|
||||||
|
|
||||||
mSize++;
|
mSize++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CRenderBucket::Sort(CCamera* pCamera)
|
void CRenderBucket::Sort(CCamera* pCamera)
|
||||||
{
|
{
|
||||||
struct {
|
if (mEnableDepthSort)
|
||||||
CCamera *pCamera;
|
|
||||||
bool operator()(SRenderablePtr left, SRenderablePtr right) {
|
|
||||||
CVector3f cPos = pCamera->Position();
|
|
||||||
CVector3f cDir = pCamera->Direction();
|
|
||||||
|
|
||||||
CVector3f distL = left.AABox.ClosestPointAlongVector(cDir) - cPos;
|
|
||||||
float dotL = distL.Dot(cDir);
|
|
||||||
CVector3f distR = right.AABox.ClosestPointAlongVector(cDir) - cPos;
|
|
||||||
float dotR = distR.Dot(cDir);
|
|
||||||
return (dotL > dotR);
|
|
||||||
}
|
|
||||||
} backToFront;
|
|
||||||
backToFront.pCamera = pCamera;
|
|
||||||
|
|
||||||
if (mSortType == BackToFront)
|
|
||||||
std::stable_sort(mRenderables.begin(), mRenderables.begin() + mSize, backToFront);
|
|
||||||
|
|
||||||
// Test: draw node bounding boxes + vertices used for sorting
|
|
||||||
/*for (u32 iNode = 0; iNode < mNodes.size(); iNode++)
|
|
||||||
{
|
{
|
||||||
SMeshPointer *pNode = &mNodes[iNode];
|
std::stable_sort(mRenderables.begin(), mRenderables.begin() + mSize,
|
||||||
CVector3f Vert = pNode->AABox.ClosestPointAlongVector(Camera.GetDirection());
|
[&, pCamera](const SRenderablePtr& rkLeft, const SRenderablePtr& rkRight) -> bool
|
||||||
CDrawUtil::DrawWireCube(pNode->AABox, CColor::skWhite);
|
{
|
||||||
|
CVector3f CamPos = pCamera->Position();
|
||||||
|
CVector3f CamDir = pCamera->Direction();
|
||||||
|
|
||||||
CVector3f Dist = Vert - Camera.GetPosition();
|
CVector3f DistL = rkLeft.AABox.ClosestPointAlongVector(CamDir) - CamPos;
|
||||||
float Dot = Dist.Dot(Camera.GetDirection());
|
CVector3f DistR = rkRight.AABox.ClosestPointAlongVector(CamDir) - CamPos;
|
||||||
|
float DotL = DistL.Dot(CamDir);
|
||||||
|
float DotR = DistR.Dot(CamDir);
|
||||||
|
return (DotL > DotR);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (mEnableDepthSortDebugVisualization)
|
||||||
|
{
|
||||||
|
for (u32 iPtr = 0; iPtr < mSize; iPtr++)
|
||||||
|
{
|
||||||
|
SRenderablePtr *pPtr = &mRenderables[iPtr];
|
||||||
|
CVector3f Point = pPtr->AABox.ClosestPointAlongVector(pCamera->Direction());
|
||||||
|
CDrawUtil::DrawWireCube(pPtr->AABox, CColor::skWhite);
|
||||||
|
|
||||||
|
CVector3f Dist = Point - pCamera->Position();
|
||||||
|
float Dot = Dist.Dot(pCamera->Direction());
|
||||||
if (Dot < 0.f) Dot = -Dot;
|
if (Dot < 0.f) Dot = -Dot;
|
||||||
if (Dot > 50.f) Dot = 50.f;
|
if (Dot > 50.f) Dot = 50.f;
|
||||||
float Intensity = 1.f - (Dot / 50.f);
|
float Intensity = 1.f - (Dot / 50.f);
|
||||||
CColor CubeColor(Intensity, Intensity, Intensity, 1.f);
|
CColor CubeColor(Intensity, Intensity, Intensity, 1.f);
|
||||||
|
|
||||||
CGraphics::sMVPBlock.ModelMatrix = CTransform4f::TranslationMatrix(Vert).ToMatrix4f();
|
CGraphics::sMVPBlock.ModelMatrix = CTransform4f::TranslationMatrix(Point).ToMatrix4f();
|
||||||
CGraphics::UpdateMVPBlock();
|
CGraphics::UpdateMVPBlock();
|
||||||
CDrawUtil::DrawCube(CubeColor);
|
CDrawUtil::DrawCube(CubeColor);
|
||||||
}*/
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CRenderBucket::Clear()
|
void CRenderBucket::Clear()
|
||||||
|
@ -72,18 +61,16 @@ void CRenderBucket::Clear()
|
||||||
mSize = 0;
|
mSize = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CRenderBucket::Draw(const SViewInfo& ViewInfo)
|
void CRenderBucket::Draw(const SViewInfo& rkViewInfo)
|
||||||
{
|
{
|
||||||
FRenderOptions Options = ViewInfo.pRenderer->RenderOptions();
|
FRenderOptions Options = rkViewInfo.pRenderer->RenderOptions();
|
||||||
|
|
||||||
for (u32 n = 0; n < mSize; n++)
|
for (u32 iPtr = 0; iPtr < mSize; iPtr++)
|
||||||
{
|
{
|
||||||
if (mRenderables[n].Command == eDrawMesh)
|
if (mRenderables[iPtr].Command == eDrawMesh)
|
||||||
mRenderables[n].pRenderable->Draw(Options, mRenderables[n].ComponentIndex, ViewInfo);
|
mRenderables[iPtr].pRenderable->Draw(Options, mRenderables[iPtr].ComponentIndex, rkViewInfo);
|
||||||
|
|
||||||
else if (mRenderables[n].Command == eDrawSelection)
|
else if (mRenderables[iPtr].Command == eDrawSelection)
|
||||||
mRenderables[n].pRenderable->DrawSelection();
|
mRenderables[iPtr].pRenderable->DrawSelection();
|
||||||
|
|
||||||
// todo: implementation for eDrawExtras
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,32 +2,39 @@
|
||||||
#define CRENDERBUCKET_H
|
#define CRENDERBUCKET_H
|
||||||
|
|
||||||
#include "CCamera.h"
|
#include "CCamera.h"
|
||||||
|
#include "CDrawUtil.h"
|
||||||
|
#include "CGraphics.h"
|
||||||
#include "FRenderOptions.h"
|
#include "FRenderOptions.h"
|
||||||
#include "SRenderablePtr.h"
|
#include "SRenderablePtr.h"
|
||||||
#include <Common/types.h>
|
#include <Common/types.h>
|
||||||
|
#include <algorithm>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
class CRenderBucket
|
class CRenderBucket
|
||||||
{
|
{
|
||||||
public:
|
bool mEnableDepthSort;
|
||||||
enum ESortType
|
bool mEnableDepthSortDebugVisualization;
|
||||||
{
|
|
||||||
BackToFront,
|
|
||||||
FrontToBack
|
|
||||||
};
|
|
||||||
private:
|
|
||||||
ESortType mSortType;
|
|
||||||
std::vector<SRenderablePtr> mRenderables;
|
std::vector<SRenderablePtr> mRenderables;
|
||||||
u32 mEstSize;
|
u32 mEstSize;
|
||||||
u32 mSize;
|
u32 mSize;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CRenderBucket();
|
CRenderBucket()
|
||||||
void SetSortType(ESortType Type);
|
: mEnableDepthSort(false)
|
||||||
void Add(const SRenderablePtr& ptr);
|
, mEnableDepthSortDebugVisualization(false)
|
||||||
|
, mEstSize(0)
|
||||||
|
, mSize(0)
|
||||||
|
{}
|
||||||
|
|
||||||
|
inline void SetDepthSortingEnabled(bool Enabled)
|
||||||
|
{
|
||||||
|
mEnableDepthSort = Enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Add(const SRenderablePtr& rkPtr);
|
||||||
void Sort(CCamera* pCamera);
|
void Sort(CCamera* pCamera);
|
||||||
void Clear();
|
void Clear();
|
||||||
void Draw(const SViewInfo& ViewInfo);
|
void Draw(const SViewInfo& rkViewInfo);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CRENDERBUCKET_H
|
#endif // CRENDERBUCKET_H
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
#include "Core/Resource/CResCache.h"
|
#include "Core/Resource/CResCache.h"
|
||||||
#include "Core/Resource/Factory/CTextureDecoder.h"
|
#include "Core/Resource/Factory/CTextureDecoder.h"
|
||||||
#include <Math/CTransform4f.h>
|
#include <Math/CTransform4f.h>
|
||||||
#include <Common/AnimUtil.h>
|
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
@ -19,14 +18,13 @@ u32 CRenderer::sNumRenderers = 0;
|
||||||
|
|
||||||
// ************ INITIALIZATION ************
|
// ************ INITIALIZATION ************
|
||||||
CRenderer::CRenderer()
|
CRenderer::CRenderer()
|
||||||
|
: mOptions(eEnableUVScroll | eEnableBackfaceCull)
|
||||||
|
, mBloomMode(eNoBloom)
|
||||||
|
, mDrawGrid(true)
|
||||||
|
, mInitialized(false)
|
||||||
|
, mContextIndex(-1)
|
||||||
{
|
{
|
||||||
mOptions = eEnableUVScroll | eEnableBackfaceCull;
|
mTransparentBucket.SetDepthSortingEnabled(true);
|
||||||
mBloomMode = eNoBloom;
|
|
||||||
mDrawGrid = true;
|
|
||||||
mInitialized = false;
|
|
||||||
mContextIndex = -1;
|
|
||||||
mOpaqueBucket.SetSortType(CRenderBucket::FrontToBack);
|
|
||||||
mTransparentBucket.SetSortType(CRenderBucket::BackToFront);
|
|
||||||
sNumRenderers++;
|
sNumRenderers++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,44 +43,44 @@ void CRenderer::Init()
|
||||||
{
|
{
|
||||||
if (!mInitialized)
|
if (!mInitialized)
|
||||||
{
|
{
|
||||||
glClearColor(mClearColor.r, mClearColor.g, mClearColor.b, mClearColor.a);
|
glClearColor(mClearColor.R, mClearColor.G, mClearColor.B, mClearColor.A);
|
||||||
mContextIndex = CGraphics::GetContextIndex();
|
mContextIndex = CGraphics::GetContextIndex();
|
||||||
mInitialized = true;
|
mInitialized = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ************ GETTERS/SETTERS ************
|
// ************ ACCESSORS ************
|
||||||
FRenderOptions CRenderer::RenderOptions() const
|
FRenderOptions CRenderer::RenderOptions() const
|
||||||
{
|
{
|
||||||
return mOptions;
|
return mOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CRenderer::ToggleBackfaceCull(bool b)
|
void CRenderer::ToggleBackfaceCull(bool Enable)
|
||||||
{
|
{
|
||||||
if (b) mOptions |= eEnableBackfaceCull;
|
if (Enable) mOptions |= eEnableBackfaceCull;
|
||||||
else mOptions &= ~eEnableBackfaceCull;
|
else mOptions &= ~eEnableBackfaceCull;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CRenderer::ToggleUVAnimation(bool b)
|
void CRenderer::ToggleUVAnimation(bool Enable)
|
||||||
{
|
{
|
||||||
if (b) mOptions |= eEnableUVScroll;
|
if (Enable) mOptions |= eEnableUVScroll;
|
||||||
else mOptions &= ~eEnableUVScroll;
|
else mOptions &= ~eEnableUVScroll;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CRenderer::ToggleGrid(bool b)
|
void CRenderer::ToggleGrid(bool Enable)
|
||||||
{
|
{
|
||||||
mDrawGrid = b;
|
mDrawGrid = Enable;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CRenderer::ToggleOccluders(bool b)
|
void CRenderer::ToggleOccluders(bool Enable)
|
||||||
{
|
{
|
||||||
if (b) mOptions |= eEnableOccluders;
|
if (Enable) mOptions |= eEnableOccluders;
|
||||||
else mOptions &= ~eEnableOccluders;
|
else mOptions &= ~eEnableOccluders;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CRenderer::ToggleAlphaDisabled(bool b)
|
void CRenderer::ToggleAlphaDisabled(bool Enable)
|
||||||
{
|
{
|
||||||
if (b) mOptions |= eNoAlpha;
|
if (Enable) mOptions |= eNoAlpha;
|
||||||
else mOptions &= ~eNoAlpha;
|
else mOptions &= ~eNoAlpha;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,11 +94,11 @@ void CRenderer::SetBloom(EBloomMode BloomMode)
|
||||||
mOptions &= ~eEnableBloom;
|
mOptions &= ~eEnableBloom;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CRenderer::SetClearColor(const CColor& Clear)
|
void CRenderer::SetClearColor(const CColor& rkClear)
|
||||||
{
|
{
|
||||||
mClearColor = Clear;
|
mClearColor = rkClear;
|
||||||
mClearColor.a = 0.f;
|
mClearColor.A = 0.f;
|
||||||
glClearColor(mClearColor.r, mClearColor.g, mClearColor.b, mClearColor.a);
|
glClearColor(mClearColor.R, mClearColor.G, mClearColor.B, mClearColor.A);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CRenderer::SetViewportSize(u32 Width, u32 Height)
|
void CRenderer::SetViewportSize(u32 Width, u32 Height)
|
||||||
|
@ -116,7 +114,7 @@ void CRenderer::SetViewportSize(u32 Width, u32 Height)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ************ RENDER ************
|
// ************ RENDER ************
|
||||||
void CRenderer::RenderBuckets(const SViewInfo& ViewInfo)
|
void CRenderer::RenderBuckets(const SViewInfo& rkViewInfo)
|
||||||
{
|
{
|
||||||
if (!mInitialized) Init();
|
if (!mInitialized) Init();
|
||||||
mSceneFramebuffer.Bind();
|
mSceneFramebuffer.Bind();
|
||||||
|
@ -129,10 +127,10 @@ void CRenderer::RenderBuckets(const SViewInfo& ViewInfo)
|
||||||
glDepthRange(0.f, 1.f);
|
glDepthRange(0.f, 1.f);
|
||||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||||
|
|
||||||
mOpaqueBucket.Draw(ViewInfo);
|
mOpaqueBucket.Draw(rkViewInfo);
|
||||||
mOpaqueBucket.Clear();
|
mOpaqueBucket.Clear();
|
||||||
mTransparentBucket.Sort(ViewInfo.pCamera);
|
mTransparentBucket.Sort(rkViewInfo.pCamera);
|
||||||
mTransparentBucket.Draw(ViewInfo);
|
mTransparentBucket.Draw(rkViewInfo);
|
||||||
mTransparentBucket.Clear();
|
mTransparentBucket.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -244,7 +242,7 @@ void CRenderer::RenderBloom()
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CRenderer::RenderSky(CModel *pSkyboxModel, const SViewInfo& ViewInfo)
|
void CRenderer::RenderSky(CModel *pSkyboxModel, const SViewInfo& rkViewInfo)
|
||||||
{
|
{
|
||||||
if (!mInitialized) Init();
|
if (!mInitialized) Init();
|
||||||
if (!pSkyboxModel) return;
|
if (!pSkyboxModel) return;
|
||||||
|
@ -261,31 +259,31 @@ void CRenderer::RenderSky(CModel *pSkyboxModel, const SViewInfo& ViewInfo)
|
||||||
CGraphics::UpdateLightBlock();
|
CGraphics::UpdateLightBlock();
|
||||||
|
|
||||||
// Load rotation-only view matrix
|
// Load rotation-only view matrix
|
||||||
CGraphics::sMVPBlock.ViewMatrix = ViewInfo.RotationOnlyViewMatrix;
|
CGraphics::sMVPBlock.ViewMatrix = rkViewInfo.RotationOnlyViewMatrix;
|
||||||
CGraphics::UpdateMVPBlock();
|
CGraphics::UpdateMVPBlock();
|
||||||
|
|
||||||
glDepthRange(1.f, 1.f);
|
glDepthRange(1.f, 1.f);
|
||||||
pSkyboxModel->Draw(mOptions, 0);
|
pSkyboxModel->Draw(mOptions, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CRenderer::AddOpaqueMesh(IRenderable *pRenderable, int AssetID, CAABox& AABox, ERenderCommand Command)
|
void CRenderer::AddOpaqueMesh(IRenderable *pRenderable, int AssetID, const CAABox& rkAABox, ERenderCommand Command)
|
||||||
{
|
{
|
||||||
SRenderablePtr ptr;
|
SRenderablePtr Ptr;
|
||||||
ptr.pRenderable = pRenderable;
|
Ptr.pRenderable = pRenderable;
|
||||||
ptr.ComponentIndex = AssetID;
|
Ptr.ComponentIndex = AssetID;
|
||||||
ptr.AABox = AABox;
|
Ptr.AABox = rkAABox;
|
||||||
ptr.Command = Command;
|
Ptr.Command = Command;
|
||||||
mOpaqueBucket.Add(ptr);
|
mOpaqueBucket.Add(Ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CRenderer::AddTransparentMesh(IRenderable *pRenderable, int AssetID, CAABox& AABox, ERenderCommand Command)
|
void CRenderer::AddTransparentMesh(IRenderable *pRenderable, int AssetID, const CAABox& rkAABox, ERenderCommand Command)
|
||||||
{
|
{
|
||||||
SRenderablePtr ptr;
|
SRenderablePtr Ptr;
|
||||||
ptr.pRenderable = pRenderable;
|
Ptr.pRenderable = pRenderable;
|
||||||
ptr.ComponentIndex = AssetID;
|
Ptr.ComponentIndex = AssetID;
|
||||||
ptr.AABox = AABox;
|
Ptr.AABox = rkAABox;
|
||||||
ptr.Command = Command;
|
Ptr.Command = Command;
|
||||||
mTransparentBucket.Add(ptr);
|
mTransparentBucket.Add(Ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CRenderer::BeginFrame()
|
void CRenderer::BeginFrame()
|
||||||
|
@ -334,7 +332,7 @@ void CRenderer::ClearDepthBuffer()
|
||||||
// ************ PRIVATE ************
|
// ************ PRIVATE ************
|
||||||
void CRenderer::InitFramebuffer()
|
void CRenderer::InitFramebuffer()
|
||||||
{
|
{
|
||||||
glClearColor(mClearColor.r, mClearColor.g, mClearColor.b, mClearColor.a);
|
glClearColor(mClearColor.R, mClearColor.G, mClearColor.B, mClearColor.A);
|
||||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||||
glDepthMask(GL_TRUE);
|
glDepthMask(GL_TRUE);
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
|
@ -53,23 +53,23 @@ public:
|
||||||
~CRenderer();
|
~CRenderer();
|
||||||
void Init();
|
void Init();
|
||||||
|
|
||||||
// Getters/Setters
|
// Accessors
|
||||||
FRenderOptions RenderOptions() const;
|
FRenderOptions RenderOptions() const;
|
||||||
void ToggleBackfaceCull(bool b);
|
void ToggleBackfaceCull(bool Enable);
|
||||||
void ToggleUVAnimation(bool b);
|
void ToggleUVAnimation(bool Enable);
|
||||||
void ToggleGrid(bool b);
|
void ToggleGrid(bool Enable);
|
||||||
void ToggleOccluders(bool b);
|
void ToggleOccluders(bool Enable);
|
||||||
void ToggleAlphaDisabled(bool b);
|
void ToggleAlphaDisabled(bool Enable);
|
||||||
void SetBloom(EBloomMode BloomMode);
|
void SetBloom(EBloomMode BloomMode);
|
||||||
void SetClearColor(const CColor& Clear);
|
void SetClearColor(const CColor& rkClear);
|
||||||
void SetViewportSize(u32 Width, u32 Height);
|
void SetViewportSize(u32 Width, u32 Height);
|
||||||
|
|
||||||
// Render
|
// Render
|
||||||
void RenderBuckets(const SViewInfo& ViewInfo);
|
void RenderBuckets(const SViewInfo& rkViewInfo);
|
||||||
void RenderBloom();
|
void RenderBloom();
|
||||||
void RenderSky(CModel *pSkyboxModel, const SViewInfo& ViewInfo);
|
void RenderSky(CModel *pSkyboxModel, const SViewInfo& rkViewInfo);
|
||||||
void AddOpaqueMesh(IRenderable *pRenderable, int AssetID, CAABox& AABox, ERenderCommand Command);
|
void AddOpaqueMesh(IRenderable *pRenderable, int AssetID, const CAABox& rkAABox, ERenderCommand Command);
|
||||||
void AddTransparentMesh(IRenderable *pRenderable, int AssetID, CAABox& AABox, ERenderCommand Command);
|
void AddTransparentMesh(IRenderable *pRenderable, int AssetID, const CAABox& rkAABox, ERenderCommand Command);
|
||||||
void BeginFrame();
|
void BeginFrame();
|
||||||
void EndFrame();
|
void EndFrame();
|
||||||
void ClearDepthBuffer();
|
void ClearDepthBuffer();
|
||||||
|
|
|
@ -12,8 +12,8 @@ class IRenderable
|
||||||
public:
|
public:
|
||||||
IRenderable() {}
|
IRenderable() {}
|
||||||
virtual ~IRenderable() {}
|
virtual ~IRenderable() {}
|
||||||
virtual void AddToRenderer(CRenderer* pRenderer, const SViewInfo& ViewInfo) = 0;
|
virtual void AddToRenderer(CRenderer* pRenderer, const SViewInfo& rkViewInfo) = 0;
|
||||||
virtual void Draw(FRenderOptions /*Options*/, int /*ComponentIndex*/, const SViewInfo& /*ViewInfo*/) {}
|
virtual void Draw(FRenderOptions /*Options*/, int /*ComponentIndex*/, const SViewInfo& /*rkViewInfo*/) {}
|
||||||
virtual void DrawSelection() {}
|
virtual void DrawSelection() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,7 @@
|
||||||
#define SRENDERABLEPTR_H
|
#define SRENDERABLEPTR_H
|
||||||
|
|
||||||
#include "ERenderCommand.h"
|
#include "ERenderCommand.h"
|
||||||
#include "Core/Resource/CMaterial.h"
|
#include "IRenderable.h"
|
||||||
#include "Core/Scene/CSceneNode.h"
|
|
||||||
#include <Common/types.h>
|
#include <Common/types.h>
|
||||||
#include <Math/CAABox.h>
|
#include <Math/CAABox.h>
|
||||||
|
|
||||||
|
|
|
@ -1,30 +0,0 @@
|
||||||
#include "CAnimSet.h"
|
|
||||||
|
|
||||||
CAnimSet::CAnimSet() : CResource()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
CAnimSet::~CAnimSet()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 CAnimSet::getNodeCount()
|
|
||||||
{
|
|
||||||
return nodes.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
TString CAnimSet::getNodeName(u32 node)
|
|
||||||
{
|
|
||||||
if (node >= nodes.size())
|
|
||||||
return nodes[0].name;
|
|
||||||
else
|
|
||||||
return nodes[node].name;
|
|
||||||
}
|
|
||||||
|
|
||||||
CModel* CAnimSet::getNodeModel(u32 node)
|
|
||||||
{
|
|
||||||
if (node >= nodes.size())
|
|
||||||
return nodes[0].model;
|
|
||||||
else
|
|
||||||
return nodes[node].model;
|
|
||||||
}
|
|
|
@ -16,22 +16,21 @@ class CAnimSet : public CResource
|
||||||
|
|
||||||
struct SNode
|
struct SNode
|
||||||
{
|
{
|
||||||
TString name;
|
TString Name;
|
||||||
TResPtr<CModel> model;
|
TResPtr<CModel> pModel;
|
||||||
u32 skinID;
|
u32 SkinID;
|
||||||
u32 skelID;
|
u32 SkelID;
|
||||||
|
|
||||||
SNode() { model = nullptr; }
|
SNode() { pModel = nullptr; }
|
||||||
};
|
};
|
||||||
std::vector<SNode> nodes;
|
std::vector<SNode> mNodes;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CAnimSet();
|
CAnimSet() : CResource() {}
|
||||||
~CAnimSet();
|
|
||||||
|
|
||||||
u32 getNodeCount();
|
u32 NumNodes() const { return mNodes.size(); }
|
||||||
TString getNodeName(u32 node);
|
TString NodeName(u32 Index) { if (Index >= mNodes.size()) Index = 0; return mNodes[Index].Name; }
|
||||||
CModel* getNodeModel(u32 node);
|
CModel* NodeModel(u32 Index) { if (Index >= mNodes.size()) Index = 0; return mNodes[Index].pModel; }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CCHARACTERSET_H
|
#endif // CCHARACTERSET_H
|
||||||
|
|
|
@ -6,47 +6,46 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
CAnimationParameters::CAnimationParameters()
|
CAnimationParameters::CAnimationParameters()
|
||||||
|
: mGame(ePrime)
|
||||||
|
, mNodeIndex(0)
|
||||||
|
, mUnknown1(0)
|
||||||
|
, mUnknown2(0)
|
||||||
|
, mUnknown3(0)
|
||||||
{
|
{
|
||||||
mGame = ePrime;
|
|
||||||
mNodeIndex = 0;
|
|
||||||
mUnknown1 = 0;
|
|
||||||
mUnknown2 = 0;
|
|
||||||
mUnknown3 = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CAnimationParameters::CAnimationParameters(EGame Game)
|
CAnimationParameters::CAnimationParameters(EGame Game)
|
||||||
|
: mGame(Game)
|
||||||
|
, mNodeIndex(0)
|
||||||
|
, mUnknown1(0)
|
||||||
|
, mUnknown2(0)
|
||||||
|
, mUnknown3(0)
|
||||||
{
|
{
|
||||||
mGame = Game;
|
|
||||||
mNodeIndex = 0;
|
|
||||||
mUnknown1 = 0;
|
|
||||||
mUnknown2 = 0;
|
|
||||||
mUnknown3 = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CAnimationParameters::CAnimationParameters(IInputStream& SCLY, EGame Game)
|
CAnimationParameters::CAnimationParameters(IInputStream& rSCLY, EGame Game)
|
||||||
|
: mGame(Game)
|
||||||
|
, mNodeIndex(0)
|
||||||
|
, mUnknown1(0)
|
||||||
|
, mUnknown2(0)
|
||||||
|
, mUnknown3(0)
|
||||||
{
|
{
|
||||||
mGame = Game;
|
|
||||||
mNodeIndex = 0;
|
|
||||||
mUnknown1 = 0;
|
|
||||||
mUnknown2 = 0;
|
|
||||||
mUnknown3 = 0;
|
|
||||||
|
|
||||||
if (Game <= eEchoes)
|
if (Game <= eEchoes)
|
||||||
{
|
{
|
||||||
mCharacter = CResourceInfo(SCLY.ReadLong(), "ANCS");
|
mCharacter = CResourceInfo(rSCLY.ReadLong(), "ANCS");
|
||||||
mNodeIndex = SCLY.ReadLong();
|
mNodeIndex = rSCLY.ReadLong();
|
||||||
mUnknown1 = SCLY.ReadLong();
|
mUnknown1 = rSCLY.ReadLong();
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (Game <= eCorruption)
|
else if (Game <= eCorruption)
|
||||||
{
|
{
|
||||||
mCharacter = CResourceInfo(SCLY.ReadLongLong(), "CHAR");
|
mCharacter = CResourceInfo(rSCLY.ReadLongLong(), "CHAR");
|
||||||
mUnknown1 = SCLY.ReadLong();
|
mUnknown1 = rSCLY.ReadLong();
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (Game == eReturns)
|
else if (Game == eReturns)
|
||||||
{
|
{
|
||||||
u8 Flags = SCLY.ReadByte();
|
u8 Flags = rSCLY.ReadByte();
|
||||||
|
|
||||||
// 0x80 - CharacterAnimationSet is empty.
|
// 0x80 - CharacterAnimationSet is empty.
|
||||||
if (Flags & 0x80)
|
if (Flags & 0x80)
|
||||||
|
@ -57,19 +56,19 @@ CAnimationParameters::CAnimationParameters(IInputStream& SCLY, EGame Game)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mCharacter = CResourceInfo(SCLY.ReadLongLong(), "CHAR");
|
mCharacter = CResourceInfo(rSCLY.ReadLongLong(), "CHAR");
|
||||||
|
|
||||||
// 0x20 - Default Anim is present
|
// 0x20 - Default Anim is present
|
||||||
if (Flags & 0x20)
|
if (Flags & 0x20)
|
||||||
mUnknown1 = SCLY.ReadLong();
|
mUnknown1 = rSCLY.ReadLong();
|
||||||
else
|
else
|
||||||
mUnknown1 = -1;
|
mUnknown1 = -1;
|
||||||
|
|
||||||
// 0x40 - Two-value struct is present
|
// 0x40 - Two-value struct is present
|
||||||
if (Flags & 0x40)
|
if (Flags & 0x40)
|
||||||
{
|
{
|
||||||
mUnknown2 = SCLY.ReadLong();
|
mUnknown2 = rSCLY.ReadLong();
|
||||||
mUnknown3 = SCLY.ReadLong();
|
mUnknown3 = rSCLY.ReadLong();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -147,8 +146,8 @@ CModel* CAnimationParameters::GetCurrentModel(s32 NodeIndex /*= -1*/)
|
||||||
if (pSet->Type() != eAnimSet) return nullptr;
|
if (pSet->Type() != eAnimSet) return nullptr;
|
||||||
if (NodeIndex == -1) NodeIndex = mNodeIndex;
|
if (NodeIndex == -1) NodeIndex = mNodeIndex;
|
||||||
|
|
||||||
if (pSet->getNodeCount() <= (u32) NodeIndex) return nullptr;
|
if (pSet->NumNodes() <= (u32) NodeIndex) return nullptr;
|
||||||
return pSet->getNodeModel(NodeIndex);
|
return pSet->NodeModel(NodeIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
TString CAnimationParameters::GetCurrentCharacterName(s32 NodeIndex /*= -1*/)
|
TString CAnimationParameters::GetCurrentCharacterName(s32 NodeIndex /*= -1*/)
|
||||||
|
@ -160,26 +159,11 @@ TString CAnimationParameters::GetCurrentCharacterName(s32 NodeIndex /*= -1*/)
|
||||||
if (pSet->Type() != eAnimSet) return "";
|
if (pSet->Type() != eAnimSet) return "";
|
||||||
if (NodeIndex == -1) NodeIndex = mNodeIndex;
|
if (NodeIndex == -1) NodeIndex = mNodeIndex;
|
||||||
|
|
||||||
if (pSet->getNodeCount() <= (u32) NodeIndex) return "";
|
if (pSet->NumNodes() <= (u32) NodeIndex) return "";
|
||||||
return pSet->getNodeName((u32) NodeIndex);
|
return pSet->NodeName((u32) NodeIndex);
|
||||||
}
|
|
||||||
|
|
||||||
// ************ GETTERS ************
|
|
||||||
EGame CAnimationParameters::Version()
|
|
||||||
{
|
|
||||||
return mGame;
|
|
||||||
}
|
|
||||||
|
|
||||||
CAnimSet* CAnimationParameters::AnimSet()
|
|
||||||
{
|
|
||||||
return (CAnimSet*) mCharacter.Load();
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 CAnimationParameters::CharacterIndex()
|
|
||||||
{
|
|
||||||
return mNodeIndex;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ************ ACCESSORS ************
|
||||||
u32 CAnimationParameters::Unknown(u32 Index)
|
u32 CAnimationParameters::Unknown(u32 Index)
|
||||||
{
|
{
|
||||||
switch (Index)
|
switch (Index)
|
||||||
|
@ -191,7 +175,6 @@ u32 CAnimationParameters::Unknown(u32 Index)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ************ SETTERS ************
|
|
||||||
void CAnimationParameters::SetResource(CResourceInfo Res)
|
void CAnimationParameters::SetResource(CResourceInfo Res)
|
||||||
{
|
{
|
||||||
if (Res.Type() == "ANCS" || Res.Type() == "CHAR")
|
if (Res.Type() == "ANCS" || Res.Type() == "CHAR")
|
||||||
|
@ -203,11 +186,6 @@ void CAnimationParameters::SetResource(CResourceInfo Res)
|
||||||
Log::Error("Resource with invalid type passed to CAnimationParameters: " + Res.ToString());
|
Log::Error("Resource with invalid type passed to CAnimationParameters: " + Res.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
void CAnimationParameters::SetNodeIndex(u32 Index)
|
|
||||||
{
|
|
||||||
mNodeIndex = Index;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CAnimationParameters::SetUnknown(u32 Index, u32 Value)
|
void CAnimationParameters::SetUnknown(u32 Index, u32 Value)
|
||||||
{
|
{
|
||||||
switch (Index)
|
switch (Index)
|
||||||
|
|
|
@ -20,21 +20,20 @@ class CAnimationParameters
|
||||||
public:
|
public:
|
||||||
CAnimationParameters();
|
CAnimationParameters();
|
||||||
CAnimationParameters(EGame Game);
|
CAnimationParameters(EGame Game);
|
||||||
CAnimationParameters(IInputStream& SCLY, EGame Game);
|
CAnimationParameters(IInputStream& rSCLY, EGame Game);
|
||||||
void Write(IOutputStream& rSCLY);
|
void Write(IOutputStream& rSCLY);
|
||||||
|
|
||||||
CModel* GetCurrentModel(s32 NodeIndex = -1);
|
CModel* GetCurrentModel(s32 NodeIndex = -1);
|
||||||
TString GetCurrentCharacterName(s32 NodeIndex = -1);
|
TString GetCurrentCharacterName(s32 NodeIndex = -1);
|
||||||
|
|
||||||
// Getters
|
// Accessors
|
||||||
EGame Version();
|
inline EGame Version() const { return mGame; }
|
||||||
CAnimSet* AnimSet();
|
inline CAnimSet* AnimSet() const { return (CAnimSet*) mCharacter.Load(); }
|
||||||
u32 CharacterIndex();
|
inline u32 CharacterIndex() { return mNodeIndex; }
|
||||||
u32 Unknown(u32 index);
|
inline void SetNodeIndex(u32 Index) { mNodeIndex = Index; }
|
||||||
|
|
||||||
// Setters
|
u32 Unknown(u32 Index);
|
||||||
void SetResource(CResourceInfo Res);
|
void SetResource(CResourceInfo Res);
|
||||||
void SetNodeIndex(u32 Index);
|
|
||||||
void SetUnknown(u32 Index, u32 Value);
|
void SetUnknown(u32 Index, u32 Value);
|
||||||
|
|
||||||
// Operators
|
// Operators
|
||||||
|
|
|
@ -33,32 +33,34 @@ void CCollisionMesh::BufferGL()
|
||||||
|
|
||||||
// Add all the verts to our VBO, first...
|
// Add all the verts to our VBO, first...
|
||||||
mVBO.Reserve(mCollisionVertices.size());
|
mVBO.Reserve(mCollisionVertices.size());
|
||||||
for (u16 v = 0; v < mCollisionVertices.size(); v++)
|
for (u16 iVtx = 0; iVtx < mCollisionVertices.size(); iVtx++)
|
||||||
mVBO.AddVertex(CVertex(mCollisionVertices[v].Pos));
|
mVBO.AddVertex(CVertex(mCollisionVertices[iVtx].Pos));
|
||||||
|
|
||||||
// Then add all the relevant indices to the IBO
|
// Then add all the relevant indices to the IBO
|
||||||
mIBO.Reserve(mCollisionFaces.size() * 3);
|
mIBO.Reserve(mCollisionFaces.size() * 3);
|
||||||
for (u32 v = 0; v < mCollisionFaces.size(); v++)
|
for (u32 iVtx = 0; iVtx < mCollisionFaces.size(); iVtx++)
|
||||||
{
|
{
|
||||||
u16 Verts[3];
|
u16 Verts[3];
|
||||||
|
|
||||||
CCollisionFace *Face = &mCollisionFaces[v];
|
CCollisionFace *pFace = &mCollisionFaces[iVtx];
|
||||||
CCollisionLine *LineA = GetLine(Face->Lines[0]);
|
CCollisionLine *pLineA = GetLine(pFace->Lines[0]);
|
||||||
CCollisionLine *LineB = GetLine(Face->Lines[1]);
|
CCollisionLine *pLineB = GetLine(pFace->Lines[1]);
|
||||||
Verts[0] = LineA->Vertices[0];
|
Verts[0] = pLineA->Vertices[0];
|
||||||
Verts[1] = LineA->Vertices[1];
|
Verts[1] = pLineA->Vertices[1];
|
||||||
|
|
||||||
// We have two vertex indices; the last one is one of the ones on line B, but we're not sure which one
|
// We have two vertex indices; the last one is one of the ones on line B, but we're not sure which one
|
||||||
if ((LineB->Vertices[0] != Verts[0]) &&
|
if ((pLineB->Vertices[0] != Verts[0]) &&
|
||||||
(LineB->Vertices[0] != Verts[1]))
|
(pLineB->Vertices[0] != Verts[1]))
|
||||||
Verts[2] = LineB->Vertices[0];
|
Verts[2] = pLineB->Vertices[0];
|
||||||
else
|
else
|
||||||
Verts[2] = LineB->Vertices[1];
|
Verts[2] = pLineB->Vertices[1];
|
||||||
|
|
||||||
// Some faces have a property that indicates they need to be inverted
|
// Some faces have a property that indicates they need to be inverted
|
||||||
if (!Face->Properties.Invert)
|
if (!pFace->Properties.Invert)
|
||||||
mIBO.AddIndices(&Verts[0], 3);
|
mIBO.AddIndices(&Verts[0], 3);
|
||||||
else {
|
|
||||||
|
else
|
||||||
|
{
|
||||||
mIBO.AddIndex(Verts[2]);
|
mIBO.AddIndex(Verts[2]);
|
||||||
mIBO.AddIndex(Verts[1]);
|
mIBO.AddIndex(Verts[1]);
|
||||||
mIBO.AddIndex(Verts[0]);
|
mIBO.AddIndex(Verts[0]);
|
||||||
|
@ -88,17 +90,17 @@ void CCollisionMesh::DrawWireframe()
|
||||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||||
}
|
}
|
||||||
|
|
||||||
CCollisionMesh::CCollisionVertex* CCollisionMesh::GetVertex(u16 index)
|
CCollisionMesh::CCollisionVertex* CCollisionMesh::GetVertex(u16 Index)
|
||||||
{
|
{
|
||||||
return &mCollisionVertices[index];
|
return &mCollisionVertices[Index];
|
||||||
}
|
}
|
||||||
|
|
||||||
CCollisionMesh::CCollisionLine* CCollisionMesh::GetLine(u16 index)
|
CCollisionMesh::CCollisionLine* CCollisionMesh::GetLine(u16 Index)
|
||||||
{
|
{
|
||||||
return &mCollisionLines[index];
|
return &mCollisionLines[Index];
|
||||||
}
|
}
|
||||||
|
|
||||||
CCollisionMesh::CCollisionFace* CCollisionMesh::GetFace(u16 index)
|
CCollisionMesh::CCollisionFace* CCollisionMesh::GetFace(u16 Index)
|
||||||
{
|
{
|
||||||
return &mCollisionFaces[index];
|
return &mCollisionFaces[Index];
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ class CCollisionMesh
|
||||||
SOctreeNode *pChildren[8];
|
SOctreeNode *pChildren[8];
|
||||||
};
|
};
|
||||||
|
|
||||||
SOctreeNode* Root;
|
SOctreeNode* mpRoot;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SCollisionProperties
|
struct SCollisionProperties
|
||||||
|
@ -65,16 +65,16 @@ class CCollisionMesh
|
||||||
bool mBuffered;
|
bool mBuffered;
|
||||||
|
|
||||||
CAABox mAABox;
|
CAABox mAABox;
|
||||||
CCollisionOctree *mOctree;
|
CCollisionOctree *mpOctree;
|
||||||
std::vector<u32> mFlags;
|
std::vector<u32> mFlags;
|
||||||
std::vector<CCollisionVertex> mCollisionVertices;
|
std::vector<CCollisionVertex> mCollisionVertices;
|
||||||
std::vector<CCollisionLine> mCollisionLines;
|
std::vector<CCollisionLine> mCollisionLines;
|
||||||
std::vector<CCollisionFace> mCollisionFaces;
|
std::vector<CCollisionFace> mCollisionFaces;
|
||||||
bool mOctreeLoaded;
|
bool mOctreeLoaded;
|
||||||
|
|
||||||
CCollisionVertex *GetVertex(u16 index);
|
CCollisionVertex *GetVertex(u16 Index);
|
||||||
CCollisionLine *GetLine(u16 index);
|
CCollisionLine *GetLine(u16 Index);
|
||||||
CCollisionFace *GetFace(u16 index);
|
CCollisionFace *GetFace(u16 Index);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CCollisionMesh();
|
CCollisionMesh();
|
||||||
|
|
|
@ -1,38 +0,0 @@
|
||||||
#include "CCollisionMeshGroup.h"
|
|
||||||
|
|
||||||
CCollisionMeshGroup::CCollisionMeshGroup()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
CCollisionMeshGroup::~CCollisionMeshGroup()
|
|
||||||
{
|
|
||||||
for (auto it = mMeshes.begin(); it != mMeshes.end(); it++)
|
|
||||||
delete *it;
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 CCollisionMeshGroup::NumMeshes()
|
|
||||||
{
|
|
||||||
return mMeshes.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
CCollisionMesh* CCollisionMeshGroup::MeshByIndex(u32 index)
|
|
||||||
{
|
|
||||||
return mMeshes[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
void CCollisionMeshGroup::AddMesh(CCollisionMesh *pMesh)
|
|
||||||
{
|
|
||||||
mMeshes.push_back(pMesh);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CCollisionMeshGroup::Draw()
|
|
||||||
{
|
|
||||||
for (auto it = mMeshes.begin(); it != mMeshes.end(); it++)
|
|
||||||
(*it)->Draw();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CCollisionMeshGroup::DrawWireframe()
|
|
||||||
{
|
|
||||||
for (auto it = mMeshes.begin(); it != mMeshes.end(); it++)
|
|
||||||
(*it)->DrawWireframe();
|
|
||||||
}
|
|
|
@ -12,14 +12,29 @@ class CCollisionMeshGroup : public CResource
|
||||||
std::vector<CCollisionMesh*> mMeshes;
|
std::vector<CCollisionMesh*> mMeshes;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CCollisionMeshGroup();
|
CCollisionMeshGroup() {}
|
||||||
~CCollisionMeshGroup();
|
|
||||||
|
|
||||||
u32 NumMeshes();
|
~CCollisionMeshGroup()
|
||||||
CCollisionMesh* MeshByIndex(u32 index);
|
{
|
||||||
void AddMesh(CCollisionMesh *pMesh);
|
for (auto it = mMeshes.begin(); it != mMeshes.end(); it++)
|
||||||
void Draw();
|
delete *it;
|
||||||
void DrawWireframe();
|
}
|
||||||
|
|
||||||
|
inline u32 NumMeshes() const { return mMeshes.size(); }
|
||||||
|
inline CCollisionMesh* MeshByIndex(u32 Index) const { return mMeshes[Index]; }
|
||||||
|
inline void AddMesh(CCollisionMesh *pMesh) { mMeshes.push_back(pMesh); }
|
||||||
|
|
||||||
|
inline void Draw()
|
||||||
|
{
|
||||||
|
for (auto it = mMeshes.begin(); it != mMeshes.end(); it++)
|
||||||
|
(*it)->Draw();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void DrawWireframe()
|
||||||
|
{
|
||||||
|
for (auto it = mMeshes.begin(); it != mMeshes.end(); it++)
|
||||||
|
(*it)->DrawWireframe();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CCOLLISIONMESHGROUP_H
|
#endif // CCOLLISIONMESHGROUP_H
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
#include "CResCache.h"
|
#include "CResCache.h"
|
||||||
#include "Core/Render/CDrawUtil.h"
|
#include "Core/Render/CDrawUtil.h"
|
||||||
#include "Core/Render/CRenderer.h"
|
#include "Core/Render/CRenderer.h"
|
||||||
#include <Common/AnimUtil.h>
|
|
||||||
|
|
||||||
CDynamicVertexBuffer CFont::smGlyphVertices;
|
CDynamicVertexBuffer CFont::smGlyphVertices;
|
||||||
CIndexBuffer CFont::smGlyphIndices;
|
CIndexBuffer CFont::smGlyphIndices;
|
||||||
|
@ -16,14 +15,14 @@ CFont::~CFont()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
inline float PtsToFloat(s32 pt)
|
inline float PtsToFloat(s32 Pt)
|
||||||
{
|
{
|
||||||
// This is a bit of an arbitrary number but it works
|
// This is a bit of an arbitrary number but it works
|
||||||
// 1 / (1280 / 1.333333f / 2)
|
// 1 / (1280 / 1.333333f / 2)
|
||||||
return 0.00208333f * pt;
|
return 0.00208333f * Pt;
|
||||||
}
|
}
|
||||||
|
|
||||||
CVector2f CFont::RenderString(const TString& String, CRenderer* /*pRenderer*/, float /*AspectRatio*/,
|
CVector2f CFont::RenderString(const TString& rkString, CRenderer* /*pRenderer*/, float /*AspectRatio*/,
|
||||||
CVector2f /*Position*/, CColor FillColor, CColor StrokeColor, u32 FontSize)
|
CVector2f /*Position*/, CColor FillColor, CColor StrokeColor, u32 FontSize)
|
||||||
{
|
{
|
||||||
// WIP
|
// WIP
|
||||||
|
@ -49,16 +48,16 @@ CVector2f CFont::RenderString(const TString& String, CRenderer* /*pRenderer*/, f
|
||||||
if (FontSize == CFONT_DEFAULT_SIZE) Scale = 1.f;
|
if (FontSize == CFONT_DEFAULT_SIZE) Scale = 1.f;
|
||||||
else Scale = (float) FontSize / (mDefaultSize != 0 ? mDefaultSize : 18);
|
else Scale = (float) FontSize / (mDefaultSize != 0 ? mDefaultSize : 18);
|
||||||
|
|
||||||
for (u32 iChar = 0; iChar < String.Length(); iChar++)
|
for (u32 iChar = 0; iChar < rkString.Length(); iChar++)
|
||||||
{
|
{
|
||||||
// Get character, check for newline
|
// Get character, check for newline
|
||||||
char Char = String[iChar];
|
char Char = rkString[iChar];
|
||||||
|
|
||||||
if (Char == '\n')
|
if (Char == '\n')
|
||||||
{
|
{
|
||||||
pPrevGlyph = nullptr;
|
pPrevGlyph = nullptr;
|
||||||
PrintHead.x = -1;
|
PrintHead.X = -1;
|
||||||
PrintHead.y -= (PtsToFloat(mLineHeight) + PtsToFloat(mLineMargin) + PtsToFloat(mUnknown)) * Scale;
|
PrintHead.Y -= (PtsToFloat(mLineHeight) + PtsToFloat(mLineMargin) + PtsToFloat(mUnknown)) * Scale;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,7 +67,7 @@ CVector2f CFont::RenderString(const TString& String, CRenderer* /*pRenderer*/, f
|
||||||
SGlyph *pGlyph = &iGlyph->second;
|
SGlyph *pGlyph = &iGlyph->second;
|
||||||
|
|
||||||
// Apply left padding and kerning
|
// Apply left padding and kerning
|
||||||
PrintHead.x += PtsToFloat(pGlyph->LeftPadding) * Scale;
|
PrintHead.X += PtsToFloat(pGlyph->LeftPadding) * Scale;
|
||||||
|
|
||||||
if (pPrevGlyph)
|
if (pPrevGlyph)
|
||||||
{
|
{
|
||||||
|
@ -77,9 +76,9 @@ CVector2f CFont::RenderString(const TString& String, CRenderer* /*pRenderer*/, f
|
||||||
for (u32 iKern = pPrevGlyph->KerningIndex; iKern < mKerningTable.size(); iKern++)
|
for (u32 iKern = pPrevGlyph->KerningIndex; iKern < mKerningTable.size(); iKern++)
|
||||||
{
|
{
|
||||||
if (mKerningTable[iKern].CharacterA != pPrevGlyph->Character) break;
|
if (mKerningTable[iKern].CharacterA != pPrevGlyph->Character) break;
|
||||||
if (mKerningTable[iKern].CharacterB == String[iChar])
|
if (mKerningTable[iKern].CharacterB == rkString[iChar])
|
||||||
{
|
{
|
||||||
PrintHead.x += PtsToFloat(mKerningTable[iKern].Adjust) * Scale;
|
PrintHead.X += PtsToFloat(mKerningTable[iKern].Adjust) * Scale;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -87,16 +86,16 @@ CVector2f CFont::RenderString(const TString& String, CRenderer* /*pRenderer*/, f
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add a newline if this character goes over the right edge of the screen
|
// Add a newline if this character goes over the right edge of the screen
|
||||||
if (PrintHead.x + ((PtsToFloat(pGlyph->PrintAdvance) + PtsToFloat(pGlyph->RightPadding)) * Scale) > 1)
|
if (PrintHead.X + ((PtsToFloat(pGlyph->PrintAdvance) + PtsToFloat(pGlyph->RightPadding)) * Scale) > 1)
|
||||||
{
|
{
|
||||||
PrintHead.x = -1;
|
PrintHead.X = -1;
|
||||||
PrintHead.y -= (PtsToFloat(mLineHeight) + PtsToFloat(mLineMargin) + PtsToFloat(mUnknown)) * Scale;
|
PrintHead.Y -= (PtsToFloat(mLineHeight) + PtsToFloat(mLineMargin) + PtsToFloat(mUnknown)) * Scale;
|
||||||
|
|
||||||
if (Char == ' ') continue;
|
if (Char == ' ') continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
float XTrans = PrintHead.x;
|
float XTrans = PrintHead.X;
|
||||||
float YTrans = PrintHead.y + ((PtsToFloat(pGlyph->BaseOffset * 2) - PtsToFloat(mVerticalOffset * 2)) * Scale);
|
float YTrans = PrintHead.Y + ((PtsToFloat(pGlyph->BaseOffset * 2) - PtsToFloat(mVerticalOffset * 2)) * Scale);
|
||||||
|
|
||||||
CTransform4f GlyphTransform = PtScale;
|
CTransform4f GlyphTransform = PtScale;
|
||||||
GlyphTransform.Scale(CVector3f((float) pGlyph->Width / 2, (float) pGlyph->Height, 1.f));
|
GlyphTransform.Scale(CVector3f((float) pGlyph->Width / 2, (float) pGlyph->Height, 1.f));
|
||||||
|
@ -115,7 +114,7 @@ CVector2f CFont::RenderString(const TString& String, CRenderer* /*pRenderer*/, f
|
||||||
|
|
||||||
// Draw fill
|
// Draw fill
|
||||||
glUniform1i(LayerLoc, GlyphLayer);
|
glUniform1i(LayerLoc, GlyphLayer);
|
||||||
glUniform4fv(ColorLoc, 1, &FillColor.r);
|
glUniform4fv(ColorLoc, 1, &FillColor.R);
|
||||||
smGlyphIndices.DrawElements();
|
smGlyphIndices.DrawElements();
|
||||||
|
|
||||||
// Draw stroke
|
// Draw stroke
|
||||||
|
@ -127,13 +126,13 @@ CVector2f CFont::RenderString(const TString& String, CRenderer* /*pRenderer*/, f
|
||||||
else if (mTextureFormat == 8) StrokeLayer = GlyphLayer - 2;
|
else if (mTextureFormat == 8) StrokeLayer = GlyphLayer - 2;
|
||||||
|
|
||||||
glUniform1i(LayerLoc, StrokeLayer);
|
glUniform1i(LayerLoc, StrokeLayer);
|
||||||
glUniform4fv(ColorLoc, 1, &StrokeColor.r);
|
glUniform4fv(ColorLoc, 1, &StrokeColor.R);
|
||||||
smGlyphIndices.DrawElements();
|
smGlyphIndices.DrawElements();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update print head
|
// Update print head
|
||||||
PrintHead.x += PtsToFloat(pGlyph->PrintAdvance) * Scale;
|
PrintHead.X += PtsToFloat(pGlyph->PrintAdvance) * Scale;
|
||||||
PrintHead.x += PtsToFloat(pGlyph->RightPadding) * Scale;
|
PrintHead.X += PtsToFloat(pGlyph->RightPadding) * Scale;
|
||||||
pPrevGlyph = pGlyph;
|
pPrevGlyph = pGlyph;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -61,7 +61,7 @@ public:
|
||||||
CFont();
|
CFont();
|
||||||
~CFont();
|
~CFont();
|
||||||
CResource* MakeCopy(CResCache *pCopyCache);
|
CResource* MakeCopy(CResCache *pCopyCache);
|
||||||
CVector2f RenderString(const TString& String, CRenderer *pRenderer, float AspectRatio,
|
CVector2f RenderString(const TString& rkString, CRenderer *pRenderer, float AspectRatio,
|
||||||
CVector2f Position = CVector2f(0,0),
|
CVector2f Position = CVector2f(0,0),
|
||||||
CColor FillColor = CColor::skWhite, CColor StrokeColor = CColor::skBlack,
|
CColor FillColor = CColor::skWhite, CColor StrokeColor = CColor::skBlack,
|
||||||
u32 FontSize = CFONT_DEFAULT_SIZE);
|
u32 FontSize = CFONT_DEFAULT_SIZE);
|
||||||
|
|
|
@ -26,17 +26,17 @@ CGameArea::~CGameArea()
|
||||||
for (u32 iSCLY = 0; iSCLY < mScriptLayers.size(); iSCLY++)
|
for (u32 iSCLY = 0; iSCLY < mScriptLayers.size(); iSCLY++)
|
||||||
delete mScriptLayers[iSCLY];
|
delete mScriptLayers[iSCLY];
|
||||||
|
|
||||||
for (u32 lyr = 0; lyr < mLightLayers.size(); lyr++)
|
for (u32 iLyr = 0; iLyr < mLightLayers.size(); iLyr++)
|
||||||
for (u32 lit = 0; lit < mLightLayers[lyr].size(); lit++)
|
for (u32 iLight = 0; iLight < mLightLayers[iLyr].size(); iLight++)
|
||||||
delete mLightLayers[lyr][lit];
|
delete mLightLayers[iLyr][iLight];
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGameArea::AddWorldModel(CModel *mdl)
|
void CGameArea::AddWorldModel(CModel *pModel)
|
||||||
{
|
{
|
||||||
mTerrainModels.push_back(mdl);
|
mWorldModels.push_back(pModel);
|
||||||
mVertexCount += mdl->GetVertexCount();
|
mVertexCount += pModel->GetVertexCount();
|
||||||
mTriangleCount += mdl->GetTriangleCount();
|
mTriangleCount += pModel->GetTriangleCount();
|
||||||
mAABox.ExpandBounds(mdl->AABox());
|
mAABox.ExpandBounds(pModel->AABox());
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGameArea::MergeTerrain()
|
void CGameArea::MergeTerrain()
|
||||||
|
@ -44,9 +44,9 @@ void CGameArea::MergeTerrain()
|
||||||
if (mTerrainMerged) return;
|
if (mTerrainMerged) return;
|
||||||
|
|
||||||
// Nothing really complicated here - iterate through every terrain submesh, add each to a static model
|
// Nothing really complicated here - iterate through every terrain submesh, add each to a static model
|
||||||
for (u32 iMdl = 0; iMdl < mTerrainModels.size(); iMdl++)
|
for (u32 iMdl = 0; iMdl < mWorldModels.size(); iMdl++)
|
||||||
{
|
{
|
||||||
CModel *pMdl = mTerrainModels[iMdl];
|
CModel *pMdl = mWorldModels[iMdl];
|
||||||
u32 SubmeshCount = pMdl->GetSurfaceCount();
|
u32 SubmeshCount = pMdl->GetSurfaceCount();
|
||||||
|
|
||||||
for (u32 iSurf = 0; iSurf < SubmeshCount; iSurf++)
|
for (u32 iSurf = 0; iSurf < SubmeshCount; iSurf++)
|
||||||
|
@ -54,8 +54,8 @@ void CGameArea::MergeTerrain()
|
||||||
SSurface *pSurf = pMdl->GetSurface(iSurf);
|
SSurface *pSurf = pMdl->GetSurface(iSurf);
|
||||||
CMaterial *pMat = mMaterialSet->MaterialByIndex(pSurf->MaterialID);
|
CMaterial *pMat = mMaterialSet->MaterialByIndex(pSurf->MaterialID);
|
||||||
|
|
||||||
bool newMat = true;
|
bool NewMat = true;
|
||||||
for (std::vector<CStaticModel*>::iterator it = mStaticTerrainModels.begin(); it != mStaticTerrainModels.end(); it++)
|
for (std::vector<CStaticModel*>::iterator it = mStaticWorldModels.begin(); it != mStaticWorldModels.end(); it++)
|
||||||
{
|
{
|
||||||
if ((*it)->GetMaterial() == pMat)
|
if ((*it)->GetMaterial() == pMat)
|
||||||
{
|
{
|
||||||
|
@ -66,18 +66,18 @@ void CGameArea::MergeTerrain()
|
||||||
// This is maybe not the most efficient way to do this, but it works.
|
// This is maybe not the most efficient way to do this, but it works.
|
||||||
CStaticModel *pStatic = *it;
|
CStaticModel *pStatic = *it;
|
||||||
pStatic->AddSurface(pSurf);
|
pStatic->AddSurface(pSurf);
|
||||||
mStaticTerrainModels.erase(it);
|
mStaticWorldModels.erase(it);
|
||||||
mStaticTerrainModels.push_back(pStatic);
|
mStaticWorldModels.push_back(pStatic);
|
||||||
newMat = false;
|
NewMat = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newMat)
|
if (NewMat)
|
||||||
{
|
{
|
||||||
CStaticModel *pStatic = new CStaticModel(pMat);
|
CStaticModel *pStatic = new CStaticModel(pMat);
|
||||||
pStatic->AddSurface(pSurf);
|
pStatic->AddSurface(pSurf);
|
||||||
mStaticTerrainModels.push_back(pStatic);
|
mStaticWorldModels.push_back(pStatic);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -85,13 +85,13 @@ void CGameArea::MergeTerrain()
|
||||||
|
|
||||||
void CGameArea::ClearTerrain()
|
void CGameArea::ClearTerrain()
|
||||||
{
|
{
|
||||||
for (u32 t = 0; t < mTerrainModels.size(); t++)
|
for (u32 iModel = 0; iModel < mWorldModels.size(); iModel++)
|
||||||
delete mTerrainModels[t];
|
delete mWorldModels[iModel];
|
||||||
mTerrainModels.clear();
|
mWorldModels.clear();
|
||||||
|
|
||||||
for (u32 s = 0; s < mStaticTerrainModels.size(); s++)
|
for (u32 iStatic = 0; iStatic < mStaticWorldModels.size(); iStatic++)
|
||||||
delete mStaticTerrainModels[s];
|
delete mStaticWorldModels[iStatic];
|
||||||
mStaticTerrainModels.clear();
|
mStaticWorldModels.clear();
|
||||||
|
|
||||||
if (mMaterialSet) delete mMaterialSet;
|
if (mMaterialSet) delete mMaterialSet;
|
||||||
|
|
||||||
|
|
|
@ -46,8 +46,8 @@ class CGameArea : public CResource
|
||||||
|
|
||||||
// Geometry
|
// Geometry
|
||||||
CMaterialSet *mMaterialSet;
|
CMaterialSet *mMaterialSet;
|
||||||
std::vector<CModel*> mTerrainModels; // TerrainModels is the original version of each model; this is currently mainly used in the POI map editor
|
std::vector<CModel*> mWorldModels; // TerrainModels is the original version of each model; this is currently mainly used in the POI map editor
|
||||||
std::vector<CStaticModel*> mStaticTerrainModels; // StaticTerrainModels is the merged terrain for faster rendering in the world editor
|
std::vector<CStaticModel*> mStaticWorldModels; // StaticTerrainModels is the merged terrain for faster rendering in the world editor
|
||||||
// Script
|
// Script
|
||||||
std::vector<CScriptLayer*> mScriptLayers;
|
std::vector<CScriptLayer*> mScriptLayers;
|
||||||
CScriptLayer *mpGeneratorLayer;
|
CScriptLayer *mpGeneratorLayer;
|
||||||
|
@ -63,7 +63,7 @@ public:
|
||||||
CGameArea();
|
CGameArea();
|
||||||
~CGameArea();
|
~CGameArea();
|
||||||
|
|
||||||
void AddWorldModel(CModel *mdl);
|
void AddWorldModel(CModel *pModel);
|
||||||
void MergeTerrain();
|
void MergeTerrain();
|
||||||
void ClearTerrain();
|
void ClearTerrain();
|
||||||
void ClearScriptLayers();
|
void ClearScriptLayers();
|
||||||
|
@ -81,19 +81,19 @@ public:
|
||||||
// Inline Accessors
|
// Inline Accessors
|
||||||
inline EGame Version() const { return mVersion; }
|
inline EGame Version() const { return mVersion; }
|
||||||
inline u32 WorldIndex() const { return mWorldIndex; }
|
inline u32 WorldIndex() const { return mWorldIndex; }
|
||||||
inline CTransform4f GetTransform() const { return mTransform; }
|
inline CTransform4f Transform() const { return mTransform; }
|
||||||
inline u32 GetTerrainModelCount() const { return mTerrainModels.size(); }
|
inline u32 NumWorldModels() const { return mWorldModels.size(); }
|
||||||
inline u32 GetStaticModelCount() const { return mStaticTerrainModels.size(); }
|
inline u32 NumStaticModels() const { return mStaticWorldModels.size(); }
|
||||||
inline CModel* GetTerrainModel(u32 iMdl) const { return mTerrainModels[iMdl]; }
|
inline CModel* TerrainModel(u32 iMdl) const { return mWorldModels[iMdl]; }
|
||||||
inline CStaticModel* GetStaticModel(u32 iMdl) const { return mStaticTerrainModels[iMdl]; }
|
inline CStaticModel* StaticModel(u32 iMdl) const { return mStaticWorldModels[iMdl]; }
|
||||||
inline CCollisionMeshGroup* GetCollision() const { return mpCollision; }
|
inline CCollisionMeshGroup* Collision() const { return mpCollision; }
|
||||||
inline u32 GetScriptLayerCount() const { return mScriptLayers.size(); }
|
inline u32 NumScriptLayers() const { return mScriptLayers.size(); }
|
||||||
inline CScriptLayer* GetScriptLayer(u32 Index) const { return mScriptLayers[Index]; }
|
inline CScriptLayer* ScriptLayer(u32 Index) const { return mScriptLayers[Index]; }
|
||||||
inline CScriptLayer* GetGeneratorLayer() const { return mpGeneratorLayer; }
|
inline CScriptLayer* GeneratedObjectsLayer() const { return mpGeneratorLayer; }
|
||||||
inline u32 GetLightLayerCount() const { return mLightLayers.size(); }
|
inline u32 NumLightLayers() const { return mLightLayers.size(); }
|
||||||
inline u32 GetLightCount(u32 LayerIndex) const { return (LayerIndex < mLightLayers.size() ? mLightLayers[LayerIndex].size() : 0); }
|
inline u32 NumLights(u32 LayerIndex) const { return (LayerIndex < mLightLayers.size() ? mLightLayers[LayerIndex].size() : 0); }
|
||||||
inline CLight* GetLight(u32 LayerIndex, u32 LightIndex) const { return mLightLayers[LayerIndex][LightIndex]; }
|
inline CLight* Light(u32 LayerIndex, u32 LightIndex) const { return mLightLayers[LayerIndex][LightIndex]; }
|
||||||
inline CPoiToWorld* GetPoiToWorldMap() const { return mpPoiToWorldMap; }
|
inline CPoiToWorld* PoiToWorldMap() const { return mpPoiToWorldMap; }
|
||||||
inline CAABox AABox() const { return mAABox; }
|
inline CAABox AABox() const { return mAABox; }
|
||||||
|
|
||||||
inline void SetWorldIndex(u32 NewWorldIndex) { mWorldIndex = NewWorldIndex; }
|
inline void SetWorldIndex(u32 NewWorldIndex) { mWorldIndex = NewWorldIndex; }
|
||||||
|
|
|
@ -7,14 +7,14 @@
|
||||||
#define CLIGHT_NO_INTENSITY 0x80
|
#define CLIGHT_NO_INTENSITY 0x80
|
||||||
|
|
||||||
CLight::CLight()
|
CLight::CLight()
|
||||||
|
: mPosition(skDefaultLightPos)
|
||||||
|
, mDirection(skDefaultLightDir)
|
||||||
|
, mDistAttenCoefficients(0.f, 1.f, 0.f)
|
||||||
|
, mAngleAttenCoefficients(0.f, 1.f, 0.f)
|
||||||
|
, mCachedRadius(0.f)
|
||||||
|
, mCachedIntensity(0.f)
|
||||||
|
, mDirtyFlags(CLIGHT_NO_RADIUS | CLIGHT_NO_INTENSITY)
|
||||||
{
|
{
|
||||||
mPosition = skDefaultLightPos;
|
|
||||||
mDirection = skDefaultLightDir;
|
|
||||||
mDistAttenCoefficients = CVector3f(0.f, 1.f, 0.f);
|
|
||||||
mAngleAttenCoefficients = CVector3f(0.f, 1.f, 0.f);
|
|
||||||
mCachedRadius = 0.f;
|
|
||||||
mCachedIntensity = 0.f;
|
|
||||||
mDirtyFlags = CLIGHT_NO_RADIUS | CLIGHT_NO_INTENSITY;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ************ DATA MANIPULATION ************
|
// ************ DATA MANIPULATION ************
|
||||||
|
@ -22,30 +22,30 @@ CLight::CLight()
|
||||||
// This function is reverse engineered from the kiosk demo's code
|
// This function is reverse engineered from the kiosk demo's code
|
||||||
float CLight::CalculateRadius() const
|
float CLight::CalculateRadius() const
|
||||||
{
|
{
|
||||||
if ((mDistAttenCoefficients.y >= FLT_EPSILON) ||
|
if ((mDistAttenCoefficients.Y >= FLT_EPSILON) ||
|
||||||
(mDistAttenCoefficients.z >= FLT_EPSILON))
|
(mDistAttenCoefficients.Z >= FLT_EPSILON))
|
||||||
{
|
{
|
||||||
float Intensity = GetIntensity();
|
float Intensity = GetIntensity();
|
||||||
|
|
||||||
if (mDistAttenCoefficients.z > FLT_EPSILON)
|
if (mDistAttenCoefficients.Z > FLT_EPSILON)
|
||||||
{
|
{
|
||||||
if (Intensity <= FLT_EPSILON)
|
if (Intensity <= FLT_EPSILON)
|
||||||
return 0.f;
|
return 0.f;
|
||||||
|
|
||||||
float IntensityMod = (Intensity * 5.f / 255.f * mDistAttenCoefficients.z);
|
float IntensityMod = (Intensity * 5.f / 255.f * mDistAttenCoefficients.Z);
|
||||||
return sqrt(Intensity / IntensityMod);
|
return sqrtf(Intensity / IntensityMod);
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (mDistAttenCoefficients.y <= FLT_EPSILON)
|
if (mDistAttenCoefficients.Y <= FLT_EPSILON)
|
||||||
return 0.f;
|
return 0.f;
|
||||||
|
|
||||||
float IntensityMod = (Intensity * 5.f) / 255.f;
|
float IntensityMod = (Intensity * 5.f) / 255.f;
|
||||||
if (IntensityMod < 0.2f)
|
if (IntensityMod < 0.2f)
|
||||||
IntensityMod = 0.2f;
|
IntensityMod = 0.2f;
|
||||||
|
|
||||||
return Intensity / (IntensityMod * mDistAttenCoefficients.y);
|
return Intensity / (IntensityMod * mDistAttenCoefficients.Y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,10 +56,10 @@ float CLight::CalculateRadius() const
|
||||||
float CLight::CalculateIntensity() const
|
float CLight::CalculateIntensity() const
|
||||||
{
|
{
|
||||||
// Get the color component with the greatest numeric value
|
// Get the color component with the greatest numeric value
|
||||||
float Greatest = (mColor.g >= mColor.b) ? mColor.g : mColor.b;
|
float Greatest = (mColor.G >= mColor.B) ? mColor.G : mColor.B;
|
||||||
Greatest = (mColor.r >= Greatest) ? mColor.r : Greatest;
|
Greatest = (mColor.R >= Greatest) ? mColor.R : Greatest;
|
||||||
|
|
||||||
float Multiplier = (mType == eCustom) ? mAngleAttenCoefficients.x : 1.0f;
|
float Multiplier = (mType == eCustom) ? mAngleAttenCoefficients.X : 1.0f;
|
||||||
return Greatest * Multiplier;
|
return Greatest * Multiplier;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,42 +78,7 @@ CVector3f CLight::CalculateSpotAngleAtten()
|
||||||
return CVector3f(0.f, -RadianCosine / InvCosine, 1.f / InvCosine);
|
return CVector3f(0.f, -RadianCosine / InvCosine, 1.f / InvCosine);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ************ GETTERS ************
|
// ************ ACCESSORS ************
|
||||||
ELightType CLight::GetType() const
|
|
||||||
{
|
|
||||||
return mType;
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 CLight::GetLayerIndex() const
|
|
||||||
{
|
|
||||||
return mLayerIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
CVector3f CLight::GetPosition() const
|
|
||||||
{
|
|
||||||
return mPosition;
|
|
||||||
}
|
|
||||||
|
|
||||||
CVector3f CLight::GetDirection() const
|
|
||||||
{
|
|
||||||
return mDirection;
|
|
||||||
}
|
|
||||||
|
|
||||||
CColor CLight::GetColor() const
|
|
||||||
{
|
|
||||||
return mColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
CVector3f CLight::GetDistAttenuation() const
|
|
||||||
{
|
|
||||||
return mDistAttenCoefficients;
|
|
||||||
}
|
|
||||||
|
|
||||||
CVector3f CLight::GetAngleAttenuation() const
|
|
||||||
{
|
|
||||||
return mAngleAttenCoefficients;
|
|
||||||
}
|
|
||||||
|
|
||||||
float CLight::GetRadius() const
|
float CLight::GetRadius() const
|
||||||
{
|
{
|
||||||
if (mDirtyFlags & CLIGHT_NO_RADIUS)
|
if (mDirtyFlags & CLIGHT_NO_RADIUS)
|
||||||
|
@ -136,25 +101,9 @@ float CLight::GetIntensity() const
|
||||||
return mCachedIntensity;
|
return mCachedIntensity;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ************ SETTERS ************
|
void CLight::SetColor(const CColor& rkColor)
|
||||||
void CLight::SetLayer(u32 index)
|
|
||||||
{
|
{
|
||||||
mLayerIndex = index;
|
mColor = rkColor;
|
||||||
}
|
|
||||||
|
|
||||||
void CLight::SetPosition(const CVector3f& Position)
|
|
||||||
{
|
|
||||||
mPosition = Position;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CLight::SetDirection(const CVector3f& Direction)
|
|
||||||
{
|
|
||||||
mDirection = Direction;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CLight::SetColor(const CColor& Color)
|
|
||||||
{
|
|
||||||
mColor = Color;
|
|
||||||
mDirtyFlags = CLIGHT_NO_RADIUS | CLIGHT_NO_INTENSITY;
|
mDirtyFlags = CLIGHT_NO_RADIUS | CLIGHT_NO_INTENSITY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,16 +115,16 @@ void CLight::SetSpotCutoff(float Cutoff)
|
||||||
|
|
||||||
void CLight::SetDistAtten(float DistCoefA, float DistCoefB, float DistCoefC)
|
void CLight::SetDistAtten(float DistCoefA, float DistCoefB, float DistCoefC)
|
||||||
{
|
{
|
||||||
mDistAttenCoefficients.x = DistCoefA;
|
mDistAttenCoefficients.X = DistCoefA;
|
||||||
mDistAttenCoefficients.y = DistCoefB;
|
mDistAttenCoefficients.Y = DistCoefB;
|
||||||
mDistAttenCoefficients.z = DistCoefC;
|
mDistAttenCoefficients.Z = DistCoefC;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CLight::SetAngleAtten(float AngleCoefA, float AngleCoefB, float AngleCoefC)
|
void CLight::SetAngleAtten(float AngleCoefA, float AngleCoefB, float AngleCoefC)
|
||||||
{
|
{
|
||||||
mAngleAttenCoefficients.x = AngleCoefA;
|
mAngleAttenCoefficients.X = AngleCoefA;
|
||||||
mAngleAttenCoefficients.y = AngleCoefB;
|
mAngleAttenCoefficients.Y = AngleCoefB;
|
||||||
mAngleAttenCoefficients.z = AngleCoefC;
|
mAngleAttenCoefficients.Z = AngleCoefC;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ************ OTHER ************
|
// ************ OTHER ************
|
||||||
|
@ -184,9 +133,7 @@ void CLight::Load() const
|
||||||
u8 Index = (u8) CGraphics::sNumLights;
|
u8 Index = (u8) CGraphics::sNumLights;
|
||||||
if (Index >= 8) return;
|
if (Index >= 8) return;
|
||||||
|
|
||||||
CGraphics::SLightBlock::SGXLight *Light = &CGraphics::sLightBlock.Lights[Index];
|
CGraphics::SLightBlock::SGXLight *pLight = &CGraphics::sLightBlock.Lights[Index];
|
||||||
CVector3f PosView = CGraphics::sMVPBlock.ViewMatrix * mPosition;
|
|
||||||
CVector3f DirView = CGraphics::sMVPBlock.ViewMatrix * mDirection;
|
|
||||||
|
|
||||||
switch (mType)
|
switch (mType)
|
||||||
{
|
{
|
||||||
|
@ -194,25 +141,25 @@ void CLight::Load() const
|
||||||
// LocalAmbient is already accounted for in CGraphics::sAreaAmbientColor
|
// LocalAmbient is already accounted for in CGraphics::sAreaAmbientColor
|
||||||
return;
|
return;
|
||||||
case eDirectional:
|
case eDirectional:
|
||||||
Light->Position = CVector4f(-mDirection * 1048576.f, 1.f);
|
pLight->Position = CVector4f(-mDirection * 1048576.f, 1.f);
|
||||||
Light->Direction = CVector4f(mDirection, 0.f);
|
pLight->Direction = CVector4f(mDirection, 0.f);
|
||||||
Light->Color = mColor * CGraphics::sWorldLightMultiplier;
|
pLight->Color = mColor * CGraphics::sWorldLightMultiplier;
|
||||||
Light->DistAtten = CVector4f(1.f, 0.f, 0.f, 0.f);
|
pLight->DistAtten = CVector4f(1.f, 0.f, 0.f, 0.f);
|
||||||
Light->AngleAtten = CVector4f(1.f, 0.f, 0.f, 0.f);
|
pLight->AngleAtten = CVector4f(1.f, 0.f, 0.f, 0.f);
|
||||||
break;
|
break;
|
||||||
case eSpot:
|
case eSpot:
|
||||||
Light->Position = CVector4f(mPosition, 1.f);
|
pLight->Position = CVector4f(mPosition, 1.f);
|
||||||
Light->Direction = CVector4f(mDirection, 0.f);
|
pLight->Direction = CVector4f(mDirection, 0.f);
|
||||||
Light->Color = mColor * CGraphics::sWorldLightMultiplier;
|
pLight->Color = mColor * CGraphics::sWorldLightMultiplier;
|
||||||
Light->DistAtten = mDistAttenCoefficients;
|
pLight->DistAtten = mDistAttenCoefficients;
|
||||||
Light->AngleAtten = mAngleAttenCoefficients;
|
pLight->AngleAtten = mAngleAttenCoefficients;
|
||||||
break;
|
break;
|
||||||
case eCustom:
|
case eCustom:
|
||||||
Light->Position = CVector4f(mPosition, 1.f);
|
pLight->Position = CVector4f(mPosition, 1.f);
|
||||||
Light->Direction = CVector4f(mDirection, 0.f);
|
pLight->Direction = CVector4f(mDirection, 0.f);
|
||||||
Light->Color = mColor * CGraphics::sWorldLightMultiplier;
|
pLight->Color = mColor * CGraphics::sWorldLightMultiplier;
|
||||||
Light->DistAtten = mDistAttenCoefficients;
|
pLight->DistAtten = mDistAttenCoefficients;
|
||||||
Light->AngleAtten = mAngleAttenCoefficients;
|
pLight->AngleAtten = mAngleAttenCoefficients;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
|
@ -221,57 +168,57 @@ void CLight::Load() const
|
||||||
}
|
}
|
||||||
|
|
||||||
// ************ STATIC ************
|
// ************ STATIC ************
|
||||||
CLight* CLight::BuildLocalAmbient(const CVector3f& Position, const CColor& Color)
|
CLight* CLight::BuildLocalAmbient(const CVector3f& rkPosition, const CColor& rkColor)
|
||||||
{
|
{
|
||||||
CLight *Light = new CLight;
|
CLight *pLight = new CLight;
|
||||||
Light->mType = eLocalAmbient;
|
pLight->mType = eLocalAmbient;
|
||||||
Light->mPosition = Position;
|
pLight->mPosition = rkPosition;
|
||||||
Light->mDirection = skDefaultLightDir;
|
pLight->mDirection = skDefaultLightDir;
|
||||||
Light->mColor = Color;
|
pLight->mColor = rkColor;
|
||||||
Light->mSpotCutoff = 0.f;
|
pLight->mSpotCutoff = 0.f;
|
||||||
return Light;
|
return pLight;
|
||||||
}
|
}
|
||||||
|
|
||||||
CLight* CLight::BuildDirectional(const CVector3f& Position, const CVector3f& Direction, const CColor& Color)
|
CLight* CLight::BuildDirectional(const CVector3f& rkPosition, const CVector3f& rkDirection, const CColor& rkColor)
|
||||||
{
|
{
|
||||||
CLight *Light = new CLight;
|
CLight *pLight = new CLight;
|
||||||
Light->mType = eDirectional;
|
pLight->mType = eDirectional;
|
||||||
Light->mPosition = Position;
|
pLight->mPosition = rkPosition;
|
||||||
Light->mDirection = Direction;
|
pLight->mDirection = rkDirection;
|
||||||
Light->mColor = Color;
|
pLight->mColor = rkColor;
|
||||||
Light->mSpotCutoff = 0.f;
|
pLight->mSpotCutoff = 0.f;
|
||||||
return Light;
|
return pLight;
|
||||||
}
|
}
|
||||||
|
|
||||||
CLight* CLight::BuildSpot(const CVector3f& Position, const CVector3f& Direction, const CColor& Color, float Cutoff)
|
CLight* CLight::BuildSpot(const CVector3f& rkPosition, const CVector3f& rkDirection, const CColor& rkColor, float Cutoff)
|
||||||
{
|
{
|
||||||
CLight *Light = new CLight;
|
CLight *pLight = new CLight;
|
||||||
Light->mType = eSpot;
|
pLight->mType = eSpot;
|
||||||
Light->mPosition = Position;
|
pLight->mPosition = rkPosition;
|
||||||
Light->mDirection = -Direction.Normalized();
|
pLight->mDirection = -rkDirection.Normalized();
|
||||||
Light->mColor = Color;
|
pLight->mColor = rkColor;
|
||||||
Light->mSpotCutoff = Cutoff * 0.5f;
|
pLight->mSpotCutoff = Cutoff * 0.5f;
|
||||||
Light->mAngleAttenCoefficients = Light->CalculateSpotAngleAtten();
|
pLight->mAngleAttenCoefficients = pLight->CalculateSpotAngleAtten();
|
||||||
return Light;
|
return pLight;
|
||||||
}
|
}
|
||||||
|
|
||||||
CLight* CLight::BuildCustom(const CVector3f& Position, const CVector3f& Direction, const CColor& Color,
|
CLight* CLight::BuildCustom(const CVector3f& rkPosition, const CVector3f& rkDirection, const CColor& rkColor,
|
||||||
float DistAttenA, float DistAttenB, float DistAttenC,
|
float DistAttenA, float DistAttenB, float DistAttenC,
|
||||||
float AngleAttenA, float AngleAttenB, float AngleAttenC)
|
float AngleAttenA, float AngleAttenB, float AngleAttenC)
|
||||||
{
|
{
|
||||||
CLight *Light = new CLight;
|
CLight *pLight = new CLight;
|
||||||
Light->mType = eCustom;
|
pLight->mType = eCustom;
|
||||||
Light->mPosition = Position;
|
pLight->mPosition = rkPosition;
|
||||||
Light->mDirection = Direction;
|
pLight->mDirection = rkDirection;
|
||||||
Light->mColor = Color;
|
pLight->mColor = rkColor;
|
||||||
Light->mSpotCutoff = 0.f;
|
pLight->mSpotCutoff = 0.f;
|
||||||
Light->mDistAttenCoefficients.x = DistAttenA;
|
pLight->mDistAttenCoefficients.X = DistAttenA;
|
||||||
Light->mDistAttenCoefficients.y = DistAttenB;
|
pLight->mDistAttenCoefficients.Y = DistAttenB;
|
||||||
Light->mDistAttenCoefficients.z = DistAttenC;
|
pLight->mDistAttenCoefficients.Z = DistAttenC;
|
||||||
Light->mAngleAttenCoefficients.x = AngleAttenA;
|
pLight->mAngleAttenCoefficients.X = AngleAttenA;
|
||||||
Light->mAngleAttenCoefficients.y = AngleAttenB;
|
pLight->mAngleAttenCoefficients.Y = AngleAttenB;
|
||||||
Light->mAngleAttenCoefficients.z = AngleAttenC * AngleAttenC;
|
pLight->mAngleAttenCoefficients.Z = AngleAttenC * AngleAttenC;
|
||||||
return Light;
|
return pLight;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ************ CONSTANTS ************
|
// ************ CONSTANTS ************
|
||||||
|
|
|
@ -41,22 +41,23 @@ private:
|
||||||
CVector3f CalculateSpotAngleAtten();
|
CVector3f CalculateSpotAngleAtten();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Getters
|
// Accessors
|
||||||
ELightType GetType() const;
|
inline ELightType Type() const { return mType; }
|
||||||
u32 GetLayerIndex() const;
|
inline u32 LayerIndex() const { return mLayerIndex; }
|
||||||
CVector3f GetPosition() const;
|
inline CVector3f Position() const { return mPosition; }
|
||||||
CVector3f GetDirection() const;
|
inline CVector3f Direction() const { return mDirection; }
|
||||||
CColor GetColor() const;
|
inline CColor Color() const { return mColor; }
|
||||||
CVector3f GetDistAttenuation() const;
|
inline CVector3f DistAttenuation() const { return mDistAttenCoefficients; }
|
||||||
CVector3f GetAngleAttenuation() const;
|
inline CVector3f AngleAttenuation() const { return mAngleAttenCoefficients; }
|
||||||
|
|
||||||
|
inline void SetLayer(u32 Index) { mLayerIndex = Index; }
|
||||||
|
inline void SetPosition(const CVector3f& rkPosition) { mPosition = rkPosition; }
|
||||||
|
inline void SetDirection(const CVector3f& rkDirection) { mDirection = rkDirection; }
|
||||||
|
|
||||||
float GetRadius() const;
|
float GetRadius() const;
|
||||||
float GetIntensity() const;
|
float GetIntensity() const;
|
||||||
|
|
||||||
// Setters
|
void SetColor(const CColor& rkColor);
|
||||||
void SetLayer(u32 index);
|
|
||||||
void SetPosition(const CVector3f& Position);
|
|
||||||
void SetDirection(const CVector3f& Direction);
|
|
||||||
void SetColor(const CColor& Color);
|
|
||||||
void SetSpotCutoff(float Cutoff);
|
void SetSpotCutoff(float Cutoff);
|
||||||
void SetDistAtten(float DistCoefA, float DistCoefB, float DistCoefC);
|
void SetDistAtten(float DistCoefA, float DistCoefB, float DistCoefC);
|
||||||
void SetAngleAtten(float AngleCoefA, float AngleCoefB, float AngleCoefC);
|
void SetAngleAtten(float AngleCoefA, float AngleCoefB, float AngleCoefC);
|
||||||
|
@ -65,10 +66,10 @@ public:
|
||||||
void Load() const;
|
void Load() const;
|
||||||
|
|
||||||
// Static
|
// Static
|
||||||
static CLight* BuildLocalAmbient(const CVector3f& Position, const CColor& Color);
|
static CLight* BuildLocalAmbient(const CVector3f& rkPosition, const CColor& rkColor);
|
||||||
static CLight* BuildDirectional(const CVector3f& Position, const CVector3f& Direction, const CColor& Color);
|
static CLight* BuildDirectional(const CVector3f& rkPosition, const CVector3f& rkDirection, const CColor& rkColor);
|
||||||
static CLight* BuildSpot(const CVector3f& Position, const CVector3f& Direction, const CColor& Color, float Cutoff);
|
static CLight* BuildSpot(const CVector3f& rkPosition, const CVector3f& rkDirection, const CColor& rkColor, float Cutoff);
|
||||||
static CLight* BuildCustom(const CVector3f& Position, const CVector3f& Direction, const CColor& Color,
|
static CLight* BuildCustom(const CVector3f& rkPosition, const CVector3f& rkDirection, const CColor& rkColor,
|
||||||
float DistAttenA, float DistAttenB, float DistAttenC,
|
float DistAttenA, float DistAttenB, float DistAttenC,
|
||||||
float AngleAttenA, float AngleAttenB, float AngleAttenC);
|
float AngleAttenA, float AngleAttenB, float AngleAttenC);
|
||||||
|
|
||||||
|
|
|
@ -13,31 +13,44 @@ u64 CMaterial::sCurrentMaterial = 0;
|
||||||
CColor CMaterial::sCurrentTint = CColor::skWhite;
|
CColor CMaterial::sCurrentTint = CColor::skWhite;
|
||||||
|
|
||||||
CMaterial::CMaterial()
|
CMaterial::CMaterial()
|
||||||
|
: mpShader(nullptr)
|
||||||
|
, mShaderStatus(eNoShader)
|
||||||
|
, mRecalcHash(true)
|
||||||
|
, mEnableBloom(false)
|
||||||
|
, mVersion(eUnknownVersion)
|
||||||
|
, mOptions(eNoSettings)
|
||||||
|
, mVtxDesc(eNoAttributes)
|
||||||
|
, mBlendSrcFac(GL_ONE)
|
||||||
|
, mBlendDstFac(GL_ZERO)
|
||||||
|
, mLightingEnabled(true)
|
||||||
|
, mEchoesUnknownA(0)
|
||||||
|
, mEchoesUnknownB(0)
|
||||||
|
, mpIndirectTexture(nullptr)
|
||||||
{
|
{
|
||||||
mpShader = nullptr;
|
|
||||||
mShaderStatus = eNoShader;
|
|
||||||
mRecalcHash = true;
|
|
||||||
mEnableBloom = false;
|
|
||||||
mVersion = eUnknownVersion;
|
|
||||||
mOptions = eNoSettings;
|
|
||||||
mVtxDesc = eNoAttributes;
|
|
||||||
mBlendSrcFac = GL_ONE;
|
|
||||||
mBlendDstFac = GL_ZERO;
|
|
||||||
mLightingEnabled = true;
|
|
||||||
mEchoesUnknownA = 0;
|
|
||||||
mEchoesUnknownB = 0;
|
|
||||||
mpIndirectTexture = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CMaterial::CMaterial(EGame version, FVertexDescription vtxDesc)
|
CMaterial::CMaterial(EGame Version, FVertexDescription VtxDesc)
|
||||||
|
: mpShader(nullptr)
|
||||||
|
, mShaderStatus(eNoShader)
|
||||||
|
, mRecalcHash(true)
|
||||||
|
, mEnableBloom(Version == eCorruption)
|
||||||
|
, mVersion(Version)
|
||||||
|
, mOptions(eDepthWrite)
|
||||||
|
, mVtxDesc(VtxDesc)
|
||||||
|
, mBlendSrcFac(GL_ONE)
|
||||||
|
, mBlendDstFac(GL_ZERO)
|
||||||
|
, mLightingEnabled(true)
|
||||||
|
, mEchoesUnknownA(0)
|
||||||
|
, mEchoesUnknownB(0)
|
||||||
|
, mpIndirectTexture(nullptr)
|
||||||
{
|
{
|
||||||
mpShader = nullptr;
|
mpShader = nullptr;
|
||||||
mShaderStatus = eNoShader;
|
mShaderStatus = eNoShader;
|
||||||
mRecalcHash = true;
|
mRecalcHash = true;
|
||||||
mEnableBloom = (version == eCorruption);
|
mEnableBloom = (Version == eCorruption);
|
||||||
mVersion = version;
|
mVersion = Version;
|
||||||
mOptions = eDepthWrite;
|
mOptions = eDepthWrite;
|
||||||
mVtxDesc = vtxDesc;
|
mVtxDesc = VtxDesc;
|
||||||
mBlendSrcFac = GL_ONE;
|
mBlendSrcFac = GL_ONE;
|
||||||
mBlendDstFac = GL_ZERO;
|
mBlendDstFac = GL_ZERO;
|
||||||
mLightingEnabled = true;
|
mLightingEnabled = true;
|
||||||
|
@ -218,114 +231,6 @@ void CMaterial::Update()
|
||||||
mShaderStatus = eNoShader;
|
mShaderStatus = eNoShader;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ************ GETTERS ************
|
|
||||||
TString CMaterial::Name() const
|
|
||||||
{
|
|
||||||
return mName;
|
|
||||||
}
|
|
||||||
|
|
||||||
EGame CMaterial::Version() const
|
|
||||||
{
|
|
||||||
return mVersion;
|
|
||||||
}
|
|
||||||
|
|
||||||
CMaterial::FMaterialOptions CMaterial::Options() const
|
|
||||||
{
|
|
||||||
return mOptions;
|
|
||||||
}
|
|
||||||
|
|
||||||
FVertexDescription CMaterial::VtxDesc() const
|
|
||||||
{
|
|
||||||
return mVtxDesc;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLenum CMaterial::BlendSrcFac() const {
|
|
||||||
return mBlendSrcFac;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLenum CMaterial::BlendDstFac() const {
|
|
||||||
return mBlendDstFac;
|
|
||||||
}
|
|
||||||
|
|
||||||
CColor CMaterial::Konst(u32 KIndex) const
|
|
||||||
{
|
|
||||||
if (KIndex > 3) return CColor::skTransparentBlack;
|
|
||||||
else return mKonstColors[KIndex];
|
|
||||||
}
|
|
||||||
|
|
||||||
CTexture* CMaterial::IndTexture() const
|
|
||||||
{
|
|
||||||
return mpIndirectTexture;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CMaterial::IsLightingEnabled() const
|
|
||||||
{
|
|
||||||
return mLightingEnabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 CMaterial::EchoesUnknownA() const
|
|
||||||
{
|
|
||||||
return mEchoesUnknownA;
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 CMaterial::EchoesUnknownB() const
|
|
||||||
{
|
|
||||||
return mEchoesUnknownB;
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 CMaterial::PassCount() const
|
|
||||||
{
|
|
||||||
return mPasses.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
CMaterialPass* CMaterial::Pass(u32 PassIndex) const
|
|
||||||
{
|
|
||||||
return mPasses[PassIndex];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ************ SETTERS ************
|
|
||||||
void CMaterial::SetName(const TString& name)
|
|
||||||
{
|
|
||||||
mName = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CMaterial::SetOptions(FMaterialOptions Options)
|
|
||||||
{
|
|
||||||
mOptions = Options;
|
|
||||||
mRecalcHash = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CMaterial::SetVertexDescription(FVertexDescription desc)
|
|
||||||
{
|
|
||||||
mVtxDesc = desc;
|
|
||||||
mRecalcHash = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CMaterial::SetBlendMode(GLenum SrcFac, GLenum DstFac)
|
|
||||||
{
|
|
||||||
mBlendSrcFac = SrcFac;
|
|
||||||
mBlendDstFac = DstFac;
|
|
||||||
mRecalcHash = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CMaterial::SetKonst(CColor& Konst, u32 KIndex)
|
|
||||||
{
|
|
||||||
mKonstColors[KIndex] = Konst;
|
|
||||||
mRecalcHash = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CMaterial::SetIndTexture(CTexture *pTex)
|
|
||||||
{
|
|
||||||
mpIndirectTexture = pTex;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CMaterial::SetLightingEnabled(bool Enabled)
|
|
||||||
{
|
|
||||||
mLightingEnabled = Enabled;
|
|
||||||
mRecalcHash = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CMaterial::SetNumPasses(u32 NumPasses)
|
void CMaterial::SetNumPasses(u32 NumPasses)
|
||||||
{
|
{
|
||||||
if (NumPasses < mPasses.size())
|
if (NumPasses < mPasses.size())
|
||||||
|
@ -345,9 +250,3 @@ void CMaterial::SetNumPasses(u32 NumPasses)
|
||||||
|
|
||||||
mRecalcHash = true;
|
mRecalcHash = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ************ STATIC ************
|
|
||||||
void CMaterial::KillCachedMaterial()
|
|
||||||
{
|
|
||||||
sCurrentMaterial = 0;
|
|
||||||
}
|
|
||||||
|
|
|
@ -74,41 +74,41 @@ private:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CMaterial();
|
CMaterial();
|
||||||
CMaterial(EGame version, FVertexDescription vtxDesc);
|
CMaterial(EGame Version, FVertexDescription VtxDesc);
|
||||||
~CMaterial();
|
~CMaterial();
|
||||||
|
|
||||||
CMaterial* Clone();
|
CMaterial* Clone();
|
||||||
void GenerateShader(bool AllowRegen = true);
|
void GenerateShader(bool AllowRegen = true);
|
||||||
bool SetCurrent(FRenderOptions Options);
|
bool SetCurrent(FRenderOptions Options);
|
||||||
u64 HashParameters();
|
u64 HashParameters();
|
||||||
void Update();
|
void Update();
|
||||||
|
|
||||||
// Getters
|
|
||||||
TString Name() const;
|
|
||||||
EGame Version() const;
|
|
||||||
FMaterialOptions Options() const;
|
|
||||||
FVertexDescription VtxDesc() const;
|
|
||||||
GLenum BlendSrcFac() const;
|
|
||||||
GLenum BlendDstFac() const;
|
|
||||||
CColor Konst(u32 KIndex) const;
|
|
||||||
CTexture* IndTexture() const;
|
|
||||||
bool IsLightingEnabled() const;
|
|
||||||
u32 EchoesUnknownA() const;
|
|
||||||
u32 EchoesUnknownB() const;
|
|
||||||
u32 PassCount() const;
|
|
||||||
CMaterialPass* Pass(u32 PassIndex) const;
|
|
||||||
|
|
||||||
// Setters
|
|
||||||
void SetName(const TString& name);
|
|
||||||
void SetOptions(FMaterialOptions Options);
|
|
||||||
void SetVertexDescription(FVertexDescription desc);
|
|
||||||
void SetBlendMode(GLenum SrcFac, GLenum DstFac);
|
|
||||||
void SetKonst(CColor& Konst, u32 KIndex);
|
|
||||||
void SetIndTexture(CTexture *pTex);
|
|
||||||
void SetLightingEnabled(bool Enabled);
|
|
||||||
void SetNumPasses(u32 NumPasses);
|
void SetNumPasses(u32 NumPasses);
|
||||||
|
|
||||||
|
// Accessors
|
||||||
|
inline TString Name() const { return mName; }
|
||||||
|
inline EGame Version() const { return mVersion; }
|
||||||
|
inline FMaterialOptions Options() const { return mOptions; }
|
||||||
|
inline FVertexDescription VtxDesc() const { return mVtxDesc; }
|
||||||
|
inline GLenum BlendSrcFac() const { return mBlendSrcFac; }
|
||||||
|
inline GLenum BlendDstFac() const { return mBlendDstFac; }
|
||||||
|
inline CColor Konst(u32 KIndex) const { return mKonstColors[KIndex]; }
|
||||||
|
inline CTexture* IndTexture() const { return mpIndirectTexture; }
|
||||||
|
inline bool IsLightingEnabled() const { return mLightingEnabled; }
|
||||||
|
inline u32 EchoesUnknownA() const { return mEchoesUnknownA; }
|
||||||
|
inline u32 EchoesUnknownB() const { return mEchoesUnknownB; }
|
||||||
|
inline u32 PassCount() const { return mPasses.size(); }
|
||||||
|
inline CMaterialPass* Pass(u32 PassIndex) const { return mPasses[PassIndex]; }
|
||||||
|
|
||||||
|
inline void SetName(const TString& rkName) { mName = rkName; }
|
||||||
|
inline void SetOptions(FMaterialOptions Options) { mOptions = Options; mRecalcHash = true; }
|
||||||
|
inline void SetVertexDescription(FVertexDescription Desc) { mVtxDesc = Desc; mRecalcHash = true; }
|
||||||
|
inline void SetBlendMode(GLenum SrcFac, GLenum DstFac) { mBlendSrcFac = SrcFac; mBlendDstFac = DstFac; mRecalcHash = true; }
|
||||||
|
inline void SetKonst(CColor& Konst, u32 KIndex) { mKonstColors[KIndex] = Konst; mRecalcHash = true; }
|
||||||
|
inline void SetIndTexture(CTexture *pTex) { mpIndirectTexture = pTex; }
|
||||||
|
inline void SetLightingEnabled(bool Enabled) { mLightingEnabled = Enabled; mRecalcHash = true; }
|
||||||
|
|
||||||
// Static
|
// Static
|
||||||
static void KillCachedMaterial();
|
inline static void KillCachedMaterial() { sCurrentMaterial = 0; }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // MATERIAL_H
|
#endif // MATERIAL_H
|
||||||
|
|
|
@ -1,24 +1,22 @@
|
||||||
#include "CMaterialPass.h"
|
#include "CMaterialPass.h"
|
||||||
#include "CMaterial.h"
|
#include "CMaterial.h"
|
||||||
#include "Core/Render/CGraphics.h"
|
#include "Core/Render/CGraphics.h"
|
||||||
#include <Common/AnimUtil.h>
|
#include <Common/CTimer.h>
|
||||||
|
|
||||||
CMaterialPass::CMaterialPass(CMaterial *pParent)
|
CMaterialPass::CMaterialPass(CMaterial *pParent)
|
||||||
|
: mPassType("CUST")
|
||||||
|
, mSettings(eNoPassSettings)
|
||||||
|
, mpTexture(nullptr)
|
||||||
|
, mEnabled(true)
|
||||||
|
, mpParentMat(pParent)
|
||||||
|
, mColorOutput(ePrevReg)
|
||||||
|
, mAlphaOutput(ePrevReg)
|
||||||
|
, mKColorSel(eKonstOne)
|
||||||
|
, mKAlphaSel(eKonstOne)
|
||||||
|
, mRasSel(eRasColorNull)
|
||||||
|
, mTexCoordSource(0xFF)
|
||||||
|
, mAnimMode(eNoUVAnim)
|
||||||
{
|
{
|
||||||
mPassType = "CUST";
|
|
||||||
mSettings = eNoPassSettings;
|
|
||||||
mpTexture = nullptr;
|
|
||||||
mEnabled = true;
|
|
||||||
mpParentMat = pParent;
|
|
||||||
|
|
||||||
mColorOutput = ePrevReg;
|
|
||||||
mAlphaOutput = ePrevReg;
|
|
||||||
mKColorSel = eKonstOne;
|
|
||||||
mKAlphaSel = eKonstOne;
|
|
||||||
mRasSel = eRasColorNull;
|
|
||||||
mTexCoordSource = 0xFF;
|
|
||||||
mAnimMode = eNoUVAnim;
|
|
||||||
|
|
||||||
for (u32 iParam = 0; iParam < 4; iParam++)
|
for (u32 iParam = 0; iParam < 4; iParam++)
|
||||||
{
|
{
|
||||||
mColorInputs[iParam] = eZeroRGB;
|
mColorInputs[iParam] = eZeroRGB;
|
||||||
|
@ -36,10 +34,13 @@ CMaterialPass* CMaterialPass::Clone(CMaterial *pParent)
|
||||||
CMaterialPass *pOut = new CMaterialPass(pParent);
|
CMaterialPass *pOut = new CMaterialPass(pParent);
|
||||||
pOut->mPassType = mPassType;
|
pOut->mPassType = mPassType;
|
||||||
pOut->mSettings = mSettings;
|
pOut->mSettings = mSettings;
|
||||||
for (u32 iIn = 0; iIn < 4; iIn++) {
|
|
||||||
|
for (u32 iIn = 0; iIn < 4; iIn++)
|
||||||
|
{
|
||||||
pOut->mColorInputs[iIn] = mColorInputs[iIn];
|
pOut->mColorInputs[iIn] = mColorInputs[iIn];
|
||||||
pOut->mAlphaInputs[iIn] = mAlphaInputs[iIn];
|
pOut->mAlphaInputs[iIn] = mAlphaInputs[iIn];
|
||||||
}
|
}
|
||||||
|
|
||||||
pOut->mColorOutput = mColorOutput;
|
pOut->mColorOutput = mColorOutput;
|
||||||
pOut->mAlphaOutput = mAlphaOutput;
|
pOut->mAlphaOutput = mAlphaOutput;
|
||||||
pOut->mKColorSel = mKColorSel;
|
pOut->mKColorSel = mKColorSel;
|
||||||
|
@ -48,30 +49,32 @@ CMaterialPass* CMaterialPass::Clone(CMaterial *pParent)
|
||||||
pOut->mTexCoordSource = mTexCoordSource;
|
pOut->mTexCoordSource = mTexCoordSource;
|
||||||
pOut->mpTexture = mpTexture;
|
pOut->mpTexture = mpTexture;
|
||||||
pOut->mAnimMode = mAnimMode;
|
pOut->mAnimMode = mAnimMode;
|
||||||
|
|
||||||
for (u32 iParam = 0; iParam < 4; iParam++)
|
for (u32 iParam = 0; iParam < 4; iParam++)
|
||||||
pOut->mAnimParams[iParam] = mAnimParams[iParam];
|
pOut->mAnimParams[iParam] = mAnimParams[iParam];
|
||||||
|
|
||||||
pOut->mEnabled = mEnabled;
|
pOut->mEnabled = mEnabled;
|
||||||
|
|
||||||
return pOut;
|
return pOut;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMaterialPass::HashParameters(CHashFNV1A &Hash)
|
void CMaterialPass::HashParameters(CHashFNV1A& rHash)
|
||||||
{
|
{
|
||||||
if (mEnabled)
|
if (mEnabled)
|
||||||
{
|
{
|
||||||
Hash.HashLong(mPassType.ToLong());
|
rHash.HashLong(mPassType.ToLong());
|
||||||
Hash.HashLong(mSettings);
|
rHash.HashLong(mSettings);
|
||||||
Hash.HashData(&mColorInputs[0], sizeof(ETevColorInput) * 4);
|
rHash.HashData(&mColorInputs[0], sizeof(ETevColorInput) * 4);
|
||||||
Hash.HashData(&mAlphaInputs[0], sizeof(ETevAlphaInput) * 4);
|
rHash.HashData(&mAlphaInputs[0], sizeof(ETevAlphaInput) * 4);
|
||||||
Hash.HashLong(mColorOutput);
|
rHash.HashLong(mColorOutput);
|
||||||
Hash.HashLong(mAlphaOutput);
|
rHash.HashLong(mAlphaOutput);
|
||||||
Hash.HashLong(mKColorSel);
|
rHash.HashLong(mKColorSel);
|
||||||
Hash.HashLong(mKAlphaSel);
|
rHash.HashLong(mKAlphaSel);
|
||||||
Hash.HashLong(mRasSel);
|
rHash.HashLong(mRasSel);
|
||||||
Hash.HashLong(mTexCoordSource);
|
rHash.HashLong(mTexCoordSource);
|
||||||
Hash.HashLong(mAnimMode);
|
rHash.HashLong(mAnimMode);
|
||||||
Hash.HashData(mAnimParams, sizeof(float) * 4);
|
rHash.HashData(mAnimParams, sizeof(float) * 4);
|
||||||
Hash.HashByte(mEnabled);
|
rHash.HashByte(mEnabled);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,7 +88,7 @@ void CMaterialPass::SetAnimCurrent(FRenderOptions Options, u32 PassIndex)
|
||||||
{
|
{
|
||||||
if (mAnimMode == eNoUVAnim) return;
|
if (mAnimMode == eNoUVAnim) return;
|
||||||
|
|
||||||
float s = AnimUtil::SecondsMod900();
|
float Seconds = CTimer::SecondsMod900();
|
||||||
const CMatrix4f& ModelMtx = CGraphics::sMVPBlock.ModelMatrix;
|
const CMatrix4f& ModelMtx = CGraphics::sMVPBlock.ModelMatrix;
|
||||||
const CMatrix4f& ViewMtx = CGraphics::sMVPBlock.ViewMatrix;
|
const CMatrix4f& ViewMtx = CGraphics::sMVPBlock.ViewMatrix;
|
||||||
|
|
||||||
|
@ -98,9 +101,9 @@ void CMaterialPass::SetAnimCurrent(FRenderOptions Options, u32 PassIndex)
|
||||||
case eInverseMV: // Mode 0
|
case eInverseMV: // Mode 0
|
||||||
case eSimpleMode: // Mode 10 - maybe not correct?
|
case eSimpleMode: // Mode 10 - maybe not correct?
|
||||||
{
|
{
|
||||||
glm::mat4 mtx = glm::inverse(glm::transpose(ViewMtx.ToGlmMat4()) * glm::transpose(ModelMtx.ToGlmMat4()));
|
glm::mat4 InvMV = glm::inverse(glm::transpose(ViewMtx.ToGlmMat4()) * glm::transpose(ModelMtx.ToGlmMat4()));
|
||||||
mtx[0][3] = mtx[1][3] = mtx[2][3] = 0.f;
|
InvMV[0][3] = InvMV[1][3] = InvMV[2][3] = 0.f;
|
||||||
TexMtx = CMatrix4f::FromGlmMat4(mtx);
|
TexMtx = CMatrix4f::FromGlmMat4(InvMV);
|
||||||
PostMtx = CMatrix4f(0.5f, 0.0f, 0.0f, 0.5f,
|
PostMtx = CMatrix4f(0.5f, 0.0f, 0.0f, 0.5f,
|
||||||
0.0f, 0.5f, 0.0f, 0.5f,
|
0.0f, 0.5f, 0.0f, 0.5f,
|
||||||
0.0f, 0.0f, 0.0f, 1.0f,
|
0.0f, 0.0f, 0.0f, 1.0f,
|
||||||
|
@ -110,8 +113,8 @@ void CMaterialPass::SetAnimCurrent(FRenderOptions Options, u32 PassIndex)
|
||||||
|
|
||||||
case eInverseMVTranslated: // Mode 1
|
case eInverseMVTranslated: // Mode 1
|
||||||
{
|
{
|
||||||
glm::mat4 mtx = glm::inverse(glm::transpose(ViewMtx.ToGlmMat4()) * glm::transpose(ModelMtx.ToGlmMat4()));
|
glm::mat4 InvMV = glm::inverse(glm::transpose(ViewMtx.ToGlmMat4()) * glm::transpose(ModelMtx.ToGlmMat4()));
|
||||||
TexMtx = CMatrix4f::FromGlmMat4(mtx);
|
TexMtx = CMatrix4f::FromGlmMat4(InvMV);
|
||||||
PostMtx = CMatrix4f(0.5f, 0.0f, 0.0f, 0.5f,
|
PostMtx = CMatrix4f(0.5f, 0.0f, 0.0f, 0.5f,
|
||||||
0.0f, 0.5f, 0.0f, 0.5f,
|
0.0f, 0.5f, 0.0f, 0.5f,
|
||||||
0.0f, 0.0f, 0.0f, 1.0f,
|
0.0f, 0.0f, 0.0f, 1.0f,
|
||||||
|
@ -122,8 +125,8 @@ void CMaterialPass::SetAnimCurrent(FRenderOptions Options, u32 PassIndex)
|
||||||
{
|
{
|
||||||
if (Options & eEnableUVScroll)
|
if (Options & eEnableUVScroll)
|
||||||
{
|
{
|
||||||
TexMtx[0][3] = (s * mAnimParams[2]) + mAnimParams[0];
|
TexMtx[0][3] = (Seconds * mAnimParams[2]) + mAnimParams[0];
|
||||||
TexMtx[1][3] = (s * mAnimParams[3]) + mAnimParams[1];
|
TexMtx[1][3] = (Seconds * mAnimParams[3]) + mAnimParams[1];
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -132,7 +135,7 @@ void CMaterialPass::SetAnimCurrent(FRenderOptions Options, u32 PassIndex)
|
||||||
{
|
{
|
||||||
if (Options & eEnableUVScroll)
|
if (Options & eEnableUVScroll)
|
||||||
{
|
{
|
||||||
float Angle = (s * mAnimParams[1]) + mAnimParams[0];
|
float Angle = (Seconds * mAnimParams[1]) + mAnimParams[0];
|
||||||
|
|
||||||
float ACos = cos(Angle);
|
float ACos = cos(Angle);
|
||||||
float ASin = sin(Angle);
|
float ASin = sin(Angle);
|
||||||
|
@ -152,7 +155,7 @@ void CMaterialPass::SetAnimCurrent(FRenderOptions Options, u32 PassIndex)
|
||||||
{
|
{
|
||||||
if (Options & eEnableUVScroll)
|
if (Options & eEnableUVScroll)
|
||||||
{
|
{
|
||||||
float Offset = mAnimParams[2] * mAnimParams[0] * (mAnimParams[3] + s);
|
float Offset = mAnimParams[2] * mAnimParams[0] * (mAnimParams[3] + Seconds);
|
||||||
Offset = (float)(short)(float)(mAnimParams[1] * fmod(Offset, 1.0f)) * mAnimParams[2];
|
Offset = (float)(short)(float)(mAnimParams[1] * fmod(Offset, 1.0f)) * mAnimParams[2];
|
||||||
if (mAnimMode == eHFilmstrip) TexMtx[0][3] = Offset;
|
if (mAnimMode == eHFilmstrip) TexMtx[0][3] = Offset;
|
||||||
if (mAnimMode == eVFilmstrip) TexMtx[1][3] = Offset;
|
if (mAnimMode == eVFilmstrip) TexMtx[1][3] = Offset;
|
||||||
|
@ -175,23 +178,22 @@ void CMaterialPass::SetAnimCurrent(FRenderOptions Options, u32 PassIndex)
|
||||||
|
|
||||||
case eConvolutedModeA: // Mode 7
|
case eConvolutedModeA: // Mode 7
|
||||||
{
|
{
|
||||||
CMatrix4f view = CGraphics::sMVPBlock.ViewMatrix;
|
CMatrix4f View = CGraphics::sMVPBlock.ViewMatrix;
|
||||||
|
|
||||||
// Oh god I seriously need a CMatrix4f inverse function.
|
glm::mat4 Mtx = glm::inverse(glm::transpose(ViewMtx.ToGlmMat4()) * glm::transpose(ModelMtx.ToGlmMat4()));
|
||||||
glm::mat4 mtx = glm::inverse(glm::transpose(ViewMtx.ToGlmMat4()) * glm::transpose(ModelMtx.ToGlmMat4()));
|
Mtx[0][3] = Mtx[1][3] = Mtx[2][3] = 0.f;
|
||||||
mtx[0][3] = mtx[1][3] = mtx[2][3] = 0.f;
|
TexMtx = CMatrix4f::FromGlmMat4(Mtx);
|
||||||
TexMtx = CMatrix4f::FromGlmMat4(mtx);
|
|
||||||
|
|
||||||
float xy = (view[3][0] + view[3][1]) * 0.025f * mAnimParams[1];
|
float XY = (View[3][0] + View[3][1]) * 0.025f * mAnimParams[1];
|
||||||
xy = (xy - (int) xy);
|
XY = (XY - (int) XY);
|
||||||
|
|
||||||
float z = view[3][2] * 0.05f * mAnimParams[1];
|
float Z = View[3][2] * 0.05f * mAnimParams[1];
|
||||||
z = (z - (int) z);
|
Z = (Z - (int) Z);
|
||||||
|
|
||||||
float halfA = mAnimParams[0] * 0.5f;
|
float HalfA = mAnimParams[0] * 0.5f;
|
||||||
|
|
||||||
PostMtx = CMatrix4f(halfA, 0.0f, 0.0f, xy,
|
PostMtx = CMatrix4f(HalfA, 0.0f, 0.0f, XY,
|
||||||
0.0f, 0.0f, halfA, z,
|
0.0f, 0.0f, HalfA, Z,
|
||||||
0.0f, 0.0f, 0.0f, 1.0f,
|
0.0f, 0.0f, 0.0f, 1.0f,
|
||||||
0.0f, 0.0f, 0.0f, 1.0f);
|
0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -45,7 +45,7 @@ public:
|
||||||
CMaterialPass(CMaterial *pParent);
|
CMaterialPass(CMaterial *pParent);
|
||||||
~CMaterialPass();
|
~CMaterialPass();
|
||||||
CMaterialPass* Clone(CMaterial *pParent);
|
CMaterialPass* Clone(CMaterial *pParent);
|
||||||
void HashParameters(CHashFNV1A& Hash);
|
void HashParameters(CHashFNV1A& rHash);
|
||||||
void LoadTexture(u32 PassIndex);
|
void LoadTexture(u32 PassIndex);
|
||||||
void SetAnimCurrent(FRenderOptions Options, u32 PassIndex);
|
void SetAnimCurrent(FRenderOptions Options, u32 PassIndex);
|
||||||
|
|
||||||
|
@ -65,61 +65,20 @@ public:
|
||||||
void SetEnabled(bool Enabled);
|
void SetEnabled(bool Enabled);
|
||||||
|
|
||||||
// Getters
|
// Getters
|
||||||
inline CFourCC Type() const {
|
inline CFourCC Type() const { return mPassType; }
|
||||||
return mPassType;
|
inline TString NamedType() const { return PassTypeName(mPassType); }
|
||||||
}
|
inline ETevColorInput ColorInput(u32 Input) const { return mColorInputs[Input]; }
|
||||||
|
inline ETevAlphaInput AlphaInput(u32 Input) const { return mAlphaInputs[Input]; }
|
||||||
inline TString NamedType() const {
|
inline ETevOutput ColorOutput() const { return mColorOutput; }
|
||||||
return PassTypeName(mPassType);
|
inline ETevOutput AlphaOutput() const { return mAlphaOutput; }
|
||||||
}
|
inline ETevKSel KColorSel() const { return mKColorSel; }
|
||||||
|
inline ETevKSel KAlphaSel() const { return mKAlphaSel; }
|
||||||
inline ETevColorInput ColorInput(u32 Input) const {
|
inline ETevRasSel RasSel() const { return mRasSel; }
|
||||||
return mColorInputs[Input];
|
inline u32 TexCoordSource() const { return mTexCoordSource; }
|
||||||
}
|
inline CTexture* Texture() const { return mpTexture; }
|
||||||
|
inline EUVAnimMode AnimMode() const { return mAnimMode; }
|
||||||
inline ETevAlphaInput AlphaInput(u32 Input) const {
|
inline float AnimParam(u32 ParamIndex) const { return mAnimParams[ParamIndex]; }
|
||||||
return mAlphaInputs[Input];
|
inline bool IsEnabled() const { return mEnabled; }
|
||||||
}
|
|
||||||
|
|
||||||
inline ETevOutput ColorOutput() const {
|
|
||||||
return mColorOutput;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline ETevOutput AlphaOutput() const {
|
|
||||||
return mAlphaOutput;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline ETevKSel KColorSel() const {
|
|
||||||
return mKColorSel;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline ETevKSel KAlphaSel() const {
|
|
||||||
return mKAlphaSel;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline ETevRasSel RasSel() const {
|
|
||||||
return mRasSel;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline u32 TexCoordSource() const {
|
|
||||||
return mTexCoordSource;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline CTexture* Texture() const {
|
|
||||||
return mpTexture;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline EUVAnimMode AnimMode() const {
|
|
||||||
return mAnimMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline float AnimParam(u32 ParamIndex) const {
|
|
||||||
return mAnimParams[ParamIndex];
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool IsEnabled() const {
|
|
||||||
return mEnabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Static
|
// Static
|
||||||
static TString PassTypeName(CFourCC Type);
|
static TString PassTypeName(CFourCC Type);
|
||||||
|
|
|
@ -1,49 +0,0 @@
|
||||||
#include "CMaterialSet.h"
|
|
||||||
#include "CResCache.h"
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
CMaterialSet::CMaterialSet()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
CMaterialSet::~CMaterialSet()
|
|
||||||
{
|
|
||||||
for (u32 iMat = 0; iMat < mMaterials.size(); iMat++)
|
|
||||||
delete mMaterials[iMat];
|
|
||||||
}
|
|
||||||
|
|
||||||
CMaterialSet* CMaterialSet::Clone()
|
|
||||||
{
|
|
||||||
CMaterialSet *pOut = new CMaterialSet();
|
|
||||||
|
|
||||||
pOut->mMaterials.resize(mMaterials.size());
|
|
||||||
for (u32 iMat = 0; iMat < mMaterials.size(); iMat++)
|
|
||||||
pOut->mMaterials[iMat] = mMaterials[iMat]->Clone();
|
|
||||||
|
|
||||||
return pOut;
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 CMaterialSet::NumMaterials()
|
|
||||||
{
|
|
||||||
return mMaterials.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
CMaterial* CMaterialSet::MaterialByIndex(u32 index)
|
|
||||||
{
|
|
||||||
if (index >= NumMaterials()) return nullptr;
|
|
||||||
return mMaterials[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
CMaterial* CMaterialSet::MaterialByName(const TString& name)
|
|
||||||
{
|
|
||||||
for (auto it = mMaterials.begin(); it != mMaterials.end(); it++)
|
|
||||||
if ((*it)->Name() == name) return *it;
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 CMaterialSet::MaterialIndexByName(const TString& name)
|
|
||||||
{
|
|
||||||
for (u32 iMat = 0; iMat < mMaterials.size(); iMat++)
|
|
||||||
if (mMaterials[iMat]->Name() == name) return iMat;
|
|
||||||
return -1;
|
|
||||||
}
|
|
|
@ -14,13 +14,51 @@ class CMaterialSet
|
||||||
std::vector<CMaterial*> mMaterials;
|
std::vector<CMaterial*> mMaterials;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CMaterialSet();
|
CMaterialSet() {}
|
||||||
~CMaterialSet();
|
|
||||||
CMaterialSet* Clone();
|
~CMaterialSet()
|
||||||
u32 NumMaterials();
|
{
|
||||||
CMaterial* MaterialByIndex(u32 index);
|
for (u32 iMat = 0; iMat < mMaterials.size(); iMat++)
|
||||||
CMaterial* MaterialByName(const TString& name);
|
delete mMaterials[iMat];
|
||||||
u32 MaterialIndexByName(const TString& name);
|
}
|
||||||
|
|
||||||
|
CMaterialSet* Clone()
|
||||||
|
{
|
||||||
|
CMaterialSet *pOut = new CMaterialSet();
|
||||||
|
|
||||||
|
pOut->mMaterials.resize(mMaterials.size());
|
||||||
|
for (u32 iMat = 0; iMat < mMaterials.size(); iMat++)
|
||||||
|
pOut->mMaterials[iMat] = mMaterials[iMat]->Clone();
|
||||||
|
|
||||||
|
return pOut;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 NumMaterials()
|
||||||
|
{
|
||||||
|
return mMaterials.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
CMaterial* MaterialByIndex(u32 Index)
|
||||||
|
{
|
||||||
|
if (Index >= NumMaterials()) return nullptr;
|
||||||
|
return mMaterials[Index];
|
||||||
|
}
|
||||||
|
|
||||||
|
CMaterial* MaterialByName(const TString& rkName)
|
||||||
|
{
|
||||||
|
for (auto it = mMaterials.begin(); it != mMaterials.end(); it++)
|
||||||
|
if ((*it)->Name() == rkName) return *it;
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 MaterialIndexByName(const TString& rkName)
|
||||||
|
{
|
||||||
|
for (u32 iMat = 0; iMat < mMaterials.size(); iMat++)
|
||||||
|
if (mMaterials[iMat]->Name() == rkName) return iMat;
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CMATERIALSET_H
|
#endif // CMATERIALSET_H
|
||||||
|
|
|
@ -10,161 +10,166 @@
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
|
|
||||||
CPakFile::CPakFile()
|
CPakFile::CPakFile()
|
||||||
|
: mpPak(nullptr)
|
||||||
{
|
{
|
||||||
pak = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CPakFile::CPakFile(IInputStream* pakfile)
|
CPakFile::CPakFile(IInputStream* pPakFile)
|
||||||
{
|
{
|
||||||
pak = pakfile;
|
mpPak = pPakFile;
|
||||||
if (!pak->IsValid()) return;
|
if (!mpPak->IsValid()) return;
|
||||||
|
|
||||||
version = pak->ReadLong();
|
mVersion = mpPak->ReadLong();
|
||||||
pak->Seek(0x4, SEEK_CUR);
|
mpPak->Seek(0x4, SEEK_CUR);
|
||||||
|
|
||||||
u32 namedResCount = pak->ReadLong();
|
u32 NamedResCount = mpPak->ReadLong();
|
||||||
NamedResTable.resize(namedResCount);
|
mNamedResTable.resize(NamedResCount);
|
||||||
|
|
||||||
for (u32 n = 0; n < namedResCount; n++)
|
for (u32 iName = 0; iName < NamedResCount; iName++)
|
||||||
{
|
{
|
||||||
SNamedResource *res = &NamedResTable[n];
|
SNamedResource *pRes = &mNamedResTable[iName];
|
||||||
res->resType = CFourCC(*pak);
|
pRes->Type = CFourCC(*mpPak);
|
||||||
res->resID = (u64) pak->ReadLong();
|
pRes->ID = (u64) mpPak->ReadLong();
|
||||||
u32 resNameLength = pak->ReadLong();
|
u32 resNameLength = mpPak->ReadLong();
|
||||||
res->resName = pak->ReadString(resNameLength);
|
pRes->Name = mpPak->ReadString(resNameLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 resCount = pak->ReadLong();
|
u32 ResCount = mpPak->ReadLong();
|
||||||
ResInfoTable.resize(resCount);
|
mResInfoTable.resize(ResCount);
|
||||||
|
|
||||||
for (u32 r = 0; r < resCount; r++)
|
for (u32 iRes = 0; iRes < ResCount; iRes++)
|
||||||
{
|
{
|
||||||
SResInfo *res = &ResInfoTable[r];
|
SResInfo *pRes = &mResInfoTable[iRes];
|
||||||
res->compressed = (pak->ReadLong() != 0);
|
pRes->Compressed = (mpPak->ReadLong() != 0);
|
||||||
res->resType = CFourCC(*pak);
|
pRes->Type = CFourCC(*mpPak);
|
||||||
res->resID = (u64) pak->ReadLong();
|
pRes->ID = (u64) mpPak->ReadLong();
|
||||||
res->size = pak->ReadLong();
|
pRes->Size = mpPak->ReadLong();
|
||||||
res->offset = pak->ReadLong();
|
pRes->Offset = mpPak->ReadLong();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CPakFile::~CPakFile()
|
CPakFile::~CPakFile()
|
||||||
{
|
{
|
||||||
if (pak) delete pak;
|
if (mpPak) delete mpPak;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<SNamedResource> CPakFile::getNamedResources()
|
std::vector<SNamedResource> CPakFile::NamedResources()
|
||||||
{
|
{
|
||||||
return NamedResTable;
|
return mNamedResTable;
|
||||||
}
|
}
|
||||||
|
|
||||||
SResInfo CPakFile::getResourceInfo(u64 assetID, CFourCC assetType)
|
SResInfo CPakFile::ResourceInfo(u64 AssetID, CFourCC AssetType)
|
||||||
{
|
{
|
||||||
// TODO: figure out how the game finds assets in paks, implement similar system to speed things up
|
// TODO: figure out how the game finds assets in paks, implement similar system to speed things up
|
||||||
if (ResInfoTable.empty())
|
if (mResInfoTable.empty())
|
||||||
return SResInfo();
|
return SResInfo();
|
||||||
|
|
||||||
for (u32 r = 0; r < ResInfoTable.size(); r++)
|
for (u32 iRes = 0; iRes < mResInfoTable.size(); iRes++)
|
||||||
{
|
{
|
||||||
if (((u64) (ResInfoTable[r].resID & 0xFFFFFFFF) == (u64) (assetID & 0xFFFFFFFF)) && (ResInfoTable[r].resType == assetType))
|
if (((u64) (mResInfoTable[iRes].ID & 0xFFFFFFFF) == (u64) (AssetID & 0xFFFFFFFF)) && (mResInfoTable[iRes].Type == AssetType))
|
||||||
return ResInfoTable[r];
|
return mResInfoTable[iRes];
|
||||||
}
|
}
|
||||||
|
|
||||||
return SResInfo();
|
return SResInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<u8>* CPakFile::getResource(u64 assetID, CFourCC assetType)
|
std::vector<u8>* CPakFile::Resource(u64 AssetID, CFourCC AssetType)
|
||||||
{
|
{
|
||||||
SResInfo info = getResourceInfo(assetID, assetType);
|
SResInfo Info = ResourceInfo(AssetID, AssetType);
|
||||||
|
|
||||||
// make sure SResInfo is valid
|
// make sure SResInfo is valid
|
||||||
if ((u64) (info.resID & 0xFFFFFFFF) != (u64) (assetID & 0xFFFFFFFF)) return nullptr;
|
if ((u64) (Info.ID & 0xFFFFFFFF) != (u64) (AssetID & 0xFFFFFFFF)) return nullptr;
|
||||||
else return getResource(info);
|
else return Resource(Info);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<u8>* CPakFile::getResource(SResInfo& info)
|
std::vector<u8>* CPakFile::Resource(SResInfo& rInfo)
|
||||||
{
|
{
|
||||||
pak->Seek(info.offset, SEEK_SET);
|
mpPak->Seek(rInfo.Offset, SEEK_SET);
|
||||||
std::vector<u8> *res_buf = new std::vector<u8>;
|
std::vector<u8> *pResBuf = new std::vector<u8>;
|
||||||
|
|
||||||
if (info.compressed)
|
if (rInfo.Compressed)
|
||||||
{
|
{
|
||||||
u32 decmp_size = pak->ReadLong();
|
u32 DecmpSize = mpPak->ReadLong();
|
||||||
res_buf->resize(decmp_size);
|
pResBuf->resize(DecmpSize);
|
||||||
|
|
||||||
std::vector<u8> cmp_buf(info.size - 4);
|
std::vector<u8> CmpBuf(rInfo.Size - 4);
|
||||||
pak->ReadBytes(&cmp_buf[0], info.size - 4);
|
mpPak->ReadBytes(&CmpBuf[0], rInfo.Size - 4);
|
||||||
|
|
||||||
bool dcmp = decompress(cmp_buf.data(), cmp_buf.size(), res_buf->data(), res_buf->size());
|
bool Success = Decompress(CmpBuf.data(), CmpBuf.size(), pResBuf->data(), pResBuf->size());
|
||||||
|
|
||||||
if (!dcmp) {
|
if (!Success)
|
||||||
delete res_buf;
|
{
|
||||||
|
delete pResBuf;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else {
|
else
|
||||||
res_buf->resize(info.size);
|
{
|
||||||
pak->ReadBytes(res_buf->data(), info.size);
|
pResBuf->resize(rInfo.Size);
|
||||||
|
mpPak->ReadBytes(pResBuf->data(), rInfo.Size);
|
||||||
}
|
}
|
||||||
|
|
||||||
return res_buf;
|
return pResBuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CPakFile::decompress(u8 *src, u32 src_len, u8 *dst, u32 dst_len)
|
bool CPakFile::Decompress(u8 *pSrc, u32 SrcLen, u8 *pDst, u32 DstLen)
|
||||||
{
|
{
|
||||||
if ((src[0] == 0x78) && (src[1] == 0xda))
|
if ((pSrc[0] == 0x78) && (pSrc[1] == 0xda))
|
||||||
{
|
{
|
||||||
// zlib
|
// zlib
|
||||||
z_stream z;
|
z_stream z;
|
||||||
z.zalloc = Z_NULL;
|
z.zalloc = Z_NULL;
|
||||||
z.zfree = Z_NULL;
|
z.zfree = Z_NULL;
|
||||||
z.opaque = Z_NULL;
|
z.opaque = Z_NULL;
|
||||||
z.avail_in = src_len;
|
z.avail_in = SrcLen;
|
||||||
z.next_in = src;
|
z.next_in = pSrc;
|
||||||
z.avail_out = dst_len;
|
z.avail_out = DstLen;
|
||||||
z.next_out = dst;
|
z.next_out = pDst;
|
||||||
|
|
||||||
s32 ret = inflateInit(&z);
|
s32 Ret = inflateInit(&z);
|
||||||
|
|
||||||
if (ret == Z_OK)
|
if (Ret == Z_OK)
|
||||||
{
|
{
|
||||||
ret = inflate(&z, Z_NO_FLUSH);
|
Ret = inflate(&z, Z_NO_FLUSH);
|
||||||
|
|
||||||
if ((ret == Z_OK) || (ret == Z_STREAM_END))
|
if ((Ret == Z_OK) || (Ret == Z_STREAM_END))
|
||||||
ret = inflateEnd(&z);
|
Ret = inflateEnd(&z);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ret != Z_OK) && (ret != Z_STREAM_END)) {
|
if ((Ret != Z_OK) && (Ret != Z_STREAM_END)) {
|
||||||
Log::Error("zlib error: " + TString::FromInt32(ret, 0, 10));
|
Log::Error("zlib error: " + TString::FromInt32(Ret, 0, 10));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
else return true;
|
else return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
// LZO
|
// LZO
|
||||||
lzo_uint decmp;
|
lzo_uint Decmp;
|
||||||
s32 ret;
|
s32 Ret;
|
||||||
u8 *src_end = src + src_len;
|
u8 *pSrcEnd = pSrc + SrcLen;
|
||||||
u8 *dst_end = dst + dst_len;
|
u8 *pDstEnd = pDst + DstLen;
|
||||||
lzo_init();
|
lzo_init();
|
||||||
|
|
||||||
while ((src < src_end) && (dst < dst_end)) {
|
while ((pSrc < pSrcEnd) && (pDst < pDstEnd))
|
||||||
short block_size;
|
{
|
||||||
memcpy(&block_size, src, 2);
|
short BlockSize;
|
||||||
if (IOUtil::kSystemEndianness == IOUtil::eLittleEndian) IOUtil::SwapBytes(block_size);
|
memcpy(&BlockSize, pSrc, 2);
|
||||||
src += 2;
|
if (IOUtil::kSystemEndianness == IOUtil::eLittleEndian) IOUtil::SwapBytes(BlockSize);
|
||||||
|
pSrc += 2;
|
||||||
|
|
||||||
ret = lzo1x_decompress(src, block_size, dst, &decmp, LZO1X_MEM_DECOMPRESS);
|
Ret = lzo1x_decompress(pSrc, BlockSize, pDst, &Decmp, LZO1X_MEM_DECOMPRESS);
|
||||||
if (ret != LZO_E_OK) break;
|
if (Ret != LZO_E_OK) break;
|
||||||
src += block_size;
|
pSrc += BlockSize;
|
||||||
dst += decmp;
|
pDst += Decmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret != LZO_E_OK) {
|
if (Ret != LZO_E_OK)
|
||||||
Log::Error("LZO error: " + TString::FromInt32(ret, 0, 10));
|
{
|
||||||
|
Log::Error("LZO error: " + TString::FromInt32(Ret, 0, 10));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,22 +10,22 @@
|
||||||
class CPakFile
|
class CPakFile
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
u32 version;
|
u32 mVersion;
|
||||||
std::vector<SNamedResource> NamedResTable;
|
std::vector<SNamedResource> mNamedResTable;
|
||||||
std::vector<SResInfo> ResInfoTable;
|
std::vector<SResInfo> mResInfoTable;
|
||||||
IInputStream* pak;
|
IInputStream* mpPak;
|
||||||
|
|
||||||
bool decompress(u8 *src, u32 src_len, u8 *dst, u32 dst_len);
|
bool Decompress(u8 *pSrc, u32 SrcLen, u8 *pDst, u32 DstLen);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CPakFile();
|
CPakFile();
|
||||||
CPakFile(IInputStream* pakfile);
|
CPakFile(IInputStream* pPakFile);
|
||||||
~CPakFile();
|
~CPakFile();
|
||||||
|
|
||||||
std::vector<SNamedResource> getNamedResources();
|
std::vector<SNamedResource> NamedResources();
|
||||||
SResInfo getResourceInfo(u64 assetID, CFourCC assetType);
|
SResInfo ResourceInfo(u64 AssetID, CFourCC AssetType);
|
||||||
std::vector<u8>* getResource(u64 assetID, CFourCC assetType);
|
std::vector<u8>* Resource(u64 AssetID, CFourCC AssetType);
|
||||||
std::vector<u8>* getResource(SResInfo& info);
|
std::vector<u8>* Resource(SResInfo& rInfo);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CPAKFILE_H
|
#endif // CPAKFILE_H
|
||||||
|
|
|
@ -17,8 +17,8 @@
|
||||||
#include <boost/filesystem.hpp>
|
#include <boost/filesystem.hpp>
|
||||||
|
|
||||||
CResCache::CResCache()
|
CResCache::CResCache()
|
||||||
|
: mpPak(nullptr)
|
||||||
{
|
{
|
||||||
mpPak = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CResCache::~CResCache()
|
CResCache::~CResCache()
|
||||||
|
@ -34,11 +34,11 @@ void CResCache::Clean()
|
||||||
// I couldn't get this to work properly using reverse iterators, lol.
|
// I couldn't get this to work properly using reverse iterators, lol.
|
||||||
// Resources get cached after their dependencies, which is why I go backwards
|
// Resources get cached after their dependencies, which is why I go backwards
|
||||||
// while loop is to ensure -all- unused resources are cleaned. Not sure of a better way to do it.
|
// while loop is to ensure -all- unused resources are cleaned. Not sure of a better way to do it.
|
||||||
int numResourcesCleaned = 1;
|
int NumResourcesCleaned = 1;
|
||||||
|
|
||||||
while (numResourcesCleaned)
|
while (NumResourcesCleaned)
|
||||||
{
|
{
|
||||||
numResourcesCleaned = 0;
|
NumResourcesCleaned = 0;
|
||||||
|
|
||||||
for (auto it = mResourceCache.end(); it != mResourceCache.begin();)
|
for (auto it = mResourceCache.end(); it != mResourceCache.begin();)
|
||||||
{
|
{
|
||||||
|
@ -47,41 +47,42 @@ void CResCache::Clean()
|
||||||
{
|
{
|
||||||
delete it->second;
|
delete it->second;
|
||||||
it = mResourceCache.erase(it);
|
it = mResourceCache.erase(it);
|
||||||
numResourcesCleaned++;
|
NumResourcesCleaned++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Log::Write(std::to_string(mResourceCache.size()) + " resources loaded");
|
Log::Write(std::to_string(mResourceCache.size()) + " resources loaded");
|
||||||
}
|
}
|
||||||
|
|
||||||
void CResCache::SetFolder(TString path)
|
void CResCache::SetFolder(TString Path)
|
||||||
{
|
{
|
||||||
path.EnsureEndsWith("/");
|
Path.EnsureEndsWith("/");
|
||||||
mResSource.Path = path;
|
mResSource.Path = Path;
|
||||||
mResSource.Source = SResSource::Folder;
|
mResSource.Source = SResSource::eFolder;
|
||||||
Log::Write("Set resource folder: " + path);
|
Log::Write("Set resource folder: " + Path);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CResCache::SetPak(const TString& path)
|
void CResCache::SetPak(const TString& rkPath)
|
||||||
{
|
{
|
||||||
CFileInStream *pakfile = new CFileInStream(path.ToStdString(), IOUtil::eBigEndian);
|
CFileInStream *pPakFile = new CFileInStream(rkPath.ToStdString(), IOUtil::eBigEndian);
|
||||||
if (!pakfile->IsValid())
|
|
||||||
|
if (!pPakFile->IsValid())
|
||||||
{
|
{
|
||||||
Log::Error("Couldn't load pak file: " + path);
|
Log::Error("Couldn't load pak file: " + rkPath);
|
||||||
delete pakfile;
|
delete pPakFile;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mpPak) delete mpPak;
|
if (mpPak) delete mpPak;
|
||||||
mpPak = new CPakFile(pakfile);
|
mpPak = new CPakFile(pPakFile);
|
||||||
mResSource.Path = path;
|
mResSource.Path = rkPath;
|
||||||
mResSource.Source = SResSource::PakFile;
|
mResSource.Source = SResSource::ePakFile;
|
||||||
Log::Write("Loaded pak file: " + path);
|
Log::Write("Loaded pak file: " + rkPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CResCache::SetResSource(SResSource& ResSource)
|
void CResCache::SetResSource(SResSource& rResSource)
|
||||||
{
|
{
|
||||||
mResSource = ResSource;
|
mResSource = rResSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
SResSource CResCache::GetResSource()
|
SResSource CResCache::GetResSource()
|
||||||
|
@ -94,7 +95,7 @@ TString CResCache::GetSourcePath()
|
||||||
return mResSource.Path;
|
return mResSource.Path;
|
||||||
}
|
}
|
||||||
|
|
||||||
CResource* CResCache::GetResource(CUniqueID ResID, CFourCC type)
|
CResource* CResCache::GetResource(CUniqueID ResID, CFourCC Type)
|
||||||
{
|
{
|
||||||
if (!ResID.IsValid()) return nullptr;
|
if (!ResID.IsValid()) return nullptr;
|
||||||
|
|
||||||
|
@ -107,110 +108,111 @@ CResource* CResCache::GetResource(CUniqueID ResID, CFourCC type)
|
||||||
TString Source;
|
TString Source;
|
||||||
|
|
||||||
// Load from pak
|
// Load from pak
|
||||||
if (mResSource.Source == SResSource::PakFile)
|
if (mResSource.Source == SResSource::ePakFile)
|
||||||
{
|
{
|
||||||
pBuffer = mpPak->getResource(ResID.ToLongLong(), type);
|
pBuffer = mpPak->Resource(ResID.ToLongLong(), Type);
|
||||||
Source = ResID.ToString() + "." + type.ToString();
|
Source = ResID.ToString() + "." + Type.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load from folder
|
// Load from folder
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Source = mResSource.Path + ResID.ToString() + "." + type.ToString();
|
Source = mResSource.Path + ResID.ToString() + "." + Type.ToString();
|
||||||
CFileInStream file(Source.ToStdString(), IOUtil::eBigEndian);
|
CFileInStream File(Source.ToStdString(), IOUtil::eBigEndian);
|
||||||
if (!file.IsValid())
|
|
||||||
|
if (!File.IsValid())
|
||||||
{
|
{
|
||||||
Log::Error("Couldn't open resource: " + ResID.ToString() + "." + type.ToString());
|
Log::Error("Couldn't open resource: " + ResID.ToString() + "." + Type.ToString());
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
pBuffer = new std::vector<u8>;
|
pBuffer = new std::vector<u8>;
|
||||||
pBuffer->resize(file.Size());
|
pBuffer->resize(File.Size());
|
||||||
file.ReadBytes(pBuffer->data(), pBuffer->size());
|
File.ReadBytes(pBuffer->data(), pBuffer->size());
|
||||||
}
|
}
|
||||||
if (!pBuffer) return nullptr;
|
if (!pBuffer) return nullptr;
|
||||||
|
|
||||||
// Load resource
|
// Load resource
|
||||||
CMemoryInStream mem(pBuffer->data(), pBuffer->size(), IOUtil::eBigEndian);
|
CMemoryInStream Mem(pBuffer->data(), pBuffer->size(), IOUtil::eBigEndian);
|
||||||
mem.SetSourceString(*Source.GetFileName());
|
Mem.SetSourceString(*Source.GetFileName());
|
||||||
CResource *Res = nullptr;
|
CResource *pRes = nullptr;
|
||||||
bool SupportedFormat = true;
|
bool SupportedFormat = true;
|
||||||
|
|
||||||
if (type == "CMDL") Res = CModelLoader::LoadCMDL(mem);
|
if (Type == "CMDL") pRes = CModelLoader::LoadCMDL(Mem);
|
||||||
else if (type == "TXTR") Res = CTextureDecoder::LoadTXTR(mem);
|
else if (Type == "TXTR") pRes = CTextureDecoder::LoadTXTR(Mem);
|
||||||
else if (type == "ANCS") Res = CAnimSetLoader::LoadANCS(mem);
|
else if (Type == "ANCS") pRes = CAnimSetLoader::LoadANCS(Mem);
|
||||||
else if (type == "CHAR") Res = CAnimSetLoader::LoadCHAR(mem);
|
else if (Type == "CHAR") pRes = CAnimSetLoader::LoadCHAR(Mem);
|
||||||
else if (type == "MREA") Res = CAreaLoader::LoadMREA(mem);
|
else if (Type == "MREA") pRes = CAreaLoader::LoadMREA(Mem);
|
||||||
else if (type == "MLVL") Res = CWorldLoader::LoadMLVL(mem);
|
else if (Type == "MLVL") pRes = CWorldLoader::LoadMLVL(Mem);
|
||||||
else if (type == "STRG") Res = CStringLoader::LoadSTRG(mem);
|
else if (Type == "STRG") pRes = CStringLoader::LoadSTRG(Mem);
|
||||||
else if (type == "FONT") Res = CFontLoader::LoadFONT(mem);
|
else if (Type == "FONT") pRes = CFontLoader::LoadFONT(Mem);
|
||||||
else if (type == "SCAN") Res = CScanLoader::LoadSCAN(mem);
|
else if (Type == "SCAN") pRes = CScanLoader::LoadSCAN(Mem);
|
||||||
else if (type == "DCLN") Res = CCollisionLoader::LoadDCLN(mem);
|
else if (Type == "DCLN") pRes = CCollisionLoader::LoadDCLN(Mem);
|
||||||
else if (type == "EGMC") Res = CPoiToWorldLoader::LoadEGMC(mem);
|
else if (Type == "EGMC") pRes = CPoiToWorldLoader::LoadEGMC(Mem);
|
||||||
else SupportedFormat = false;
|
else SupportedFormat = false;
|
||||||
|
|
||||||
// Log errors
|
// Log errors
|
||||||
if (!SupportedFormat)
|
if (!SupportedFormat)
|
||||||
Log::Write("Unsupported format; unable to load " + type.ToString() + " " + ResID.ToString());
|
Log::Write("Unsupported format; unable to load " + Type.ToString() + " " + ResID.ToString());
|
||||||
|
|
||||||
if (!Res) Res = new CResource(); // Default for invalid resource or unsupported format
|
if (!pRes) pRes = new CResource(); // Default for invalid resource or unsupported format
|
||||||
|
|
||||||
// Add to cache and cleanup
|
// Add to cache and cleanup
|
||||||
Res->mID = ResID;
|
pRes->mID = ResID;
|
||||||
Res->mResSource = Source;
|
pRes->mResSource = Source;
|
||||||
mResourceCache[ResID.ToLongLong()] = Res;
|
mResourceCache[ResID.ToLongLong()] = pRes;
|
||||||
delete pBuffer;
|
delete pBuffer;
|
||||||
return Res;
|
return pRes;
|
||||||
}
|
}
|
||||||
|
|
||||||
CResource* CResCache::GetResource(const TString& ResPath)
|
CResource* CResCache::GetResource(const TString& rkResPath)
|
||||||
{
|
{
|
||||||
// Since this function takes a string argument it always loads directly from a file - no pak
|
// Since this function takes a string argument it always loads directly from a file - no pak
|
||||||
CUniqueID ResID = ResPath.Hash64();
|
CUniqueID ResID = rkResPath.Hash64();
|
||||||
|
|
||||||
auto got = mResourceCache.find(ResID.ToLongLong());
|
auto Got = mResourceCache.find(ResID.ToLongLong());
|
||||||
|
|
||||||
if (got != mResourceCache.end())
|
if (Got != mResourceCache.end())
|
||||||
return got->second;
|
return Got->second;
|
||||||
|
|
||||||
CFileInStream file(ResPath.ToStdString(), IOUtil::eBigEndian);
|
CFileInStream File(rkResPath.ToStdString(), IOUtil::eBigEndian);
|
||||||
if (!file.IsValid())
|
if (!File.IsValid())
|
||||||
{
|
{
|
||||||
Log::Error("Couldn't open resource: " + ResPath);
|
Log::Error("Couldn't open resource: " + rkResPath);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save old ResSource to restore later
|
// Save old ResSource to restore later
|
||||||
const SResSource OldSource = mResSource;
|
const SResSource OldSource = mResSource;
|
||||||
mResSource.Source = SResSource::Folder;
|
mResSource.Source = SResSource::eFolder;
|
||||||
mResSource.Path = ResPath.GetFileDirectory();
|
mResSource.Path = rkResPath.GetFileDirectory();
|
||||||
|
|
||||||
// Load resource
|
// Load resource
|
||||||
CResource *Res = nullptr;
|
CResource *pRes = nullptr;
|
||||||
CFourCC type = ResPath.GetFileExtension().ToUpper();
|
CFourCC Type = rkResPath.GetFileExtension().ToUpper();
|
||||||
bool SupportedFormat = true;
|
bool SupportedFormat = true;
|
||||||
|
|
||||||
if (type == "CMDL") Res = CModelLoader::LoadCMDL(file);
|
if (Type == "CMDL") pRes = CModelLoader::LoadCMDL(File);
|
||||||
else if (type == "TXTR") Res = CTextureDecoder::LoadTXTR(file);
|
else if (Type == "TXTR") pRes = CTextureDecoder::LoadTXTR(File);
|
||||||
else if (type == "ANCS") Res = CAnimSetLoader::LoadANCS(file);
|
else if (Type == "ANCS") pRes = CAnimSetLoader::LoadANCS(File);
|
||||||
else if (type == "CHAR") Res = CAnimSetLoader::LoadCHAR(file);
|
else if (Type == "CHAR") pRes = CAnimSetLoader::LoadCHAR(File);
|
||||||
else if (type == "MREA") Res = CAreaLoader::LoadMREA(file);
|
else if (Type == "MREA") pRes = CAreaLoader::LoadMREA(File);
|
||||||
else if (type == "MLVL") Res = CWorldLoader::LoadMLVL(file);
|
else if (Type == "MLVL") pRes = CWorldLoader::LoadMLVL(File);
|
||||||
else if (type == "STRG") Res = CStringLoader::LoadSTRG(file);
|
else if (Type == "STRG") pRes = CStringLoader::LoadSTRG(File);
|
||||||
else if (type == "FONT") Res = CFontLoader::LoadFONT(file);
|
else if (Type == "FONT") pRes = CFontLoader::LoadFONT(File);
|
||||||
else if (type == "SCAN") Res = CScanLoader::LoadSCAN(file);
|
else if (Type == "SCAN") pRes = CScanLoader::LoadSCAN(File);
|
||||||
else if (type == "DCLN") Res = CCollisionLoader::LoadDCLN(file);
|
else if (Type == "DCLN") pRes = CCollisionLoader::LoadDCLN(File);
|
||||||
else if (type == "EGMC") Res = CPoiToWorldLoader::LoadEGMC(file);
|
else if (Type == "EGMC") pRes = CPoiToWorldLoader::LoadEGMC(File);
|
||||||
else SupportedFormat = false;
|
else SupportedFormat = false;
|
||||||
|
|
||||||
if (!Res) Res = new CResource(); // Default for unsupported formats
|
if (!pRes) pRes = new CResource(); // Default for unsupported formats
|
||||||
|
|
||||||
// Add to cache and cleanup
|
// Add to cache and cleanup
|
||||||
Res->mID = *ResPath;
|
pRes->mID = *rkResPath;
|
||||||
Res->mResSource = ResPath;
|
pRes->mResSource = rkResPath;
|
||||||
mResourceCache[ResID.ToLongLong()] = Res;
|
mResourceCache[ResID.ToLongLong()] = pRes;
|
||||||
mResSource = OldSource;
|
mResSource = OldSource;
|
||||||
return Res;
|
return pRes;
|
||||||
}
|
}
|
||||||
|
|
||||||
CFourCC CResCache::FindResourceType(CUniqueID ResID, const TStringList& rkPossibleTypes)
|
CFourCC CResCache::FindResourceType(CUniqueID ResID, const TStringList& rkPossibleTypes)
|
||||||
|
@ -220,13 +222,13 @@ CFourCC CResCache::FindResourceType(CUniqueID ResID, const TStringList& rkPossib
|
||||||
return CFourCC(rkPossibleTypes.front());
|
return CFourCC(rkPossibleTypes.front());
|
||||||
|
|
||||||
// Determine extension from pak
|
// Determine extension from pak
|
||||||
if (mResSource.Source == SResSource::PakFile)
|
if (mResSource.Source == SResSource::ePakFile)
|
||||||
{
|
{
|
||||||
for (auto it = rkPossibleTypes.begin(); it != rkPossibleTypes.end(); it++)
|
for (auto it = rkPossibleTypes.begin(); it != rkPossibleTypes.end(); it++)
|
||||||
{
|
{
|
||||||
SResInfo ResInfo = mpPak->getResourceInfo(ResID.ToLongLong(), CFourCC(*it));
|
SResInfo ResInfo = mpPak->ResourceInfo(ResID.ToLongLong(), CFourCC(*it));
|
||||||
|
|
||||||
if (ResInfo.resType != "NULL")
|
if (ResInfo.Type != "NULL")
|
||||||
return CFourCC(*it);
|
return CFourCC(*it);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -251,20 +253,20 @@ CFourCC CResCache::FindResourceType(CUniqueID ResID, const TStringList& rkPossib
|
||||||
void CResCache::CacheResource(CResource *pRes)
|
void CResCache::CacheResource(CResource *pRes)
|
||||||
{
|
{
|
||||||
u64 ID = pRes->ResID().ToLongLong();
|
u64 ID = pRes->ResID().ToLongLong();
|
||||||
auto got = mResourceCache.find(ID);
|
auto Got = mResourceCache.find(ID);
|
||||||
|
|
||||||
if (got != mResourceCache.end())
|
if (Got != mResourceCache.end())
|
||||||
mResourceCache[ID] = pRes;
|
mResourceCache[ID] = pRes;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CResCache::DeleteResource(CUniqueID ResID)
|
void CResCache::DeleteResource(CUniqueID ResID)
|
||||||
{
|
{
|
||||||
auto got = mResourceCache.find(ResID.ToLongLong());
|
auto Got = mResourceCache.find(ResID.ToLongLong());
|
||||||
|
|
||||||
if (got != mResourceCache.end())
|
if (Got != mResourceCache.end())
|
||||||
{
|
{
|
||||||
delete got->second;
|
delete Got->second;
|
||||||
mResourceCache.erase(got, got);
|
mResourceCache.erase(Got, Got);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ struct SResSource
|
||||||
{
|
{
|
||||||
TString Path;
|
TString Path;
|
||||||
enum {
|
enum {
|
||||||
Folder, PakFile
|
eFolder, ePakFile
|
||||||
} Source;
|
} Source;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -25,13 +25,13 @@ public:
|
||||||
CResCache();
|
CResCache();
|
||||||
~CResCache();
|
~CResCache();
|
||||||
void Clean();
|
void Clean();
|
||||||
void SetFolder(TString path);
|
void SetFolder(TString Path);
|
||||||
void SetPak(const TString& path);
|
void SetPak(const TString& rkPath);
|
||||||
void SetResSource(SResSource& ResSource);
|
void SetResSource(SResSource& rResSource);
|
||||||
SResSource GetResSource();
|
SResSource GetResSource();
|
||||||
TString GetSourcePath();
|
TString GetSourcePath();
|
||||||
CResource* GetResource(CUniqueID ResID, CFourCC type);
|
CResource* GetResource(CUniqueID ResID, CFourCC Type);
|
||||||
CResource* GetResource(const TString& ResPath);
|
CResource* GetResource(const TString& rkResPath);
|
||||||
CFourCC FindResourceType(CUniqueID ResID, const TStringList& rkPossibleTypes);
|
CFourCC FindResourceType(CUniqueID ResID, const TStringList& rkPossibleTypes);
|
||||||
void CacheResource(CResource *pRes);
|
void CacheResource(CResource *pRes);
|
||||||
void DeleteResource(CUniqueID ResID);
|
void DeleteResource(CUniqueID ResID);
|
||||||
|
|
|
@ -1,45 +1,4 @@
|
||||||
#include "CResource.h"
|
#include "CResource.h"
|
||||||
#include "CResCache.h"
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
CResource::CResource()
|
|
||||||
{
|
|
||||||
mRefCount = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
CResource::~CResource()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
TString CResource::Source()
|
|
||||||
{
|
|
||||||
return mResSource.GetFileName();
|
|
||||||
}
|
|
||||||
|
|
||||||
TString CResource::FullSource()
|
|
||||||
{
|
|
||||||
return mResSource;
|
|
||||||
}
|
|
||||||
|
|
||||||
CUniqueID CResource::ResID()
|
|
||||||
{
|
|
||||||
return mID;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CResource::Lock()
|
|
||||||
{
|
|
||||||
mRefCount++;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CResource::Release()
|
|
||||||
{
|
|
||||||
mRefCount--;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CResource::IsValidResource()
|
|
||||||
{
|
|
||||||
return (Type() != eResource);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ************ STATIC ************
|
// ************ STATIC ************
|
||||||
EResType CResource::ResTypeForExtension(CFourCC Extension)
|
EResType CResource::ResTypeForExtension(CFourCC Extension)
|
||||||
|
|
|
@ -35,14 +35,16 @@ class CResource
|
||||||
int mRefCount;
|
int mRefCount;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CResource();
|
CResource() : mRefCount(0) {}
|
||||||
virtual ~CResource();
|
virtual ~CResource() {}
|
||||||
TString Source();
|
|
||||||
TString FullSource();
|
inline TString Source() const { return mResSource.GetFileName(); }
|
||||||
CUniqueID ResID();
|
inline TString FullSource() const { return mResSource; }
|
||||||
void Lock();
|
inline CUniqueID ResID() const { return mID; }
|
||||||
void Release();
|
inline void Lock() { mRefCount++; }
|
||||||
bool IsValidResource();
|
inline void Release() { mRefCount--; }
|
||||||
|
inline bool IsValidResource() { return (Type() != eResource); }
|
||||||
|
|
||||||
static EResType ResTypeForExtension(CFourCC Extension);
|
static EResType ResTypeForExtension(CFourCC Extension);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,39 +0,0 @@
|
||||||
#include "CScan.h"
|
|
||||||
|
|
||||||
CScan::CScan()
|
|
||||||
{
|
|
||||||
mpFrame = nullptr;
|
|
||||||
mpStringTable = nullptr;
|
|
||||||
mIsSlow = false;
|
|
||||||
mIsImportant = false;
|
|
||||||
mCategory = eNone;
|
|
||||||
}
|
|
||||||
|
|
||||||
CScan::~CScan()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
EGame CScan::Version()
|
|
||||||
{
|
|
||||||
return mVersion;
|
|
||||||
}
|
|
||||||
|
|
||||||
CStringTable* CScan::ScanText()
|
|
||||||
{
|
|
||||||
return mpStringTable;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CScan::IsImportant()
|
|
||||||
{
|
|
||||||
return mIsImportant;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CScan::IsSlow()
|
|
||||||
{
|
|
||||||
return mIsSlow;
|
|
||||||
}
|
|
||||||
|
|
||||||
CScan::ELogbookCategory CScan::LogbookCategory()
|
|
||||||
{
|
|
||||||
return mCategory;
|
|
||||||
}
|
|
|
@ -31,13 +31,20 @@ private:
|
||||||
ELogbookCategory mCategory;
|
ELogbookCategory mCategory;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CScan();
|
CScan()
|
||||||
~CScan();
|
: CResource()
|
||||||
EGame Version();
|
, mpFrame(nullptr)
|
||||||
CStringTable* ScanText();
|
, mpStringTable(nullptr)
|
||||||
bool IsImportant();
|
, mIsSlow(false)
|
||||||
bool IsSlow();
|
, mIsImportant(false)
|
||||||
ELogbookCategory LogbookCategory();
|
, mCategory(eNone)
|
||||||
|
{}
|
||||||
|
|
||||||
|
EGame Version() const { return mVersion; }
|
||||||
|
CStringTable* ScanText() const { return mpStringTable; }
|
||||||
|
bool IsImportant() const { return mIsImportant; }
|
||||||
|
bool IsSlow() const { return mIsSlow; }
|
||||||
|
ELogbookCategory LogbookCategory() const { return mCategory; }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CSCAN_H
|
#endif // CSCAN_H
|
||||||
|
|
|
@ -1,52 +0,0 @@
|
||||||
#include "CStringTable.h"
|
|
||||||
|
|
||||||
CStringTable::CStringTable() : CResource()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
CStringTable::~CStringTable()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
CResource* CStringTable::MakeCopy(CResCache*)
|
|
||||||
{
|
|
||||||
// Not using parameter 1 (CResCache* - pResCache)
|
|
||||||
return new CStringTable(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ************ SETTERS ************
|
|
||||||
u32 CStringTable::GetStringCount()
|
|
||||||
{
|
|
||||||
return mNumStrings;
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 CStringTable::GetLangCount()
|
|
||||||
{
|
|
||||||
return mLangTables.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
CFourCC CStringTable::GetLangTag(u32 Index)
|
|
||||||
{
|
|
||||||
return mLangTables[Index].Language;
|
|
||||||
}
|
|
||||||
|
|
||||||
TWideString CStringTable::GetString(CFourCC Lang, u32 StringIndex)
|
|
||||||
{
|
|
||||||
for (u32 iLang = 0; iLang < GetLangCount(); iLang++)
|
|
||||||
{
|
|
||||||
if (GetLangTag(iLang) == Lang)
|
|
||||||
return GetString(iLang, StringIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
return std::wstring();
|
|
||||||
}
|
|
||||||
|
|
||||||
TWideString CStringTable::GetString(u32 LangIndex, u32 StringIndex)
|
|
||||||
{
|
|
||||||
return mLangTables[LangIndex].Strings[StringIndex];
|
|
||||||
}
|
|
||||||
|
|
||||||
TString CStringTable::GetStringName(u32 StringIndex)
|
|
||||||
{
|
|
||||||
return mStringNames[StringIndex];
|
|
||||||
}
|
|
|
@ -23,17 +23,24 @@ class CStringTable : public CResource
|
||||||
std::vector<SLangTable> mLangTables;
|
std::vector<SLangTable> mLangTables;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CStringTable();
|
CStringTable() {}
|
||||||
~CStringTable();
|
|
||||||
CResource* MakeCopy(CResCache *pCopyCache);
|
|
||||||
|
|
||||||
// Getters
|
inline u32 NumStrings() const { return mLangTables.size(); }
|
||||||
u32 GetStringCount();
|
inline u32 NumLanguages() const { return mLangTables.size(); }
|
||||||
u32 GetLangCount();
|
inline CFourCC LanguageTag(u32 Index) const { return mLangTables[Index].Language; }
|
||||||
CFourCC GetLangTag(u32 Index);
|
inline TWideString String(u32 LangIndex, u32 StringIndex) const { return mLangTables[LangIndex].Strings[StringIndex]; }
|
||||||
TWideString GetString(CFourCC Lang, u32 StringIndex);
|
inline TString StringName(u32 StringIndex) const { return mStringNames[StringIndex]; }
|
||||||
TWideString GetString(u32 LangIndex, u32 StringIndex);
|
|
||||||
TString GetStringName(u32 StringIndex);
|
TWideString String(CFourCC Lang, u32 StringIndex) const
|
||||||
|
{
|
||||||
|
for (u32 iLang = 0; iLang < NumLanguages(); iLang++)
|
||||||
|
{
|
||||||
|
if (LanguageTag(iLang) == Lang)
|
||||||
|
return String(iLang, StringIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TWideString();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CSTRINGTABLE_H
|
#endif // CSTRINGTABLE_H
|
||||||
|
|
|
@ -1,51 +1,32 @@
|
||||||
#include "CTexture.h"
|
#include "CTexture.h"
|
||||||
|
|
||||||
CTexture::CTexture() : CResource()
|
CTexture::CTexture()
|
||||||
|
: CResource()
|
||||||
|
, mTexelFormat(eRGBA8)
|
||||||
|
, mSourceTexelFormat(eRGBA8)
|
||||||
|
, mWidth(0)
|
||||||
|
, mHeight(0)
|
||||||
|
, mNumMipMaps(0)
|
||||||
|
, mLinearSize(0)
|
||||||
|
, mBufferExists(false)
|
||||||
|
, mpImgDataBuffer(nullptr)
|
||||||
|
, mImgDataSize(0)
|
||||||
|
, mGLBufferExists(false)
|
||||||
{
|
{
|
||||||
mTexelFormat = eRGBA8;
|
|
||||||
mSourceTexelFormat = eRGBA8;
|
|
||||||
mWidth = 0;
|
|
||||||
mHeight = 0;
|
|
||||||
mNumMipMaps = 0;
|
|
||||||
mLinearSize = 0;
|
|
||||||
|
|
||||||
mBufferExists = false;
|
|
||||||
mImgDataBuffer = nullptr;
|
|
||||||
mImgDataSize = 0;
|
|
||||||
|
|
||||||
mGLBufferExists = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
CTexture::CTexture(const CTexture& Source)
|
|
||||||
{
|
|
||||||
mTexelFormat = Source.mTexelFormat;
|
|
||||||
mSourceTexelFormat = Source.mSourceTexelFormat;
|
|
||||||
mWidth = Source.mWidth;
|
|
||||||
mHeight = Source.mHeight;
|
|
||||||
mLinearSize = Source.mLinearSize;
|
|
||||||
|
|
||||||
mBufferExists = Source.mBufferExists;
|
|
||||||
mImgDataSize = Source.mImgDataSize;
|
|
||||||
mImgDataBuffer = new u8[mImgDataSize];
|
|
||||||
memcpy(mImgDataBuffer, Source.mImgDataBuffer, mImgDataSize);
|
|
||||||
|
|
||||||
mGLBufferExists = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CTexture::CTexture(u32 Width, u32 Height)
|
CTexture::CTexture(u32 Width, u32 Height)
|
||||||
|
: mTexelFormat(eRGBA8)
|
||||||
|
, mSourceTexelFormat(eRGBA8)
|
||||||
|
, mWidth((u16) Width)
|
||||||
|
, mHeight((u16) Height)
|
||||||
|
, mNumMipMaps(1)
|
||||||
|
, mLinearSize(Width * Height * 4)
|
||||||
|
, mBufferExists(false)
|
||||||
|
, mpImgDataBuffer(nullptr)
|
||||||
|
, mImgDataSize(0)
|
||||||
|
, mGLBufferExists(false)
|
||||||
{
|
{
|
||||||
mTexelFormat = eRGBA8;
|
|
||||||
mSourceTexelFormat = eRGBA8;
|
|
||||||
mWidth = (u16) Width;
|
|
||||||
mHeight = (u16) Height;
|
|
||||||
mNumMipMaps = 1;
|
|
||||||
mLinearSize = Width * Height * 4;
|
|
||||||
|
|
||||||
mBufferExists = false;
|
|
||||||
mImgDataBuffer = nullptr;
|
|
||||||
mImgDataSize = 0;
|
|
||||||
|
|
||||||
mGLBufferExists = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CTexture::~CTexture()
|
CTexture::~CTexture()
|
||||||
|
@ -61,8 +42,8 @@ bool CTexture::BufferGL()
|
||||||
GLenum GLFormat, GLType;
|
GLenum GLFormat, GLType;
|
||||||
bool IsCompressed = false;
|
bool IsCompressed = false;
|
||||||
|
|
||||||
switch (mTexelFormat) {
|
switch (mTexelFormat)
|
||||||
|
{
|
||||||
case eLuminance:
|
case eLuminance:
|
||||||
GLFormat = GL_LUMINANCE;
|
GLFormat = GL_LUMINANCE;
|
||||||
GLType = GL_UNSIGNED_BYTE;
|
GLType = GL_UNSIGNED_BYTE;
|
||||||
|
@ -97,7 +78,7 @@ bool CTexture::BufferGL()
|
||||||
|
|
||||||
for (u32 iMip = 0; iMip < mNumMipMaps; iMip++)
|
for (u32 iMip = 0; iMip < mNumMipMaps; iMip++)
|
||||||
{
|
{
|
||||||
GLvoid *pData = (mBufferExists) ? (mImgDataBuffer + MipOffset) : NULL;
|
GLvoid *pData = (mBufferExists) ? (mpImgDataBuffer + MipOffset) : NULL;
|
||||||
|
|
||||||
if (!IsCompressed)
|
if (!IsCompressed)
|
||||||
glTexImage2D(GL_TEXTURE_2D, iMip, GLFormat, MipW, MipH, 0, GLFormat, GLType, pData);
|
glTexImage2D(GL_TEXTURE_2D, iMip, GLFormat, MipW, MipH, 0, GLFormat, GLType, pData);
|
||||||
|
@ -147,16 +128,16 @@ void CTexture::Resize(u32 Width, u32 Height)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float CTexture::ReadTexelAlpha(const CVector2f& TexCoord)
|
float CTexture::ReadTexelAlpha(const CVector2f& rkTexCoord)
|
||||||
{
|
{
|
||||||
// todo: support texel formats other than DXT1
|
// todo: support texel formats other than DXT1
|
||||||
// DXT1 is definitely the most complicated one anyway; try reusing CTextureDecoder functions for other formats
|
// DXT1 is definitely the most complicated one anyway; try reusing CTextureDecoder functions for other formats
|
||||||
u32 TexelX = (u32) ((mWidth - 1) * TexCoord.x);
|
u32 TexelX = (u32) ((mWidth - 1) * rkTexCoord.X);
|
||||||
u32 TexelY = (u32) ((mHeight - 1) * (1.f - fmodf(TexCoord.y, 1.f)));
|
u32 TexelY = (u32) ((mHeight - 1) * (1.f - fmodf(rkTexCoord.Y, 1.f)));
|
||||||
|
|
||||||
if (mTexelFormat == eDXT1 && mBufferExists)
|
if (mTexelFormat == eDXT1 && mBufferExists)
|
||||||
{
|
{
|
||||||
CMemoryInStream Buffer(mImgDataBuffer, mImgDataSize, IOUtil::kSystemEndianness);
|
CMemoryInStream Buffer(mpImgDataBuffer, mImgDataSize, IOUtil::kSystemEndianness);
|
||||||
|
|
||||||
// 8 bytes per 4x4 16-pixel block, left-to-right top-to-bottom
|
// 8 bytes per 4x4 16-pixel block, left-to-right top-to-bottom
|
||||||
u32 BlockIdxX = TexelX / 4;
|
u32 BlockIdxX = TexelX / 4;
|
||||||
|
@ -190,83 +171,84 @@ float CTexture::ReadTexelAlpha(const CVector2f& TexCoord)
|
||||||
return 1.f;
|
return 1.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CTexture::WriteDDS(IOutputStream& out)
|
bool CTexture::WriteDDS(IOutputStream& rOut)
|
||||||
{
|
{
|
||||||
if (!out.IsValid()) return false;
|
if (!rOut.IsValid()) return false;
|
||||||
|
|
||||||
CopyGLBuffer();
|
CopyGLBuffer();
|
||||||
|
|
||||||
out.WriteString("DDS ", 4); // "DDS " fourCC
|
rOut.WriteString("DDS ", 4); // "DDS " fourCC
|
||||||
out.WriteLong(0x7C); // dwSize
|
rOut.WriteLong(0x7C); // dwSize
|
||||||
out.WriteLong(0x21007); // dwFlags
|
rOut.WriteLong(0x21007); // dwFlags
|
||||||
out.WriteLong(mHeight); // dwHeight
|
rOut.WriteLong(mHeight); // dwHeight
|
||||||
out.WriteLong(mWidth); // dwWidth
|
rOut.WriteLong(mWidth); // dwWidth
|
||||||
out.WriteLong(mLinearSize); // dwPitchOrLinearSize
|
rOut.WriteLong(mLinearSize); // dwPitchOrLinearSize
|
||||||
out.WriteLong(0); // dwDepth
|
rOut.WriteLong(0); // dwDepth
|
||||||
out.WriteLong(mNumMipMaps - 1); // dwMipMapCount
|
rOut.WriteLong(mNumMipMaps - 1); // dwMipMapCount
|
||||||
|
|
||||||
for (u32 i = 0; i < 11; i++)
|
for (u32 iRes = 0; iRes < 11; iRes++)
|
||||||
out.WriteLong(0); // dwReserved1[11]
|
rOut.WriteLong(0); // dwReserved1[11]
|
||||||
|
|
||||||
// DDS_PIXELFORMAT
|
// DDS_PIXELFORMAT
|
||||||
out.WriteLong(32); // DDS_PIXELFORMAT.dwSize
|
rOut.WriteLong(32); // DDS_PIXELFORMAT.dwSize
|
||||||
|
u32 PFFlags = 0, PFBpp = 0, PFRBitMask = 0, PFGBitMask = 0, PFBBitMask = 0, PFABitMask = 0;
|
||||||
|
|
||||||
u32 pfFlags = 0, pfBpp = 0, pfRBitMask = 0, pfGBitMask = 0, pfBBitMask = 0, pfABitMask = 0;
|
switch (mTexelFormat)
|
||||||
switch (mTexelFormat) {
|
{
|
||||||
case eLuminance:
|
case eLuminance:
|
||||||
pfFlags = 0x20000;
|
PFFlags = 0x20000;
|
||||||
pfBpp = 0x8;
|
PFBpp = 0x8;
|
||||||
pfRBitMask = 0xFF;
|
PFRBitMask = 0xFF;
|
||||||
break;
|
break;
|
||||||
case eLuminanceAlpha:
|
case eLuminanceAlpha:
|
||||||
pfFlags = 0x20001;
|
PFFlags = 0x20001;
|
||||||
pfBpp = 0x10;
|
PFBpp = 0x10;
|
||||||
pfRBitMask = 0x00FF;
|
PFRBitMask = 0x00FF;
|
||||||
pfABitMask = 0xFF00;
|
PFABitMask = 0xFF00;
|
||||||
break;
|
break;
|
||||||
case eRGBA4:
|
case eRGBA4:
|
||||||
pfFlags = 0x41;
|
PFFlags = 0x41;
|
||||||
pfBpp = 0x10;
|
PFBpp = 0x10;
|
||||||
pfRBitMask = 0x0F00;
|
PFRBitMask = 0x0F00;
|
||||||
pfGBitMask = 0x00F0;
|
PFGBitMask = 0x00F0;
|
||||||
pfBBitMask = 0x000F;
|
PFBBitMask = 0x000F;
|
||||||
pfABitMask = 0xF000;
|
PFABitMask = 0xF000;
|
||||||
break;
|
break;
|
||||||
case eRGB565:
|
case eRGB565:
|
||||||
pfFlags = 0x40;
|
PFFlags = 0x40;
|
||||||
pfBpp = 0x10;
|
PFBpp = 0x10;
|
||||||
pfRBitMask = 0xF800;
|
PFRBitMask = 0xF800;
|
||||||
pfGBitMask = 0x7E0;
|
PFGBitMask = 0x7E0;
|
||||||
pfBBitMask = 0x1F;
|
PFBBitMask = 0x1F;
|
||||||
break;
|
break;
|
||||||
case eRGBA8:
|
case eRGBA8:
|
||||||
pfFlags = 0x41;
|
PFFlags = 0x41;
|
||||||
pfBpp = 0x20;
|
PFBpp = 0x20;
|
||||||
pfRBitMask = 0x00FF0000;
|
PFRBitMask = 0x00FF0000;
|
||||||
pfGBitMask = 0x0000FF00;
|
PFGBitMask = 0x0000FF00;
|
||||||
pfBBitMask = 0x000000FF;
|
PFBBitMask = 0x000000FF;
|
||||||
pfABitMask = 0xFF000000;
|
PFABitMask = 0xFF000000;
|
||||||
break;
|
break;
|
||||||
case eDXT1:
|
case eDXT1:
|
||||||
pfFlags = 0x4;
|
PFFlags = 0x4;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
out.WriteLong(pfFlags); // DDS_PIXELFORMAT.dwFlags
|
rOut.WriteLong(PFFlags); // DDS_PIXELFORMAT.dwFlags
|
||||||
(mTexelFormat == eDXT1) ? out.WriteString("DXT1", 4) : out.WriteLong(0); // DDS_PIXELFORMAT.dwFourCC
|
(mTexelFormat == eDXT1) ? rOut.WriteString("DXT1", 4) : rOut.WriteLong(0); // DDS_PIXELFORMAT.dwFourCC
|
||||||
out.WriteLong(pfBpp); // DDS_PIXELFORMAT.dwRGBBitCount
|
rOut.WriteLong(PFBpp); // DDS_PIXELFORMAT.dwRGBBitCount
|
||||||
out.WriteLong(pfRBitMask); // DDS_PIXELFORMAT.dwRBitMask
|
rOut.WriteLong(PFRBitMask); // DDS_PIXELFORMAT.dwRBitMask
|
||||||
out.WriteLong(pfGBitMask); // DDS_PIXELFORMAT.dwGBitMask
|
rOut.WriteLong(PFGBitMask); // DDS_PIXELFORMAT.dwGBitMask
|
||||||
out.WriteLong(pfBBitMask); // DDS_PIXELFORMAT.dwBBitMask
|
rOut.WriteLong(PFBBitMask); // DDS_PIXELFORMAT.dwBBitMask
|
||||||
out.WriteLong(pfABitMask); // DDS_PIXELFORMAT.dwABitMask
|
rOut.WriteLong(PFABitMask); // DDS_PIXELFORMAT.dwABitMask
|
||||||
|
|
||||||
out.WriteLong(0x401000); // dwCaps
|
rOut.WriteLong(0x401000); // dwCaps
|
||||||
out.WriteLong(0); // dwCaps2
|
rOut.WriteLong(0); // dwCaps2
|
||||||
out.WriteLong(0); // dwCaps3
|
rOut.WriteLong(0); // dwCaps3
|
||||||
out.WriteLong(0); // dwCaps4
|
rOut.WriteLong(0); // dwCaps4
|
||||||
out.WriteLong(0); // dwReserved2
|
rOut.WriteLong(0); // dwReserved2
|
||||||
|
|
||||||
out.WriteBytes(mImgDataBuffer, mImgDataSize); // Image data
|
rOut.WriteBytes(mpImgDataBuffer, mImgDataSize); // Image data
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -325,15 +307,15 @@ void CTexture::CopyGLBuffer()
|
||||||
// Clear existing buffer
|
// Clear existing buffer
|
||||||
if (mBufferExists)
|
if (mBufferExists)
|
||||||
{
|
{
|
||||||
delete[] mImgDataBuffer;
|
delete[] mpImgDataBuffer;
|
||||||
mBufferExists = false;
|
mBufferExists = false;
|
||||||
mImgDataBuffer = nullptr;
|
mpImgDataBuffer = nullptr;
|
||||||
mImgDataSize = 0;
|
mImgDataSize = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate buffer size
|
// Calculate buffer size
|
||||||
mImgDataSize = CalcTotalSize();
|
mImgDataSize = CalcTotalSize();
|
||||||
mImgDataBuffer = new u8[mImgDataSize];
|
mpImgDataBuffer = new u8[mImgDataSize];
|
||||||
mBufferExists = true;
|
mBufferExists = true;
|
||||||
|
|
||||||
// Get texture
|
// Get texture
|
||||||
|
@ -344,7 +326,7 @@ void CTexture::CopyGLBuffer()
|
||||||
|
|
||||||
for (u32 iMip = 0; iMip < mNumMipMaps; iMip++)
|
for (u32 iMip = 0; iMip < mNumMipMaps; iMip++)
|
||||||
{
|
{
|
||||||
void *pData = mImgDataBuffer + MipOffset;
|
void *pData = mpImgDataBuffer + MipOffset;
|
||||||
|
|
||||||
glGetTexImage(GL_TEXTURE_2D, iMip, GL_RGBA, GL_UNSIGNED_BYTE, pData);
|
glGetTexImage(GL_TEXTURE_2D, iMip, GL_RGBA, GL_UNSIGNED_BYTE, pData);
|
||||||
|
|
||||||
|
@ -361,9 +343,9 @@ void CTexture::DeleteBuffers()
|
||||||
{
|
{
|
||||||
if (mBufferExists)
|
if (mBufferExists)
|
||||||
{
|
{
|
||||||
delete[] mImgDataBuffer;
|
delete[] mpImgDataBuffer;
|
||||||
mBufferExists = false;
|
mBufferExists = false;
|
||||||
mImgDataBuffer = nullptr;
|
mpImgDataBuffer = nullptr;
|
||||||
mImgDataSize = 0;
|
mImgDataSize = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,32 +21,31 @@ class CTexture : public CResource
|
||||||
u32 mNumMipMaps; // The number of mipmaps this texture has
|
u32 mNumMipMaps; // The number of mipmaps this texture has
|
||||||
u32 mLinearSize; // The size of the top level mipmap, in bytes
|
u32 mLinearSize; // The size of the top level mipmap, in bytes
|
||||||
|
|
||||||
bool mBufferExists; // Boolean that indicates whether image data buffer has valid data
|
bool mBufferExists; // Indicates whether image data buffer has valid data
|
||||||
u8 *mImgDataBuffer; // Pointer to image data buffer
|
u8 *mpImgDataBuffer; // Pointer to image data buffer
|
||||||
u32 mImgDataSize; // Size of image data buffer
|
u32 mImgDataSize; // Size of image data buffer
|
||||||
|
|
||||||
bool mGLBufferExists; // Boolean that indicates whether GL buffer has valid data
|
bool mGLBufferExists; // Indicates whether GL buffer has valid data
|
||||||
GLuint mTextureID; // ID for texture GL buffer
|
GLuint mTextureID; // ID for texture GL buffer
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CTexture();
|
CTexture();
|
||||||
CTexture(const CTexture& Source);
|
|
||||||
CTexture(u32 Width, u32 Height);
|
CTexture(u32 Width, u32 Height);
|
||||||
~CTexture();
|
~CTexture();
|
||||||
|
|
||||||
bool BufferGL();
|
bool BufferGL();
|
||||||
void Bind(u32 GLTextureUnit);
|
void Bind(u32 GLTextureUnit);
|
||||||
void Resize(u32 Width, u32 Height);
|
void Resize(u32 Width, u32 Height);
|
||||||
float ReadTexelAlpha(const CVector2f& TexCoord);
|
float ReadTexelAlpha(const CVector2f& rkTexCoord);
|
||||||
bool WriteDDS(IOutputStream& out);
|
bool WriteDDS(IOutputStream& rOut);
|
||||||
|
|
||||||
// Getters
|
// Getters
|
||||||
ETexelFormat TexelFormat();
|
ETexelFormat TexelFormat() const { return mTexelFormat; }
|
||||||
ETexelFormat SourceTexelFormat();
|
ETexelFormat SourceTexelFormat() const { return mSourceTexelFormat; }
|
||||||
u32 Width();
|
u32 Width() const { return (u32) mWidth; }
|
||||||
u32 Height();
|
u32 Height() const { return (u32) mHeight; }
|
||||||
u32 NumMipMaps();
|
u32 NumMipMaps() const { return mNumMipMaps; }
|
||||||
GLuint TextureID();
|
GLuint TextureID() const { return mTextureID; }
|
||||||
|
|
||||||
// Static
|
// Static
|
||||||
static u32 FormatBPP(ETexelFormat Format);
|
static u32 FormatBPP(ETexelFormat Format);
|
||||||
|
@ -59,28 +58,4 @@ private:
|
||||||
void DeleteBuffers();
|
void DeleteBuffers();
|
||||||
};
|
};
|
||||||
|
|
||||||
inline ETexelFormat CTexture::TexelFormat() {
|
|
||||||
return mTexelFormat;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline ETexelFormat CTexture::SourceTexelFormat() {
|
|
||||||
return mSourceTexelFormat;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline u32 CTexture::Width() {
|
|
||||||
return (u32) mWidth;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline u32 CTexture::Height() {
|
|
||||||
return (u32) mHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline u32 CTexture::NumMipMaps() {
|
|
||||||
return mNumMipMaps;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline GLuint CTexture::TextureID() {
|
|
||||||
return mTextureID;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // CTEXTURE_H
|
#endif // CTEXTURE_H
|
||||||
|
|
|
@ -2,14 +2,15 @@
|
||||||
#include "CResCache.h"
|
#include "CResCache.h"
|
||||||
#include "Core/Resource/Script/CScriptLayer.h"
|
#include "Core/Resource/Script/CScriptLayer.h"
|
||||||
|
|
||||||
CWorld::CWorld() : CResource()
|
CWorld::CWorld()
|
||||||
|
: CResource()
|
||||||
|
, mWorldVersion(eUnknownVersion)
|
||||||
|
, mpWorldName(nullptr)
|
||||||
|
, mpDarkWorldName(nullptr)
|
||||||
|
, mpSaveWorld(nullptr)
|
||||||
|
, mpDefaultSkybox(nullptr)
|
||||||
|
, mpMapWorld(nullptr)
|
||||||
{
|
{
|
||||||
mWorldVersion = eUnknownVersion;
|
|
||||||
mpWorldName = nullptr;
|
|
||||||
mpDarkWorldName = nullptr;
|
|
||||||
mpSaveWorld = nullptr;
|
|
||||||
mpDefaultSkybox = nullptr;
|
|
||||||
mpMapWorld = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CWorld::~CWorld()
|
CWorld::~CWorld()
|
||||||
|
@ -23,76 +24,13 @@ void CWorld::SetAreaLayerInfo(CGameArea *pArea)
|
||||||
// the start window and the start window already knows the area index.
|
// the start window and the start window already knows the area index.
|
||||||
SArea& AreaInfo = mAreas[pArea->WorldIndex()];
|
SArea& AreaInfo = mAreas[pArea->WorldIndex()];
|
||||||
|
|
||||||
for (u32 iLyr = 0; iLyr < pArea->GetScriptLayerCount(); iLyr++)
|
for (u32 iLyr = 0; iLyr < pArea->NumScriptLayers(); iLyr++)
|
||||||
{
|
{
|
||||||
if (AreaInfo.Layers.size() <= iLyr) break;
|
if (AreaInfo.Layers.size() <= iLyr) break;
|
||||||
CScriptLayer *pLayer = pArea->GetScriptLayer(iLyr);
|
CScriptLayer *pLayer = pArea->ScriptLayer(iLyr);
|
||||||
SArea::SLayer& LayerInfo = AreaInfo.Layers[iLyr];
|
SArea::SLayer& rLayerInfo = AreaInfo.Layers[iLyr];
|
||||||
|
|
||||||
pLayer->SetName(LayerInfo.LayerName);
|
pLayer->SetName(rLayerInfo.LayerName);
|
||||||
pLayer->SetActive(LayerInfo.EnabledByDefault);
|
pLayer->SetActive(rLayerInfo.EnabledByDefault);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ************ GETTERS ************
|
|
||||||
// World
|
|
||||||
EGame CWorld::Version()
|
|
||||||
{
|
|
||||||
return mWorldVersion;
|
|
||||||
}
|
|
||||||
|
|
||||||
CStringTable* CWorld::GetWorldName()
|
|
||||||
{
|
|
||||||
return mpWorldName;
|
|
||||||
}
|
|
||||||
|
|
||||||
CStringTable* CWorld::GetDarkWorldName()
|
|
||||||
{
|
|
||||||
return mpDarkWorldName;
|
|
||||||
}
|
|
||||||
|
|
||||||
CResource* CWorld::GetSaveWorld()
|
|
||||||
{
|
|
||||||
return mpSaveWorld;
|
|
||||||
}
|
|
||||||
|
|
||||||
CModel* CWorld::GetDefaultSkybox()
|
|
||||||
{
|
|
||||||
return mpDefaultSkybox;
|
|
||||||
}
|
|
||||||
|
|
||||||
CResource* CWorld::GetMapWorld()
|
|
||||||
{
|
|
||||||
return mpMapWorld;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Area
|
|
||||||
u32 CWorld::GetNumAreas()
|
|
||||||
{
|
|
||||||
return mAreas.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
u64 CWorld::GetAreaResourceID(u32 AreaIndex)
|
|
||||||
{
|
|
||||||
return mAreas[AreaIndex].FileID;
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 CWorld::GetAreaAttachedCount(u32 AreaIndex)
|
|
||||||
{
|
|
||||||
return mAreas[AreaIndex].AttachedAreaIDs.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 CWorld::GetAreaAttachedID(u32 AreaIndex, u32 AttachedIndex)
|
|
||||||
{
|
|
||||||
return (u32) mAreas[AreaIndex].AttachedAreaIDs[AttachedIndex];
|
|
||||||
}
|
|
||||||
|
|
||||||
TString CWorld::GetAreaInternalName(u32 AreaIndex)
|
|
||||||
{
|
|
||||||
return mAreas[AreaIndex].InternalName;
|
|
||||||
}
|
|
||||||
|
|
||||||
CStringTable* CWorld::GetAreaName(u32 AreaIndex)
|
|
||||||
{
|
|
||||||
return mAreas[AreaIndex].pAreaName;
|
|
||||||
}
|
|
||||||
|
|
|
@ -86,20 +86,20 @@ public:
|
||||||
|
|
||||||
void SetAreaLayerInfo(CGameArea *pArea);
|
void SetAreaLayerInfo(CGameArea *pArea);
|
||||||
|
|
||||||
// Setters
|
// Accessors
|
||||||
EGame Version();
|
inline EGame Version() const { return mWorldVersion; }
|
||||||
CStringTable* GetWorldName();
|
inline CStringTable* WorldName() const { return mpWorldName; }
|
||||||
CStringTable* GetDarkWorldName();
|
inline CStringTable* DarkWorldName() const { return mpDarkWorldName; }
|
||||||
CResource* GetSaveWorld();
|
inline CResource* SaveWorld() const { return mpSaveWorld; }
|
||||||
CModel* GetDefaultSkybox();
|
inline CModel* DefaultSkybox() const { return mpDefaultSkybox; }
|
||||||
CResource* GetMapWorld();
|
inline CResource* MapWorld() const { return mpMapWorld; }
|
||||||
|
|
||||||
u32 GetNumAreas();
|
inline u32 NumAreas() const { return mAreas.size(); }
|
||||||
u64 GetAreaResourceID(u32 AreaIndex);
|
inline u64 AreaResourceID(u32 AreaIndex) const { return mAreas[AreaIndex].FileID; }
|
||||||
u32 GetAreaAttachedCount(u32 AreaIndex);
|
inline u32 AreaAttachedCount(u32 AreaIndex) const { return mAreas[AreaIndex].AttachedAreaIDs.size(); }
|
||||||
u32 GetAreaAttachedID(u32 AreaIndex, u32 AttachedIndex);
|
inline u32 AreaAttachedID(u32 AreaIndex, u32 AttachedIndex) const { return mAreas[AreaIndex].AttachedAreaIDs[AttachedIndex]; }
|
||||||
TString GetAreaInternalName(u32 AreaIndex);
|
inline TString AreaInternalName(u32 AreaIndex) const { return mAreas[AreaIndex].InternalName; }
|
||||||
CStringTable* GetAreaName(u32 AreaIndex);
|
inline CStringTable* AreaName(u32 AreaIndex) const { return mAreas[AreaIndex].pAreaName; }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CWORLD_H
|
#endif // CWORLD_H
|
||||||
|
|
|
@ -32,8 +32,8 @@ void CAreaCooker::DetermineSectionNumbersPrime()
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (u32 iMesh = 0; iMesh < mpArea->mTerrainModels.size(); iMesh++)
|
for (u32 iMesh = 0; iMesh < mpArea->mWorldModels.size(); iMesh++)
|
||||||
GeometrySections += mpArea->mTerrainModels[iMesh]->GetSurfaceCount();
|
GeometrySections += mpArea->mWorldModels[iMesh]->GetSurfaceCount();
|
||||||
|
|
||||||
// Set section numbers
|
// Set section numbers
|
||||||
u32 SecNum = GeometrySections;
|
u32 SecNum = GeometrySections;
|
||||||
|
@ -349,9 +349,9 @@ void CAreaCooker::WriteCookedArea(CGameArea *pArea, IOutputStream& rOut)
|
||||||
Cooker.WriteAreaData(rOut);
|
Cooker.WriteAreaData(rOut);
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 CAreaCooker::GetMREAVersion(EGame version)
|
u32 CAreaCooker::GetMREAVersion(EGame Version)
|
||||||
{
|
{
|
||||||
switch (version)
|
switch (Version)
|
||||||
{
|
{
|
||||||
case ePrimeDemo: return 0xC;
|
case ePrimeDemo: return 0xC;
|
||||||
case ePrime: return 0xF;
|
case ePrime: return 0xF;
|
||||||
|
|
|
@ -64,7 +64,7 @@ class CAreaCooker
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static void WriteCookedArea(CGameArea *pArea, IOutputStream& rOut);
|
static void WriteCookedArea(CGameArea *pArea, IOutputStream& rOut);
|
||||||
static u32 GetMREAVersion(EGame version);
|
static u32 GetMREAVersion(EGame Version);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CAREACOOKER_H
|
#endif // CAREACOOKER_H
|
||||||
|
|
|
@ -2,11 +2,11 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
CMaterialCooker::CMaterialCooker()
|
CMaterialCooker::CMaterialCooker()
|
||||||
|
: mpMat(nullptr)
|
||||||
{
|
{
|
||||||
mpMat = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMaterialCooker::WriteMatSetPrime(IOutputStream& Out)
|
void CMaterialCooker::WriteMatSetPrime(IOutputStream& rOut)
|
||||||
{
|
{
|
||||||
// Gather texture list from the materials before starting
|
// Gather texture list from the materials before starting
|
||||||
mTextureIDs.clear();
|
mTextureIDs.clear();
|
||||||
|
@ -30,47 +30,46 @@ void CMaterialCooker::WriteMatSetPrime(IOutputStream& Out)
|
||||||
mTextureIDs.erase(std::unique(mTextureIDs.begin(), mTextureIDs.end()), mTextureIDs.end());
|
mTextureIDs.erase(std::unique(mTextureIDs.begin(), mTextureIDs.end()), mTextureIDs.end());
|
||||||
|
|
||||||
// Write texture IDs
|
// Write texture IDs
|
||||||
Out.WriteLong(mTextureIDs.size());
|
rOut.WriteLong(mTextureIDs.size());
|
||||||
|
|
||||||
for (u32 iTex = 0; iTex < mTextureIDs.size(); iTex++)
|
for (u32 iTex = 0; iTex < mTextureIDs.size(); iTex++)
|
||||||
Out.WriteLong(mTextureIDs[iTex]);
|
rOut.WriteLong(mTextureIDs[iTex]);
|
||||||
|
|
||||||
// Write material offset filler
|
// Write material offset filler
|
||||||
Out.WriteLong(NumMats);
|
rOut.WriteLong(NumMats);
|
||||||
u32 MatOffsetsStart = Out.Tell();
|
u32 MatOffsetsStart = rOut.Tell();
|
||||||
|
|
||||||
for (u32 iMat = 0; iMat < NumMats; iMat++)
|
for (u32 iMat = 0; iMat < NumMats; iMat++)
|
||||||
Out.WriteLong(0);
|
rOut.WriteLong(0);
|
||||||
|
|
||||||
// Write materials
|
// Write materials
|
||||||
u32 MatsStart = Out.Tell();
|
u32 MatsStart = rOut.Tell();
|
||||||
std::vector<u32> MatEndOffsets(NumMats);
|
std::vector<u32> MatEndOffsets(NumMats);
|
||||||
|
|
||||||
for (u32 iMat = 0; iMat < NumMats; iMat++)
|
for (u32 iMat = 0; iMat < NumMats; iMat++)
|
||||||
{
|
{
|
||||||
mpMat = mpSet->mMaterials[iMat];
|
mpMat = mpSet->mMaterials[iMat];
|
||||||
WriteMaterialPrime(Out);
|
WriteMaterialPrime(rOut);
|
||||||
MatEndOffsets[iMat] = Out.Tell() - MatsStart;
|
MatEndOffsets[iMat] = rOut.Tell() - MatsStart;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write material offsets
|
// Write material offsets
|
||||||
u32 MatsEnd = Out.Tell();
|
u32 MatsEnd = rOut.Tell();
|
||||||
Out.Seek(MatOffsetsStart, SEEK_SET);
|
rOut.Seek(MatOffsetsStart, SEEK_SET);
|
||||||
|
|
||||||
for (u32 iMat = 0; iMat < NumMats; iMat++)
|
for (u32 iMat = 0; iMat < NumMats; iMat++)
|
||||||
Out.WriteLong(MatEndOffsets[iMat]);
|
rOut.WriteLong(MatEndOffsets[iMat]);
|
||||||
|
|
||||||
// Done!
|
// Done!
|
||||||
Out.Seek(MatsEnd, SEEK_SET);
|
rOut.Seek(MatsEnd, SEEK_SET);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMaterialCooker::WriteMatSetCorruption(IOutputStream&)
|
void CMaterialCooker::WriteMatSetCorruption(IOutputStream& /*rOut*/)
|
||||||
{
|
{
|
||||||
// Not using parameter 1 (IOutputStream& - Out)
|
|
||||||
// todo
|
// todo
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMaterialCooker::WriteMaterialPrime(IOutputStream& Out)
|
void CMaterialCooker::WriteMaterialPrime(IOutputStream& rOut)
|
||||||
{
|
{
|
||||||
// Gather data from the passes before we start writing
|
// Gather data from the passes before we start writing
|
||||||
u32 TexFlags = 0;
|
u32 TexFlags = 0;
|
||||||
|
@ -143,12 +142,12 @@ void CMaterialCooker::WriteMaterialPrime(IOutputStream& Out)
|
||||||
|
|
||||||
Flags |= (HasKonst ? 0x8 : 0x0) | (mpMat->Options() & ~0x8) | (TexFlags << 16);
|
Flags |= (HasKonst ? 0x8 : 0x0) | (mpMat->Options() & ~0x8) | (TexFlags << 16);
|
||||||
|
|
||||||
Out.WriteLong(Flags);
|
rOut.WriteLong(Flags);
|
||||||
|
|
||||||
// Texture indices
|
// Texture indices
|
||||||
Out.WriteLong(TexIndices.size());
|
rOut.WriteLong(TexIndices.size());
|
||||||
for (u32 iTex = 0; iTex < TexIndices.size(); iTex++)
|
for (u32 iTex = 0; iTex < TexIndices.size(); iTex++)
|
||||||
Out.WriteLong(TexIndices[iTex]);
|
rOut.WriteLong(TexIndices[iTex]);
|
||||||
|
|
||||||
// Vertex description
|
// Vertex description
|
||||||
FVertexDescription Desc = mpMat->VtxDesc();
|
FVertexDescription Desc = mpMat->VtxDesc();
|
||||||
|
@ -156,24 +155,24 @@ void CMaterialCooker::WriteMaterialPrime(IOutputStream& Out)
|
||||||
if (mVersion < eEchoes)
|
if (mVersion < eEchoes)
|
||||||
Desc &= 0x00FFFFFF;
|
Desc &= 0x00FFFFFF;
|
||||||
|
|
||||||
Out.WriteLong(Desc);
|
rOut.WriteLong(Desc);
|
||||||
|
|
||||||
// Echoes unknowns
|
// Echoes unknowns
|
||||||
if (mVersion == eEchoes)
|
if (mVersion == eEchoes)
|
||||||
{
|
{
|
||||||
Out.WriteLong(mpMat->EchoesUnknownA());
|
rOut.WriteLong(mpMat->EchoesUnknownA());
|
||||||
Out.WriteLong(mpMat->EchoesUnknownB());
|
rOut.WriteLong(mpMat->EchoesUnknownB());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Group index
|
// Group index
|
||||||
Out.WriteLong(GroupIndex);
|
rOut.WriteLong(GroupIndex);
|
||||||
|
|
||||||
// Konst
|
// Konst
|
||||||
if (HasKonst)
|
if (HasKonst)
|
||||||
{
|
{
|
||||||
Out.WriteLong(NumKonst);
|
rOut.WriteLong(NumKonst);
|
||||||
for (u32 iKonst = 0; iKonst < NumKonst; iKonst++)
|
for (u32 iKonst = 0; iKonst < NumKonst; iKonst++)
|
||||||
Out.WriteLong( mpMat->Konst(iKonst).ToLongRGBA() );
|
rOut.WriteLong( mpMat->Konst(iKonst).ToLongRGBA() );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Blend Mode
|
// Blend Mode
|
||||||
|
@ -182,16 +181,16 @@ void CMaterialCooker::WriteMaterialPrime(IOutputStream& Out)
|
||||||
u16 BlendDstFac = (u16) mpMat->BlendDstFac();
|
u16 BlendDstFac = (u16) mpMat->BlendDstFac();
|
||||||
if (BlendSrcFac >= 0x300) BlendSrcFac -= 0x2FE;
|
if (BlendSrcFac >= 0x300) BlendSrcFac -= 0x2FE;
|
||||||
if (BlendDstFac >= 0x300) BlendDstFac -= 0x2FE;
|
if (BlendDstFac >= 0x300) BlendDstFac -= 0x2FE;
|
||||||
Out.WriteShort(BlendDstFac);
|
rOut.WriteShort(BlendDstFac);
|
||||||
Out.WriteShort(BlendSrcFac);
|
rOut.WriteShort(BlendSrcFac);
|
||||||
|
|
||||||
// Color Channels
|
// Color Channels
|
||||||
Out.WriteLong(1);
|
rOut.WriteLong(1);
|
||||||
Out.WriteLong(0x3000 | (mpMat->IsLightingEnabled() ? 1 : 0));
|
rOut.WriteLong(0x3000 | (mpMat->IsLightingEnabled() ? 1 : 0));
|
||||||
|
|
||||||
// TEV
|
// TEV
|
||||||
u32 NumPasses = mpMat->PassCount();
|
u32 NumPasses = mpMat->PassCount();
|
||||||
Out.WriteLong(NumPasses);
|
rOut.WriteLong(NumPasses);
|
||||||
|
|
||||||
for (u32 iPass = 0; iPass < NumPasses; iPass++)
|
for (u32 iPass = 0; iPass < NumPasses; iPass++)
|
||||||
{
|
{
|
||||||
|
@ -209,14 +208,14 @@ void CMaterialCooker::WriteMaterialPrime(IOutputStream& Out)
|
||||||
u32 ColorOpFlags = 0x100 | (pPass->ColorOutput() << 9);
|
u32 ColorOpFlags = 0x100 | (pPass->ColorOutput() << 9);
|
||||||
u32 AlphaOpFlags = 0x100 | (pPass->AlphaOutput() << 9);
|
u32 AlphaOpFlags = 0x100 | (pPass->AlphaOutput() << 9);
|
||||||
|
|
||||||
Out.WriteLong(ColorInputFlags);
|
rOut.WriteLong(ColorInputFlags);
|
||||||
Out.WriteLong(AlphaInputFlags);
|
rOut.WriteLong(AlphaInputFlags);
|
||||||
Out.WriteLong(ColorOpFlags);
|
rOut.WriteLong(ColorOpFlags);
|
||||||
Out.WriteLong(AlphaOpFlags);
|
rOut.WriteLong(AlphaOpFlags);
|
||||||
Out.WriteByte(0); // Padding
|
rOut.WriteByte(0); // Padding
|
||||||
Out.WriteByte(pPass->KAlphaSel());
|
rOut.WriteByte(pPass->KAlphaSel());
|
||||||
Out.WriteByte(pPass->KColorSel());
|
rOut.WriteByte(pPass->KColorSel());
|
||||||
Out.WriteByte(pPass->RasSel());
|
rOut.WriteByte(pPass->RasSel());
|
||||||
}
|
}
|
||||||
|
|
||||||
// TEV Tex/UV input selection
|
// TEV Tex/UV input selection
|
||||||
|
@ -224,22 +223,22 @@ void CMaterialCooker::WriteMaterialPrime(IOutputStream& Out)
|
||||||
|
|
||||||
for (u32 iPass = 0; iPass < NumPasses; iPass++)
|
for (u32 iPass = 0; iPass < NumPasses; iPass++)
|
||||||
{
|
{
|
||||||
Out.WriteShort(0); // Padding
|
rOut.WriteShort(0); // Padding
|
||||||
|
|
||||||
if (mpMat->Pass(iPass)->Texture())
|
if (mpMat->Pass(iPass)->Texture())
|
||||||
{
|
{
|
||||||
Out.WriteByte((u8) CurTexIdx);
|
rOut.WriteByte((u8) CurTexIdx);
|
||||||
Out.WriteByte((u8) CurTexIdx);
|
rOut.WriteByte((u8) CurTexIdx);
|
||||||
CurTexIdx++;
|
CurTexIdx++;
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
Out.WriteShort((u16) 0xFFFF);
|
rOut.WriteShort((u16) 0xFFFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TexGen
|
// TexGen
|
||||||
u32 NumTexCoords = CurTexIdx; // TexIdx is currently equal to the tex coord count
|
u32 NumTexCoords = CurTexIdx; // TexIdx is currently equal to the tex coord count
|
||||||
Out.WriteLong(NumTexCoords);
|
rOut.WriteLong(NumTexCoords);
|
||||||
u32 CurTexMtx = 0;
|
u32 CurTexMtx = 0;
|
||||||
|
|
||||||
for (u32 iPass = 0; iPass < NumPasses; iPass++)
|
for (u32 iPass = 0; iPass < NumPasses; iPass++)
|
||||||
|
@ -280,15 +279,15 @@ void CMaterialCooker::WriteMaterialPrime(IOutputStream& Out)
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 TexGenFlags = (CoordSource << 4) | (TexMtxIdx << 9) | (Normalize << 14) | (PostMtxIdx << 15);
|
u32 TexGenFlags = (CoordSource << 4) | (TexMtxIdx << 9) | (Normalize << 14) | (PostMtxIdx << 15);
|
||||||
Out.WriteLong(TexGenFlags);
|
rOut.WriteLong(TexGenFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Animations
|
// Animations
|
||||||
u32 AnimSizeOffset = Out.Tell();
|
u32 AnimSizeOffset = rOut.Tell();
|
||||||
u32 NumAnims = CurTexMtx; // CurTexMtx is currently equal to the anim count
|
u32 NumAnims = CurTexMtx; // CurTexMtx is currently equal to the anim count
|
||||||
Out.WriteLong(0); // Anim size filler
|
rOut.WriteLong(0); // Anim size filler
|
||||||
u32 AnimsStart = Out.Tell();
|
u32 AnimsStart = rOut.Tell();
|
||||||
Out.WriteLong(NumAnims);
|
rOut.WriteLong(NumAnims);
|
||||||
|
|
||||||
for (u32 iPass = 0; iPass < NumPasses; iPass++)
|
for (u32 iPass = 0; iPass < NumPasses; iPass++)
|
||||||
{
|
{
|
||||||
|
@ -296,38 +295,37 @@ void CMaterialCooker::WriteMaterialPrime(IOutputStream& Out)
|
||||||
u32 AnimMode = pPass->AnimMode();
|
u32 AnimMode = pPass->AnimMode();
|
||||||
if (AnimMode == eNoUVAnim) continue;
|
if (AnimMode == eNoUVAnim) continue;
|
||||||
|
|
||||||
Out.WriteLong(AnimMode);
|
rOut.WriteLong(AnimMode);
|
||||||
|
|
||||||
if ((AnimMode > 1) && (AnimMode != 6))
|
if ((AnimMode > 1) && (AnimMode != 6))
|
||||||
{
|
{
|
||||||
Out.WriteFloat(pPass->AnimParam(0));
|
rOut.WriteFloat(pPass->AnimParam(0));
|
||||||
Out.WriteFloat(pPass->AnimParam(1));
|
rOut.WriteFloat(pPass->AnimParam(1));
|
||||||
|
|
||||||
if ((AnimMode == 2) || (AnimMode == 4) || (AnimMode == 5))
|
if ((AnimMode == 2) || (AnimMode == 4) || (AnimMode == 5))
|
||||||
{
|
{
|
||||||
Out.WriteFloat(pPass->AnimParam(2));
|
rOut.WriteFloat(pPass->AnimParam(2));
|
||||||
Out.WriteFloat(pPass->AnimParam(3));
|
rOut.WriteFloat(pPass->AnimParam(3));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 AnimsEnd = Out.Tell();
|
u32 AnimsEnd = rOut.Tell();
|
||||||
u32 AnimsSize = AnimsEnd - AnimsStart;
|
u32 AnimsSize = AnimsEnd - AnimsStart;
|
||||||
Out.Seek(AnimSizeOffset, SEEK_SET);
|
rOut.Seek(AnimSizeOffset, SEEK_SET);
|
||||||
Out.WriteLong(AnimsSize);
|
rOut.WriteLong(AnimsSize);
|
||||||
Out.Seek(AnimsEnd, SEEK_SET);
|
rOut.Seek(AnimsEnd, SEEK_SET);
|
||||||
|
|
||||||
// Done!
|
// Done!
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMaterialCooker::WriteMaterialCorruption(IOutputStream&)
|
void CMaterialCooker::WriteMaterialCorruption(IOutputStream& /*rOut*/)
|
||||||
{
|
{
|
||||||
// Not using parameter 1 (IOutputStream& - Out)
|
|
||||||
// todo
|
// todo
|
||||||
}
|
}
|
||||||
|
|
||||||
// ************ STATIC ************
|
// ************ STATIC ************
|
||||||
void CMaterialCooker::WriteCookedMatSet(CMaterialSet *pSet, EGame Version, IOutputStream &Out)
|
void CMaterialCooker::WriteCookedMatSet(CMaterialSet *pSet, EGame Version, IOutputStream& rOut)
|
||||||
{
|
{
|
||||||
CMaterialCooker Cooker;
|
CMaterialCooker Cooker;
|
||||||
Cooker.mpSet = pSet;
|
Cooker.mpSet = pSet;
|
||||||
|
@ -339,12 +337,12 @@ void CMaterialCooker::WriteCookedMatSet(CMaterialSet *pSet, EGame Version, IOutp
|
||||||
case ePrime:
|
case ePrime:
|
||||||
case eEchoesDemo:
|
case eEchoesDemo:
|
||||||
case eEchoes:
|
case eEchoes:
|
||||||
Cooker.WriteMatSetPrime(Out);
|
Cooker.WriteMatSetPrime(rOut);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMaterialCooker::WriteCookedMaterial(CMaterial *pMat, EGame Version, IOutputStream &Out)
|
void CMaterialCooker::WriteCookedMaterial(CMaterial *pMat, EGame Version, IOutputStream& rOut)
|
||||||
{
|
{
|
||||||
CMaterialCooker Cooker;
|
CMaterialCooker Cooker;
|
||||||
Cooker.mpMat = pMat;
|
Cooker.mpMat = pMat;
|
||||||
|
@ -356,7 +354,7 @@ void CMaterialCooker::WriteCookedMaterial(CMaterial *pMat, EGame Version, IOutpu
|
||||||
case ePrime:
|
case ePrime:
|
||||||
case eEchoesDemo:
|
case eEchoesDemo:
|
||||||
case eEchoes:
|
case eEchoes:
|
||||||
Cooker.WriteMaterialPrime(Out);
|
Cooker.WriteMaterialPrime(rOut);
|
||||||
break;
|
break;
|
||||||
// TODO: Corruption/Uncooked
|
// TODO: Corruption/Uncooked
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,14 +14,14 @@ class CMaterialCooker
|
||||||
std::vector<u64> mMaterialHashes;
|
std::vector<u64> mMaterialHashes;
|
||||||
|
|
||||||
CMaterialCooker();
|
CMaterialCooker();
|
||||||
void WriteMatSetPrime(IOutputStream& Out);
|
void WriteMatSetPrime(IOutputStream& rOut);
|
||||||
void WriteMatSetCorruption(IOutputStream& Out);
|
void WriteMatSetCorruption(IOutputStream& rOut);
|
||||||
void WriteMaterialPrime(IOutputStream& Out);
|
void WriteMaterialPrime(IOutputStream& rOut);
|
||||||
void WriteMaterialCorruption(IOutputStream& Out);
|
void WriteMaterialCorruption(IOutputStream& rOut);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static void WriteCookedMatSet(CMaterialSet *pSet, EGame Version, IOutputStream& Out);
|
static void WriteCookedMatSet(CMaterialSet *pSet, EGame Version, IOutputStream& rOut);
|
||||||
static void WriteCookedMaterial(CMaterial *pMat, EGame Version, IOutputStream& Out);
|
static void WriteCookedMaterial(CMaterial *pMat, EGame Version, IOutputStream& rOut);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CMATERIALCOOKER_H
|
#endif // CMATERIALCOOKER_H
|
||||||
|
|
|
@ -9,14 +9,6 @@ CModelCooker::CModelCooker()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SortVertsByArrayPos(const CVertex& A, const CVertex& B) {
|
|
||||||
return (A.ArrayPosition < B.ArrayPosition);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CheckDuplicateVertsByArrayPos(const CVertex& A, const CVertex& B) {
|
|
||||||
return (A.ArrayPosition == B.ArrayPosition);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CModelCooker::GenerateSurfaceData()
|
void CModelCooker::GenerateSurfaceData()
|
||||||
{
|
{
|
||||||
// Need to gather metadata from the model before we can start
|
// Need to gather metadata from the model before we can start
|
||||||
|
@ -60,65 +52,65 @@ void CModelCooker::GenerateSurfaceData()
|
||||||
mNumVertices = mVertices.size();
|
mNumVertices = mVertices.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CModelCooker::WriteEditorModel(IOutputStream& /*Out*/)
|
void CModelCooker::WriteEditorModel(IOutputStream& /*rOut*/)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void CModelCooker::WriteModelPrime(IOutputStream& Out)
|
void CModelCooker::WriteModelPrime(IOutputStream& rOut)
|
||||||
{
|
{
|
||||||
GenerateSurfaceData();
|
GenerateSurfaceData();
|
||||||
|
|
||||||
// Header
|
// Header
|
||||||
Out.WriteLong(0xDEADBABE);
|
rOut.WriteLong(0xDEADBABE);
|
||||||
Out.WriteLong(GetCMDLVersion(mVersion));
|
rOut.WriteLong(GetCMDLVersion(mVersion));
|
||||||
Out.WriteLong(5);
|
rOut.WriteLong(5);
|
||||||
mpModel->mAABox.Write(Out);
|
mpModel->mAABox.Write(rOut);
|
||||||
|
|
||||||
u32 NumSections = mNumMatSets + mNumSurfaces + 6;
|
u32 NumSections = mNumMatSets + mNumSurfaces + 6;
|
||||||
Out.WriteLong(NumSections);
|
rOut.WriteLong(NumSections);
|
||||||
Out.WriteLong(mNumMatSets);
|
rOut.WriteLong(mNumMatSets);
|
||||||
|
|
||||||
u32 SectionSizesOffset = Out.Tell();
|
u32 SectionSizesOffset = rOut.Tell();
|
||||||
for (u32 iSec = 0; iSec < NumSections; iSec++)
|
for (u32 iSec = 0; iSec < NumSections; iSec++)
|
||||||
Out.WriteLong(0);
|
rOut.WriteLong(0);
|
||||||
|
|
||||||
Out.WriteToBoundary(32, 0);
|
rOut.WriteToBoundary(32, 0);
|
||||||
|
|
||||||
std::vector<u32> SectionSizes;
|
std::vector<u32> SectionSizes;
|
||||||
SectionSizes.reserve(NumSections);
|
SectionSizes.reserve(NumSections);
|
||||||
|
|
||||||
CSectionMgrOut SectionMgr;
|
CSectionMgrOut SectionMgr;
|
||||||
SectionMgr.SetSectionCount(NumSections);
|
SectionMgr.SetSectionCount(NumSections);
|
||||||
SectionMgr.Init(Out);
|
SectionMgr.Init(rOut);
|
||||||
|
|
||||||
// Materials
|
// Materials
|
||||||
for (u32 iSet = 0; iSet < mNumMatSets; iSet++)
|
for (u32 iSet = 0; iSet < mNumMatSets; iSet++)
|
||||||
{
|
{
|
||||||
CMaterialCooker::WriteCookedMatSet(mpModel->mMaterialSets[iSet], mVersion, Out);
|
CMaterialCooker::WriteCookedMatSet(mpModel->mMaterialSets[iSet], mVersion, rOut);
|
||||||
Out.WriteToBoundary(32, 0);
|
rOut.WriteToBoundary(32, 0);
|
||||||
SectionMgr.AddSize(Out);
|
SectionMgr.AddSize(rOut);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Vertices
|
// Vertices
|
||||||
for (u32 iPos = 0; iPos < mNumVertices; iPos++)
|
for (u32 iPos = 0; iPos < mNumVertices; iPos++)
|
||||||
mVertices[iPos].Position.Write(Out);
|
mVertices[iPos].Position.Write(rOut);
|
||||||
|
|
||||||
Out.WriteToBoundary(32, 0);
|
rOut.WriteToBoundary(32, 0);
|
||||||
SectionMgr.AddSize(Out);
|
SectionMgr.AddSize(rOut);
|
||||||
|
|
||||||
// Normals
|
// Normals
|
||||||
for (u32 iNrm = 0; iNrm < mNumVertices; iNrm++)
|
for (u32 iNrm = 0; iNrm < mNumVertices; iNrm++)
|
||||||
mVertices[iNrm].Normal.Write(Out);
|
mVertices[iNrm].Normal.Write(rOut);
|
||||||
|
|
||||||
Out.WriteToBoundary(32, 0);
|
rOut.WriteToBoundary(32, 0);
|
||||||
SectionMgr.AddSize(Out);
|
SectionMgr.AddSize(rOut);
|
||||||
|
|
||||||
// Colors
|
// Colors
|
||||||
for (u32 iColor = 0; iColor < mNumVertices; iColor++)
|
for (u32 iColor = 0; iColor < mNumVertices; iColor++)
|
||||||
mVertices[iColor].Color[0].Write(Out);
|
mVertices[iColor].Color[0].Write(rOut);
|
||||||
|
|
||||||
Out.WriteToBoundary(32, 0);
|
rOut.WriteToBoundary(32, 0);
|
||||||
SectionMgr.AddSize(Out);
|
SectionMgr.AddSize(rOut);
|
||||||
|
|
||||||
// Float UV coordinates
|
// Float UV coordinates
|
||||||
for (u32 iTexSlot = 0; iTexSlot < 8; iTexSlot++)
|
for (u32 iTexSlot = 0; iTexSlot < 8; iTexSlot++)
|
||||||
|
@ -127,50 +119,50 @@ void CModelCooker::WriteModelPrime(IOutputStream& Out)
|
||||||
if (HasTexSlot)
|
if (HasTexSlot)
|
||||||
{
|
{
|
||||||
for (u32 iTex = 0; iTex < mNumVertices; iTex++)
|
for (u32 iTex = 0; iTex < mNumVertices; iTex++)
|
||||||
mVertices[iTex].Tex[iTexSlot].Write(Out);
|
mVertices[iTex].Tex[iTexSlot].Write(rOut);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Out.WriteToBoundary(32, 0);
|
rOut.WriteToBoundary(32, 0);
|
||||||
SectionMgr.AddSize(Out);
|
SectionMgr.AddSize(rOut);
|
||||||
SectionMgr.AddSize(Out); // Skipping short UV coordinates
|
SectionMgr.AddSize(rOut); // Skipping short UV coordinates
|
||||||
|
|
||||||
// Surface offsets
|
// Surface offsets
|
||||||
Out.WriteLong(mNumSurfaces);
|
rOut.WriteLong(mNumSurfaces);
|
||||||
u32 SurfaceOffsetsStart = Out.Tell();
|
u32 SurfaceOffsetsStart = rOut.Tell();
|
||||||
|
|
||||||
for (u32 iSurf = 0; iSurf < mNumSurfaces; iSurf++)
|
for (u32 iSurf = 0; iSurf < mNumSurfaces; iSurf++)
|
||||||
Out.WriteLong(0);
|
rOut.WriteLong(0);
|
||||||
|
|
||||||
Out.WriteToBoundary(32, 0);
|
rOut.WriteToBoundary(32, 0);
|
||||||
SectionMgr.AddSize(Out);
|
SectionMgr.AddSize(rOut);
|
||||||
|
|
||||||
// Surfaces
|
// Surfaces
|
||||||
u32 SurfacesStart = Out.Tell();
|
u32 SurfacesStart = rOut.Tell();
|
||||||
std::vector<u32> SurfaceEndOffsets(mNumSurfaces);
|
std::vector<u32> SurfaceEndOffsets(mNumSurfaces);
|
||||||
|
|
||||||
for (u32 iSurf = 0; iSurf < mNumSurfaces; iSurf++)
|
for (u32 iSurf = 0; iSurf < mNumSurfaces; iSurf++)
|
||||||
{
|
{
|
||||||
SSurface *pSurface = mpModel->GetSurface(iSurf);
|
SSurface *pSurface = mpModel->GetSurface(iSurf);
|
||||||
|
|
||||||
pSurface->CenterPoint.Write(Out);
|
pSurface->CenterPoint.Write(rOut);
|
||||||
Out.WriteLong(pSurface->MaterialID);
|
rOut.WriteLong(pSurface->MaterialID);
|
||||||
Out.WriteShort((u16) 0x8000);
|
rOut.WriteShort((u16) 0x8000);
|
||||||
u32 PrimTableSizeOffset = Out.Tell();
|
u32 PrimTableSizeOffset = rOut.Tell();
|
||||||
Out.WriteShort(0);
|
rOut.WriteShort(0);
|
||||||
Out.WriteLongLong(0);
|
rOut.WriteLongLong(0);
|
||||||
Out.WriteLong(0);
|
rOut.WriteLong(0);
|
||||||
pSurface->ReflectionDirection.Write(Out);
|
pSurface->ReflectionDirection.Write(rOut);
|
||||||
Out.WriteToBoundary(32, 0);
|
rOut.WriteToBoundary(32, 0);
|
||||||
|
|
||||||
u32 PrimTableStart = Out.Tell();
|
u32 PrimTableStart = rOut.Tell();
|
||||||
FVertexDescription MatAttribs = mpModel->GetMaterialBySurface(0, iSurf)->VtxDesc();
|
FVertexDescription MatAttribs = mpModel->GetMaterialBySurface(0, iSurf)->VtxDesc();
|
||||||
|
|
||||||
for (u32 iPrim = 0; iPrim < pSurface->Primitives.size(); iPrim++)
|
for (u32 iPrim = 0; iPrim < pSurface->Primitives.size(); iPrim++)
|
||||||
{
|
{
|
||||||
SSurface::SPrimitive *pPrimitive = &pSurface->Primitives[iPrim];
|
SSurface::SPrimitive *pPrimitive = &pSurface->Primitives[iPrim];
|
||||||
Out.WriteByte((u8) pPrimitive->Type);
|
rOut.WriteByte((u8) pPrimitive->Type);
|
||||||
Out.WriteShort((u16) pPrimitive->Vertices.size());
|
rOut.WriteShort((u16) pPrimitive->Vertices.size());
|
||||||
|
|
||||||
for (u32 iVert = 0; iVert < pPrimitive->Vertices.size(); iVert++)
|
for (u32 iVert = 0; iVert < pPrimitive->Vertices.size(); iVert++)
|
||||||
{
|
{
|
||||||
|
@ -180,59 +172,59 @@ void CModelCooker::WriteModelPrime(IOutputStream& Out)
|
||||||
{
|
{
|
||||||
for (u32 iMtxAttribs = 0; iMtxAttribs < 8; iMtxAttribs++)
|
for (u32 iMtxAttribs = 0; iMtxAttribs < 8; iMtxAttribs++)
|
||||||
if (MatAttribs & (ePosMtx << iMtxAttribs))
|
if (MatAttribs & (ePosMtx << iMtxAttribs))
|
||||||
Out.WriteByte(pVert->MatrixIndices[iMtxAttribs]);
|
rOut.WriteByte(pVert->MatrixIndices[iMtxAttribs]);
|
||||||
}
|
}
|
||||||
|
|
||||||
u16 VertexIndex = (u16) pVert->ArrayPosition;
|
u16 VertexIndex = (u16) pVert->ArrayPosition;
|
||||||
|
|
||||||
if (MatAttribs & ePosition)
|
if (MatAttribs & ePosition)
|
||||||
Out.WriteShort(VertexIndex);
|
rOut.WriteShort(VertexIndex);
|
||||||
|
|
||||||
if (MatAttribs & eNormal)
|
if (MatAttribs & eNormal)
|
||||||
Out.WriteShort(VertexIndex);
|
rOut.WriteShort(VertexIndex);
|
||||||
|
|
||||||
if (MatAttribs & eColor0)
|
if (MatAttribs & eColor0)
|
||||||
Out.WriteShort(VertexIndex);
|
rOut.WriteShort(VertexIndex);
|
||||||
|
|
||||||
if (MatAttribs & eColor1)
|
if (MatAttribs & eColor1)
|
||||||
Out.WriteShort(VertexIndex);
|
rOut.WriteShort(VertexIndex);
|
||||||
|
|
||||||
u16 TexOffset = 0;
|
u16 TexOffset = 0;
|
||||||
for (u32 iTex = 0; iTex < 8; iTex++)
|
for (u32 iTex = 0; iTex < 8; iTex++)
|
||||||
{
|
{
|
||||||
if (MatAttribs & (eTex0 << (iTex * 2)))
|
if (MatAttribs & (eTex0 << (iTex * 2)))
|
||||||
{
|
{
|
||||||
Out.WriteShort(VertexIndex + TexOffset);
|
rOut.WriteShort(VertexIndex + TexOffset);
|
||||||
TexOffset += (u16) mNumVertices;
|
TexOffset += (u16) mNumVertices;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Out.WriteToBoundary(32, 0);
|
rOut.WriteToBoundary(32, 0);
|
||||||
u32 PrimTableEnd = Out.Tell();
|
u32 PrimTableEnd = rOut.Tell();
|
||||||
u32 PrimTableSize = PrimTableEnd - PrimTableStart;
|
u32 PrimTableSize = PrimTableEnd - PrimTableStart;
|
||||||
Out.Seek(PrimTableSizeOffset, SEEK_SET);
|
rOut.Seek(PrimTableSizeOffset, SEEK_SET);
|
||||||
Out.WriteShort((u16) PrimTableSize);
|
rOut.WriteShort((u16) PrimTableSize);
|
||||||
Out.Seek(PrimTableEnd, SEEK_SET);
|
rOut.Seek(PrimTableEnd, SEEK_SET);
|
||||||
|
|
||||||
SectionMgr.AddSize(Out);
|
SectionMgr.AddSize(rOut);
|
||||||
SurfaceEndOffsets[iSurf] = Out.Tell() - SurfacesStart;
|
SurfaceEndOffsets[iSurf] = rOut.Tell() - SurfacesStart;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Done writing the file - now we go back to fill in surface offsets + section sizes
|
// Done writing the file - now we go back to fill in surface offsets + section sizes
|
||||||
Out.Seek(SurfaceOffsetsStart, SEEK_SET);
|
rOut.Seek(SurfaceOffsetsStart, SEEK_SET);
|
||||||
|
|
||||||
for (u32 iSurf = 0; iSurf < mNumSurfaces; iSurf++)
|
for (u32 iSurf = 0; iSurf < mNumSurfaces; iSurf++)
|
||||||
Out.WriteLong(SurfaceEndOffsets[iSurf]);
|
rOut.WriteLong(SurfaceEndOffsets[iSurf]);
|
||||||
|
|
||||||
Out.Seek(SectionSizesOffset, SEEK_SET);
|
rOut.Seek(SectionSizesOffset, SEEK_SET);
|
||||||
SectionMgr.WriteSizes(Out);
|
SectionMgr.WriteSizes(rOut);
|
||||||
|
|
||||||
// Done!
|
// Done!
|
||||||
}
|
}
|
||||||
|
|
||||||
void CModelCooker::WriteCookedModel(CModel *pModel, EGame Version, IOutputStream& CMDL)
|
void CModelCooker::WriteCookedModel(CModel *pModel, EGame Version, IOutputStream& rOut)
|
||||||
{
|
{
|
||||||
CModelCooker Cooker;
|
CModelCooker Cooker;
|
||||||
Cooker.mpModel = pModel;
|
Cooker.mpModel = pModel;
|
||||||
|
@ -244,12 +236,12 @@ void CModelCooker::WriteCookedModel(CModel *pModel, EGame Version, IOutputStream
|
||||||
case ePrime:
|
case ePrime:
|
||||||
case eEchoesDemo:
|
case eEchoesDemo:
|
||||||
case eEchoes:
|
case eEchoes:
|
||||||
Cooker.WriteModelPrime(CMDL);
|
Cooker.WriteModelPrime(rOut);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CModelCooker::WriteUncookedModel(CModel* /*pModel*/, IOutputStream& /*EMDL*/)
|
void CModelCooker::WriteUncookedModel(CModel* /*pModel*/, IOutputStream& /*rOut*/)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,12 +18,12 @@ class CModelCooker
|
||||||
|
|
||||||
CModelCooker();
|
CModelCooker();
|
||||||
void GenerateSurfaceData();
|
void GenerateSurfaceData();
|
||||||
void WriteEditorModel(IOutputStream& Out);
|
void WriteEditorModel(IOutputStream& rOut);
|
||||||
void WriteModelPrime(IOutputStream& Out);
|
void WriteModelPrime(IOutputStream& rOut);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static void WriteCookedModel(CModel *pModel, EGame Version, IOutputStream& Out);
|
static void WriteCookedModel(CModel *pModel, EGame Version, IOutputStream& rOut);
|
||||||
static void WriteUncookedModel(CModel *pModel, IOutputStream& Out);
|
static void WriteUncookedModel(CModel *pModel, IOutputStream& rOut);
|
||||||
static u32 GetCMDLVersion(EGame Version);
|
static u32 GetCMDLVersion(EGame Version);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -12,13 +12,13 @@ void CPoiToWorldCooker::WriteEGMC(CPoiToWorld *pPoiToWorld, IOutputStream& rOut)
|
||||||
|
|
||||||
for (u32 iPoi = 0; iPoi < pPoiToWorld->NumMappedPOIs(); iPoi++)
|
for (u32 iPoi = 0; iPoi < pPoiToWorld->NumMappedPOIs(); iPoi++)
|
||||||
{
|
{
|
||||||
const CPoiToWorld::SPoiMap *kpMap = pPoiToWorld->MapByIndex(iPoi);
|
const CPoiToWorld::SPoiMap *pkMap = pPoiToWorld->MapByIndex(iPoi);
|
||||||
|
|
||||||
for (auto it = kpMap->ModelIDs.begin(); it != kpMap->ModelIDs.end(); it++)
|
for (auto it = pkMap->ModelIDs.begin(); it != pkMap->ModelIDs.end(); it++)
|
||||||
{
|
{
|
||||||
SPoiMapping Mapping;
|
SPoiMapping Mapping;
|
||||||
Mapping.MeshID = *it;
|
Mapping.MeshID = *it;
|
||||||
Mapping.PoiID = kpMap->PoiID;
|
Mapping.PoiID = pkMap->PoiID;
|
||||||
Mappings.push_back(Mapping);
|
Mappings.push_back(Mapping);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,33 +0,0 @@
|
||||||
#include "CSectionMgrOut.h"
|
|
||||||
|
|
||||||
CSectionMgrOut::CSectionMgrOut()
|
|
||||||
{
|
|
||||||
mSectionCount = 0;
|
|
||||||
mCurSectionStart = 0;
|
|
||||||
mCurSectionIndex = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSectionMgrOut::SetSectionCount(u32 Count)
|
|
||||||
{
|
|
||||||
mSectionCount = Count;
|
|
||||||
mSectionSizes.resize(Count);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSectionMgrOut::Init(const IOutputStream& OutputStream)
|
|
||||||
{
|
|
||||||
mCurSectionStart = OutputStream.Tell();
|
|
||||||
mCurSectionIndex = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSectionMgrOut::AddSize(IOutputStream& OutputStream)
|
|
||||||
{
|
|
||||||
mSectionSizes[mCurSectionIndex] = OutputStream.Tell() - mCurSectionStart;
|
|
||||||
mCurSectionIndex++;
|
|
||||||
mCurSectionStart = OutputStream.Tell();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSectionMgrOut::WriteSizes(IOutputStream& OutputStream)
|
|
||||||
{
|
|
||||||
for (u32 iSec = 0; iSec < mSectionCount; iSec++)
|
|
||||||
OutputStream.WriteLong(mSectionSizes[iSec]);
|
|
||||||
}
|
|
|
@ -14,11 +14,36 @@ class CSectionMgrOut
|
||||||
std::vector<u32> mSectionSizes;
|
std::vector<u32> mSectionSizes;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CSectionMgrOut();
|
CSectionMgrOut()
|
||||||
void SetSectionCount(u32 Count);
|
: mSectionCount(0)
|
||||||
void Init(const IOutputStream& OutputStream);
|
, mCurSectionStart(0)
|
||||||
void AddSize(IOutputStream& OutputStream);
|
, mCurSectionIndex(0)
|
||||||
void WriteSizes(IOutputStream& OutputStream);
|
{}
|
||||||
|
|
||||||
|
void SetSectionCount(u32 Count)
|
||||||
|
{
|
||||||
|
mSectionCount = Count;
|
||||||
|
mSectionSizes.resize(Count);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Init(const IOutputStream& rOut)
|
||||||
|
{
|
||||||
|
mCurSectionStart = rOut.Tell();
|
||||||
|
mCurSectionIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddSize(IOutputStream& rOut)
|
||||||
|
{
|
||||||
|
mSectionSizes[mCurSectionIndex] = rOut.Tell() - mCurSectionStart;
|
||||||
|
mCurSectionIndex++;
|
||||||
|
mCurSectionStart = rOut.Tell();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WriteSizes(IOutputStream& rOut)
|
||||||
|
{
|
||||||
|
for (u32 iSec = 0; iSec < mSectionCount; iSec++)
|
||||||
|
rOut.WriteLong(mSectionSizes[iSec]);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CBLOCKMGROUT_H
|
#endif // CBLOCKMGROUT_H
|
||||||
|
|
|
@ -41,7 +41,7 @@ void CTemplateWriter::SavePropertyTemplate(IPropertyTemplate *pTemp)
|
||||||
void CTemplateWriter::SaveAllTemplates()
|
void CTemplateWriter::SaveAllTemplates()
|
||||||
{
|
{
|
||||||
// Create directory
|
// Create directory
|
||||||
std::list<CMasterTemplate*> MasterList = CMasterTemplate::GetMasterList();
|
std::list<CMasterTemplate*> MasterList = CMasterTemplate::MasterList();
|
||||||
boost::filesystem::create_directory(smTemplatesDir.ToStdString());
|
boost::filesystem::create_directory(smTemplatesDir.ToStdString());
|
||||||
|
|
||||||
// Resave property list
|
// Resave property list
|
||||||
|
@ -77,8 +77,8 @@ void CTemplateWriter::SaveAllTemplates()
|
||||||
pGame->LinkEndChild(pGameName);
|
pGame->LinkEndChild(pGameName);
|
||||||
|
|
||||||
XMLElement *pAreaVersion = GameList.NewElement("mrea");
|
XMLElement *pAreaVersion = GameList.NewElement("mrea");
|
||||||
u32 VersionNumber = CAreaCooker::GetMREAVersion(pMaster->GetGame());
|
u32 VersionNumber = CAreaCooker::GetMREAVersion(pMaster->Game());
|
||||||
pAreaVersion->SetText(*TString::HexString(VersionNumber, true, true, 2));
|
pAreaVersion->SetText(*TString::HexString(VersionNumber, 2));
|
||||||
pGame->LinkEndChild(pAreaVersion);
|
pGame->LinkEndChild(pAreaVersion);
|
||||||
|
|
||||||
XMLElement *pTempPath = GameList.NewElement("master");
|
XMLElement *pTempPath = GameList.NewElement("master");
|
||||||
|
@ -139,7 +139,7 @@ void CTemplateWriter::SaveGameTemplates(CMasterTemplate *pMaster)
|
||||||
|
|
||||||
TString StrID;
|
TString StrID;
|
||||||
if (ObjID <= 0xFF)
|
if (ObjID <= 0xFF)
|
||||||
StrID = TString::HexString(ObjID, true, true, 2);
|
StrID = TString::HexString(ObjID, 2);
|
||||||
else
|
else
|
||||||
StrID = CFourCC(ObjID).ToString();
|
StrID = CFourCC(ObjID).ToString();
|
||||||
|
|
||||||
|
@ -177,7 +177,7 @@ void CTemplateWriter::SaveGameTemplates(CMasterTemplate *pMaster)
|
||||||
}
|
}
|
||||||
|
|
||||||
TString StrID;
|
TString StrID;
|
||||||
if (ID <= 0xFF) StrID = TString::HexString(ID, true, true, 2);
|
if (ID <= 0xFF) StrID = TString::HexString(ID, 2);
|
||||||
else StrID = CFourCC(ID).ToString();
|
else StrID = CFourCC(ID).ToString();
|
||||||
|
|
||||||
XMLElement *pSubElem = Master.NewElement(*Type);
|
XMLElement *pSubElem = Master.NewElement(*Type);
|
||||||
|
@ -210,7 +210,7 @@ void CTemplateWriter::SavePropertyList()
|
||||||
TString Name = it->second;
|
TString Name = it->second;
|
||||||
|
|
||||||
XMLElement *pElem = List.NewElement("property");
|
XMLElement *pElem = List.NewElement("property");
|
||||||
pElem->SetAttribute("ID", *TString::HexString(ID, true, true, 8));
|
pElem->SetAttribute("ID", *TString::HexString(ID));
|
||||||
pElem->SetAttribute("name", *Name);
|
pElem->SetAttribute("name", *Name);
|
||||||
pBase->LinkEndChild(pElem);
|
pBase->LinkEndChild(pElem);
|
||||||
}
|
}
|
||||||
|
@ -262,7 +262,7 @@ void CTemplateWriter::SaveScriptTemplate(CScriptTemplate *pTemp)
|
||||||
XMLElement *pEditorProperties = ScriptXML.NewElement("properties");
|
XMLElement *pEditorProperties = ScriptXML.NewElement("properties");
|
||||||
pEditor->LinkEndChild(pEditorProperties);
|
pEditor->LinkEndChild(pEditorProperties);
|
||||||
|
|
||||||
TString propNames[6] = {
|
TString PropNames[6] = {
|
||||||
"InstanceName", "Position", "Rotation",
|
"InstanceName", "Position", "Rotation",
|
||||||
"Scale", "Active", "LightParameters"
|
"Scale", "Active", "LightParameters"
|
||||||
};
|
};
|
||||||
|
@ -277,7 +277,7 @@ void CTemplateWriter::SaveScriptTemplate(CScriptTemplate *pTemp)
|
||||||
if (!pPropStrings[iProp]->IsEmpty())
|
if (!pPropStrings[iProp]->IsEmpty())
|
||||||
{
|
{
|
||||||
XMLElement *pProperty = ScriptXML.NewElement("property");
|
XMLElement *pProperty = ScriptXML.NewElement("property");
|
||||||
pProperty->SetAttribute("name", *propNames[iProp]);
|
pProperty->SetAttribute("name", *PropNames[iProp]);
|
||||||
pProperty->SetAttribute("ID", **pPropStrings[iProp]);
|
pProperty->SetAttribute("ID", **pPropStrings[iProp]);
|
||||||
pEditorProperties->LinkEndChild(pProperty);
|
pEditorProperties->LinkEndChild(pProperty);
|
||||||
}
|
}
|
||||||
|
@ -373,7 +373,7 @@ void CTemplateWriter::SaveScriptTemplate(CScriptTemplate *pTemp)
|
||||||
if (pProp->Type() == eBoolProperty)
|
if (pProp->Type() == eBoolProperty)
|
||||||
StrVal = (it->Value == 1 ? "true" : "false");
|
StrVal = (it->Value == 1 ? "true" : "false");
|
||||||
else
|
else
|
||||||
StrVal = TString::HexString((u32) it->Value, true, true, (it->Value > 0xFF ? 8 : 2));
|
StrVal = TString::HexString((u32) it->Value, (it->Value > 0xFF ? 8 : 2));
|
||||||
|
|
||||||
XMLElement *pCondition = ScriptXML.NewElement("condition");
|
XMLElement *pCondition = ScriptXML.NewElement("condition");
|
||||||
pCondition->SetAttribute("value", *StrVal);
|
pCondition->SetAttribute("value", *StrVal);
|
||||||
|
@ -469,7 +469,7 @@ void CTemplateWriter::SaveProperties(XMLDocument *pDoc, XMLElement *pParent, CSt
|
||||||
// Get ID
|
// Get ID
|
||||||
IPropertyTemplate *pProp = pTemp->PropertyByIndex(iProp);
|
IPropertyTemplate *pProp = pTemp->PropertyByIndex(iProp);
|
||||||
u32 ID = pProp->PropertyID();
|
u32 ID = pProp->PropertyID();
|
||||||
TString StrID = TString::HexString(ID, true, true, (ID > 0xFF ? 8 : 2));
|
TString StrID = TString::HexString(ID, (ID > 0xFF ? 8 : 2));
|
||||||
|
|
||||||
// Create element
|
// Create element
|
||||||
XMLElement *pElem;
|
XMLElement *pElem;
|
||||||
|
@ -495,7 +495,7 @@ void CTemplateWriter::SaveProperties(XMLDocument *pDoc, XMLElement *pParent, CSt
|
||||||
|
|
||||||
if (pProp->Game() >= eEchoesDemo && ID > 0xFF)
|
if (pProp->Game() >= eEchoesDemo && ID > 0xFF)
|
||||||
{
|
{
|
||||||
TString MasterName = CMasterTemplate::GetPropertyName(ID);
|
TString MasterName = CMasterTemplate::PropertyName(ID);
|
||||||
|
|
||||||
if (Name != MasterName)
|
if (Name != MasterName)
|
||||||
pElem->SetAttribute("name", *Name);
|
pElem->SetAttribute("name", *Name);
|
||||||
|
@ -652,7 +652,7 @@ void CTemplateWriter::SaveProperties(XMLDocument *pDoc, XMLElement *pParent, CSt
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CStructTemplate *pOriginal = pMaster->GetStructAtSource(pStruct->mSourceFile);
|
CStructTemplate *pOriginal = pMaster->StructAtSource(pStruct->mSourceFile);
|
||||||
|
|
||||||
if (pOriginal)
|
if (pOriginal)
|
||||||
SavePropertyOverrides(pDoc, pElem, pStruct, pOriginal);
|
SavePropertyOverrides(pDoc, pElem, pStruct, pOriginal);
|
||||||
|
@ -696,7 +696,7 @@ void CTemplateWriter::SavePropertyOverrides(XMLDocument *pDoc, XMLElement *pPare
|
||||||
|
|
||||||
// ID
|
// ID
|
||||||
u32 ID = pProp->PropertyID();
|
u32 ID = pProp->PropertyID();
|
||||||
pElem->SetAttribute("ID", *TString::HexString(pProp->PropertyID(), true, true, (ID > 0xFF ? 8 : 2)));
|
pElem->SetAttribute("ID", *TString::HexString(pProp->PropertyID(), (ID > 0xFF ? 8 : 2)));
|
||||||
|
|
||||||
// Name
|
// Name
|
||||||
if (pProp->Name() != pSource->Name())
|
if (pProp->Name() != pSource->Name())
|
||||||
|
@ -793,7 +793,7 @@ void CTemplateWriter::SaveEnumerators(XMLDocument *pDoc, XMLElement *pParent, CE
|
||||||
{
|
{
|
||||||
XMLElement *pElem = pDoc->NewElement("enumerator");
|
XMLElement *pElem = pDoc->NewElement("enumerator");
|
||||||
u32 EnumerID = pTemp->EnumeratorID(iEnum);
|
u32 EnumerID = pTemp->EnumeratorID(iEnum);
|
||||||
pElem->SetAttribute("ID", *TString::HexString(EnumerID, true, true, (EnumerID > 0xFF ? 8 : 2)));
|
pElem->SetAttribute("ID", *TString::HexString(EnumerID, (EnumerID > 0xFF ? 8 : 2)));
|
||||||
pElem->SetAttribute("name", *pTemp->EnumeratorName(iEnum));
|
pElem->SetAttribute("name", *pTemp->EnumeratorName(iEnum));
|
||||||
pEnumerators->LinkEndChild(pElem);
|
pEnumerators->LinkEndChild(pElem);
|
||||||
}
|
}
|
||||||
|
@ -807,7 +807,7 @@ void CTemplateWriter::SaveBitFlags(XMLDocument *pDoc, XMLElement *pParent, CBitf
|
||||||
for (u32 iFlag = 0; iFlag < pTemp->NumFlags(); iFlag++)
|
for (u32 iFlag = 0; iFlag < pTemp->NumFlags(); iFlag++)
|
||||||
{
|
{
|
||||||
XMLElement *pElem = pDoc->NewElement("flag");
|
XMLElement *pElem = pDoc->NewElement("flag");
|
||||||
pElem->SetAttribute("mask", *TString::HexString(pTemp->FlagMask(iFlag), true, true, 8));
|
pElem->SetAttribute("mask", *TString::HexString(pTemp->FlagMask(iFlag)));
|
||||||
pElem->SetAttribute("name", *pTemp->FlagName(iFlag));
|
pElem->SetAttribute("name", *pTemp->FlagName(iFlag));
|
||||||
pFlags->LinkEndChild(pElem);
|
pFlags->LinkEndChild(pElem);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,34 +2,34 @@
|
||||||
#include <Common/Log.h>
|
#include <Common/Log.h>
|
||||||
|
|
||||||
CTextureEncoder::CTextureEncoder()
|
CTextureEncoder::CTextureEncoder()
|
||||||
|
: mpTexture(nullptr)
|
||||||
{
|
{
|
||||||
mpTexture = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CTextureEncoder::WriteTXTR(IOutputStream& TXTR)
|
void CTextureEncoder::WriteTXTR(IOutputStream& rTXTR)
|
||||||
{
|
{
|
||||||
// Only DXT1->CMPR supported at the moment
|
// Only DXT1->CMPR supported at the moment
|
||||||
TXTR.WriteLong(mOutputFormat);
|
rTXTR.WriteLong(mOutputFormat);
|
||||||
TXTR.WriteShort(mpTexture->mWidth);
|
rTXTR.WriteShort(mpTexture->mWidth);
|
||||||
TXTR.WriteShort(mpTexture->mHeight);
|
rTXTR.WriteShort(mpTexture->mHeight);
|
||||||
TXTR.WriteLong(mpTexture->mNumMipMaps);
|
rTXTR.WriteLong(mpTexture->mNumMipMaps);
|
||||||
|
|
||||||
u32 MipW = mpTexture->Width() / 4;
|
u32 MipW = mpTexture->Width() / 4;
|
||||||
u32 MipH = mpTexture->Height() / 4;
|
u32 MipH = mpTexture->Height() / 4;
|
||||||
CMemoryInStream Image(mpTexture->mImgDataBuffer, mpTexture->mImgDataSize, IOUtil::eLittleEndian);
|
CMemoryInStream Image(mpTexture->mpImgDataBuffer, mpTexture->mImgDataSize, IOUtil::eLittleEndian);
|
||||||
u32 MipOffset = Image.Tell();
|
u32 MipOffset = Image.Tell();
|
||||||
|
|
||||||
for (u32 iMip = 0; iMip < mpTexture->mNumMipMaps; iMip++)
|
for (u32 iMip = 0; iMip < mpTexture->mNumMipMaps; iMip++)
|
||||||
{
|
{
|
||||||
for (u32 BlockY = 0; BlockY < MipH; BlockY += 2)
|
for (u32 iBlockY = 0; iBlockY < MipH; iBlockY += 2)
|
||||||
for (u32 BlockX = 0; BlockX < MipW; BlockX += 2)
|
for (u32 iBlockX = 0; iBlockX < MipW; iBlockX += 2)
|
||||||
for (u32 ImgY = BlockY; ImgY < BlockY + 2; ImgY++)
|
for (u32 iImgY = iBlockY; iImgY < iBlockY + 2; iImgY++)
|
||||||
for (u32 ImgX = BlockX; ImgX < BlockX + 2; ImgX++)
|
for (u32 iImgX = iBlockX; iImgX < iBlockX + 2; iImgX++)
|
||||||
{
|
{
|
||||||
u32 SrcPos = ((ImgY * MipW) + ImgX) * 8;
|
u32 SrcPos = ((iImgY * MipW) + iImgX) * 8;
|
||||||
Image.Seek(MipOffset + SrcPos, SEEK_SET);
|
Image.Seek(MipOffset + SrcPos, SEEK_SET);
|
||||||
|
|
||||||
ReadSubBlockCMPR(Image, TXTR);
|
ReadSubBlockCMPR(Image, rTXTR);
|
||||||
}
|
}
|
||||||
|
|
||||||
MipOffset += MipW * MipH * 8;
|
MipOffset += MipW * MipH * 8;
|
||||||
|
@ -45,20 +45,21 @@ void CTextureEncoder::DetermineBestOutputFormat()
|
||||||
// todo
|
// todo
|
||||||
}
|
}
|
||||||
|
|
||||||
void CTextureEncoder::ReadSubBlockCMPR(IInputStream& Source, IOutputStream& Dest)
|
void CTextureEncoder::ReadSubBlockCMPR(IInputStream& rSource, IOutputStream& rDest)
|
||||||
{
|
{
|
||||||
Dest.WriteShort(Source.ReadShort());
|
rDest.WriteShort(rSource.ReadShort());
|
||||||
Dest.WriteShort(Source.ReadShort());
|
rDest.WriteShort(rSource.ReadShort());
|
||||||
|
|
||||||
for (u32 byte = 0; byte < 4; byte++) {
|
for (u32 iByte = 0; iByte < 4; iByte++)
|
||||||
u8 b = Source.ReadByte();
|
{
|
||||||
b = ((b & 0x3) << 6) | ((b & 0xC) << 2) | ((b & 0x30) >> 2) | ((b & 0xC0) >> 6);
|
u8 Byte = rSource.ReadByte();
|
||||||
Dest.WriteByte(b);
|
Byte = ((Byte & 0x3) << 6) | ((Byte & 0xC) << 2) | ((Byte & 0x30) >> 2) | ((Byte & 0xC0) >> 6);
|
||||||
|
rDest.WriteByte(Byte);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ************ STATIC ************
|
// ************ STATIC ************
|
||||||
void CTextureEncoder::EncodeTXTR(IOutputStream& TXTR, CTexture *pTex)
|
void CTextureEncoder::EncodeTXTR(IOutputStream& rTXTR, CTexture *pTex)
|
||||||
{
|
{
|
||||||
if (pTex->mTexelFormat != eDXT1)
|
if (pTex->mTexelFormat != eDXT1)
|
||||||
{
|
{
|
||||||
|
@ -70,13 +71,13 @@ void CTextureEncoder::EncodeTXTR(IOutputStream& TXTR, CTexture *pTex)
|
||||||
Encoder.mpTexture = pTex;
|
Encoder.mpTexture = pTex;
|
||||||
Encoder.mSourceFormat = eDXT1;
|
Encoder.mSourceFormat = eDXT1;
|
||||||
Encoder.mOutputFormat = eGX_CMPR;
|
Encoder.mOutputFormat = eGX_CMPR;
|
||||||
Encoder.WriteTXTR(TXTR);
|
Encoder.WriteTXTR(rTXTR);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CTextureEncoder::EncodeTXTR(IOutputStream& TXTR, CTexture *pTex, ETexelFormat /*OutputFormat*/)
|
void CTextureEncoder::EncodeTXTR(IOutputStream& rTXTR, CTexture *pTex, ETexelFormat /*OutputFormat*/)
|
||||||
{
|
{
|
||||||
// todo: support for encoding a specific format
|
// todo: support for encoding a specific format
|
||||||
EncodeTXTR(TXTR, pTex);
|
EncodeTXTR(rTXTR, pTex);
|
||||||
}
|
}
|
||||||
|
|
||||||
ETexelFormat CTextureEncoder::GetGXFormat(ETexelFormat Format)
|
ETexelFormat CTextureEncoder::GetGXFormat(ETexelFormat Format)
|
||||||
|
|
|
@ -13,13 +13,13 @@ class CTextureEncoder
|
||||||
ETexelFormat mOutputFormat;
|
ETexelFormat mOutputFormat;
|
||||||
|
|
||||||
CTextureEncoder();
|
CTextureEncoder();
|
||||||
void WriteTXTR(IOutputStream& TXTR);
|
void WriteTXTR(IOutputStream& rTXTR);
|
||||||
void DetermineBestOutputFormat();
|
void DetermineBestOutputFormat();
|
||||||
void ReadSubBlockCMPR(IInputStream& Source, IOutputStream& Dest);
|
void ReadSubBlockCMPR(IInputStream& rSource, IOutputStream& rDest);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static void EncodeTXTR(IOutputStream& TXTR, CTexture *pTex);
|
static void EncodeTXTR(IOutputStream& rTXTR, CTexture *pTex);
|
||||||
static void EncodeTXTR(IOutputStream& TXTR, CTexture *pTex, ETexelFormat OutputFormat);
|
static void EncodeTXTR(IOutputStream& rTXTR, CTexture *pTex, ETexelFormat OutputFormat);
|
||||||
static ETexelFormat GetGXFormat(ETexelFormat Format);
|
static ETexelFormat GetGXFormat(ETexelFormat Format);
|
||||||
static ETexelFormat GetFormat(ETexelFormat Format);
|
static ETexelFormat GetFormat(ETexelFormat Format);
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,9 +4,9 @@ CWorldCooker::CWorldCooker()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 CWorldCooker::GetMLVLVersion(EGame version)
|
u32 CWorldCooker::GetMLVLVersion(EGame Version)
|
||||||
{
|
{
|
||||||
switch (version)
|
switch (Version)
|
||||||
{
|
{
|
||||||
case ePrimeDemo: return 0xD;
|
case ePrimeDemo: return 0xD;
|
||||||
case ePrime: return 0x11;
|
case ePrime: return 0x11;
|
||||||
|
|
|
@ -8,7 +8,7 @@ class CWorldCooker
|
||||||
{
|
{
|
||||||
CWorldCooker();
|
CWorldCooker();
|
||||||
public:
|
public:
|
||||||
static u32 GetMLVLVersion(EGame version);
|
static u32 GetMLVLVersion(EGame Version);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CWORLDCOOKER_H
|
#endif // CWORLDCOOKER_H
|
||||||
|
|
|
@ -6,189 +6,192 @@ CAnimSetLoader::CAnimSetLoader()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
CAnimSet* CAnimSetLoader::LoadCorruptionCHAR(IInputStream& CHAR)
|
CAnimSet* CAnimSetLoader::LoadCorruptionCHAR(IInputStream& rCHAR)
|
||||||
{
|
{
|
||||||
// For now, we only read enough to fetch the model
|
// For now, we only read enough to fetch the model
|
||||||
CHAR.Seek(0x1, SEEK_CUR);
|
rCHAR.Seek(0x1, SEEK_CUR);
|
||||||
set->nodes.resize(1);
|
pSet->mNodes.resize(1);
|
||||||
CAnimSet::SNode& node = set->nodes[0];
|
CAnimSet::SNode& node = pSet->mNodes[0];
|
||||||
|
|
||||||
node.name = CHAR.ReadString();
|
node.Name = rCHAR.ReadString();
|
||||||
node.model = gResCache.GetResource(CHAR.ReadLongLong(), "CMDL");
|
node.pModel = gResCache.GetResource(rCHAR.ReadLongLong(), "CMDL");
|
||||||
return set;
|
return pSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
CAnimSet* CAnimSetLoader::LoadReturnsCHAR(IInputStream& CHAR)
|
CAnimSet* CAnimSetLoader::LoadReturnsCHAR(IInputStream& rCHAR)
|
||||||
{
|
{
|
||||||
// For now, we only read enough to fetch the model
|
// For now, we only read enough to fetch the model
|
||||||
CHAR.Seek(0x16, SEEK_CUR);
|
rCHAR.Seek(0x16, SEEK_CUR);
|
||||||
set->nodes.resize(1);
|
pSet->mNodes.resize(1);
|
||||||
CAnimSet::SNode& node = set->nodes[0];
|
CAnimSet::SNode& rNode = pSet->mNodes[0];
|
||||||
|
|
||||||
node.name = CHAR.ReadString();
|
rNode.Name = rCHAR.ReadString();
|
||||||
CHAR.Seek(0x14, SEEK_CUR);
|
rCHAR.Seek(0x14, SEEK_CUR);
|
||||||
CHAR.ReadString();
|
rCHAR.ReadString();
|
||||||
node.model = gResCache.GetResource(CHAR.ReadLongLong(), "CMDL");
|
rNode.pModel = gResCache.GetResource(rCHAR.ReadLongLong(), "CMDL");
|
||||||
return set;
|
return pSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CAnimSetLoader::LoadPASDatabase(IInputStream& PAS4)
|
void CAnimSetLoader::LoadPASDatabase(IInputStream& rPAS4)
|
||||||
{
|
{
|
||||||
// For now, just parse the data; don't store it
|
// For now, just parse the data; don't store it
|
||||||
PAS4.Seek(0x4, SEEK_CUR); // Skipping PAS4 FourCC
|
rPAS4.Seek(0x4, SEEK_CUR); // Skipping PAS4 FourCC
|
||||||
u32 anim_state_count = PAS4.ReadLong();
|
u32 AnimStateCount = rPAS4.ReadLong();
|
||||||
PAS4.Seek(0x4, SEEK_CUR); // Skipping default anim state
|
rPAS4.Seek(0x4, SEEK_CUR); // Skipping default anim state
|
||||||
|
|
||||||
for (u32 s = 0; s < anim_state_count; s++)
|
for (u32 iState = 0; iState < AnimStateCount; iState++)
|
||||||
{
|
{
|
||||||
PAS4.Seek(0x4, SEEK_CUR); // Skipping unknown value
|
rPAS4.Seek(0x4, SEEK_CUR); // Skipping unknown value
|
||||||
u32 parm_info_count = PAS4.ReadLong();
|
u32 ParmInfoCount = rPAS4.ReadLong();
|
||||||
u32 anim_info_count = PAS4.ReadLong();
|
u32 AnimInfoCount = rPAS4.ReadLong();
|
||||||
|
|
||||||
u32 skip = 0;
|
u32 Skip = 0;
|
||||||
for (u32 p = 0; p < parm_info_count; p++)
|
for (u32 iParm = 0; iParm < ParmInfoCount; iParm++)
|
||||||
{
|
{
|
||||||
u32 type = PAS4.ReadLong();
|
u32 Type = rPAS4.ReadLong();
|
||||||
PAS4.Seek(0x8, SEEK_CUR);
|
rPAS4.Seek(0x8, SEEK_CUR);
|
||||||
|
|
||||||
switch (type) {
|
switch (Type) {
|
||||||
case 0: // Int32
|
case 0: // Int32
|
||||||
case 1: // Uint32
|
case 1: // Uint32
|
||||||
case 2: // Real32
|
case 2: // Real32
|
||||||
case 4: // Enum
|
case 4: // Enum
|
||||||
PAS4.Seek(0x8, SEEK_CUR);
|
rPAS4.Seek(0x8, SEEK_CUR);
|
||||||
skip += 4;
|
Skip += 4;
|
||||||
break;
|
break;
|
||||||
case 3: // Bool
|
case 3: // Bool
|
||||||
PAS4.Seek(0x2, SEEK_CUR);
|
rPAS4.Seek(0x2, SEEK_CUR);
|
||||||
skip++;
|
Skip++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (u32 a = 0; a < anim_info_count; a++)
|
for (u32 iInfo = 0; iInfo < AnimInfoCount; iInfo++)
|
||||||
PAS4.Seek(0x4 + skip, SEEK_CUR);
|
rPAS4.Seek(0x4 + Skip, SEEK_CUR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ************ STATIC ************
|
// ************ STATIC ************
|
||||||
CAnimSet* CAnimSetLoader::LoadANCS(IInputStream& ANCS)
|
CAnimSet* CAnimSetLoader::LoadANCS(IInputStream& rANCS)
|
||||||
{
|
{
|
||||||
if (!ANCS.IsValid()) return nullptr;
|
if (!rANCS.IsValid()) return nullptr;
|
||||||
|
|
||||||
u32 magic = ANCS.ReadLong();
|
u32 Magic = rANCS.ReadLong();
|
||||||
if (magic != 0x00010001)
|
if (Magic != 0x00010001)
|
||||||
{
|
{
|
||||||
Log::FileError(ANCS.GetSourceString(), "Invalid ANCS magic: " + TString::HexString(magic));
|
Log::FileError(rANCS.GetSourceString(), "Invalid ANCS magic: " + TString::HexString(Magic));
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
CAnimSetLoader loader;
|
CAnimSetLoader Loader;
|
||||||
loader.set = new CAnimSet;
|
Loader.pSet = new CAnimSet;
|
||||||
|
|
||||||
u32 node_count = ANCS.ReadLong();
|
u32 NodeCount = rANCS.ReadLong();
|
||||||
loader.set->nodes.resize(node_count);
|
Loader.pSet->mNodes.resize(NodeCount);
|
||||||
|
|
||||||
for (u32 n = 0; n < node_count; n++)
|
for (u32 iNode = 0; iNode < NodeCount; iNode++)
|
||||||
{
|
{
|
||||||
CAnimSet::SNode *node = &loader.set->nodes[n];
|
CAnimSet::SNode *pNode = &Loader.pSet->mNodes[iNode];
|
||||||
|
|
||||||
ANCS.Seek(0x4, SEEK_CUR); // Skipping node self-index
|
rANCS.Seek(0x4, SEEK_CUR); // Skipping node self-index
|
||||||
u16 unknown1 = ANCS.ReadShort();
|
u16 Unknown1 = rANCS.ReadShort();
|
||||||
if (n == 0) loader.mVersion = (unknown1 == 0xA) ? eEchoes : ePrime; // Best version indicator we know of unfortunately
|
if (iNode == 0) Loader.mVersion = (Unknown1 == 0xA) ? eEchoes : ePrime; // Best version indicator we know of unfortunately
|
||||||
node->name = ANCS.ReadString();
|
pNode->Name = rANCS.ReadString();
|
||||||
node->model = gResCache.GetResource(ANCS.ReadLong(), "CMDL");
|
pNode->pModel = gResCache.GetResource(rANCS.ReadLong(), "CMDL");
|
||||||
node->skinID = ANCS.ReadLong();
|
pNode->SkinID = rANCS.ReadLong();
|
||||||
node->skelID = ANCS.ReadLong();
|
pNode->SkelID = rANCS.ReadLong();
|
||||||
|
|
||||||
// Unfortunately that's all that's actually supported at the moment. Hope to expand later.
|
// Unfortunately that's all that's actually supported at the moment. Hope to expand later.
|
||||||
// Since there's no size value I have to actually read the rest of the node to reach the next one
|
// Since there's no size value I have to actually read the rest of the node to reach the next one
|
||||||
u32 anim_count = ANCS.ReadLong();
|
u32 AnimCount = rANCS.ReadLong();
|
||||||
for (u32 a = 0; a < anim_count; a++)
|
for (u32 iAnim = 0; iAnim < AnimCount; iAnim++)
|
||||||
{
|
{
|
||||||
ANCS.Seek(0x4, SEEK_CUR);
|
rANCS.Seek(0x4, SEEK_CUR);
|
||||||
if (loader.mVersion == ePrime) ANCS.Seek(0x1, SEEK_CUR);
|
if (Loader.mVersion == ePrime) rANCS.Seek(0x1, SEEK_CUR);
|
||||||
ANCS.ReadString();
|
rANCS.ReadString();
|
||||||
}
|
}
|
||||||
|
|
||||||
// PAS Database
|
// PAS Database
|
||||||
loader.LoadPASDatabase(ANCS);
|
Loader.LoadPASDatabase(rANCS);
|
||||||
|
|
||||||
// Particles
|
// Particles
|
||||||
u32 particle_count = ANCS.ReadLong();
|
u32 ParticleCount = rANCS.ReadLong();
|
||||||
ANCS.Seek(particle_count * 4, SEEK_CUR);
|
rANCS.Seek(ParticleCount * 4, SEEK_CUR);
|
||||||
u32 swoosh_count = ANCS.ReadLong();
|
u32 SwooshCount = rANCS.ReadLong();
|
||||||
ANCS.Seek(swoosh_count * 4, SEEK_CUR);
|
rANCS.Seek(SwooshCount * 4, SEEK_CUR);
|
||||||
if (unknown1 != 5) ANCS.Seek(0x4, SEEK_CUR);
|
if (Unknown1 != 5) rANCS.Seek(0x4, SEEK_CUR);
|
||||||
u32 electric_count = ANCS.ReadLong();
|
u32 ElectricCount = rANCS.ReadLong();
|
||||||
ANCS.Seek(electric_count * 4, SEEK_CUR);
|
rANCS.Seek(ElectricCount * 4, SEEK_CUR);
|
||||||
if (loader.mVersion == eEchoes) {
|
|
||||||
u32 spsc_count = ANCS.ReadLong();
|
|
||||||
ANCS.Seek(spsc_count * 4, SEEK_CUR);
|
|
||||||
}
|
|
||||||
ANCS.Seek(0x4, SEEK_CUR);
|
|
||||||
if (loader.mVersion == eEchoes) ANCS.Seek(0x4, SEEK_CUR);
|
|
||||||
|
|
||||||
u32 anim_count2 = ANCS.ReadLong();
|
if (Loader.mVersion == eEchoes)
|
||||||
for (u32 a = 0; a < anim_count2; a++)
|
|
||||||
{
|
{
|
||||||
ANCS.ReadString();
|
u32 SPSCCount = rANCS.ReadLong();
|
||||||
ANCS.Seek(0x18, SEEK_CUR);
|
rANCS.Seek(SPSCCount * 4, SEEK_CUR);
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 EffectGroupCount = ANCS.ReadLong();
|
rANCS.Seek(0x4, SEEK_CUR);
|
||||||
for (u32 g = 0; g < EffectGroupCount; g++)
|
if (Loader.mVersion == eEchoes) rANCS.Seek(0x4, SEEK_CUR);
|
||||||
{
|
|
||||||
ANCS.ReadString();
|
|
||||||
u32 EffectCount = ANCS.ReadLong();
|
|
||||||
|
|
||||||
for (u32 e = 0; e < EffectCount; e++)
|
u32 AnimCount2 = rANCS.ReadLong();
|
||||||
|
for (u32 iAnim = 0; iAnim < AnimCount2; iAnim++)
|
||||||
{
|
{
|
||||||
ANCS.ReadString();
|
rANCS.ReadString();
|
||||||
ANCS.Seek(0x8, SEEK_CUR);
|
rANCS.Seek(0x18, SEEK_CUR);
|
||||||
if (loader.mVersion == ePrime) ANCS.ReadString();
|
}
|
||||||
if (loader.mVersion == eEchoes) ANCS.Seek(0x4, SEEK_CUR);
|
|
||||||
ANCS.Seek(0xC, SEEK_CUR);
|
u32 EffectGroupCount = rANCS.ReadLong();
|
||||||
|
for (u32 iGrp = 0; iGrp < EffectGroupCount; iGrp++)
|
||||||
|
{
|
||||||
|
rANCS.ReadString();
|
||||||
|
u32 EffectCount = rANCS.ReadLong();
|
||||||
|
|
||||||
|
for (u32 iEffect = 0; iEffect < EffectCount; iEffect++)
|
||||||
|
{
|
||||||
|
rANCS.ReadString();
|
||||||
|
rANCS.Seek(0x8, SEEK_CUR);
|
||||||
|
if (Loader.mVersion == ePrime) rANCS.ReadString();
|
||||||
|
if (Loader.mVersion == eEchoes) rANCS.Seek(0x4, SEEK_CUR);
|
||||||
|
rANCS.Seek(0xC, SEEK_CUR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ANCS.Seek(0x8, SEEK_CUR);
|
rANCS.Seek(0x8, SEEK_CUR);
|
||||||
|
|
||||||
u32 unknown_count = ANCS.ReadLong();
|
u32 UnknownCount = rANCS.ReadLong();
|
||||||
ANCS.Seek(unknown_count * 4, SEEK_CUR);
|
rANCS.Seek(UnknownCount * 4, SEEK_CUR);
|
||||||
|
|
||||||
if (loader.mVersion == eEchoes)
|
if (Loader.mVersion == eEchoes)
|
||||||
{
|
{
|
||||||
ANCS.Seek(0x5, SEEK_CUR);
|
rANCS.Seek(0x5, SEEK_CUR);
|
||||||
u32 unknown_count2 = ANCS.ReadLong();
|
u32 UnknownCount2 = rANCS.ReadLong();
|
||||||
ANCS.Seek(unknown_count2 * 0x1C, SEEK_CUR);
|
rANCS.Seek(UnknownCount2 * 0x1C, SEEK_CUR);
|
||||||
}
|
}
|
||||||
// Lots of work for data I'm not even using x.x
|
// Lots of work for data I'm not even using x.x
|
||||||
}
|
}
|
||||||
|
|
||||||
return loader.set;
|
return Loader.pSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
CAnimSet* CAnimSetLoader::LoadCHAR(IInputStream &CHAR)
|
CAnimSet* CAnimSetLoader::LoadCHAR(IInputStream& rCHAR)
|
||||||
{
|
{
|
||||||
if (!CHAR.IsValid()) return nullptr;
|
if (!rCHAR.IsValid()) return nullptr;
|
||||||
|
|
||||||
CAnimSetLoader loader;
|
CAnimSetLoader Loader;
|
||||||
u8 check = CHAR.ReadByte();
|
u8 Check = rCHAR.ReadByte();
|
||||||
|
|
||||||
if (check == 0x5 || check == 0x3)
|
if (Check == 0x5 || Check == 0x3)
|
||||||
{
|
{
|
||||||
loader.mVersion = eCorruption;
|
Loader.mVersion = eCorruption;
|
||||||
loader.set = new CAnimSet();
|
Loader.pSet = new CAnimSet();
|
||||||
return loader.LoadCorruptionCHAR(CHAR);
|
return Loader.LoadCorruptionCHAR(rCHAR);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (check == 0x59)
|
if (Check == 0x59)
|
||||||
{
|
{
|
||||||
loader.mVersion = eReturns;
|
Loader.mVersion = eReturns;
|
||||||
loader.set = new CAnimSet();
|
Loader.pSet = new CAnimSet();
|
||||||
return loader.LoadReturnsCHAR(CHAR);
|
return Loader.LoadReturnsCHAR(rCHAR);
|
||||||
}
|
}
|
||||||
|
|
||||||
Log::FileError(CHAR.GetSourceString(), "CHAR has invalid first byte: " + TString::HexString(check));
|
Log::FileError(rCHAR.GetSourceString(), "CHAR has invalid first byte: " + TString::HexString(Check, 2));
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,18 +7,18 @@
|
||||||
|
|
||||||
class CAnimSetLoader
|
class CAnimSetLoader
|
||||||
{
|
{
|
||||||
TResPtr<CAnimSet> set;
|
TResPtr<CAnimSet> pSet;
|
||||||
CResCache *mpResCache;
|
CResCache *mpResCache;
|
||||||
EGame mVersion;
|
EGame mVersion;
|
||||||
|
|
||||||
CAnimSetLoader();
|
CAnimSetLoader();
|
||||||
CAnimSet* LoadCorruptionCHAR(IInputStream& CHAR);
|
CAnimSet* LoadCorruptionCHAR(IInputStream& rCHAR);
|
||||||
CAnimSet* LoadReturnsCHAR(IInputStream& CHAR);
|
CAnimSet* LoadReturnsCHAR(IInputStream& rCHAR);
|
||||||
void LoadPASDatabase(IInputStream& PAS4);
|
void LoadPASDatabase(IInputStream& rPAS4);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static CAnimSet* LoadANCS(IInputStream& ANCS);
|
static CAnimSet* LoadANCS(IInputStream& rANCS);
|
||||||
static CAnimSet* LoadCHAR(IInputStream& CHAR);
|
static CAnimSet* LoadCHAR(IInputStream& rCHAR);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CCHARACTERLOADER_H
|
#endif // CCHARACTERLOADER_H
|
||||||
|
|
|
@ -11,26 +11,26 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
CAreaLoader::CAreaLoader()
|
CAreaLoader::CAreaLoader()
|
||||||
|
: mpMREA(nullptr)
|
||||||
|
, mHasDecompressedBuffer(false)
|
||||||
|
, mGeometryBlockNum(-1)
|
||||||
|
, mScriptLayerBlockNum(-1)
|
||||||
|
, mCollisionBlockNum(-1)
|
||||||
|
, mUnknownBlockNum(-1)
|
||||||
|
, mLightsBlockNum(-1)
|
||||||
|
, mEmptyBlockNum(-1)
|
||||||
|
, mPathBlockNum(-1)
|
||||||
|
, mOctreeBlockNum(-1)
|
||||||
|
, mScriptGeneratorBlockNum(-1)
|
||||||
|
, mFFFFBlockNum(-1)
|
||||||
|
, mUnknown2BlockNum(-1)
|
||||||
|
, mEGMCBlockNum(-1)
|
||||||
|
, mBoundingBoxesBlockNum(-1)
|
||||||
|
, mDependenciesBlockNum(-1)
|
||||||
|
, mGPUBlockNum(-1)
|
||||||
|
, mPVSBlockNum(-1)
|
||||||
|
, mRSOBlockNum(-1)
|
||||||
{
|
{
|
||||||
mpMREA = nullptr;
|
|
||||||
mHasDecompressedBuffer = false;
|
|
||||||
mGeometryBlockNum = -1;
|
|
||||||
mScriptLayerBlockNum = -1;
|
|
||||||
mCollisionBlockNum = -1;
|
|
||||||
mUnknownBlockNum = -1;
|
|
||||||
mLightsBlockNum = -1;
|
|
||||||
mEmptyBlockNum = -1;
|
|
||||||
mPathBlockNum = -1;
|
|
||||||
mOctreeBlockNum = -1;
|
|
||||||
mScriptGeneratorBlockNum = -1;
|
|
||||||
mFFFFBlockNum = -1;
|
|
||||||
mUnknown2BlockNum = -1;
|
|
||||||
mEGMCBlockNum = -1;
|
|
||||||
mBoundingBoxesBlockNum = -1;
|
|
||||||
mDependenciesBlockNum = -1;
|
|
||||||
mGPUBlockNum = -1;
|
|
||||||
mPVSBlockNum = -1;
|
|
||||||
mRSOBlockNum = -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CAreaLoader::~CAreaLoader()
|
CAreaLoader::~CAreaLoader()
|
||||||
|
@ -38,7 +38,7 @@ CAreaLoader::~CAreaLoader()
|
||||||
if (mHasDecompressedBuffer)
|
if (mHasDecompressedBuffer)
|
||||||
{
|
{
|
||||||
delete mpMREA;
|
delete mpMREA;
|
||||||
delete[] mDecmpBuffer;
|
delete[] mpDecmpBuffer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,17 +177,17 @@ void CAreaLoader::ReadLightsPrime()
|
||||||
Log::FileWrite(mpMREA->GetSourceString(), "Reading MREA dynamic lights (MP1/MP2)");
|
Log::FileWrite(mpMREA->GetSourceString(), "Reading MREA dynamic lights (MP1/MP2)");
|
||||||
mpSectionMgr->ToSection(mLightsBlockNum);
|
mpSectionMgr->ToSection(mLightsBlockNum);
|
||||||
|
|
||||||
u32 babedead = mpMREA->ReadLong();
|
u32 BabeDead = mpMREA->ReadLong();
|
||||||
if (babedead != 0xbabedead) return;
|
if (BabeDead != 0xbabedead) return;
|
||||||
|
|
||||||
mpArea->mLightLayers.resize(2);
|
mpArea->mLightLayers.resize(2);
|
||||||
|
|
||||||
for (u32 ly = 0; ly < 2; ly++)
|
for (u32 iLyr = 0; iLyr < 2; iLyr++)
|
||||||
{
|
{
|
||||||
u32 NumLights = mpMREA->ReadLong();
|
u32 NumLights = mpMREA->ReadLong();
|
||||||
mpArea->mLightLayers[ly].resize(NumLights);
|
mpArea->mLightLayers[iLyr].resize(NumLights);
|
||||||
|
|
||||||
for (u32 l = 0; l < NumLights; l++)
|
for (u32 iLight = 0; iLight < NumLights; iLight++)
|
||||||
{
|
{
|
||||||
ELightType Type = ELightType(mpMREA->ReadLong());
|
ELightType Type = ELightType(mpMREA->ReadLong());
|
||||||
CVector3f Color(*mpMREA);
|
CVector3f Color(*mpMREA);
|
||||||
|
@ -200,9 +200,9 @@ void CAreaLoader::ReadLightsPrime()
|
||||||
mpMREA->Seek(0x4, SEEK_CUR);
|
mpMREA->Seek(0x4, SEEK_CUR);
|
||||||
|
|
||||||
// Relevant data is read - now we process and form a CLight out of it
|
// Relevant data is read - now we process and form a CLight out of it
|
||||||
CLight *Light;
|
CLight *pLight;
|
||||||
|
|
||||||
CColor LightColor = CColor(Color.x, Color.y, Color.z, 0.f);
|
CColor LightColor = CColor(Color.X, Color.Y, Color.Z, 0.f);
|
||||||
if (Multiplier < FLT_EPSILON)
|
if (Multiplier < FLT_EPSILON)
|
||||||
Multiplier = FLT_EPSILON;
|
Multiplier = FLT_EPSILON;
|
||||||
|
|
||||||
|
@ -212,29 +212,29 @@ void CAreaLoader::ReadLightsPrime()
|
||||||
Color *= Multiplier;
|
Color *= Multiplier;
|
||||||
|
|
||||||
// Clamp
|
// Clamp
|
||||||
if (Color.x > 1.f) Color.x = 1.f;
|
if (Color.X > 1.f) Color.X = 1.f;
|
||||||
if (Color.y > 1.f) Color.y = 1.f;
|
if (Color.Y > 1.f) Color.Y = 1.f;
|
||||||
if (Color.z > 1.f) Color.z = 1.f;
|
if (Color.Z > 1.f) Color.Z = 1.f;
|
||||||
CColor MultColor(Color.x, Color.y, Color.z, 1.f);
|
CColor MultColor(Color.X, Color.Y, Color.Z, 1.f);
|
||||||
|
|
||||||
Light = CLight::BuildLocalAmbient(Position, MultColor);
|
pLight = CLight::BuildLocalAmbient(Position, MultColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Directional
|
// Directional
|
||||||
else if (Type == eDirectional)
|
else if (Type == eDirectional)
|
||||||
{
|
{
|
||||||
Light = CLight::BuildDirectional(Position, Direction, LightColor);
|
pLight = CLight::BuildDirectional(Position, Direction, LightColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Spot
|
// Spot
|
||||||
else if (Type == eSpot)
|
else if (Type == eSpot)
|
||||||
{
|
{
|
||||||
Light = CLight::BuildSpot(Position, Direction.Normalized(), LightColor, SpotCutoff);
|
pLight = CLight::BuildSpot(Position, Direction.Normalized(), LightColor, SpotCutoff);
|
||||||
|
|
||||||
float DistAttenA = (FalloffType == 0) ? (2.f / Multiplier) : 0.f;
|
float DistAttenA = (FalloffType == 0) ? (2.f / Multiplier) : 0.f;
|
||||||
float DistAttenB = (FalloffType == 1) ? (250.f / Multiplier) : 0.f;
|
float DistAttenB = (FalloffType == 1) ? (250.f / Multiplier) : 0.f;
|
||||||
float DistAttenC = (FalloffType == 2) ? (25000.f / Multiplier) : 0.f;
|
float DistAttenC = (FalloffType == 2) ? (25000.f / Multiplier) : 0.f;
|
||||||
Light->SetDistAtten(DistAttenA, DistAttenB, DistAttenC);
|
pLight->SetDistAtten(DistAttenA, DistAttenB, DistAttenC);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Custom
|
// Custom
|
||||||
|
@ -244,13 +244,13 @@ void CAreaLoader::ReadLightsPrime()
|
||||||
float DistAttenB = (FalloffType == 1) ? (249.9998f / Multiplier) : 0.f;
|
float DistAttenB = (FalloffType == 1) ? (249.9998f / Multiplier) : 0.f;
|
||||||
float DistAttenC = (FalloffType == 2) ? (25000.f / Multiplier) : 0.f;
|
float DistAttenC = (FalloffType == 2) ? (25000.f / Multiplier) : 0.f;
|
||||||
|
|
||||||
Light = CLight::BuildCustom(Position, Direction, LightColor,
|
pLight = CLight::BuildCustom(Position, Direction, LightColor,
|
||||||
DistAttenA, DistAttenB, DistAttenC,
|
DistAttenA, DistAttenB, DistAttenC,
|
||||||
1.f, 0.f, 0.f);
|
1.f, 0.f, 0.f);
|
||||||
}
|
}
|
||||||
|
|
||||||
Light->SetLayer(ly);
|
pLight->SetLayer(iLyr);
|
||||||
mpArea->mLightLayers[ly][l] = Light;
|
mpArea->mLightLayers[iLyr][iLight] = pLight;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -435,8 +435,8 @@ void CAreaLoader::ReadLightsCorruption()
|
||||||
Log::FileWrite(mpMREA->GetSourceString(), "Reading MREA dynamic lights (MP3)");
|
Log::FileWrite(mpMREA->GetSourceString(), "Reading MREA dynamic lights (MP3)");
|
||||||
mpSectionMgr->ToSection(mLightsBlockNum);
|
mpSectionMgr->ToSection(mLightsBlockNum);
|
||||||
|
|
||||||
u32 babedead = mpMREA->ReadLong();
|
u32 BabeDead = mpMREA->ReadLong();
|
||||||
if (babedead != 0xbabedead) return;
|
if (BabeDead != 0xbabedead) return;
|
||||||
|
|
||||||
mpArea->mLightLayers.resize(4);
|
mpArea->mLightLayers.resize(4);
|
||||||
|
|
||||||
|
@ -449,11 +449,11 @@ void CAreaLoader::ReadLightsCorruption()
|
||||||
{
|
{
|
||||||
ELightType Type = (ELightType) mpMREA->ReadLong();
|
ELightType Type = (ELightType) mpMREA->ReadLong();
|
||||||
|
|
||||||
float r = mpMREA->ReadFloat();
|
float R = mpMREA->ReadFloat();
|
||||||
float g = mpMREA->ReadFloat();
|
float G = mpMREA->ReadFloat();
|
||||||
float b = mpMREA->ReadFloat();
|
float B = mpMREA->ReadFloat();
|
||||||
float a = mpMREA->ReadFloat();
|
float A = mpMREA->ReadFloat();
|
||||||
CColor LightColor(r, g, b, a);
|
CColor LightColor(R, G, B, A);
|
||||||
|
|
||||||
CVector3f Position(*mpMREA);
|
CVector3f Position(*mpMREA);
|
||||||
CVector3f Direction(*mpMREA);
|
CVector3f Direction(*mpMREA);
|
||||||
|
@ -466,7 +466,7 @@ void CAreaLoader::ReadLightsCorruption()
|
||||||
mpMREA->Seek(0x18, SEEK_CUR);
|
mpMREA->Seek(0x18, SEEK_CUR);
|
||||||
|
|
||||||
// Relevant data is read - now we process and form a CLight out of it
|
// Relevant data is read - now we process and form a CLight out of it
|
||||||
CLight *Light;
|
CLight *pLight;
|
||||||
|
|
||||||
if (Multiplier < FLT_EPSILON)
|
if (Multiplier < FLT_EPSILON)
|
||||||
Multiplier = FLT_EPSILON;
|
Multiplier = FLT_EPSILON;
|
||||||
|
@ -474,24 +474,24 @@ void CAreaLoader::ReadLightsCorruption()
|
||||||
// Local Ambient
|
// Local Ambient
|
||||||
if (Type == eLocalAmbient)
|
if (Type == eLocalAmbient)
|
||||||
{
|
{
|
||||||
Light = CLight::BuildLocalAmbient(Position, LightColor * Multiplier);
|
pLight = CLight::BuildLocalAmbient(Position, LightColor * Multiplier);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Directional
|
// Directional
|
||||||
else if (Type == eDirectional)
|
else if (Type == eDirectional)
|
||||||
{
|
{
|
||||||
Light = CLight::BuildDirectional(Position, Direction, LightColor);
|
pLight = CLight::BuildDirectional(Position, Direction, LightColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Spot
|
// Spot
|
||||||
else if (Type == eSpot)
|
else if (Type == eSpot)
|
||||||
{
|
{
|
||||||
Light = CLight::BuildSpot(Position, Direction.Normalized(), LightColor, SpotCutoff);
|
pLight = CLight::BuildSpot(Position, Direction.Normalized(), LightColor, SpotCutoff);
|
||||||
|
|
||||||
float DistAttenA = (FalloffType == 0) ? (2.f / Multiplier) : 0.f;
|
float DistAttenA = (FalloffType == 0) ? (2.f / Multiplier) : 0.f;
|
||||||
float DistAttenB = (FalloffType == 1) ? (250.f / Multiplier) : 0.f;
|
float DistAttenB = (FalloffType == 1) ? (250.f / Multiplier) : 0.f;
|
||||||
float DistAttenC = (FalloffType == 2) ? (25000.f / Multiplier) : 0.f;
|
float DistAttenC = (FalloffType == 2) ? (25000.f / Multiplier) : 0.f;
|
||||||
Light->SetDistAtten(DistAttenA, DistAttenB, DistAttenC);
|
pLight->SetDistAtten(DistAttenA, DistAttenB, DistAttenC);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Custom
|
// Custom
|
||||||
|
@ -501,13 +501,13 @@ void CAreaLoader::ReadLightsCorruption()
|
||||||
float DistAttenB = (FalloffType == 1) ? (249.9998f / Multiplier) : 0.f;
|
float DistAttenB = (FalloffType == 1) ? (249.9998f / Multiplier) : 0.f;
|
||||||
float DistAttenC = (FalloffType == 2) ? (25000.f / Multiplier) : 0.f;
|
float DistAttenC = (FalloffType == 2) ? (25000.f / Multiplier) : 0.f;
|
||||||
|
|
||||||
Light = CLight::BuildCustom(Position, Direction, LightColor,
|
pLight = CLight::BuildCustom(Position, Direction, LightColor,
|
||||||
DistAttenA, DistAttenB, DistAttenC,
|
DistAttenA, DistAttenB, DistAttenC,
|
||||||
1.f, 0.f, 0.f);
|
1.f, 0.f, 0.f);
|
||||||
}
|
}
|
||||||
|
|
||||||
Light->SetLayer(iLayer);
|
pLight->SetLayer(iLayer);
|
||||||
mpArea->mLightLayers[iLayer][iLight] = Light;
|
mpArea->mLightLayers[iLayer][iLight] = pLight;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -517,15 +517,15 @@ void CAreaLoader::ReadCompressedBlocks()
|
||||||
{
|
{
|
||||||
mTotalDecmpSize = 0;
|
mTotalDecmpSize = 0;
|
||||||
|
|
||||||
for (u32 c = 0; c < mClusters.size(); c++)
|
for (u32 iClust = 0; iClust < mClusters.size(); iClust++)
|
||||||
{
|
{
|
||||||
mClusters[c].BufferSize = mpMREA->ReadLong();
|
mClusters[iClust].BufferSize = mpMREA->ReadLong();
|
||||||
mClusters[c].DecompressedSize = mpMREA->ReadLong();
|
mClusters[iClust].DecompressedSize = mpMREA->ReadLong();
|
||||||
mClusters[c].CompressedSize = mpMREA->ReadLong();
|
mClusters[iClust].CompressedSize = mpMREA->ReadLong();
|
||||||
mClusters[c].NumSections = mpMREA->ReadLong();
|
mClusters[iClust].NumSections = mpMREA->ReadLong();
|
||||||
mTotalDecmpSize += mClusters[c].DecompressedSize;
|
mTotalDecmpSize += mClusters[iClust].DecompressedSize;
|
||||||
|
|
||||||
if (mClusters[c].CompressedSize != 0) mpArea->mUsesCompression = true;
|
if (mClusters[iClust].CompressedSize != 0) mpArea->mUsesCompression = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
mpMREA->SeekToBoundary(32);
|
mpMREA->SeekToBoundary(32);
|
||||||
|
@ -539,39 +539,39 @@ void CAreaLoader::Decompress()
|
||||||
if (mVersion < eEchoes) return;
|
if (mVersion < eEchoes) return;
|
||||||
|
|
||||||
// Decompress clusters
|
// Decompress clusters
|
||||||
mDecmpBuffer = new u8[mTotalDecmpSize];
|
mpDecmpBuffer = new u8[mTotalDecmpSize];
|
||||||
u32 Offset = 0;
|
u32 Offset = 0;
|
||||||
|
|
||||||
for (u32 c = 0; c < mClusters.size(); c++)
|
for (u32 iClust = 0; iClust < mClusters.size(); iClust++)
|
||||||
{
|
{
|
||||||
SCompressedCluster *cc = &mClusters[c];
|
SCompressedCluster *pClust = &mClusters[iClust];
|
||||||
|
|
||||||
// Is it decompressed already?
|
// Is it decompressed already?
|
||||||
if (mClusters[c].CompressedSize == 0)
|
if (mClusters[iClust].CompressedSize == 0)
|
||||||
{
|
{
|
||||||
mpMREA->ReadBytes(mDecmpBuffer + Offset, cc->DecompressedSize);
|
mpMREA->ReadBytes(mpDecmpBuffer + Offset, pClust->DecompressedSize);
|
||||||
Offset += cc->DecompressedSize;
|
Offset += pClust->DecompressedSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
u32 StartOffset = 32 - (mClusters[c].CompressedSize % 32); // For some reason they pad the beginning instead of the end
|
u32 StartOffset = 32 - (mClusters[iClust].CompressedSize % 32); // For some reason they pad the beginning instead of the end
|
||||||
if (StartOffset != 32)
|
if (StartOffset != 32)
|
||||||
mpMREA->Seek(StartOffset, SEEK_CUR);
|
mpMREA->Seek(StartOffset, SEEK_CUR);
|
||||||
|
|
||||||
std::vector<u8> cmp(mClusters[c].CompressedSize);
|
std::vector<u8> CompressedBuf(mClusters[iClust].CompressedSize);
|
||||||
mpMREA->ReadBytes(cmp.data(), cmp.size());
|
mpMREA->ReadBytes(CompressedBuf.data(), CompressedBuf.size());
|
||||||
|
|
||||||
bool Success = CompressionUtil::DecompressSegmentedData(cmp.data(), cmp.size(), mDecmpBuffer + Offset, cc->DecompressedSize);
|
bool Success = CompressionUtil::DecompressSegmentedData(CompressedBuf.data(), CompressedBuf.size(), mpDecmpBuffer + Offset, pClust->DecompressedSize);
|
||||||
if (!Success)
|
if (!Success)
|
||||||
throw "Failed to decompress MREA!";
|
throw "Failed to decompress MREA!";
|
||||||
|
|
||||||
Offset += cc->DecompressedSize;
|
Offset += pClust->DecompressedSize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TString Source = mpMREA->GetSourceString();
|
TString Source = mpMREA->GetSourceString();
|
||||||
mpMREA = new CMemoryInStream(mDecmpBuffer, mTotalDecmpSize, IOUtil::eBigEndian);
|
mpMREA = new CMemoryInStream(mpDecmpBuffer, mTotalDecmpSize, IOUtil::eBigEndian);
|
||||||
mpMREA->SetSourceString(Source.ToStdString());
|
mpMREA->SetSourceString(Source.ToStdString());
|
||||||
mpSectionMgr->SetInputStream(mpMREA);
|
mpSectionMgr->SetInputStream(mpMREA);
|
||||||
mHasDecompressedBuffer = true;
|
mHasDecompressedBuffer = true;
|
||||||
|
@ -609,14 +609,14 @@ void CAreaLoader::ReadEGMC()
|
||||||
void CAreaLoader::SetUpObjects()
|
void CAreaLoader::SetUpObjects()
|
||||||
{
|
{
|
||||||
// Iterate over all objects
|
// Iterate over all objects
|
||||||
for (u32 iLyr = 0; iLyr < mpArea->GetScriptLayerCount() + 1; iLyr++)
|
for (u32 iLyr = 0; iLyr < mpArea->NumScriptLayers() + 1; iLyr++)
|
||||||
{
|
{
|
||||||
CScriptLayer *pLayer;
|
CScriptLayer *pLayer;
|
||||||
if (iLyr < mpArea->GetScriptLayerCount()) pLayer = mpArea->mScriptLayers[iLyr];
|
if (iLyr < mpArea->NumScriptLayers()) pLayer = mpArea->mScriptLayers[iLyr];
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pLayer = mpArea->GetGeneratorLayer();
|
pLayer = mpArea->GeneratedObjectsLayer();
|
||||||
if (!pLayer) break;
|
if (!pLayer) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -657,17 +657,17 @@ CGameArea* CAreaLoader::LoadMREA(IInputStream& MREA)
|
||||||
// Validation
|
// Validation
|
||||||
if (!MREA.IsValid()) return nullptr;
|
if (!MREA.IsValid()) return nullptr;
|
||||||
|
|
||||||
u32 deadbeef = MREA.ReadLong();
|
u32 DeadBeef = MREA.ReadLong();
|
||||||
if (deadbeef != 0xdeadbeef)
|
if (DeadBeef != 0xdeadbeef)
|
||||||
{
|
{
|
||||||
Log::FileError(MREA.GetSourceString(), "Invalid MREA magic: " + TString::HexString(deadbeef));
|
Log::FileError(MREA.GetSourceString(), "Invalid MREA magic: " + TString::HexString(DeadBeef));
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Header
|
// Header
|
||||||
Loader.mpArea = new CGameArea;
|
Loader.mpArea = new CGameArea;
|
||||||
u32 version = MREA.ReadLong();
|
u32 Version = MREA.ReadLong();
|
||||||
Loader.mVersion = GetFormatVersion(version);
|
Loader.mVersion = GetFormatVersion(Version);
|
||||||
Loader.mpArea->mVersion = Loader.mVersion;
|
Loader.mpArea->mVersion = Loader.mVersion;
|
||||||
Loader.mpMREA = &MREA;
|
Loader.mpMREA = &MREA;
|
||||||
|
|
||||||
|
@ -718,7 +718,7 @@ CGameArea* CAreaLoader::LoadMREA(IInputStream& MREA)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
Log::FileError(MREA.GetSourceString(), "Unsupported MREA version: " + TString::HexString(version));
|
Log::FileError(MREA.GetSourceString(), "Unsupported MREA version: " + TString::HexString(Version, 0));
|
||||||
Loader.mpArea.Delete();
|
Loader.mpArea.Delete();
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -728,9 +728,9 @@ CGameArea* CAreaLoader::LoadMREA(IInputStream& MREA)
|
||||||
return Loader.mpArea;
|
return Loader.mpArea;
|
||||||
}
|
}
|
||||||
|
|
||||||
EGame CAreaLoader::GetFormatVersion(u32 version)
|
EGame CAreaLoader::GetFormatVersion(u32 Version)
|
||||||
{
|
{
|
||||||
switch (version)
|
switch (Version)
|
||||||
{
|
{
|
||||||
case 0xC: return ePrimeDemo;
|
case 0xC: return ePrimeDemo;
|
||||||
case 0xF: return ePrime;
|
case 0xF: return ePrime;
|
||||||
|
|
|
@ -25,7 +25,7 @@ class CAreaLoader
|
||||||
std::unordered_map<u32, std::vector<CLink*>> mConnectionMap;
|
std::unordered_map<u32, std::vector<CLink*>> mConnectionMap;
|
||||||
|
|
||||||
// Compression
|
// Compression
|
||||||
u8 *mDecmpBuffer;
|
u8 *mpDecmpBuffer;
|
||||||
bool mHasDecompressedBuffer;
|
bool mHasDecompressedBuffer;
|
||||||
std::vector<SCompressedCluster> mClusters;
|
std::vector<SCompressedCluster> mClusters;
|
||||||
u32 mTotalDecmpSize;
|
u32 mTotalDecmpSize;
|
||||||
|
@ -80,8 +80,8 @@ class CAreaLoader
|
||||||
void SetUpObjects();
|
void SetUpObjects();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static CGameArea* LoadMREA(IInputStream& MREA);
|
static CGameArea* LoadMREA(IInputStream& rMREA);
|
||||||
static EGame GetFormatVersion(u32 version);
|
static EGame GetFormatVersion(u32 Version);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CAREALOADER_H
|
#endif // CAREALOADER_H
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue