diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
index cdfa624e..05f7bd42 100644
--- a/.idea/codeStyles/Project.xml
+++ b/.idea/codeStyles/Project.xml
@@ -7,8 +7,15 @@
+
+
+
+
+
+
+
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 92bf071c..47246c17 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -16,7 +16,7 @@ endif()
# Ensure submodules checked out
if (NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/externals/LibCommon/CMakeLists.txt)
- message(FATAL_ERROR "Please run 'git submodules update --init --recursive' to fetch submodules.")
+ message(FATAL_ERROR "Please run 'git submodule update --init --recursive' to fetch submodules.")
endif()
include(./dew.cmake)
diff --git a/src/Core/GameProject/AssetNameGeneration.cpp b/src/Core/GameProject/AssetNameGeneration.cpp
index a6ca5274..ee724035 100644
--- a/src/Core/GameProject/AssetNameGeneration.cpp
+++ b/src/Core/GameProject/AssetNameGeneration.cpp
@@ -172,7 +172,7 @@ void GenerateAssetNames(CGameProject *pProj)
for (uint32 iMat = 0; iMat < pSet->NumMaterials(); iMat++)
{
- CMaterial *pMat = pSet->MaterialByIndex(iMat);
+ CMaterial *pMat = pSet->MaterialByIndex(iMat, true);
for (uint32 iPass = 0; iPass < pMat->PassCount(); iPass++)
{
@@ -239,7 +239,7 @@ void GenerateAssetNames(CGameProject *pProj)
for (uint32 iMat = 0; iMat < pMaterials->NumMaterials(); iMat++)
{
- CMaterial *pMat = pMaterials->MaterialByIndex(iMat);
+ CMaterial *pMat = pMaterials->MaterialByIndex(iMat, true);
bool FoundLightmap = false;
for (uint32 iPass = 0; iPass < pMat->PassCount(); iPass++)
@@ -415,7 +415,7 @@ void GenerateAssetNames(CGameProject *pProj)
for (uint32 iMat = 0; iMat < pSet->NumMaterials(); iMat++)
{
- CMaterial *pMat = pSet->MaterialByIndex(iMat);
+ CMaterial *pMat = pSet->MaterialByIndex(iMat, true);
for (uint32 iPass = 0; iPass < pMat->PassCount(); iPass++)
{
diff --git a/src/Core/OpenGL/CShaderGenerator.cpp b/src/Core/OpenGL/CShaderGenerator.cpp
index d0d76b83..829447b6 100644
--- a/src/Core/OpenGL/CShaderGenerator.cpp
+++ b/src/Core/OpenGL/CShaderGenerator.cpp
@@ -366,6 +366,36 @@ bool CShaderGenerator::CreateVertexShader(const CMaterial& rkMat)
return mpShader->CompileVertexSource(ShaderCode.str().c_str());
}
+static TString GetColorInputExpression(const CMaterialPass* pPass, ETevColorInput iInput)
+{
+ if (iInput == ETevColorInput::kTextureRGB)
+ {
+ TString Ret("Tex.");
+ for (uint32 i = 0; i < 3; ++i)
+ Ret += pPass->TexSwapComp(i);
+ return Ret;
+ }
+ else if (iInput == ETevColorInput::kTextureAAA)
+ {
+ TString Ret("Tex.");
+ for (uint32 i = 0; i < 3; ++i)
+ Ret += pPass->TexSwapComp(3);
+ return Ret;
+ }
+ return gkTevColor[iInput];
+}
+
+static TString GetAlphaInputExpression(const CMaterialPass* pPass, ETevAlphaInput iInput)
+{
+ if (iInput == ETevAlphaInput::kTextureAlpha)
+ {
+ TString Ret("Tex.");
+ Ret += pPass->TexSwapComp(3);
+ return Ret;
+ }
+ return gkTevAlpha[iInput];
+}
+
bool CShaderGenerator::CreatePixelShader(const CMaterial& rkMat)
{
std::stringstream ShaderCode;
@@ -391,7 +421,7 @@ bool CShaderGenerator::CreatePixelShader(const CMaterial& rkMat)
<< "\n"
<< "layout(std140) uniform PixelBlock {\n"
<< " vec4 KonstColors[4];\n"
- << " vec4 TevColor;\n"
+ << " vec4 TevColor[4];\n"
<< " vec4 TintColor;\n"
<< " float LightmapMultiplier;\n"
<< "};\n\n";
@@ -405,7 +435,7 @@ bool CShaderGenerator::CreatePixelShader(const CMaterial& rkMat)
ShaderCode << "void main()\n"
<< "{\n"
<< " vec4 TevInA = vec4(0, 0, 0, 0), TevInB = vec4(0, 0, 0, 0), TevInC = vec4(0, 0, 0, 0), TevInD = vec4(0, 0, 0, 0);\n"
- << " vec4 Prev = vec4(0, 0, 0, 0), C0 = TevColor, C1 = C0, C2 = C0;\n"
+ << " vec4 Prev = TevColor[0], C0 = TevColor[1], C1 = TevColor[2], C2 = TevColor[3];\n"
<< " vec4 Ras = vec4(0, 0, 0, 1), Tex = vec4(0, 0, 0, 0);\n"
<< " vec4 Konst = vec4(1, 1, 1, 1);\n";
@@ -430,18 +460,13 @@ bool CShaderGenerator::CreatePixelShader(const CMaterial& rkMat)
if (pPass->TexCoordSource() != 0xFF)
ShaderCode << " TevCoord = (Tex" << iPass << ".z == 0.0 ? Tex" << iPass << ".xy : Tex" << iPass << ".xy / Tex" << iPass << ".z);\n";
- if (pPass->Texture() != nullptr)
+ if (pPass->Texture())
ShaderCode << " Tex = texture(Texture" << iPass << ", TevCoord)";
- // A couple pass types require special swizzles to access different texture color channels as alpha
- if ((PassType == "TRAN") || (PassType == "INCA") || (PassType == "BLOI"))
- ShaderCode << ".rgbr";
- else if (PassType == "BLOL")
- ShaderCode << ".rgbg";
-
// Apply lightmap multiplier
- if ( (PassType == "DIFF") ||
- (PassType == "CUST" && (rkMat.Options() & EMaterialOption::Lightmap) && iPass == 0) )
+ bool UseLightmapMultiplier = (PassType == "DIFF") ||
+ (PassType == "CUST" && (rkMat.Options() & EMaterialOption::Lightmap) && iPass == 0);
+ if (UseLightmapMultiplier && pPass->Texture())
ShaderCode << " * LightmapMultiplier";
ShaderCode << ";\n";
@@ -456,10 +481,13 @@ bool CShaderGenerator::CreatePixelShader(const CMaterial& rkMat)
char TevChar = iInput + 0x41; // the current stage number represented as an ASCII letter; eg 0 is 'A'
ShaderCode << " TevIn" << TevChar << " = vec4("
- << gkTevColor[pPass->ColorInput(iInput) & 0xF]
+ << GetColorInputExpression(pPass, ETevColorInput(pPass->ColorInput(iInput) & 0xF))
<< ", "
- << gkTevAlpha[pPass->AlphaInput(iInput) & 0x7]
- << ");\n";
+ << GetAlphaInputExpression(pPass, ETevAlphaInput(pPass->AlphaInput(iInput) & 0x7))
+ << ")";
+ if (UseLightmapMultiplier && !pPass->Texture() && iInput == 1)
+ ShaderCode << " * LightmapMultiplier";
+ ShaderCode << ";\n";
}
ShaderCode << " // RGB Combine\n"
@@ -467,8 +495,7 @@ bool CShaderGenerator::CreatePixelShader(const CMaterial& rkMat)
<< gkTevRigid[pPass->ColorOutput()]
<< ".rgb = ";
- ShaderCode << "clamp(vec3(TevInD.rgb + ((1.0 - TevInC.rgb) * TevInA.rgb + TevInC.rgb * TevInB.rgb))";
- if ((PassType == "CLR ") && (Lightmap)) ShaderCode << "* (2.0 - (1.0 - LightmapMultiplier))"; // Apply tevscale 2.0 on the color pass if lightmap is present. Scale so we don't apply if lightmaps are off.
+ ShaderCode << "clamp(vec3(TevInD.rgb + ((1.0 - TevInC.rgb) * TevInA.rgb + TevInC.rgb * TevInB.rgb)) * " << pPass->TevColorScale();
ShaderCode << ", vec3(0, 0, 0), vec3(1.0, 1.0, 1.0));\n";
ShaderCode << " // Alpha Combine\n"
@@ -476,7 +503,7 @@ bool CShaderGenerator::CreatePixelShader(const CMaterial& rkMat)
<< gkTevRigid[pPass->AlphaOutput()]
<< ".a = ";
- ShaderCode << "clamp(TevInD.a + ((1.0 - TevInC.a) * TevInA.a + TevInC.a * TevInB.a), 0.0, 1.0);\n\n";
+ ShaderCode << "clamp((TevInD.a + ((1.0 - TevInC.a) * TevInA.a + TevInC.a * TevInB.a)) * " << pPass->TevAlphaScale() << ", 0.0, 1.0);\n\n";
}
if (rkMat.Options() & EMaterialOption::Masked)
diff --git a/src/Core/Render/CGraphics.cpp b/src/Core/Render/CGraphics.cpp
index 96f20b6b..8cd07c3d 100644
--- a/src/Core/Render/CGraphics.cpp
+++ b/src/Core/Render/CGraphics.cpp
@@ -22,13 +22,13 @@ CGraphics::SLightBlock CGraphics::sLightBlock;
CGraphics::ELightingMode CGraphics::sLightMode;
uint32 CGraphics::sNumLights;
-const CColor CGraphics::skDefaultAmbientColor = CColor(0.5f, 0.5f, 0.5f, 1.f);
+const CColor CGraphics::skDefaultAmbientColor = CColor(0.5f, 0.5f, 0.5f, 0.5f);
CColor CGraphics::sAreaAmbientColor = CColor::skBlack;
float CGraphics::sWorldLightMultiplier;
CLight CGraphics::sDefaultDirectionalLights[3] = {
- CLight::BuildDirectional(CVector3f(0), CVector3f (0.f, -0.866025f, -0.5f), CColor(0.3f, 0.3f, 0.3f, 1.f)),
- CLight::BuildDirectional(CVector3f(0), CVector3f(-0.75f, 0.433013f, -0.5f), CColor(0.3f, 0.3f, 0.3f, 1.f)),
- CLight::BuildDirectional(CVector3f(0), CVector3f( 0.75f, 0.433013f, -0.5f), CColor(0.3f, 0.3f, 0.3f, 1.f))
+ CLight::BuildDirectional(CVector3f(0), CVector3f (0.f, -0.866025f, -0.5f), CColor(0.3f, 0.3f, 0.3f, 0.3f)),
+ CLight::BuildDirectional(CVector3f(0), CVector3f(-0.75f, 0.433013f, -0.5f), CColor(0.3f, 0.3f, 0.3f, 0.3f)),
+ CLight::BuildDirectional(CVector3f(0), CVector3f( 0.75f, 0.433013f, -0.5f), CColor(0.3f, 0.3f, 0.3f, 0.3f))
};
// ************ FUNCTIONS ************
@@ -167,9 +167,11 @@ void CGraphics::SetDefaultLighting()
sDefaultDirectionalLights[0].Load();
sDefaultDirectionalLights[1].Load();
sDefaultDirectionalLights[2].Load();
+ sNumLights = 0;
UpdateLightBlock();
sVertexBlock.COLOR0_Amb = CColor::skGray;
+ sVertexBlock.COLOR0_Amb.A = 0.5f;
UpdateVertexBlock();
}
diff --git a/src/Core/Render/CGraphics.h b/src/Core/Render/CGraphics.h
index 80a40aec..b2f4ac52 100644
--- a/src/Core/Render/CGraphics.h
+++ b/src/Core/Render/CGraphics.h
@@ -56,9 +56,15 @@ public:
struct SPixelBlock
{
CColor Konst[4];
- CColor TevColor;
+ CColor TevColor[4];
CColor TintColor;
float LightmapMultiplier;
+ float Padding[3];
+
+ void SetAllTevColors(const CColor& color)
+ {
+ std::fill(std::begin(TevColor), std::end(TevColor), color);
+ }
};
static SPixelBlock sPixelBlock;
diff --git a/src/Core/Render/CRenderer.cpp b/src/Core/Render/CRenderer.cpp
index eaecf961..c2f4aef5 100644
--- a/src/Core/Render/CRenderer.cpp
+++ b/src/Core/Render/CRenderer.cpp
@@ -270,7 +270,7 @@ void CRenderer::RenderSky(CModel *pSkyboxModel, const SViewInfo& rkViewInfo)
CGraphics::sMVPBlock.ModelMatrix = CMatrix4f::skIdentity;
CGraphics::sVertexBlock.COLOR0_Amb = CColor::skWhite;
- CGraphics::sPixelBlock.TevColor = CColor::skWhite;
+ CGraphics::sPixelBlock.SetAllTevColors(CColor::skWhite);
CGraphics::sPixelBlock.TintColor = CColor::skWhite;
CGraphics::sNumLights = 0;
CGraphics::UpdateVertexBlock();
diff --git a/src/Core/Resource/Area/CGameArea.cpp b/src/Core/Resource/Area/CGameArea.cpp
index c94499e7..91f6a218 100644
--- a/src/Core/Resource/Area/CGameArea.cpp
+++ b/src/Core/Resource/Area/CGameArea.cpp
@@ -79,7 +79,7 @@ void CGameArea::MergeTerrain()
for (uint32 iSurf = 0; iSurf < SubmeshCount; iSurf++)
{
SSurface *pSurf = pMdl->GetSurface(iSurf);
- CMaterial *pMat = mpMaterialSet->MaterialByIndex(pSurf->MaterialID);
+ CMaterial *pMat = mpMaterialSet->MaterialByIndex(pSurf->MaterialID, false);
bool NewMat = true;
for (std::vector::iterator it = mStaticWorldModels.begin(); it != mStaticWorldModels.end(); it++)
diff --git a/src/Core/Resource/CMaterial.cpp b/src/Core/Resource/CMaterial.cpp
index f8f4650a..711eda80 100644
--- a/src/Core/Resource/CMaterial.cpp
+++ b/src/Core/Resource/CMaterial.cpp
@@ -17,7 +17,6 @@ CMaterial::CMaterial()
: mpShader(nullptr)
, mShaderStatus(EShaderStatus::NoShader)
, mRecalcHash(true)
- , mEnableBloom(false)
, mVersion(EGame::Invalid)
, mOptions(EMaterialOption::None)
, mVtxDesc(EVertexAttribute::None)
@@ -27,16 +26,16 @@ CMaterial::CMaterial()
, mEchoesUnknownA(0)
, mEchoesUnknownB(0)
, mpIndirectTexture(nullptr)
-{
-}
+ , mpNextDrawPassMaterial(nullptr)
+ , mpBloomMaterial(nullptr)
+{}
CMaterial::CMaterial(EGame Version, FVertexDescription VtxDesc)
: mpShader(nullptr)
, mShaderStatus(EShaderStatus::NoShader)
, mRecalcHash(true)
- , mEnableBloom(Version == EGame::Corruption)
, mVersion(Version)
- , mOptions(EMaterialOption::DepthWrite)
+ , mOptions(EMaterialOption::DepthWrite | EMaterialOption::ColorWrite)
, mVtxDesc(VtxDesc)
, mBlendSrcFac(GL_ONE)
, mBlendDstFac(GL_ZERO)
@@ -44,27 +43,18 @@ CMaterial::CMaterial(EGame Version, FVertexDescription VtxDesc)
, mEchoesUnknownA(0)
, mEchoesUnknownB(0)
, mpIndirectTexture(nullptr)
-{
- mpShader = nullptr;
- mShaderStatus = EShaderStatus::NoShader;
- mRecalcHash = true;
- mEnableBloom = (Version == EGame::Corruption);
- mVersion = Version;
- mOptions = EMaterialOption::DepthWrite;
- mVtxDesc = VtxDesc;
- mBlendSrcFac = GL_ONE;
- mBlendDstFac = GL_ZERO;
- mLightingEnabled = true;
- mEchoesUnknownA = 0;
- mEchoesUnknownB = 0;
- mpIndirectTexture = nullptr;
-}
+ , mpNextDrawPassMaterial(nullptr)
+ , mpBloomMaterial(nullptr)
+{}
CMaterial::~CMaterial()
{
for (uint32 iPass = 0; iPass < mPasses.size(); iPass++)
delete mPasses[iPass];
+ delete mpNextDrawPassMaterial;
+ delete mpBloomMaterial;
+
ClearShader();
}
@@ -72,12 +62,13 @@ CMaterial* CMaterial::Clone()
{
CMaterial *pOut = new CMaterial();
pOut->mName = mName;
- pOut->mEnableBloom = mEnableBloom;
pOut->mVersion = mVersion;
pOut->mOptions = mOptions;
pOut->mVtxDesc = mVtxDesc;
for (uint32 iKonst = 0; iKonst < 4; iKonst++)
pOut->mKonstColors[iKonst] = mKonstColors[iKonst];
+ for (uint32 iTev = 0; iTev < 4; iTev++)
+ pOut->mTevColors[iTev] = mTevColors[iTev];
pOut->mBlendSrcFac = mBlendSrcFac;
pOut->mBlendDstFac = mBlendDstFac;
pOut->mLightingEnabled = mLightingEnabled;
@@ -89,6 +80,12 @@ CMaterial* CMaterial::Clone()
for (uint32 iPass = 0; iPass < mPasses.size(); iPass++)
pOut->mPasses[iPass] = mPasses[iPass]->Clone(pOut);
+ if (mpNextDrawPassMaterial)
+ pOut->mpNextDrawPassMaterial = mpNextDrawPassMaterial->Clone();
+
+ if (mpBloomMaterial)
+ pOut->mpBloomMaterial = mpBloomMaterial->Clone();
+
return pOut;
}
@@ -179,15 +176,12 @@ bool CMaterial::SetCurrent(FRenderOptions Options)
dstRGB = mBlendDstFac;
}
- // Set alpha blend equation
- bool AlphaBlended = ((mBlendSrcFac == GL_SRC_ALPHA) && (mBlendDstFac == GL_ONE_MINUS_SRC_ALPHA));
-
- if ((mEnableBloom) && (Options & ERenderOption::EnableBloom) && (!AlphaBlended)) {
- srcAlpha = mBlendSrcFac;
- dstAlpha = mBlendDstFac;
- } else {
+ if (mOptions & EMaterialOption::ZeroDestAlpha) {
srcAlpha = GL_ZERO;
dstAlpha = GL_ZERO;
+ } else {
+ srcAlpha = mBlendSrcFac;
+ dstAlpha = mBlendDstFac;
}
glBlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha);
@@ -196,6 +190,11 @@ bool CMaterial::SetCurrent(FRenderOptions Options)
for (uint32 iKonst = 0; iKonst < 4; iKonst++)
CGraphics::sPixelBlock.Konst[iKonst] = mKonstColors[iKonst];
+ // Set TEV registers
+ if (mVersion >= EGame::Corruption)
+ for (uint32 iTev = 0; iTev < 4; iTev++)
+ CGraphics::sPixelBlock.TevColor[iTev] = mTevColors[iTev];
+
// Set color channels
// COLOR0_Amb is initialized by the node instead of by the material
CGraphics::sVertexBlock.COLOR0_Mat = CColor::skWhite;
@@ -204,6 +203,11 @@ bool CMaterial::SetCurrent(FRenderOptions Options)
if ((mOptions & EMaterialOption::DepthWrite) || (Options & ERenderOption::NoAlpha)) glDepthMask(GL_TRUE);
else glDepthMask(GL_FALSE);
+ // Set color/alpha write
+ GLboolean bColorWrite = mOptions.HasFlag(EMaterialOption::ColorWrite);
+ GLboolean bAlphaWrite = mOptions.HasFlag(EMaterialOption::AlphaWrite);
+ glColorMask(bColorWrite, bColorWrite, bColorWrite, bAlphaWrite);
+
// Load uniforms
for (uint32 iPass = 0; iPass < mPasses.size(); iPass++)
mPasses[iPass]->SetAnimCurrent(Options, iPass);
@@ -249,6 +253,7 @@ uint64 CMaterial::HashParameters()
Hash.HashLong(mOptions);
Hash.HashLong(mVtxDesc);
Hash.HashData(mKonstColors, sizeof(CColor) * 4);
+ Hash.HashData(mTevColors, sizeof(CColor) * 4);
Hash.HashLong(mBlendSrcFac);
Hash.HashLong(mBlendDstFac);
Hash.HashByte(mLightingEnabled);
diff --git a/src/Core/Resource/CMaterial.h b/src/Core/Resource/CMaterial.h
index 4af52ea7..05eafeda 100644
--- a/src/Core/Resource/CMaterial.h
+++ b/src/Core/Resource/CMaterial.h
@@ -31,10 +31,32 @@ enum class EMaterialOption
Lightmap = 0x800,
ShortTexCoord = 0x2000,
AllMP1Settings = 0x2FF8,
+ ColorWrite = 0x10000,
+ AlphaWrite = 0x20000,
+ ZeroDestAlpha = 0x40000,
DrawWhiteAmbientDKCR = 0x80000
};
DECLARE_FLAGS_ENUMCLASS(EMaterialOption, FMaterialOptions)
+enum class EMP3MaterialOption
+{
+ None = 0,
+ Bloom = 0x1,
+ ForceLightingStage = 0x4,
+ PreIncandecenceTransparency = 0x8,
+ Masked = 0x10,
+ AdditiveIncandecence = 0x20,
+ Occluder = 0x100,
+ SolidWhiteOnly = 0x200,
+ ReflectionAlphaTarget = 0x400,
+ SolidColorOnly = 0x800,
+ ExcludeFromScanVisor = 0x4000,
+ XRayOpaque = 0x8000,
+ XRayAlphaTarget = 0x10000,
+ DrawWhiteAmbientDKCR = 0x80000,
+};
+DECLARE_FLAGS_ENUMCLASS(EMP3MaterialOption, FMP3MaterialOptions)
+
class CMaterial
{
friend class CMaterialLoader;
@@ -57,12 +79,12 @@ private:
EShaderStatus mShaderStatus; // A status variable so that PWE won't crash if a shader fails to compile.
uint64 mParametersHash; // A hash of all the parameters that can identify this TEV setup.
bool mRecalcHash; // Indicates the hash needs to be recalculated. Set true when parameters are changed.
- bool mEnableBloom; // Bool that toggles bloom on or off. On by default on MP3 materials, off by default on MP1 materials.
EGame mVersion;
- FMaterialOptions mOptions; // See the EMaterialOptions enum above
+ FMaterialOptions mOptions; // See the EMaterialOption enum above
FVertexDescription mVtxDesc; // Descriptor of vertex attributes used by this material
CColor mKonstColors[4]; // Konst color values for TEV
+ CColor mTevColors[4]; // Initial TEV color register values (for MP3 materials only)
GLenum mBlendSrcFac; // Source blend factor
GLenum mBlendDstFac; // Dest blend factor
bool mLightingEnabled; // Color channel control flags; indicate whether lighting is enabled
@@ -72,6 +94,16 @@ private:
std::vector mPasses;
+ // Transparent materials in MP3/DKCR may require multiple draw passes to achieve hybrid
+ // blending modes. This serves as a linked list of materials to be drawn successively
+ // for each surface.
+ CMaterial* mpNextDrawPassMaterial;
+
+ // Bloom in MP3 changes the CMaterialPass layout significantly. This is an alternate
+ // material head that may be conditionally used when the user wants to view bloom.
+ // (only set in the head non-bloom CMaterial).
+ CMaterial* mpBloomMaterial;
+
// Reuse shaders between materials that have identical TEV setups
struct SMaterialShader
{
@@ -101,18 +133,22 @@ public:
inline GLenum BlendSrcFac() const { return mBlendSrcFac; }
inline GLenum BlendDstFac() const { return mBlendDstFac; }
inline CColor Konst(uint32 KIndex) const { return mKonstColors[KIndex]; }
+ inline CColor TevColor(ETevOutput Out) const { return mTevColors[int(Out)]; }
inline CTexture* IndTexture() const { return mpIndirectTexture; }
inline bool IsLightingEnabled() const { return mLightingEnabled; }
inline uint32 EchoesUnknownA() const { return mEchoesUnknownA; }
inline uint32 EchoesUnknownB() const { return mEchoesUnknownB; }
inline uint32 PassCount() const { return mPasses.size(); }
inline CMaterialPass* Pass(uint32 PassIndex) const { return mPasses[PassIndex]; }
+ inline CMaterial* GetNextDrawPass() const { return mpNextDrawPassMaterial; }
+ inline CMaterial* GetBloomVersion() const { return mpBloomMaterial; }
inline void SetName(const TString& rkName) { mName = rkName; }
inline void SetOptions(FMaterialOptions Options) { mOptions = Options; Update(); }
inline void SetVertexDescription(FVertexDescription Desc) { mVtxDesc = Desc; Update(); }
inline void SetBlendMode(GLenum SrcFac, GLenum DstFac) { mBlendSrcFac = SrcFac; mBlendDstFac = DstFac; mRecalcHash = true; }
inline void SetKonst(const CColor& Konst, uint32 KIndex) { mKonstColors[KIndex] = Konst; Update(); }
+ inline void SetTevColor(const CColor& Color, ETevOutput Out) { mTevColors[int(Out)] = Color; }
inline void SetIndTexture(CTexture *pTex) { mpIndirectTexture = pTex; }
inline void SetLightingEnabled(bool Enabled) { mLightingEnabled = Enabled; Update(); }
diff --git a/src/Core/Resource/CMaterialPass.cpp b/src/Core/Resource/CMaterialPass.cpp
index c17c5c95..80e7ec66 100644
--- a/src/Core/Resource/CMaterialPass.cpp
+++ b/src/Core/Resource/CMaterialPass.cpp
@@ -14,8 +14,11 @@ CMaterialPass::CMaterialPass(CMaterial *pParent)
, mKColorSel(kKonstOne)
, mKAlphaSel(kKonstOne)
, mRasSel(kRasColorNull)
+ , mTevColorScale(1.f)
+ , mTevAlphaScale(1.f)
, mTexCoordSource(0xFF)
, mAnimMode(EUVAnimMode::NoUVAnim)
+ , mTexSwapComps{'r', 'g', 'b', 'a'}
{
for (uint32 iParam = 0; iParam < 4; iParam++)
{
@@ -46,13 +49,18 @@ CMaterialPass* CMaterialPass::Clone(CMaterial *pParent)
pOut->mKColorSel = mKColorSel;
pOut->mKAlphaSel = mKAlphaSel;
pOut->mRasSel = mRasSel;
+ pOut->mTevColorScale = mTevColorScale;
+ pOut->mTevAlphaScale = mTevAlphaScale;
pOut->mTexCoordSource = mTexCoordSource;
pOut->mpTexture = mpTexture;
pOut->mAnimMode = mAnimMode;
- for (uint32 iParam = 0; iParam < 4; iParam++)
+ for (uint32 iParam = 0; iParam < 8; iParam++)
pOut->mAnimParams[iParam] = mAnimParams[iParam];
+ for (uint32 iComp = 0; iComp < 4; iComp++)
+ pOut->mTexSwapComps[iComp] = mTexSwapComps[iComp];
+
pOut->mEnabled = mEnabled;
return pOut;
@@ -71,9 +79,12 @@ void CMaterialPass::HashParameters(CFNV1A& rHash)
rHash.HashLong(mKColorSel);
rHash.HashLong(mKAlphaSel);
rHash.HashLong(mRasSel);
+ rHash.HashLong(mTevColorScale);
+ rHash.HashLong(mTevAlphaScale);
rHash.HashLong(mTexCoordSource);
rHash.HashLong((uint) mAnimMode);
- rHash.HashData(mAnimParams, sizeof(float) * 4);
+ rHash.HashData(mAnimParams, sizeof(float) * 8);
+ rHash.HashData(mTexSwapComps, sizeof(char) * 4);
rHash.HashByte(mEnabled);
}
}
@@ -295,6 +306,18 @@ void CMaterialPass::SetRasSel(ETevRasSel Sel)
mpParentMat->Update();
}
+void CMaterialPass::SetTevColorScale(float Scale)
+{
+ mTevColorScale = Scale;
+ mpParentMat->Update();
+}
+
+void CMaterialPass::SetTevAlphaScale(float Scale)
+{
+ mTevAlphaScale = Scale;
+ mpParentMat->Update();
+}
+
void CMaterialPass::SetTexCoordSource(uint32 Source)
{
mTexCoordSource = Source;
@@ -317,6 +340,11 @@ void CMaterialPass::SetAnimParam(uint32 ParamIndex, float Value)
mAnimParams[ParamIndex] = Value;
}
+void CMaterialPass::SetTexSwapComp(uint32 Comp, char Value)
+{
+ mTexSwapComps[Comp] = Value;
+}
+
void CMaterialPass::SetEnabled(bool Enabled)
{
mEnabled = Enabled;
diff --git a/src/Core/Resource/CMaterialPass.h b/src/Core/Resource/CMaterialPass.h
index a7a46ea4..c80922ee 100644
--- a/src/Core/Resource/CMaterialPass.h
+++ b/src/Core/Resource/CMaterialPass.h
@@ -12,9 +12,10 @@ class CMaterial;
enum class EPassSettings
{
- None = 0x0,
- EmissiveBloom = 0x4,
- InvertOpacityMap = 0x10
+ None = 0x0,
+ BloomContribution = 0x4,
+ ModulateIncandecenceMap = 0x8,
+ InvertOpacityMap = 0x10
};
DECLARE_FLAGS_ENUMCLASS(EPassSettings, FPassSettings)
@@ -34,11 +35,14 @@ class CMaterialPass
ETevKSel mKColorSel;
ETevKSel mKAlphaSel;
ETevRasSel mRasSel;
+ float mTevColorScale;
+ float mTevAlphaScale;
uint32 mTexCoordSource; // Should maybe be an enum but worried about conflicts with EVertexDescriptionn
TResPtr mpTexture;
EUVAnimMode mAnimMode;
EUVConvolutedModeBType mAnimConvolutedModeBType;
float mAnimParams[8];
+ char mTexSwapComps[4];
bool mEnabled;
public:
@@ -58,10 +62,13 @@ public:
void SetKColorSel(ETevKSel Sel);
void SetKAlphaSel(ETevKSel Sel);
void SetRasSel(ETevRasSel Sel);
+ void SetTevColorScale(float Scale);
+ void SetTevAlphaScale(float Scale);
void SetTexCoordSource(uint32 Source);
void SetTexture(CTexture *pTex);
void SetAnimMode(EUVAnimMode Mode);
void SetAnimParam(uint32 ParamIndex, float Value);
+ void SetTexSwapComp(uint32 Comp, char Value);
void SetEnabled(bool Enabled);
// Getters
@@ -74,10 +81,13 @@ public:
inline ETevKSel KColorSel() const { return mKColorSel; }
inline ETevKSel KAlphaSel() const { return mKAlphaSel; }
inline ETevRasSel RasSel() const { return mRasSel; }
+ inline float TevColorScale() const { return mTevColorScale; }
+ inline float TevAlphaScale() const { return mTevAlphaScale; }
inline uint32 TexCoordSource() const { return mTexCoordSource; }
inline CTexture* Texture() const { return mpTexture; }
inline EUVAnimMode AnimMode() const { return mAnimMode; }
inline float AnimParam(uint32 ParamIndex) const { return mAnimParams[ParamIndex]; }
+ inline char TexSwapComp(uint32 Comp) const { return mTexSwapComps[Comp]; }
inline bool IsEnabled() const { return mEnabled; }
// Static
diff --git a/src/Core/Resource/CMaterialSet.h b/src/Core/Resource/CMaterialSet.h
index 476ad1c0..e921341b 100644
--- a/src/Core/Resource/CMaterialSet.h
+++ b/src/Core/Resource/CMaterialSet.h
@@ -38,10 +38,13 @@ public:
return mMaterials.size();
}
- CMaterial* MaterialByIndex(uint32 Index)
+ CMaterial* MaterialByIndex(uint32 Index, bool TryBloom)
{
if (Index >= NumMaterials()) return nullptr;
- return mMaterials[Index];
+ CMaterial* Ret = mMaterials[Index];
+ if (TryBloom && Ret->GetBloomVersion())
+ return Ret->GetBloomVersion();
+ return Ret;
}
CMaterial* MaterialByName(const TString& rkName)
diff --git a/src/Core/Resource/ETevEnums.h b/src/Core/Resource/ETevEnums.h
index 2d0d87c9..9b44a0bc 100644
--- a/src/Core/Resource/ETevEnums.h
+++ b/src/Core/Resource/ETevEnums.h
@@ -1,6 +1,8 @@
#ifndef ETEVENUMS
#define ETEVENUMS
+#include
+
enum ETevColorInput
{
kPrevRGB = 0x0,
@@ -103,6 +105,20 @@ enum class EUVAnimMode
NoUVAnim = -1
};
+enum class EUVAnimUVSource : uint16
+{
+ Position,
+ Normal,
+ UV
+};
+enum class EUVAnimMatrixConfig : uint16
+{
+ NoMtxNoPost,
+ MtxNoPost,
+ NoMtxPost,
+ MtxPost
+};
+
enum class EUVConvolutedModeBType {
Zero,
One,
diff --git a/src/Core/Resource/Factory/CMaterialLoader.cpp b/src/Core/Resource/Factory/CMaterialLoader.cpp
index 1b7ee4fd..ed7113a8 100644
--- a/src/Core/Resource/Factory/CMaterialLoader.cpp
+++ b/src/Core/Resource/Factory/CMaterialLoader.cpp
@@ -7,7 +7,6 @@
CMaterialLoader::CMaterialLoader()
: mCorruptionFlags(0)
- , mHasOPAC(false)
{
}
@@ -72,8 +71,7 @@ void CMaterialLoader::ReadPrimeMatSet()
CMaterial* CMaterialLoader::ReadPrimeMaterial()
{
- CMaterial *pMat = new CMaterial();
- pMat->mEnableBloom = false;
+ CMaterial *pMat = new CMaterial(mVersion, {});
// Flags
pMat->mOptions = (mpFile->ReadLong() & (uint) EMaterialOption::AllMP1Settings);
@@ -266,45 +264,75 @@ void CMaterialLoader::ReadCorruptionMatSet()
}
}
+// Represent passes as contiguous integers for random-access storage in a fixed array.
+EPASS PassFourCCToEnum(CFourCC fcc)
+{
+ if (fcc == "DIFF")
+ return EPASS::DIFF;
+ else if (fcc == "RIML")
+ return EPASS::RIML;
+ else if (fcc == "BLOL")
+ return EPASS::BLOL;
+ else if (fcc == "CLR ")
+ return EPASS::CLR;
+ else if (fcc == "TRAN")
+ return EPASS::TRAN;
+ else if (fcc == "INCA")
+ return EPASS::INCA;
+ else if (fcc == "RFLV")
+ return EPASS::RFLV;
+ else if (fcc == "RFLD")
+ return EPASS::RFLD;
+ else if (fcc == "LRLD")
+ return EPASS::LRLD;
+ else if (fcc == "LURD")
+ return EPASS::LURD;
+ else if (fcc == "BLOD")
+ return EPASS::BLOD;
+ else if (fcc == "BLOI")
+ return EPASS::BLOI;
+ else if (fcc == "XRAY")
+ return EPASS::XRAY;
+ else if (fcc == "TOON")
+ return EPASS::TOON;
+ return EPASS::DIFF;
+};
+
+EINT IntFourCCToEnum(CFourCC fcc)
+{
+ if (fcc == "OPAC")
+ return EINT::OPAC;
+ else if (fcc == "BLOD")
+ return EINT::BLOD;
+ else if (fcc == "BLOI")
+ return EINT::BLOI;
+ else if (fcc == "BNIF")
+ return EINT::BNIF;
+ else if (fcc == "XRBR")
+ return EINT::XRBR;
+ return EINT::OPAC;
+};
+
+ECLR ClrFourCCToEnum(CFourCC fcc)
+{
+ if (fcc == "CLR ")
+ return ECLR::CLR;
+ else if (fcc == "DIFB")
+ return ECLR::DIFB;
+ return ECLR::CLR;
+};
+
CMaterial* CMaterialLoader::ReadCorruptionMaterial()
{
- CMaterial *pMat = new CMaterial();
- pMat->mOptions = EMaterialOption::DepthWrite;
- pMat->mEnableBloom = true;
-
// Flags
- uint32 Flags = mpFile->ReadLong();
- if (Flags & 0x8)
- {
- pMat->mBlendSrcFac = GL_SRC_ALPHA;
- pMat->mBlendDstFac = GL_ONE_MINUS_SRC_ALPHA;
- pMat->mOptions |= EMaterialOption::Transparent;
- }
- else if (Flags & 0x20)
- {
- pMat->mBlendSrcFac = GL_ONE;
- pMat->mBlendDstFac = GL_ONE;
- pMat->mOptions |= EMaterialOption::Transparent;
- }
-
- if (Flags & 0x10) pMat->mOptions |= EMaterialOption::Masked;
- if (Flags & 0x100) pMat->mOptions |= EMaterialOption::Occluder;
- if (Flags & 0x80000) pMat->mOptions |= EMaterialOption::DrawWhiteAmbientDKCR;
- mHas0x400 = ((Flags & 0x400) != 0);
+ FMP3MaterialOptions MP3Options = mpFile->ReadLong();
mpFile->Seek(0x8, SEEK_CUR); // Don't know what any of this is
- pMat->mVtxDesc = ConvertToVertexDescription( mpFile->ReadLong() );
+ FVertexDescription VtxDesc = ConvertToVertexDescription( mpFile->ReadLong() );
mpFile->Seek(0xC, SEEK_CUR);
- // Initialize all KColors to white
- pMat->mKonstColors[0] = CColor::skWhite;
- pMat->mKonstColors[1] = CColor::skWhite;
- pMat->mKonstColors[2] = CColor::skWhite;
- // Current usage of KColors:
- // 0 - INT OPAC (transparency)
- // 1 - CLR DIFB (lightmap multiplier)
- // 2 - CLR CLR (additive color)
-
+ SMP3IntermediateMaterial Intermediate;
+ Intermediate.mOptions = MP3Options;
while (true)
{
CFourCC Type = mpFile->ReadLong();
@@ -318,12 +346,7 @@ CMaterial* CMaterialLoader::ReadCorruptionMaterial()
{
CFourCC IntType = mpFile->ReadLong();
uint8 IntVal = (uint8) mpFile->ReadLong();
-
- if (IntType == "OPAC")
- {
- pMat->mKonstColors[0] = CColor(1.f, 1.f, 1.f, (float) IntVal / 255);
- mHasOPAC = true;
- }
+ Intermediate.mINTs[int(IntFourCCToEnum(IntType))] = IntVal;
}
// CLR
@@ -331,306 +354,1192 @@ CMaterial* CMaterialLoader::ReadCorruptionMaterial()
{
CFourCC ClrType = mpFile->ReadLong();
CColor ClrVal(*mpFile, true);
-
- if (ClrType == "DIFB")
- {
- ClrVal.A = 0xFF;
- pMat->mKonstColors[1] = ClrVal;
- }
-
- if (ClrType == "CLR ")
- {
- // I'm not sure what this does. It has a clear and obvious ingame effect
- // but I need to test it further to tell specifically what it's doing.
- // All attempts at implementing this just break things.
- }
+ Intermediate.mCLRs[int(ClrFourCCToEnum(ClrType))] = ClrVal;
}
// PASS
if (Type == "PASS")
{
- CMaterialPass *pPass = new CMaterialPass(pMat);
- mPassOffsets.push_back(mpFile->Tell() - 4);
-
uint32 Size = mpFile->ReadLong();
uint32 Next = Size + mpFile->Tell();
- pPass->mPassType = mpFile->ReadLong();
- pPass->mSettings = (EPassSettings) mpFile->ReadLong();
+ CFourCC PassType = mpFile->ReadLong();
+ auto& Pass = Intermediate.mPASSes[int(PassFourCCToEnum(PassType))].emplace(SMP3IntermediateMaterial::PASS());
+
+ Pass.mPassType = PassType;
+ Pass.mSettings = (EPassSettings) mpFile->ReadLong();
- // Skip passes that don't have a texture. Honestly don't really know what to do with these right now
uint64 TextureID = mpFile->ReadLongLong();
- if (TextureID == 0xFFFFFFFFFFFFFFFF)
- {
- //Log::FileWarning(mpFile->GetSourceString(), mPassOffsets.back(), "Skipping " + pPass->mPassType.ToString() + " pass with no texture");
- delete pPass;
- continue;
- }
+ if (TextureID != 0xFFFFFFFFFFFFFFFF)
+ Pass.mpTexture = gpResourceStore->LoadResource(TextureID);
- pPass->mpTexture = gpResourceStore->LoadResource(TextureID);
+ Pass.mUvSrc = mpFile->ReadLong();
- pPass->mTexCoordSource = 4 + (uint8) mpFile->ReadLong();
uint32 AnimSize = mpFile->ReadLong();
-
if (AnimSize > 0)
{
- mpFile->Seek(0x4, SEEK_CUR);
- pPass->mAnimMode = (EUVAnimMode) mpFile->ReadLong();
+ Pass.mUvSource = (EUVAnimUVSource) mpFile->ReadShort();
+ Pass.mMtxConfig = (EUVAnimMatrixConfig) mpFile->ReadShort();
- switch (pPass->mAnimMode)
+ Pass.mAnimMode = (EUVAnimMode) mpFile->ReadLong();
+
+ switch (Pass.mAnimMode)
{
- case EUVAnimMode::UVRotation: // Rotation
- case EUVAnimMode::ConvolutedModeA: // ???
- pPass->mAnimParams[0] = mpFile->ReadFloat();
- pPass->mAnimParams[1] = mpFile->ReadFloat();
- break;
- case EUVAnimMode::UVScroll: // UV Scroll
- case EUVAnimMode::HFilmstrip: // U Scroll
- case EUVAnimMode::VFilmstrip: // V Scroll
- pPass->mAnimParams[0] = mpFile->ReadFloat();
- pPass->mAnimParams[1] = mpFile->ReadFloat();
- pPass->mAnimParams[2] = mpFile->ReadFloat();
- pPass->mAnimParams[3] = mpFile->ReadFloat();
- break;
- case EUVAnimMode::InverseMV: // Inverse ModelView Matrix
- case EUVAnimMode::InverseMVTranslated: // Inverse ModelView Matrix Translated
- case EUVAnimMode::ModelMatrix: // Model Matrix
- case EUVAnimMode::SimpleMode: // Yet-to-be-named
- break;
+ case EUVAnimMode::UVRotation: // Rotation
+ case EUVAnimMode::ConvolutedModeA: // ???
+ Pass.mAnimParams[0] = mpFile->ReadFloat();
+ Pass.mAnimParams[1] = mpFile->ReadFloat();
+ break;
+ case EUVAnimMode::UVScroll: // UV Scroll
+ case EUVAnimMode::HFilmstrip: // U Scroll
+ case EUVAnimMode::VFilmstrip: // V Scroll
+ Pass.mAnimParams[0] = mpFile->ReadFloat();
+ Pass.mAnimParams[1] = mpFile->ReadFloat();
+ Pass.mAnimParams[2] = mpFile->ReadFloat();
+ Pass.mAnimParams[3] = mpFile->ReadFloat();
+ break;
+ case EUVAnimMode::InverseMV: // Inverse ModelView Matrix
+ case EUVAnimMode::InverseMVTranslated: // Inverse ModelView Matrix Translated
+ case EUVAnimMode::ModelMatrix: // Model Matrix
+ case EUVAnimMode::SimpleMode: // Yet-to-be-named
+ break;
- // Unknown/unsupported animation type
- case EUVAnimMode::ConvolutedModeB:
- pPass->mAnimConvolutedModeBType = EUVConvolutedModeBType(mpFile->ReadLong());
- pPass->mAnimParams[0] = mpFile->ReadFloat();
- pPass->mAnimParams[1] = mpFile->ReadFloat();
- pPass->mAnimParams[2] = mpFile->ReadFloat();
- pPass->mAnimParams[3] = mpFile->ReadFloat();
- pPass->mAnimParams[4] = mpFile->ReadFloat();
- pPass->mAnimParams[5] = mpFile->ReadFloat();
- pPass->mAnimParams[6] = mpFile->ReadFloat();
- pPass->mAnimParams[7] = mpFile->ReadFloat();
- debugf("%s: UVMode8 Used with type %i", *mpFile->GetSourceString(), int(pPass->mAnimConvolutedModeBType));
- break;
- case EUVAnimMode::Eleven:
- break;
- default:
- errorf("%s [0x%X]: Unsupported animation mode encountered: %d", *mpFile->GetSourceString(), mpFile->Tell() - 8, pPass->mAnimMode);
- break;
- }
-
- // Hack until the correct way to determine tex coord source is figured out
- if ((pPass->mAnimMode < EUVAnimMode::UVScroll) ||
- (pPass->mAnimMode == EUVAnimMode::ModelMatrix) ||
- (pPass->mAnimMode == EUVAnimMode::ConvolutedModeA) ||
- (pPass->mAnimMode == EUVAnimMode::SimpleMode))
- {
- pPass->mTexCoordSource = 1;
+ // Unknown/unsupported animation type
+ case EUVAnimMode::ConvolutedModeB:
+ Pass.mAnimConvolutedModeBType = EUVConvolutedModeBType(mpFile->ReadLong());
+ Pass.mAnimParams[0] = mpFile->ReadFloat();
+ Pass.mAnimParams[1] = mpFile->ReadFloat();
+ Pass.mAnimParams[2] = mpFile->ReadFloat();
+ Pass.mAnimParams[3] = mpFile->ReadFloat();
+ Pass.mAnimParams[4] = mpFile->ReadFloat();
+ Pass.mAnimParams[5] = mpFile->ReadFloat();
+ Pass.mAnimParams[6] = mpFile->ReadFloat();
+ Pass.mAnimParams[7] = mpFile->ReadFloat();
+ debugf("%s: UVMode8 Used with type %i",
+ *mpFile->GetSourceString(), int(Pass.mAnimConvolutedModeBType));
+ break;
+ case EUVAnimMode::Eleven:
+ break;
+ default:
+ errorf("%s [0x%X]: Unsupported animation mode encountered: %d",
+ *mpFile->GetSourceString(), mpFile->Tell() - 8, Pass.mAnimMode);
+ break;
}
}
-
- else pPass->mAnimMode = EUVAnimMode::NoUVAnim;
-
- pMat->mPasses.push_back(pPass);
mpFile->Seek(Next, SEEK_SET);
}
}
- CreateCorruptionPasses(pMat);
- mHasOPAC = false;
+ // Create non-bloom and bloom versions
+ CMaterial* pMat = new CMaterial(mVersion, VtxDesc);
+ CreateCorruptionPasses(pMat, Intermediate, false);
+ pMat->mpBloomMaterial = new CMaterial(mVersion, VtxDesc);
+ CreateCorruptionPasses(pMat->mpBloomMaterial, Intermediate, true);
return pMat;
}
-void CMaterialLoader::CreateCorruptionPasses(CMaterial *pMat)
+void CMaterialLoader::SetMP3IntermediateIntoMaterialPass(CMaterialPass* pPass,
+ const SMP3IntermediateMaterial::PASS& Intermediate)
{
- uint32 NumPass = pMat->PassCount();
- bool Lightmap = false;
- bool AlphaBlended = ((pMat->mBlendSrcFac == GL_SRC_ALPHA) && (pMat->mBlendDstFac == GL_ONE_MINUS_SRC_ALPHA));
+ pPass->mPassType = Intermediate.mPassType;
+ pPass->mSettings = Intermediate.mSettings;
+ if (Intermediate.mUvSource == EUVAnimUVSource::UV)
+ pPass->mTexCoordSource = 4 + Intermediate.mUvSrc; // TEX
+ else if (Intermediate.mUvSource == EUVAnimUVSource::Position)
+ pPass->mTexCoordSource = 0; // POS
+ else if (Intermediate.mUvSource == EUVAnimUVSource::Normal)
+ pPass->mTexCoordSource = 1; // NORM
+ pPass->mpTexture = Intermediate.mpTexture;
+ pPass->mAnimMode = Intermediate.mAnimMode;
+ pPass->mAnimConvolutedModeBType = Intermediate.mAnimConvolutedModeBType;
+ std::copy(std::begin(Intermediate.mAnimParams), std::end(Intermediate.mAnimParams), std::begin(pPass->mAnimParams));
+}
- for (uint32 iPass = 0; iPass < NumPass; iPass++)
+void CMaterialLoader::SelectBestCombinerConfig(EMP3RenderConfig& OutConfig, uint8& OutAlpha,
+ const SMP3IntermediateMaterial& Material, bool Bloom)
+{
+ uint8 UseAlpha = Material.GetINT(EINT::OPAC);
+
+ EMP3RenderConfig UseConfig = EMP3RenderConfig::FullRenderOpaque;
+ if (Material.mOptions & EMP3MaterialOption::SolidWhiteOnly)
{
- CMaterialPass *pPass = pMat->Pass(iPass);
- CFourCC Type = pPass->Type();
-
- // Color Map (Diffuse)
- if (Type == "CLR ")
+ // Just white
+ UseConfig = EMP3RenderConfig::SolidWhite;
+ }
+ else if (Material.mOptions & EMP3MaterialOption::SolidColorOnly)
+ {
+ // Just KColor/KAlpha
+ UseConfig = EMP3RenderConfig::SolidKColorKAlpha;
+ }
+ else
+ {
+ bool AdditiveIncandecence = Material.mOptions & EMP3MaterialOption::AdditiveIncandecence;
+ // Essentially skips optimized variants for special rendering cases even if opaque
+ // Config 6 being an important case here
+ bool ForceAlphaBlendingConfig = Material.mOptions & EMP3MaterialOption::PreIncandecenceTransparency;
+ if (AdditiveIncandecence && !ForceAlphaBlendingConfig)
{
- pPass->SetRasSel(kRasColor0A0);
-
- if (Lightmap)
- {
- pPass->SetColorInputs(kZeroRGB, kColor0RGB, kTextureRGB, kZeroRGB);
- }
-
- else
- {
- pPass->SetColorInputs(kZeroRGB, kRasRGB, kTextureRGB, kZeroRGB);
- }
-
-
- if (pMat->mOptions & EMaterialOption::Masked)
- {
- pPass->SetAlphaInputs(kZeroAlpha, kZeroAlpha, kZeroAlpha, kTextureAlpha);
- }
- else if (mHasOPAC)
- {
- pPass->SetAlphaInputs(kZeroAlpha, kZeroAlpha, kZeroAlpha, kKonstAlpha);
- pPass->SetKColorSel(kKonst0_RGB);
- pPass->SetKAlphaSel(kKonst0_A);
- }
- else
- {
- pPass->SetAlphaInputs(kZeroAlpha, kZeroAlpha, kZeroAlpha, kPrevAlpha);
- }
-
- pPass->SetColorOutput(kPrevReg);
- pPass->SetAlphaOutput(kPrevReg);
+ // Incandecence/Reflect only
+ UseConfig = EMP3RenderConfig::AdditiveIncandecenceOnly;
}
-
- // Lightmap
- else if (Type == "DIFF")
- {
- pPass->SetColorInputs(kZeroRGB, kKonstRGB, kTextureRGB, kRasRGB);
- pPass->SetAlphaInputs(kZeroAlpha, kZeroAlpha, kZeroAlpha, kKonstAlpha);
- pPass->SetColorOutput(kColor0Reg);
- pPass->SetAlphaOutput(kColor0Reg);
- pPass->SetKColorSel(kKonst1_RGB);
- pPass->SetKAlphaSel(kKonst1_A);
- pPass->SetRasSel(kRasColor0A0);
- Lightmap = true;
- }
-
- // Bloom Lightmap
- else if (Type == "BLOL")
- {
- // Bloom maps work by writing to framebuffer alpha. Can't do this on alpha-blended mats.
- pPass->SetColorInputs(kZeroRGB, kZeroRGB, kZeroRGB, kPrevRGB);
-
- if ((AlphaBlended) || (pMat->mOptions & EMaterialOption::Masked))
- pPass->SetAlphaInputs(kZeroAlpha, kZeroAlpha, kZeroAlpha, kPrevAlpha);
- else
- pPass->SetAlphaInputs(kZeroAlpha, kZeroAlpha, kZeroAlpha, kTextureAlpha);
-
- pPass->SetColorOutput(kPrevReg);
- pPass->SetAlphaOutput(kPrevReg);
- }
-
- // Rim Light Map
- else if (Type == "RIML")
- {
- pPass->SetColorInputs(kZeroRGB, kOneRGB, kPrevRGB, kTextureRGB);
- pPass->SetAlphaInputs(kZeroAlpha, kZeroAlpha, kZeroAlpha, kPrevAlpha);
- pPass->SetColorOutput(kPrevReg);
- pPass->SetAlphaOutput(kPrevReg);
- }
-
- // Emissive Map
- else if (Type == "INCA")
- {
- pPass->SetColorInputs(kZeroRGB, kTextureRGB, kOneRGB, kPrevRGB);
-
- if ((pPass->mSettings & EPassSettings::EmissiveBloom) && (!AlphaBlended))
- {
- pPass->SetAlphaInputs(kZeroAlpha, kTextureAlpha, kKonstAlpha, kPrevAlpha);
- pPass->SetKAlphaSel(kKonstOneFourth);
- }
- else
- {
- pPass->SetAlphaInputs(kZeroAlpha, kZeroAlpha, kZeroAlpha, kPrevAlpha);
- }
-
- pPass->SetColorOutput(kPrevReg);
- pPass->SetAlphaOutput(kPrevReg);
- }
-
- // Opacity Map
- else if (Type == "TRAN")
- {
- pPass->SetColorInputs(kZeroRGB, kZeroRGB, kZeroRGB, kPrevRGB);
-
- if (pPass->mSettings & EPassSettings::InvertOpacityMap)
- pPass->SetAlphaInputs(kKonstAlpha, kZeroAlpha, kTextureAlpha, kZeroAlpha);
- else
- pPass->SetAlphaInputs(kZeroAlpha, kKonstAlpha, kTextureAlpha, kZeroAlpha);
-
- pPass->SetColorOutput(kPrevReg);
- pPass->SetAlphaOutput(kPrevReg);
- }
-
- // Specular Map
- else if (Type == "RFLV")
- {
- pPass->SetColorInputs(kZeroRGB, kZeroRGB, kZeroRGB, kTextureRGB);
- pPass->SetAlphaInputs(kZeroAlpha, kZeroAlpha, kZeroAlpha, kPrevAlpha);
- pPass->SetColorOutput(kColor2Reg);
- pPass->SetAlphaOutput(kColor2Reg);
- }
-
- // Reflection Map
- else if (Type == "RFLD")
- {
- pPass->SetColorInputs(kZeroRGB, kColor2RGB, kTextureRGB, kPrevRGB);
- pPass->SetAlphaInputs(kZeroAlpha, kZeroAlpha, kZeroAlpha, kPrevAlpha);
- pPass->SetColorOutput(kPrevReg);
- pPass->SetAlphaOutput(kPrevReg);
- if (mHas0x400) pPass->SetEnabled(false);
- }
-
- // Bloom Incandescence
- else if (Type == "BLOI")
- {
- pPass->SetColorInputs(kZeroRGB, kZeroRGB, kZeroRGB, kPrevRGB);
-
- // Comes out wrong every time even though this is exactly how the Dolphin shaders say this is done.
- if (AlphaBlended)
- pPass->SetAlphaInputs(kZeroAlpha, kZeroAlpha, kZeroAlpha, kPrevAlpha);
- else
- pPass->SetAlphaInputs(kTextureAlpha, kZeroAlpha, kZeroAlpha, kPrevAlpha);
-
- pPass->SetColorOutput(kPrevReg);
- pPass->SetAlphaOutput(kPrevReg);
- }
-
- // Bloom Diffuse
- else if (Type == "BLOD")
- {
- // Not supported yet
- }
-
- // X-Ray - since we don't support X-Ray previews, no effect
- else if (Type == "XRAY")
- {
- pPass->SetColorInputs(kZeroRGB, kZeroRGB, kZeroRGB, kPrevRGB);
- pPass->SetAlphaInputs(kZeroAlpha, kZeroAlpha, kZeroAlpha, kPrevAlpha);
- pPass->SetColorOutput(kPrevReg);
- pPass->SetAlphaOutput(kPrevReg);
- }
-
- // Toon? Don't know what it's for but got TEV setup from shader dumps
- else if (Type == "TOON")
- {
- pPass->SetColorInputs(kZeroRGB, kPrevRGB, kTextureRGB, kZeroRGB);
- pPass->SetAlphaInputs(kZeroAlpha, kZeroAlpha, kZeroAlpha, kTextureAlpha);
- pPass->SetColorOutput(kPrevReg);
- pPass->SetAlphaOutput(kPrevReg);
- }
-
- // LURD and LRLD are unknown and don't seem to do anything
- else if ((Type == "LURD") || (Type == "LRLD"))
- {
- pPass->SetColorInputs(kZeroRGB, kZeroRGB, kZeroRGB, kPrevRGB);
- pPass->SetAlphaInputs(kZeroAlpha, kZeroAlpha, kZeroAlpha, kPrevAlpha);
- pPass->SetColorOutput(kPrevReg);
- pPass->SetAlphaOutput(kPrevReg);
- }
-
- else if (Type == "CUST") {}
-
else
{
- errorf("%s [0x%X]: Unsupported material pass type: %s", *mpFile->GetSourceString(), mPassOffsets[iPass], *Type.ToString());
- pPass->mEnabled = false;
+ bool AlphaCompare = false;
+ if (Material.mOptions & EMP3MaterialOption::Masked && UseAlpha == 255)
+ {
+ AlphaCompare = true;
+ }
+
+ bool ConsiderBloom = false;
+ if ((ForceAlphaBlendingConfig || Material.GetINT(EINT::OPAC) < 255) && !AlphaCompare)
+ {
+ ConsiderBloom = true;
+ }
+
+ bool ForceNoBloom = true;
+ if (!(ConsiderBloom && Material.mOptions & EMP3MaterialOption::Bloom))
+ ForceNoBloom = false;
+
+ if (AdditiveIncandecence)
+ {
+ if (ForceNoBloom || !Bloom)
+ {
+ if (Material.GetPASS(EPASS::INCA))
+ {
+ UseConfig = EMP3RenderConfig::NoBloomAdditiveIncandecence;
+ }
+ else
+ {
+ UseConfig = EMP3RenderConfig::NoBloomTransparent;
+ }
+ }
+ else
+ {
+ UseConfig = EMP3RenderConfig::FullRenderTransparentAdditiveIncandecence;
+ }
+ }
+ else if (AlphaCompare)
+ {
+ UseConfig = EMP3RenderConfig::MaterialAlphaCompare;
+ }
+ else if (ForceAlphaBlendingConfig || UseAlpha < 255)
+ {
+ bool WithIncandecence = Material.GetPASS(EPASS::INCA) || Material.GetPASS(EPASS::BLOI);
+ if (ForceNoBloom || !Bloom)
+ {
+ if (WithIncandecence)
+ {
+ UseConfig = EMP3RenderConfig::NoBloomAdditiveIncandecence;
+ }
+ else
+ {
+ UseConfig = EMP3RenderConfig::NoBloomTransparent;
+ }
+ }
+ else
+ {
+ UseConfig = EMP3RenderConfig::FullRenderTransparent;
+ if (WithIncandecence)
+ {
+ UseConfig = EMP3RenderConfig::FullRenderTransparentAdditiveIncandecence;
+ }
+ }
+ }
}
}
+
+ if (UseConfig == EMP3RenderConfig::FullRenderOpaque)
+ {
+ if (Material.GetPASS(EPASS::DIFF) && Material.GetPASS(EPASS::CLR))
+ {
+ UseConfig = EMP3RenderConfig::OptimizedDiffuseLightingColorOpaque;
+ }
+ else if (Material.GetPASS(EPASS::DIFF) && Material.GetPASS(EPASS::BLOL) && Material.GetPASS(EPASS::CLR))
+ {
+ UseConfig = EMP3RenderConfig::OptimizedDiffuseBloomLightingColorOpaque;
+ }
+ }
+
+ OutConfig = UseConfig;
+ OutAlpha = UseAlpha;
+}
+
+static const ETevKSel KColorEighths[] =
+{
+ kKonstOneEighth,
+ kKonstOneFourth,
+ kKonstThreeEighths,
+ kKonstOneHalf,
+ kKonstFiveEighths,
+ kKonstThreeFourths,
+ kKonstSevenEighths,
+ kKonstOne
+};
+
+bool CMaterialLoader::SetupStaticDiffuseLightingStage(STevTracker& Tracker, CMaterial* pMat,
+ const SMP3IntermediateMaterial& Intermediate, bool FullAlpha)
+{
+ bool hasDIFFTexture = Intermediate.GetPASS(EPASS::DIFF).operator bool();
+ if (!hasDIFFTexture && (Intermediate.mOptions & (EMP3MaterialOption::AdditiveIncandecence |
+ EMP3MaterialOption::PreIncandecenceTransparency |
+ EMP3MaterialOption::ForceLightingStage)) !=
+ EMP3MaterialOption::ForceLightingStage)
+ return false;
+ pMat->SetTevColor(Intermediate.GetCLR(ECLR::DIFB), kColor1Reg);
+ CMaterialPass* pPass = new CMaterialPass(pMat);
+ if (hasDIFFTexture)
+ {
+ SetMP3IntermediateIntoMaterialPass(pPass, *Intermediate.GetPASS(EPASS::DIFF));
+ pPass->SetColorInputs(kZeroRGB, kTextureRGB, kColor1RGB, kRasRGB);
+ pPass->SetColorOutput(kColor0Reg);
+ if (FullAlpha)
+ {
+ /* Full Alpha */
+ pPass->SetAlphaInputs(kZeroAlpha, kZeroAlpha, kZeroAlpha, kKonstAlpha);
+ pPass->SetKAlphaSel(kKonstOne);
+ pPass->SetAlphaOutput(kPrevReg);
+ }
+ else if (!Intermediate.GetPASS(EPASS::BLOL))
+ {
+ Tracker.mStaticDiffuseLightingAlphaSet = true;
+ Tracker.mStaticLightingAlphaSet = true;
+ pPass->SetAlphaInputs(kZeroAlpha, kZeroAlpha, kZeroAlpha, kZeroAlpha);
+ pPass->SetAlphaOutput(kPrevReg);
+ }
+ else
+ {
+ Tracker.mStaticDiffuseLightingAlphaSet = true;
+ pPass->SetAlphaOutput(kPrevReg);
+ if (Intermediate.GetINT(EINT::BLOD) == 0)
+ {
+ pPass->SetAlphaInputs(kZeroAlpha, kZeroAlpha, kZeroAlpha, kRasAlpha);
+ }
+ else if (Intermediate.GetINT(EINT::BLOD) == 255)
+ {
+ pPass->SetAlphaInputs(kZeroAlpha, kTextureAlpha, kColor1Alpha, kRasAlpha);
+ }
+ else
+ {
+ pMat->SetKonst(CColor::Integral(0, 0, 0, Intermediate.GetINT(EINT::BLOD)), Tracker.mCurKColor);
+ pPass->SetKAlphaSel(ETevKSel(kKonst0_A + Tracker.mCurKColor));
+ Tracker.mCurKColor += 1;
+ pPass->SetAlphaInputs(kZeroAlpha, kTextureAlpha, kKonstAlpha, kRasAlpha);
+ }
+ Tracker.mStaticLightingAlphaSet = true;
+ }
+ pPass->SetRasSel(kRasColor0A0);
+ }
+ else
+ {
+ pPass->mPassType = "DIFF";
+ pPass->SetColorOutput(kColor0Reg);
+ pPass->SetAlphaOutput(kPrevReg);
+ pPass->SetColorInputs(kZeroRGB, kColor1RGB, kKonstRGB, kRasRGB);
+ pPass->SetAlphaInputs(kZeroAlpha, kZeroAlpha, kZeroAlpha, FullAlpha ? kKonstAlpha : kZeroAlpha);
+ pPass->SetKColorSel(kKonstOne);
+ pPass->SetKAlphaSel(kKonstOne);
+ pPass->SetRasSel(kRasColor0A0);
+ Tracker.mStaticLightingAlphaSet = true;
+ }
+ pMat->mPasses.push_back(pPass);
+ return true;
+}
+
+void CMaterialLoader::SetupStaticDiffuseLightingNoBloomStage(STevTracker& Tracker, CMaterial* pMat,
+ const SMP3IntermediateMaterial& Intermediate)
+{
+ CMaterialPass* pPass = new CMaterialPass(pMat);
+ SetMP3IntermediateIntoMaterialPass(pPass, *Intermediate.GetPASS(EPASS::DIFF));
+
+ pMat->SetTevColor(Intermediate.GetCLR(ECLR::DIFB), kColor1Reg);
+ pPass->SetColorInputs(kZeroRGB, kTextureRGB, kColor1RGB, kRasRGB);
+ pPass->SetColorOutput(kColor0Reg);
+ Tracker.mStaticDiffuseLightingAlphaSet = true;
+ Tracker.mStaticLightingAlphaSet = true;
+ pPass->SetAlphaInputs(kZeroAlpha, kZeroAlpha, kZeroAlpha, kZeroAlpha);
+ pPass->SetAlphaOutput(kPrevReg);
+ pPass->SetRasSel(kRasColor0A0);
+
+ pMat->mPasses.push_back(pPass);
+}
+
+void CMaterialLoader::SetupStaticDiffuseLightingNoBLOLStage(STevTracker& Tracker, CMaterial* pMat,
+ const SMP3IntermediateMaterial& Intermediate)
+{
+ CMaterialPass* pPass = new CMaterialPass(pMat);
+ SetMP3IntermediateIntoMaterialPass(pPass, *Intermediate.GetPASS(EPASS::DIFF));
+
+ pMat->SetTevColor(Intermediate.GetCLR(ECLR::DIFB), kColor1Reg);
+ pPass->SetColorInputs(kZeroRGB, kTextureRGB, kColor1RGB, kRasRGB);
+ pPass->SetColorOutput(kColor0Reg);
+ Tracker.mStaticDiffuseLightingAlphaSet = true;
+ pPass->SetAlphaOutput(kPrevReg);
+ if (Intermediate.GetINT(EINT::BLOD) == 0)
+ {
+ pPass->SetAlphaInputs(kZeroAlpha, kZeroAlpha, kZeroAlpha, kRasAlpha);
+ }
+ else if (Intermediate.GetINT(EINT::BLOD) == 255)
+ {
+ pPass->SetAlphaInputs(kZeroAlpha, kTextureAlpha, kColor1Alpha, kRasAlpha);
+ }
+ else
+ {
+ pMat->SetKonst(CColor::Integral(0, 0, 0, Intermediate.GetINT(EINT::BLOD)), Tracker.mCurKColor);
+ pPass->SetKAlphaSel(ETevKSel(kKonst0_A + Tracker.mCurKColor));
+ Tracker.mCurKColor += 1;
+ pPass->SetAlphaInputs(kZeroAlpha, kTextureAlpha, kKonstAlpha, kRasAlpha);
+ }
+ Tracker.mStaticLightingAlphaSet = true;
+ pPass->SetRasSel(kRasColor0A0);
+
+ pMat->mPasses.push_back(pPass);
+}
+
+void CMaterialLoader::SetupColorTextureStage(STevTracker& Tracker, CMaterial* pMat,
+ const SMP3IntermediateMaterial& Intermediate,
+ bool useStageAlpha, uint8 Alpha, bool StaticLighting)
+{
+ CMaterialPass* pPass = new CMaterialPass(pMat);
+ SetMP3IntermediateIntoMaterialPass(pPass, *Intermediate.GetPASS(EPASS::CLR));
+
+ bool useDynamicLightingAlpha = false;
+ pPass->SetColorInputs(kZeroRGB, StaticLighting ? kColor0RGB : kRasRGB, kTextureRGB, kZeroRGB);
+ pPass->SetTevColorScale(StaticLighting ? 2.f : 1.f);
+ pPass->SetColorOutput(kPrevReg);
+
+ if (useStageAlpha)
+ {
+ if (Alpha == 255)
+ {
+ pPass->SetAlphaInputs(kZeroAlpha, kZeroAlpha, kZeroAlpha, kTextureAlpha);
+ }
+ else
+ {
+ pMat->SetKonst(CColor::Integral(0, 0, 0, Alpha), Tracker.mCurKColor);
+ pPass->SetKAlphaSel(ETevKSel(kKonst0_A + Tracker.mCurKColor));
+ Tracker.mCurKColor += 1;
+ pPass->SetAlphaInputs(kZeroAlpha, kTextureAlpha, kKonstAlpha, kZeroAlpha);
+ }
+ }
+ else
+ {
+ pPass->SetAlphaInputs(kZeroAlpha, kZeroAlpha, kZeroAlpha,
+ Tracker.mStaticLightingAlphaSet ? kPrevAlpha : kRasAlpha);
+ useDynamicLightingAlpha = !Tracker.mStaticLightingAlphaSet;
+ Tracker.mStaticLightingAlphaSet = true;
+ }
+ pPass->SetAlphaOutput(kPrevReg);
+ pPass->SetRasSel((useDynamicLightingAlpha || !StaticLighting) ? kRasColor0A0 : kRasColorNull);
+
+ pMat->mPasses.push_back(pPass);
+}
+
+void CMaterialLoader::SetupColorTextureAlwaysStaticLightingStage(STevTracker& Tracker, CMaterial* pMat,
+ const SMP3IntermediateMaterial& Intermediate)
+{
+ CMaterialPass* pPass = new CMaterialPass(pMat);
+ SetMP3IntermediateIntoMaterialPass(pPass, *Intermediate.GetPASS(EPASS::CLR));
+
+ pPass->SetColorInputs(kZeroRGB, kColor0RGB, kTextureRGB, kZeroRGB);
+ pPass->SetColorOutput(kPrevReg);
+ pPass->SetTevColorScale(2.f);
+ pPass->SetAlphaInputs(kZeroAlpha, kZeroAlpha, kZeroAlpha, kPrevAlpha);
+ pPass->SetAlphaOutput(kPrevReg);
+ pPass->SetRasSel(kRasColorNull);
+
+ pMat->mPasses.push_back(pPass);
+}
+
+void CMaterialLoader::SetupColorKColorStage(STevTracker& Tracker, CMaterial* pMat,
+ const SMP3IntermediateMaterial& Intermediate,
+ bool useStageAlpha, uint8 Alpha, bool StaticLighting)
+{
+ CMaterialPass* pPass = new CMaterialPass(pMat);
+ pPass->mPassType = "CLR ";
+
+ bool useDynamicLightingAlpha = false;
+ CColor col = Intermediate.GetCLR(ECLR::CLR);
+ col.A = Alpha / 255.f;
+ pMat->SetKonst(col, Tracker.mCurKColor);
+ pPass->SetKColorSel(ETevKSel(kKonst0_RGB + Tracker.mCurKColor));
+ pPass->SetColorInputs(kZeroRGB, StaticLighting ? kColor0RGB : kRasRGB, kKonstRGB, kZeroRGB);
+ pPass->SetTevColorScale(2.f);
+ pPass->SetColorOutput(kPrevReg);
+ if (useStageAlpha)
+ {
+ pPass->SetKAlphaSel(ETevKSel(kKonst0_A + Tracker.mCurKColor));
+ pPass->SetAlphaInputs(kZeroAlpha, kZeroAlpha, kZeroAlpha, kKonstAlpha);
+ }
+ else
+ {
+ pPass->SetAlphaInputs(kZeroAlpha, kZeroAlpha, kZeroAlpha,
+ Tracker.mStaticLightingAlphaSet ? kPrevAlpha : kRasAlpha);
+ useDynamicLightingAlpha = !Tracker.mStaticLightingAlphaSet;
+ Tracker.mStaticLightingAlphaSet = true;
+ }
+ pPass->SetAlphaOutput(kPrevReg);
+ pPass->SetRasSel((useDynamicLightingAlpha || !StaticLighting) ? kRasColor0A0 : kRasColorNull);
+ Tracker.mCurKColor += 1;
+
+ pMat->mPasses.push_back(pPass);
+}
+
+bool CMaterialLoader::SetupTransparencyStage(STevTracker& Tracker, CMaterial* pMat,
+ const SMP3IntermediateMaterial& Intermediate)
+{
+ if (const auto& IntermediateTran = Intermediate.GetPASS(EPASS::TRAN)) {
+ CMaterialPass* pPass = new CMaterialPass(pMat);
+ SetMP3IntermediateIntoMaterialPass(pPass, *IntermediateTran);
+
+ if (IntermediateTran->mSettings & EPassSettings::InvertOpacityMap)
+ {
+ pPass->SetAlphaInputs(kPrevAlpha, kZeroAlpha, kTextureAlpha, kZeroAlpha);
+ }
+ else
+ {
+ pPass->SetAlphaInputs(kZeroAlpha, kPrevAlpha, kTextureAlpha, kZeroAlpha);
+ }
+ pPass->SetColorInputs(kZeroRGB, kZeroRGB, kZeroRGB, kPrevRGB);
+ pPass->SetColorOutput(kPrevReg);
+ pPass->SetAlphaOutput(kPrevReg);
+ pPass->SetRasSel(kRasColorNull);
+ pPass->SetTexSwapComp(3, IntermediateTran->GetSwapAlphaComp());
+
+ pMat->mPasses.push_back(pPass);
+ return true;
+ }
+ return false;
+}
+
+void CMaterialLoader::SetupTransparencyKAlphaMultiplyStage(STevTracker& Tracker, CMaterial* pMat,
+ const SMP3IntermediateMaterial& Intermediate,
+ bool multiplyPrevAlpha, uint8 Alpha)
+{
+ if (Intermediate.GetPASS(EPASS::CLR) || Intermediate.GetPASS(EPASS::TRAN))
+ {
+ CMaterialPass* pPass = new CMaterialPass(pMat);
+ ETevAlphaInput argA;
+ if (Alpha < 255)
+ {
+ pMat->SetKonst(CColor::Integral(255, 255, 255, Alpha), Tracker.mCurKColor);
+ pPass->SetKAlphaSel(ETevKSel(kKonst0_A + Tracker.mCurKColor));
+ if (multiplyPrevAlpha)
+ {
+ pPass->SetAlphaInputs(kZeroAlpha, kPrevAlpha, kKonstAlpha, kZeroAlpha);
+ pPass->SetAlphaOutput(kPrevReg);
+ pPass->SetRasSel(kRasColorNull);
+ pMat->mPasses.push_back(pPass);
+ pPass = new CMaterialPass(pMat);
+ argA = kPrevAlpha;
+ }
+ else
+ {
+ argA = kKonstAlpha;
+ }
+ }
+ else
+ {
+ if (multiplyPrevAlpha)
+ {
+ argA = kPrevAlpha;
+ }
+ else
+ {
+ pPass->SetKAlphaSel(kKonstOne);
+ argA = kKonstAlpha;
+ }
+ }
+ const auto& IntermediateTran = Intermediate.GetPASS(EPASS::TRAN);
+ if (IntermediateTran && IntermediateTran->mSettings & EPassSettings::InvertOpacityMap)
+ {
+ pPass->SetAlphaInputs(argA, kZeroAlpha, kTextureAlpha, kZeroAlpha);
+ }
+ else
+ {
+ pPass->SetAlphaInputs(kZeroAlpha, argA, kTextureAlpha, kZeroAlpha);
+ }
+ pPass->SetAlphaOutput(kPrevReg);
+ if (IntermediateTran)
+ {
+ SetMP3IntermediateIntoMaterialPass(pPass, *IntermediateTran);
+ pPass->SetRasSel(kRasColorNull);
+ pPass->SetTexSwapComp(3, IntermediateTran->GetSwapAlphaComp());
+ }
+ else
+ {
+ SetMP3IntermediateIntoMaterialPass(pPass, *Intermediate.GetPASS(EPASS::CLR));
+ pPass->SetRasSel(kRasColorNull);
+ }
+ Tracker.mCurKColor += 1;
+ pMat->mPasses.push_back(pPass);
+ }
+ else
+ {
+ CMaterialPass* pPass = new CMaterialPass(pMat);
+ pMat->SetKonst(CColor::Integral(255, 255, 255, Alpha), Tracker.mCurKColor);
+ pPass->SetKAlphaSel(ETevKSel(kKonst0_A + Tracker.mCurKColor));
+ if (multiplyPrevAlpha)
+ {
+ pPass->SetAlphaInputs(kZeroAlpha, kKonstAlpha, kPrevAlpha, kZeroAlpha);
+ }
+ else
+ {
+ pPass->SetAlphaInputs(kZeroAlpha, kZeroAlpha, kZeroAlpha, kKonstAlpha);
+ }
+ pPass->SetAlphaOutput(kPrevReg);
+ pPass->SetRasSel(kRasColorNull);
+ Tracker.mCurKColor += 1;
+ pMat->mPasses.push_back(pPass);
+ }
+}
+
+bool CMaterialLoader::SetupReflectionAlphaStage(STevTracker& Tracker, CMaterial* pMat,
+ const SMP3IntermediateMaterial& Intermediate)
+{
+ if (Intermediate.mOptions & EMP3MaterialOption::ReflectionAlphaTarget)
+ {
+ if (const auto& IntermediateRfld = Intermediate.GetPASS(EPASS::RFLD))
+ {
+ CMaterialPass* pPass = new CMaterialPass(pMat);
+ SetMP3IntermediateIntoMaterialPass(pPass, *IntermediateRfld);
+
+ pPass->SetColorInputs(kZeroRGB, kZeroRGB, kZeroRGB, kPrevRGB);
+ pPass->SetAlphaInputs(kZeroAlpha, kPrevAlpha, kTextureAlpha, kZeroAlpha);
+ pPass->SetColorOutput(kPrevReg);
+ pPass->SetAlphaOutput(kPrevReg);
+ pPass->SetRasSel(kRasColorNull);
+ pPass->SetTexSwapComp(3, 'r');
+
+ pMat->mPasses.push_back(pPass);
+ return true;
+ }
+ }
+ return false;
+}
+
+bool CMaterialLoader::SetupReflectionStages(STevTracker& Tracker, CMaterial* pMat,
+ const SMP3IntermediateMaterial& Intermediate,
+ ETevColorInput argD, bool StaticLighting)
+{
+ if (!Intermediate.GetPASS(EPASS::RFLD) || Intermediate.mOptions & EMP3MaterialOption::ReflectionAlphaTarget)
+ return false;
+ ETevColorInput argC = kOneRGB;
+ if (Intermediate.GetPASS(EPASS::RFLV) || Intermediate.GetPASS(EPASS::LRLD) || Intermediate.GetPASS(EPASS::LURD)) {
+ CMaterialPass* pPass = new CMaterialPass(pMat);
+ pPass->SetColorOutput(kColor2Reg);
+ pPass->SetAlphaOutput(kColor2Reg);
+ if (const auto& IntermediateRflv = Intermediate.GetPASS(EPASS::RFLV))
+ {
+ pPass->SetColorInputs(kZeroRGB, kZeroRGB, kZeroRGB, kTextureRGB);
+ pPass->SetAlphaInputs(kZeroAlpha, kZeroAlpha, kZeroAlpha, kZeroAlpha);
+ pPass->SetRasSel(kRasColorNull);
+ SetMP3IntermediateIntoMaterialPass(pPass, *IntermediateRflv);
+ }
+ else if (const auto& IntermediateLrld = Intermediate.GetPASS(EPASS::LRLD))
+ {
+ pPass->SetColorInputs(kZeroRGB, StaticLighting ? kColor0RGB : kRasRGB, kTextureRGB, kZeroRGB);
+ pPass->SetAlphaInputs(kZeroAlpha, kZeroAlpha, kZeroAlpha, kZeroAlpha);
+ pPass->SetRasSel(StaticLighting ? kRasColorNull : kRasColor0A0);
+ SetMP3IntermediateIntoMaterialPass(pPass, *IntermediateLrld);
+ }
+ else if (const auto& IntermediateLurd = Intermediate.GetPASS(EPASS::LURD))
+ {
+ pPass->SetColorInputs(kZeroRGB, StaticLighting ? kColor0RGB : kRasRGB, kTextureAAA, kTextureRGB);
+ pPass->SetAlphaInputs(kZeroAlpha, kZeroAlpha, kZeroAlpha, kZeroAlpha);
+ pPass->SetRasSel(StaticLighting ? kRasColorNull : kRasColor0A0);
+ SetMP3IntermediateIntoMaterialPass(pPass, *IntermediateLurd);
+ }
+ argC = kColor2RGB;
+ pMat->mPasses.push_back(pPass);
+ }
+ if (const auto& IntermediateRfld = Intermediate.GetPASS(EPASS::RFLD))
+ {
+ CMaterialPass* pPass = new CMaterialPass(pMat);
+ pPass->SetColorInputs(kZeroRGB, kTextureRGB, argC, argD);
+ pPass->SetAlphaInputs(kZeroAlpha, kZeroAlpha, kZeroAlpha, kPrevAlpha);
+ pPass->SetColorOutput(kPrevReg);
+ pPass->SetAlphaOutput(kPrevReg);
+ pPass->SetRasSel(kRasColorNull);
+ SetMP3IntermediateIntoMaterialPass(pPass, *IntermediateRfld);
+ pMat->mPasses.push_back(pPass);
+ }
+ return true;
+}
+
+bool CMaterialLoader::SetupQuantizedKAlphaAdd(STevTracker& Tracker, CMaterial* pMat, uint8 Value)
+{
+ CMaterialPass* pPass = new CMaterialPass(pMat);
+ pPass->SetColorInputs(kZeroRGB, kZeroRGB, kZeroRGB, kPrevRGB);
+ pPass->SetKAlphaSel(KColorEighths[Value / 32]);
+ pPass->SetAlphaInputs(kKonstAlpha, kZeroAlpha, kZeroAlpha, kPrevAlpha);
+ pPass->SetColorOutput(kPrevReg);
+ pPass->SetAlphaOutput(kPrevReg);
+ pPass->SetRasSel(kRasColorNull);
+ pMat->mPasses.push_back(pPass);
+ return true;
+}
+
+bool CMaterialLoader::SetupIncandecenceStage(STevTracker& Tracker, CMaterial* pMat,
+ const SMP3IntermediateMaterial& Intermediate)
+{
+ uint8 bloi = Intermediate.GetINT(EINT::BLOI);
+ const auto& IntermediateInca = Intermediate.GetPASS(EPASS::INCA);
+ if (!IntermediateInca)
+ {
+ if (bloi)
+ return SetupQuantizedKAlphaAdd(Tracker, pMat, bloi);
+ else
+ return false;
+ }
+
+ CMaterialPass* pPass = new CMaterialPass(pMat);
+ SetMP3IntermediateIntoMaterialPass(pPass, *IntermediateInca);
+
+ pPass->SetKColorSel(kKonstOne);
+ pPass->SetColorInputs(kZeroRGB, kKonstRGB, kTextureRGB, kPrevRGB);
+ pPass->SetColorOutput(kPrevReg);
+ pPass->SetAlphaOutput(kPrevReg);
+ pPass->SetRasSel(kRasColorNull);
+ if (IntermediateInca->mSettings & EPassSettings::BloomContribution)
+ {
+ pPass->SetTexSwapComp(3, IntermediateInca->GetSwapAlphaComp());
+ pPass->SetKAlphaSel(KColorEighths[Intermediate.GetINT(EINT::BNIF) / 32]);
+ pPass->SetAlphaInputs(kZeroAlpha, kTextureAlpha, kKonstAlpha, kPrevAlpha);
+ pMat->mPasses.push_back(pPass);
+ if (bloi)
+ SetupQuantizedKAlphaAdd(Tracker, pMat, bloi);
+ }
+ else
+ {
+ if (bloi)
+ {
+ pPass->SetKAlphaSel(KColorEighths[bloi / 32]);
+ pPass->SetAlphaInputs(kKonstAlpha, kZeroAlpha, kZeroAlpha, kPrevAlpha);
+ }
+ else
+ {
+ pPass->SetAlphaInputs(kZeroAlpha, kZeroAlpha, kZeroAlpha, kPrevAlpha);
+ }
+ pMat->mPasses.push_back(pPass);
+ }
+ return true;
+}
+
+bool CMaterialLoader::SetupIncandecenceStageNoBloom(STevTracker& Tracker, CMaterial* pMat,
+ const SMP3IntermediateMaterial& Intermediate)
+{
+ const auto& IntermediateInca = Intermediate.GetPASS(EPASS::INCA);
+ if (!IntermediateInca)
+ return false;
+
+ CMaterialPass* pPass = new CMaterialPass(pMat);
+ SetMP3IntermediateIntoMaterialPass(pPass, *IntermediateInca);
+
+ pPass->SetKColorSel(kKonstOne);
+ pPass->SetColorInputs(kZeroRGB, kKonstRGB, kTextureRGB, kPrevRGB);
+ pPass->SetAlphaInputs(kZeroAlpha, kZeroAlpha, kZeroAlpha, kPrevAlpha);
+ pPass->SetColorOutput(kPrevReg);
+ pPass->SetAlphaOutput(kPrevReg);
+ pPass->SetRasSel(kRasColorNull);
+ pMat->mPasses.push_back(pPass);
+
+ return true;
+}
+
+bool CMaterialLoader::SetupStartingIncandecenceStage(STevTracker& Tracker, CMaterial* pMat,
+ const SMP3IntermediateMaterial& Intermediate)
+{
+ bool needsBloiAdd = false;
+ uint8 bloi = Intermediate.GetINT(EINT::BLOI);
+ const auto& IntermediateInca = Intermediate.GetPASS(EPASS::INCA);
+ if (!IntermediateInca)
+ {
+ if (bloi)
+ {
+ CMaterialPass* pPass = new CMaterialPass(pMat);
+ pPass->SetColorInputs(kZeroRGB, kZeroRGB, kZeroRGB, kZeroRGB);
+ pPass->SetKAlphaSel(KColorEighths[bloi / 32]);
+ pPass->SetAlphaInputs(kZeroAlpha, kZeroAlpha, kZeroAlpha, kKonstAlpha);
+ pPass->SetColorOutput(kPrevReg);
+ pPass->SetAlphaOutput(kPrevReg);
+ pPass->SetRasSel(kRasColorNull);
+ pMat->mPasses.push_back(pPass);
+ return true;
+ }
+ return false;
+ }
+
+ CMaterialPass* pPass = new CMaterialPass(pMat);
+ SetMP3IntermediateIntoMaterialPass(pPass, *IntermediateInca);
+
+ pPass->SetKColorSel(kKonstOne);
+ pPass->SetColorInputs(kZeroRGB, kTextureRGB, kKonstRGB, kZeroRGB);
+ if (IntermediateInca->mSettings & EPassSettings::BloomContribution)
+ {
+ pPass->SetTexSwapComp(3, IntermediateInca->GetSwapAlphaComp());
+ uint8 bnif = Intermediate.GetINT(EINT::BNIF);
+ if (bloi && !bnif)
+ {
+ pPass->SetKAlphaSel(KColorEighths[bloi / 32]);
+ pPass->SetAlphaInputs(kKonstAlpha, kZeroAlpha, kZeroAlpha, kTextureAlpha);
+ }
+ else
+ {
+ pPass->SetKAlphaSel(KColorEighths[bnif / 32]);
+ pPass->SetAlphaInputs(kZeroAlpha, kTextureAlpha, kKonstAlpha, kZeroAlpha);
+ needsBloiAdd = bloi != 0;
+ }
+ }
+ else
+ {
+ if (bloi)
+ {
+ pPass->SetKAlphaSel(KColorEighths[bloi / 32]);
+ pPass->SetAlphaInputs(kZeroAlpha, kZeroAlpha, kZeroAlpha, kKonstAlpha);
+ }
+ else
+ {
+ pPass->SetAlphaInputs(kZeroAlpha, kZeroAlpha, kZeroAlpha, kZeroAlpha);
+ }
+ }
+ pPass->SetColorOutput(kPrevReg);
+ pPass->SetAlphaOutput(kPrevReg);
+ pPass->SetRasSel(kRasColorNull);
+ pMat->mPasses.push_back(pPass);
+ if (needsBloiAdd)
+ SetupQuantizedKAlphaAdd(Tracker, pMat, bloi);
+ return true;
+}
+
+void CMaterialLoader::SetupStartingIncandecenceDynamicKColorStage(STevTracker& Tracker, CMaterial* pMat,
+ const SMP3IntermediateMaterial& Intermediate)
+{
+ CMaterialPass* pPass = new CMaterialPass(pMat);
+ SetMP3IntermediateIntoMaterialPass(pPass, *Intermediate.GetPASS(EPASS::INCA));
+
+ pPass->SetKColorSel(kKonstOne);
+ pPass->SetKAlphaSel(kKonstOne);
+ pPass->SetColorInputs(kZeroRGB, kKonstRGB, kTextureRGB, kZeroRGB);
+ pPass->SetAlphaInputs(kZeroAlpha, kZeroAlpha, kZeroAlpha, kKonstAlpha);
+ pPass->SetColorOutput(kPrevReg);
+ pPass->SetAlphaOutput(kPrevReg);
+ pPass->SetRasSel(kRasColorNull);
+
+ pMat->mPasses.push_back(pPass);
+}
+
+bool CMaterialLoader::SetupStaticBloomLightingStage(STevTracker& Tracker, CMaterial* pMat,
+ const SMP3IntermediateMaterial& Intermediate, bool StaticLighting)
+{
+ const auto& IntermediateBlol = Intermediate.GetPASS(EPASS::BLOL);
+ if (!StaticLighting || !IntermediateBlol)
+ return false;
+ CMaterialPass* pPass = new CMaterialPass(pMat);
+ SetMP3IntermediateIntoMaterialPass(pPass, *IntermediateBlol);
+
+ pPass->SetTexSwapComp(3, IntermediateBlol->GetSwapAlphaComp());
+ pPass->SetColorOutput(kPrevReg);
+ pPass->SetAlphaOutput(kPrevReg);
+ pPass->SetColorInputs(kZeroRGB, kZeroRGB, kZeroRGB, kPrevRGB);
+ pPass->SetAlphaInputs(kZeroAlpha, kPrevAlpha, kTextureAlpha, kZeroAlpha);
+ pPass->SetRasSel(kRasColorNull);
+
+ pMat->mPasses.push_back(pPass);
+ return true;
+}
+
+bool CMaterialLoader::SetupStaticBloomLightingA1Stages(STevTracker& Tracker, CMaterial* pMat,
+ const SMP3IntermediateMaterial& Intermediate)
+{
+ const auto& IntermediateBlol = Intermediate.GetPASS(EPASS::BLOL);
+ CMaterialPass* pPass = new CMaterialPass(pMat);
+
+ ETevAlphaInput argC = IntermediateBlol ? kTextureAlpha : kZeroAlpha;
+ pPass->SetAlphaInputs(kZeroAlpha, kColor1Alpha, argC, kRasAlpha);
+ pPass->SetAlphaOutput(kPrevReg);
+ if (argC == kTextureAlpha) {
+ pPass->SetTexSwapComp(3, IntermediateBlol->GetSwapAlphaComp());
+ SetMP3IntermediateIntoMaterialPass(pPass, *IntermediateBlol);
+ pPass->SetRasSel(kRasColor0A0);
+ }
+ else
+ {
+ pPass->SetRasSel(kRasColor0A0);
+ }
+ Tracker.mStaticLightingAlphaSet = true;
+ pMat->mPasses.push_back(pPass);
+ SetupStaticBloomDiffuseLightingStages(Tracker, pMat, Intermediate, true);
+ return true;
+}
+
+bool CMaterialLoader::SetupStaticBloomDiffuseLightingStages(STevTracker& Tracker, CMaterial* pMat,
+ const SMP3IntermediateMaterial& Intermediate,
+ bool StaticLighting)
+{
+ if (!StaticLighting)
+ {
+ Tracker.mStaticDiffuseLightingAlphaSet = true;
+ return false;
+ }
+ bool ret = false;
+ bool useDynamicAlpha = false;
+ const auto& IntermediateBlod = Intermediate.GetPASS(EPASS::BLOD);
+ if (!IntermediateBlod)
+ {
+ useDynamicAlpha = !Tracker.mStaticDiffuseLightingAlphaSet;
+ }
+ else
+ {
+ CMaterialPass* pPass = new CMaterialPass(pMat);
+ SetMP3IntermediateIntoMaterialPass(pPass, *IntermediateBlod);
+
+ pPass->SetTexSwapComp(3, IntermediateBlod->GetSwapAlphaComp());
+ pPass->SetColorOutput(kPrevReg);
+ pPass->SetAlphaOutput(kPrevReg);
+ pPass->SetColorInputs(kZeroRGB, kZeroRGB, kZeroRGB, kPrevRGB);
+ ETevAlphaInput argC = Tracker.mStaticLightingAlphaSet ? kPrevAlpha : kRasAlpha;
+ if (!StaticLighting)
+ {
+ if (Intermediate.GetINT(EINT::BLOD) == 255 || Tracker.mStaticDiffuseLightingAlphaSet)
+ {
+ pPass->SetAlphaInputs(kZeroAlpha, kTextureAlpha, argC, kZeroAlpha);
+ Tracker.mStaticDiffuseLightingAlphaSet = true;
+ }
+ else if (Intermediate.GetINT(EINT::BLOD) == 0)
+ {
+ pPass->SetAlphaInputs(kZeroAlpha, kZeroAlpha, kZeroAlpha, kZeroAlpha);
+ Tracker.mStaticDiffuseLightingAlphaSet = true;
+ }
+ else
+ {
+ pPass->SetAlphaInputs(kZeroAlpha, kTextureAlpha, argC, kZeroAlpha);
+ useDynamicAlpha = !Tracker.mStaticDiffuseLightingAlphaSet;
+ }
+ Tracker.mStaticLightingAlphaSet = true;
+ }
+ else
+ {
+ useDynamicAlpha = !Tracker.mStaticDiffuseLightingAlphaSet;
+ pPass->SetAlphaInputs(kZeroAlpha, kPrevAlpha, kTextureAlpha, kZeroAlpha);
+ }
+ pPass->SetRasSel(argC == kRasAlpha ? kRasColor0A0 : kRasColorNull);
+ pMat->mPasses.push_back(pPass);
+ ret = true;
+ }
+ if (useDynamicAlpha)
+ {
+ if (Intermediate.GetINT(EINT::BLOD) != 255)
+ {
+ CMaterialPass* pPass = new CMaterialPass(pMat);
+
+ pPass->SetColorOutput(kPrevReg);
+ pPass->SetAlphaOutput(kPrevReg);
+ pPass->SetColorInputs(kZeroRGB, kZeroRGB, kZeroRGB, kPrevRGB);
+ if (Intermediate.GetINT(EINT::BLOD) == 0)
+ {
+ pPass->SetAlphaInputs(kZeroAlpha, kZeroAlpha, kZeroAlpha, kZeroAlpha);
+ pPass->SetRasSel(kRasColorNull);
+ }
+ else
+ {
+ ETevAlphaInput argB = Tracker.mStaticLightingAlphaSet ? kPrevAlpha : kRasAlpha;
+ pPass->SetKAlphaSel(KColorEighths[Intermediate.GetINT(EINT::BLOD) / 32]);
+ pPass->SetAlphaInputs(kZeroAlpha, argB, kKonstAlpha, kZeroAlpha);
+ pPass->SetRasSel(argB == kPrevAlpha ? kRasColor0A0 : kRasColorNull);
+ Tracker.mStaticLightingAlphaSet = true;
+ }
+ pMat->mPasses.push_back(pPass);
+ ret = true;
+ }
+ Tracker.mStaticDiffuseLightingAlphaSet = true;
+ }
+ return ret;
+}
+
+bool CMaterialLoader::SetupStaticBloomIncandecenceLightingStage(STevTracker& Tracker, CMaterial* pMat,
+ const SMP3IntermediateMaterial& Intermediate)
+{
+ const auto& IntermediateBloi = Intermediate.GetPASS(EPASS::BLOI);
+ if (!IntermediateBloi)
+ return false;
+ CMaterialPass* pPass = new CMaterialPass(pMat);
+ SetMP3IntermediateIntoMaterialPass(pPass, *IntermediateBloi);
+
+ pPass->SetColorInputs(kZeroRGB, kZeroRGB, kZeroRGB, kPrevRGB);
+ pPass->SetColorOutput(kPrevReg);
+ pPass->SetAlphaOutput(kPrevReg);
+ pPass->SetRasSel(kRasColorNull);
+ pPass->SetTexSwapComp(3, IntermediateBloi->GetSwapAlphaComp());
+ pPass->SetAlphaInputs(kTextureAlpha, kZeroAlpha, kZeroAlpha, kPrevAlpha);
+
+ pMat->mPasses.push_back(pPass);
+ return true;
+}
+
+void CMaterialLoader::SetupNoBloomTransparent(CMaterial* pMat, const SMP3IntermediateMaterial& Intermediate,
+ uint8 Alpha)
+{
+ STevTracker Tracker;
+ bool StaticLighting = SetupStaticDiffuseLightingStage(Tracker, pMat, Intermediate, true);
+ if (Intermediate.GetPASS(EPASS::CLR))
+ {
+ SetupColorTextureStage(Tracker, pMat, Intermediate, true, Alpha, StaticLighting);
+ }
+ else
+ {
+ SetupColorKColorStage(Tracker, pMat, Intermediate, true, Alpha, StaticLighting);
+ }
+ SetupTransparencyStage(Tracker, pMat, Intermediate);
+ SetupReflectionAlphaStage(Tracker, pMat, Intermediate);
+ SetupReflectionStages(Tracker, pMat, Intermediate, kPrevRGB, StaticLighting);
+ pMat->mOptions.AssignFlag(EMaterialOption::DepthWrite, false);
+ pMat->mOptions.AssignFlag(EMaterialOption::Masked, false);
+ pMat->SetBlendMode(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ pMat->mOptions.AssignFlag(EMaterialOption::Transparent, true);
+ pMat->mOptions.AssignFlag(EMaterialOption::AlphaWrite, false);
+}
+
+void CMaterialLoader::SetupNoBloomAdditiveIncandecence(CMaterial* pMat, const SMP3IntermediateMaterial& Intermediate,
+ uint8 Alpha)
+{
+ SetupNoBloomTransparent(pMat, Intermediate, Alpha);
+ CMaterial* pMatNext = new CMaterial(pMat->Version(), pMat->VtxDesc());
+ pMat->mpNextDrawPassMaterial = pMatNext;
+ pMat = pMatNext;
+ STevTracker Tracker;
+ SetupStartingIncandecenceDynamicKColorStage(Tracker, pMat, Intermediate);
+ pMat->mOptions.AssignFlag(EMaterialOption::DepthWrite, false);
+ pMat->mOptions.AssignFlag(EMaterialOption::Masked, false);
+ pMat->SetBlendMode(GL_SRC_ALPHA, GL_ONE);
+ pMat->mOptions.AssignFlag(EMaterialOption::Transparent, true);
+ pMat->mOptions.AssignFlag(EMaterialOption::AlphaWrite, false);
+}
+
+void CMaterialLoader::SetupFullRenderOpaque(CMaterial* pMat, const SMP3IntermediateMaterial& Intermediate)
+{
+ pMat->mOptions.AssignFlag(EMaterialOption::AlphaWrite, true);
+ STevTracker Tracker;
+ bool StaticLighting = SetupStaticDiffuseLightingStage(Tracker, pMat, Intermediate, false);
+ SetupStaticBloomLightingStage(Tracker, pMat, Intermediate, StaticLighting);
+ SetupStaticBloomDiffuseLightingStages(Tracker, pMat, Intermediate, StaticLighting);
+ if (Intermediate.GetPASS(EPASS::CLR))
+ {
+ SetupColorTextureStage(Tracker, pMat, Intermediate, false, 255, StaticLighting);
+ }
+ else
+ {
+ SetupColorKColorStage(Tracker, pMat, Intermediate, false, 255, StaticLighting);
+ }
+ SetupReflectionStages(Tracker, pMat, Intermediate, kPrevRGB, StaticLighting);
+ SetupIncandecenceStage(Tracker, pMat, Intermediate);
+ SetupStaticBloomIncandecenceLightingStage(Tracker, pMat, Intermediate);
+ pMat->mOptions.AssignFlag(EMaterialOption::DepthWrite, true);
+ pMat->mOptions.AssignFlag(EMaterialOption::Masked, false);
+ pMat->SetBlendMode(GL_ONE, GL_ZERO);
+ pMat->mOptions.AssignFlag(EMaterialOption::Transparent, false);
+}
+
+void CMaterialLoader::SetupOptimizedDiffuseLightingColorOpaque(CMaterial* pMat,
+ const SMP3IntermediateMaterial& Intermediate)
+{
+ pMat->mOptions.AssignFlag(EMaterialOption::AlphaWrite, true);
+ STevTracker Tracker;
+ SetupStaticDiffuseLightingNoBloomStage(Tracker, pMat, Intermediate);
+ SetupColorTextureAlwaysStaticLightingStage(Tracker, pMat, Intermediate);
+ pMat->mOptions.AssignFlag(EMaterialOption::DepthWrite, true);
+ pMat->mOptions.AssignFlag(EMaterialOption::Masked, false);
+ pMat->SetBlendMode(GL_ONE, GL_ZERO);
+ pMat->mOptions.AssignFlag(EMaterialOption::Transparent, false);
+}
+
+void CMaterialLoader::SetupOptimizedDiffuseBloomLightingColorOpaque(CMaterial* pMat,
+ const SMP3IntermediateMaterial& Intermediate)
+{
+ pMat->mOptions.AssignFlag(EMaterialOption::AlphaWrite, true);
+ STevTracker Tracker;
+ SetupStaticDiffuseLightingNoBLOLStage(Tracker, pMat, Intermediate);
+ SetupStaticBloomLightingStage(Tracker, pMat, Intermediate, true);
+ SetupColorTextureAlwaysStaticLightingStage(Tracker, pMat, Intermediate);
+ pMat->mOptions.AssignFlag(EMaterialOption::DepthWrite, true);
+ pMat->mOptions.AssignFlag(EMaterialOption::Masked, false);
+ pMat->SetBlendMode(GL_ONE, GL_ZERO);
+ pMat->mOptions.AssignFlag(EMaterialOption::Transparent, false);
+}
+
+void CMaterialLoader::SetupAdditiveIncandecenceOnly(CMaterial* pMat,
+ const SMP3IntermediateMaterial& Intermediate)
+{
+ pMat->mOptions.AssignFlag(EMaterialOption::AlphaWrite, true);
+ STevTracker Tracker;
+ SetupStartingIncandecenceStage(Tracker, pMat, Intermediate);
+ SetupStaticBloomIncandecenceLightingStage(Tracker, pMat, Intermediate);
+ SetupReflectionStages(Tracker, pMat, Intermediate, kPrevRGB, false);
+ pMat->mOptions.AssignFlag(EMaterialOption::DepthWrite, false);
+ pMat->mOptions.AssignFlag(EMaterialOption::Masked, false);
+ pMat->SetBlendMode(GL_ONE, GL_ONE);
+ pMat->mOptions.AssignFlag(EMaterialOption::Transparent, true);
+}
+
+void CMaterialLoader::SetupFullRenderTransparent(CMaterial* pMat, const SMP3IntermediateMaterial& Intermediate,
+ uint8 Alpha)
+{
+ STevTracker Tracker;
+ bool StaticLighting = SetupStaticDiffuseLightingStage(Tracker, pMat, Intermediate, true);
+ if (Intermediate.GetPASS(EPASS::CLR))
+ {
+ SetupColorTextureStage(Tracker, pMat, Intermediate, true, Alpha, StaticLighting);
+ }
+ else
+ {
+ SetupColorKColorStage(Tracker, pMat, Intermediate, true, Alpha, StaticLighting);
+ }
+ SetupTransparencyStage(Tracker, pMat, Intermediate);
+ SetupReflectionAlphaStage(Tracker, pMat, Intermediate);
+ SetupReflectionStages(Tracker, pMat, Intermediate, kPrevRGB, StaticLighting);
+ pMat->mOptions.AssignFlag(EMaterialOption::DepthWrite, false);
+ pMat->mOptions.AssignFlag(EMaterialOption::Masked, false);
+ pMat->SetBlendMode(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ pMat->mOptions.AssignFlag(EMaterialOption::Transparent, true);
+ pMat->mOptions.AssignFlag(EMaterialOption::AlphaWrite, false);
+
+ CMaterial* pMatNext = new CMaterial(pMat->Version(), pMat->VtxDesc());
+ pMat->mpNextDrawPassMaterial = pMatNext;
+ pMat = pMatNext;
+ Tracker = STevTracker();
+ pMat->mOptions.AssignFlag(EMaterialOption::AlphaWrite, true);
+ SetupTransparencyKAlphaMultiplyStage(Tracker, pMat, Intermediate, false, Alpha);
+ pMat->mOptions.AssignFlag(EMaterialOption::DepthWrite, false);
+ pMat->mOptions.AssignFlag(EMaterialOption::Masked, false);
+ pMat->SetBlendMode(GL_ZERO, GL_ONE_MINUS_SRC_ALPHA);
+ pMat->mOptions.AssignFlag(EMaterialOption::Transparent, true);
+ pMat->mOptions.AssignFlag(EMaterialOption::ColorWrite, false);
+
+ pMatNext = new CMaterial(pMat->Version(), pMat->VtxDesc());
+ pMat->mpNextDrawPassMaterial = pMatNext;
+ pMat = pMatNext;
+ Tracker = STevTracker();
+ if (SetupStaticBloomLightingA1Stages(Tracker, pMat, Intermediate))
+ {
+ SetupTransparencyKAlphaMultiplyStage(Tracker, pMat, Intermediate, true, Alpha);
+ pMat->mOptions.AssignFlag(EMaterialOption::DepthWrite, false);
+ pMat->mOptions.AssignFlag(EMaterialOption::Masked, false);
+ pMat->SetBlendMode(GL_ONE, GL_ONE);
+ pMat->mOptions.AssignFlag(EMaterialOption::Transparent, true);
+ pMat->mOptions.AssignFlag(EMaterialOption::ColorWrite, true);
+ }
+}
+
+void CMaterialLoader::SetupFullRenderTransparentAdditiveIncandecence(CMaterial* pMat,
+ const SMP3IntermediateMaterial& Intermediate,
+ uint8 Alpha)
+{
+ SetupFullRenderTransparent(pMat, Intermediate, Alpha);
+ CMaterial* pMatNext = new CMaterial(pMat->Version(), pMat->VtxDesc());
+ pMat->mpNextDrawPassMaterial = pMatNext;
+ pMat = pMatNext;
+
+ STevTracker Tracker;
+ SetupStartingIncandecenceStage(Tracker, pMat, Intermediate);
+ SetupStaticBloomIncandecenceLightingStage(Tracker, pMat, Intermediate);
+ pMat->mOptions.AssignFlag(EMaterialOption::DepthWrite, false);
+ pMat->mOptions.AssignFlag(EMaterialOption::Masked, false);
+ pMat->SetBlendMode(GL_ONE, GL_ONE);
+ pMat->mOptions.AssignFlag(EMaterialOption::Transparent, true);
+}
+
+void CMaterialLoader::SetupMaterialAlphaCompare(CMaterial* pMat, const SMP3IntermediateMaterial& Intermediate)
+{
+ STevTracker Tracker;
+ int StaticLighting = SetupStaticDiffuseLightingStage(Tracker, pMat, Intermediate, true);
+ if (Intermediate.GetPASS(EPASS::CLR))
+ {
+ SetupColorTextureStage(Tracker, pMat, Intermediate, false, 255, StaticLighting);
+ }
+ else
+ {
+ SetupColorKColorStage(Tracker, pMat, Intermediate, false, 255, StaticLighting);
+ }
+ SetupTransparencyStage(Tracker, pMat, Intermediate);
+ SetupReflectionAlphaStage(Tracker, pMat, Intermediate);
+ SetupReflectionStages(Tracker, pMat, Intermediate, kPrevRGB, StaticLighting);
+ SetupIncandecenceStageNoBloom(Tracker, pMat, Intermediate);
+ pMat->mOptions.AssignFlag(EMaterialOption::DepthWrite, true);
+ pMat->mOptions.AssignFlag(EMaterialOption::Masked, true);
+ pMat->SetBlendMode(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ pMat->mOptions.AssignFlag(EMaterialOption::Transparent, true);
+ pMat->mOptions.AssignFlag(EMaterialOption::ZeroDestAlpha, true);
+}
+
+void CMaterialLoader::SetupSolidWhite(CMaterial* pMat, const SMP3IntermediateMaterial& Intermediate)
+{
+ CMaterialPass* pPass = new CMaterialPass(pMat);
+ pPass->SetColorInputs(kZeroRGB, kZeroRGB, kZeroRGB, kOneRGB);
+ pPass->SetAlphaInputs(kZeroAlpha, kZeroAlpha, kZeroAlpha, kZeroAlpha);
+ pPass->SetColorOutput(kPrevReg);
+ pPass->SetAlphaOutput(kPrevReg);
+ pPass->SetRasSel(kRasColorNull);
+ pMat->mPasses.push_back(pPass);
+ pMat->mOptions.AssignFlag(EMaterialOption::DepthWrite, false);
+ pMat->SetBlendMode(GL_ONE, GL_ZERO);
+ pMat->mOptions.AssignFlag(EMaterialOption::Transparent, false);
+ pMat->mOptions.AssignFlag(EMaterialOption::Masked, false);
+}
+
+void CMaterialLoader::SetupSolidKColorKAlpha(CMaterial* pMat, const SMP3IntermediateMaterial& Intermediate)
+{
+ CMaterialPass* pPass = new CMaterialPass(pMat);
+ pMat->SetKonst(Intermediate.GetCLR(ECLR::CLR), 0);
+ pPass->SetKColorSel(kKonst0_RGB);
+ pPass->SetKAlphaSel(kKonst0_A);
+ pPass->SetColorInputs(kZeroRGB, kZeroRGB, kZeroRGB, kKonstRGB);
+ pPass->SetAlphaInputs(kZeroAlpha, kZeroAlpha, kZeroAlpha, kKonstAlpha);
+ pPass->SetColorOutput(kPrevReg);
+ pPass->SetAlphaOutput(kPrevReg);
+ pPass->SetRasSel(kRasColorNull);
+ pMat->mPasses.push_back(pPass);
+ pMat->mOptions.AssignFlag(EMaterialOption::DepthWrite, false);
+ pMat->mOptions.AssignFlag(EMaterialOption::Masked, false);
+ pMat->SetBlendMode(GL_SRC_ALPHA, GL_ONE);
+ pMat->mOptions.AssignFlag(EMaterialOption::Transparent, true);
+}
+
+void CMaterialLoader::CreateCorruptionPasses(CMaterial* pMat, const SMP3IntermediateMaterial& Intermediate, bool Bloom)
+{
+ pMat->mOptions.AssignFlag(EMaterialOption::Occluder,
+ Intermediate.mOptions.HasFlag(EMP3MaterialOption::Occluder));
+ pMat->mOptions.AssignFlag(EMaterialOption::DrawWhiteAmbientDKCR,
+ Intermediate.mOptions.HasFlag(EMP3MaterialOption::DrawWhiteAmbientDKCR));
+
+ EMP3RenderConfig Config;
+ uint8 Alpha;
+ SelectBestCombinerConfig(Config, Alpha, Intermediate, Bloom);
+
+ switch (Config)
+ {
+ case EMP3RenderConfig::NoBloomTransparent:
+ SetupNoBloomTransparent(pMat, Intermediate, Alpha); break;
+ case EMP3RenderConfig::NoBloomAdditiveIncandecence:
+ SetupNoBloomAdditiveIncandecence(pMat, Intermediate, Alpha); break;
+ case EMP3RenderConfig::FullRenderOpaque:
+ SetupFullRenderOpaque(pMat, Intermediate); break;
+ case EMP3RenderConfig::OptimizedDiffuseLightingColorOpaque:
+ SetupOptimizedDiffuseLightingColorOpaque(pMat, Intermediate); break;
+ case EMP3RenderConfig::OptimizedDiffuseBloomLightingColorOpaque:
+ SetupOptimizedDiffuseBloomLightingColorOpaque(pMat, Intermediate); break;
+ case EMP3RenderConfig::AdditiveIncandecenceOnly:
+ SetupAdditiveIncandecenceOnly(pMat, Intermediate); break;
+ case EMP3RenderConfig::FullRenderTransparent:
+ default:
+ SetupFullRenderTransparent(pMat, Intermediate, Alpha); break;
+ case EMP3RenderConfig::FullRenderTransparentAdditiveIncandecence:
+ SetupFullRenderTransparentAdditiveIncandecence(pMat, Intermediate, Alpha); break;
+ case EMP3RenderConfig::MaterialAlphaCompare:
+ SetupMaterialAlphaCompare(pMat, Intermediate); break;
+ case EMP3RenderConfig::SolidWhite:
+ SetupSolidWhite(pMat, Intermediate); break;
+ case EMP3RenderConfig::SolidKColorKAlpha:
+ SetupSolidKColorKAlpha(pMat, Intermediate); break;
+ }
}
CMaterial* CMaterialLoader::LoadAssimpMaterial(const aiMaterial *pAiMat)
diff --git a/src/Core/Resource/Factory/CMaterialLoader.h b/src/Core/Resource/Factory/CMaterialLoader.h
index 2adb9985..ac92511f 100644
--- a/src/Core/Resource/Factory/CMaterialLoader.h
+++ b/src/Core/Resource/Factory/CMaterialLoader.h
@@ -8,6 +8,109 @@
#include
#include
+enum class EMP3RenderConfig
+{
+ NoBloomTransparent,
+ NoBloomAdditiveIncandecence,
+ FullRenderOpaque,
+ OptimizedDiffuseLightingColorOpaque,
+ OptimizedDiffuseBloomLightingColorOpaque,
+ AdditiveIncandecenceOnly,
+ AdditiveBlendPremultiplyModColor,
+ FullRenderTransparent,
+ FullRenderTransparentAdditiveIncandecence,
+ MaterialAlphaCompare,
+ SolidWhite,
+ SolidKColor,
+ StaticAlphaCompare,
+ DynamicAlphaCompare,
+ RandomStaticAlpha,
+ SolidKColorKAlpha,
+ XRayAdditiveIncandecence,
+ XRayTransparent,
+ XRayOpaque
+};
+
+enum class EPASS
+{
+ DIFF,
+ RIML,
+ BLOL,
+ CLR,
+ TRAN,
+ INCA,
+ RFLV,
+ RFLD,
+ LRLD,
+ LURD,
+ BLOD,
+ BLOI,
+ XRAY,
+ TOON
+};
+
+enum class EINT
+{
+ OPAC,
+ BLOD,
+ BLOI,
+ BNIF,
+ XRBR
+};
+
+enum class ECLR
+{
+ CLR,
+ DIFB
+};
+
+// Material PASSes do not directly map as individual TEV stages (CMaterialPass).
+// Therefore, the material data chunks are stored in a random-access-friendly
+// container for procedural TEV stage generation.
+struct SMP3IntermediateMaterial
+{
+ FMP3MaterialOptions mOptions;
+
+ struct PASS
+ {
+ CFourCC mPassType;
+ TResPtr mpTexture = nullptr;
+ FPassSettings mSettings;
+ uint32 mUvSrc;
+ EUVAnimUVSource mUvSource = EUVAnimUVSource::UV;
+ EUVAnimMatrixConfig mMtxConfig = EUVAnimMatrixConfig::NoMtxNoPost;
+ EUVAnimMode mAnimMode = EUVAnimMode::NoUVAnim;
+ EUVConvolutedModeBType mAnimConvolutedModeBType;
+ float mAnimParams[8];
+
+ char GetSwapAlphaComp() const
+ {
+ switch (mSettings.ToInt32() & 0x3)
+ {
+ case 0: return 'r';
+ case 1: return 'g';
+ case 2: return 'b';
+ default: return 'a';
+ }
+ }
+ };
+ std::optional mPASSes[14];
+ const std::optional& GetPASS(EPASS pass) const { return mPASSes[int(pass)]; }
+
+ uint8 mINTs[5] = {255, 255, 0, 32, 255};
+ uint8 GetINT(EINT eint) const { return mINTs[int(eint)]; }
+
+ CColor mCLRs[2] = {CColor::skWhite, CColor::skWhite};
+ const CColor& GetCLR(ECLR clr) const { return mCLRs[int(clr)]; }
+};
+
+struct STevTracker
+{
+ uint8 mCurKColor = 0;
+ bool mStaticDiffuseLightingAlphaSet = false;
+ bool mStaticLightingAlphaSet = false;
+};
+
class CMaterialLoader
{
// Material data
@@ -15,13 +118,10 @@ class CMaterialLoader
IInputStream *mpFile;
EGame mVersion;
std::vector> mTextures;
- bool mHasOPAC;
- bool mHas0x400;
CColor mCorruptionColors[4];
uint8 mCorruptionInts[5];
uint32 mCorruptionFlags;
- std::vector mPassOffsets;
CMaterialLoader();
~CMaterialLoader();
@@ -33,7 +133,59 @@ class CMaterialLoader
void ReadCorruptionMatSet();
CMaterial* ReadCorruptionMaterial();
- void CreateCorruptionPasses(CMaterial *pMat);
+ void SetMP3IntermediateIntoMaterialPass(CMaterialPass* pPass, const SMP3IntermediateMaterial::PASS& Intermediate);
+ void SelectBestCombinerConfig(EMP3RenderConfig& OutConfig, uint8& OutAlpha,
+ const SMP3IntermediateMaterial& Material, bool Bloom);
+
+ bool SetupStaticDiffuseLightingStage(STevTracker& Tracker, CMaterial* pMat,
+ const SMP3IntermediateMaterial& Intermediate, bool FullAlpha);
+ void SetupStaticDiffuseLightingNoBloomStage(STevTracker& Tracker, CMaterial* pMat,
+ const SMP3IntermediateMaterial& Intermediate);
+ void SetupStaticDiffuseLightingNoBLOLStage(STevTracker& Tracker, CMaterial* pMat,
+ const SMP3IntermediateMaterial& Intermediate);
+ void SetupColorTextureStage(STevTracker& Tracker, CMaterial* pMat, const SMP3IntermediateMaterial& Intermediate,
+ bool useStageAlpha, uint8 Alpha, bool StaticLighting);
+ void SetupColorTextureAlwaysStaticLightingStage(STevTracker& Tracker, CMaterial* pMat,
+ const SMP3IntermediateMaterial& Intermediate);
+ void SetupColorKColorStage(STevTracker& Tracker, CMaterial* pMat, const SMP3IntermediateMaterial& Intermediate,
+ bool useStageAlpha, uint8 Alpha, bool StaticLighting);
+ bool SetupTransparencyStage(STevTracker& Tracker, CMaterial* pMat, const SMP3IntermediateMaterial& Intermediate);
+ void SetupTransparencyKAlphaMultiplyStage(STevTracker& Tracker, CMaterial* pMat,
+ const SMP3IntermediateMaterial& Intermediate, bool multiplyPrevAlpha,
+ uint8 Alpha);
+ bool SetupReflectionAlphaStage(STevTracker& Tracker, CMaterial* pMat, const SMP3IntermediateMaterial& Intermediate);
+ bool SetupReflectionStages(STevTracker& Tracker, CMaterial* pMat, const SMP3IntermediateMaterial& Intermediate,
+ ETevColorInput argD, bool StaticLighting);
+ bool SetupQuantizedKAlphaAdd(STevTracker& Tracker, CMaterial* pMat, uint8 Value);
+ bool SetupIncandecenceStage(STevTracker& Tracker, CMaterial* pMat, const SMP3IntermediateMaterial& Intermediate);
+ bool SetupIncandecenceStageNoBloom(STevTracker& Tracker, CMaterial* pMat,
+ const SMP3IntermediateMaterial& Intermediate);
+ bool SetupStartingIncandecenceStage(STevTracker& Tracker, CMaterial* pMat,
+ const SMP3IntermediateMaterial& Intermediate);
+ void SetupStartingIncandecenceDynamicKColorStage(STevTracker& Tracker, CMaterial* pMat,
+ const SMP3IntermediateMaterial& Intermediate);
+ bool SetupStaticBloomLightingStage(STevTracker& Tracker, CMaterial* pMat,
+ const SMP3IntermediateMaterial& Intermediate, bool StaticLighting);
+ bool SetupStaticBloomLightingA1Stages(STevTracker& Tracker, CMaterial* pMat,
+ const SMP3IntermediateMaterial& Intermediate);
+ bool SetupStaticBloomDiffuseLightingStages(STevTracker& Tracker, CMaterial* pMat,
+ const SMP3IntermediateMaterial& Intermediate, bool StaticLighting);
+ bool SetupStaticBloomIncandecenceLightingStage(STevTracker& Tracker, CMaterial* pMat,
+ const SMP3IntermediateMaterial& Intermediate);
+ void SetupNoBloomTransparent(CMaterial* pMat, const SMP3IntermediateMaterial& Intermediate, uint8 Alpha);
+ void SetupNoBloomAdditiveIncandecence(CMaterial* pMat, const SMP3IntermediateMaterial& Intermediate, uint8 Alpha);
+ void SetupFullRenderOpaque(CMaterial* pMat, const SMP3IntermediateMaterial& Intermediate);
+ void SetupOptimizedDiffuseLightingColorOpaque(CMaterial* pMat, const SMP3IntermediateMaterial& Intermediate);
+ void SetupOptimizedDiffuseBloomLightingColorOpaque(CMaterial* pMat, const SMP3IntermediateMaterial& Intermediate);
+ void SetupAdditiveIncandecenceOnly(CMaterial* pMat, const SMP3IntermediateMaterial& Intermediate);
+ void SetupFullRenderTransparent(CMaterial* pMat, const SMP3IntermediateMaterial& Intermediate, uint8 Alpha);
+ void SetupFullRenderTransparentAdditiveIncandecence(CMaterial* pMat, const SMP3IntermediateMaterial& Intermediate,
+ uint8 Alpha);
+ void SetupMaterialAlphaCompare(CMaterial* pMat, const SMP3IntermediateMaterial& Intermediate);
+ void SetupSolidWhite(CMaterial* pMat, const SMP3IntermediateMaterial& Intermediate);
+ void SetupSolidKColorKAlpha(CMaterial* pMat, const SMP3IntermediateMaterial& Intermediate);
+
+ void CreateCorruptionPasses(CMaterial *pMat, const SMP3IntermediateMaterial& Intermediate, bool Bloom);
CMaterial* LoadAssimpMaterial(const aiMaterial *pAiMat);
diff --git a/src/Core/Resource/Factory/CModelLoader.cpp b/src/Core/Resource/Factory/CModelLoader.cpp
index 49c68ab8..4a79fa40 100644
--- a/src/Core/Resource/Factory/CModelLoader.cpp
+++ b/src/Core/Resource/Factory/CModelLoader.cpp
@@ -128,7 +128,7 @@ SSurface* CModelLoader::LoadSurface(IInputStream& rModel)
LoadSurfaceHeaderDKCR(rModel, pSurf);
bool HasAABB = (pSurf->AABox != CAABox::skInfinite);
- CMaterial *pMat = mMaterials[0]->MaterialByIndex(pSurf->MaterialID);
+ CMaterial *pMat = mMaterials[0]->MaterialByIndex(pSurf->MaterialID, false);
// Primitive table
uint8 Flag = rModel.ReadByte();
@@ -282,7 +282,7 @@ void CModelLoader::LoadSurfaceHeaderDKCR(IInputStream& rModel, SSurface *pSurf)
SSurface* CModelLoader::LoadAssimpMesh(const aiMesh *pkMesh, CMaterialSet *pSet)
{
// Create vertex description and assign it to material
- CMaterial *pMat = pSet->MaterialByIndex(pkMesh->mMaterialIndex);
+ CMaterial *pMat = pSet->MaterialByIndex(pkMesh->mMaterialIndex, false);
FVertexDescription Desc = pMat->VtxDesc();
if (Desc == (FVertexDescription) EVertexAttribute::None)
diff --git a/src/Core/Resource/Model/CModel.cpp b/src/Core/Resource/Model/CModel.cpp
index 61feed81..e71719dc 100644
--- a/src/Core/Resource/Model/CModel.cpp
+++ b/src/Core/Resource/Model/CModel.cpp
@@ -108,8 +108,8 @@ void CModel::GenerateMaterialShaders()
for (uint32 iMat = 0; iMat < pSet->NumMaterials(); iMat++)
{
- CMaterial *pMat = pSet->MaterialByIndex(iMat);
- pMat->GenerateShader(false);
+ pSet->MaterialByIndex(iMat, false)->GenerateShader(false);
+ pSet->MaterialByIndex(iMat, true)->GenerateShader(false);
}
}
}
@@ -136,29 +136,40 @@ void CModel::DrawSurface(FRenderOptions Options, uint32 Surface, uint32 MatSet)
if (MatSet >= mMaterialSets.size())
MatSet = mMaterialSets.size() - 1;
+ auto DoDraw = [this, Surface]()
+ {
+ // Draw IBOs
+ mVBO.Bind();
+ glLineWidth(1.f);
+
+ for (uint32 iIBO = 0; iIBO < mSurfaceIndexBuffers[Surface].size(); iIBO++)
+ {
+ CIndexBuffer *pIBO = &mSurfaceIndexBuffers[Surface][iIBO];
+ pIBO->DrawElements();
+ }
+
+ mVBO.Unbind();
+ };
+
// Bind material
if ((Options & ERenderOption::NoMaterialSetup) == 0)
{
SSurface *pSurf = mSurfaces[Surface];
- CMaterial *pMat = mMaterialSets[MatSet]->MaterialByIndex(pSurf->MaterialID);
+ CMaterial *pMat = mMaterialSets[MatSet]->MaterialByIndex(pSurf->MaterialID, Options.HasFlag(ERenderOption::EnableBloom));
if (!Options.HasFlag(ERenderOption::EnableOccluders) && pMat->Options().HasFlag(EMaterialOption::Occluder))
return;
- pMat->SetCurrent(Options);
+ for (CMaterial* passMat = pMat; passMat; passMat = passMat->GetNextDrawPass())
+ {
+ passMat->SetCurrent(Options);
+ DoDraw();
+ }
}
-
- // Draw IBOs
- mVBO.Bind();
- glLineWidth(1.f);
-
- for (uint32 iIBO = 0; iIBO < mSurfaceIndexBuffers[Surface].size(); iIBO++)
+ else
{
- CIndexBuffer *pIBO = &mSurfaceIndexBuffers[Surface][iIBO];
- pIBO->DrawElements();
+ DoDraw();
}
-
- mVBO.Unbind();
}
void CModel::DrawWireframe(FRenderOptions Options, CColor WireColor /*= CColor::skWhite*/)
@@ -206,19 +217,22 @@ void CModel::SetSkin(CSkin *pSkin)
for (uint32 iMat = 0; iMat < pSet->NumMaterials(); iMat++)
{
- CMaterial *pMat = pSet->MaterialByIndex(iMat);
- FVertexDescription VtxDesc = pMat->VtxDesc();
-
- if (pSkin && !VtxDesc.HasAllFlags(kBoneFlags))
+ for (bool iBloom = false; !iBloom; iBloom = true)
{
- VtxDesc |= kBoneFlags;
- pMat->SetVertexDescription(VtxDesc);
- }
+ CMaterial *pMat = pSet->MaterialByIndex(iMat, iBloom);
+ FVertexDescription VtxDesc = pMat->VtxDesc();
- else if (!pSkin && VtxDesc.HasAnyFlags(kBoneFlags))
- {
- VtxDesc &= ~kBoneFlags;
- pMat->SetVertexDescription(VtxDesc);
+ if (pSkin && !VtxDesc.HasAllFlags(kBoneFlags))
+ {
+ VtxDesc |= kBoneFlags;
+ pMat->SetVertexDescription(VtxDesc);
+ }
+
+ else if (!pSkin && VtxDesc.HasAnyFlags(kBoneFlags))
+ {
+ VtxDesc &= ~kBoneFlags;
+ pMat->SetVertexDescription(VtxDesc);
+ }
}
}
}
@@ -249,7 +263,7 @@ CMaterial* CModel::GetMaterialByIndex(uint32 MatSet, uint32 Index)
if (GetMatCount() == 0)
return nullptr;
- return mMaterialSets[MatSet]->MaterialByIndex(Index);
+ return mMaterialSets[MatSet]->MaterialByIndex(Index, false);
}
CMaterial* CModel::GetMaterialBySurface(uint32 MatSet, uint32 Surface)
@@ -263,7 +277,7 @@ bool CModel::HasTransparency(uint32 MatSet)
MatSet = mMaterialSets.size() - 1;
for (uint32 iMat = 0; iMat < mMaterialSets[MatSet]->NumMaterials(); iMat++)
- if (mMaterialSets[MatSet]->MaterialByIndex(iMat)->Options() & EMaterialOption::Transparent ) return true;
+ if (mMaterialSets[MatSet]->MaterialByIndex(iMat, true)->Options() & EMaterialOption::Transparent ) return true;
return false;
}
@@ -274,7 +288,7 @@ bool CModel::IsSurfaceTransparent(uint32 Surface, uint32 MatSet)
MatSet = mMaterialSets.size() - 1;
uint32 matID = mSurfaces[Surface]->MaterialID;
- return (mMaterialSets[MatSet]->MaterialByIndex(matID)->Options() & EMaterialOption::Transparent) != 0;
+ return (mMaterialSets[MatSet]->MaterialByIndex(matID, true)->Options() & EMaterialOption::Transparent) != 0;
}
bool CModel::IsLightmapped() const
@@ -285,7 +299,7 @@ bool CModel::IsLightmapped() const
for (uint32 iMat = 0; iMat < pSet->NumMaterials(); iMat++)
{
- CMaterial *pMat = pSet->MaterialByIndex(iMat);
+ CMaterial *pMat = pSet->MaterialByIndex(iMat, true);
if (pMat->Options().HasFlag(EMaterialOption::Lightmap))
return true;
}
diff --git a/src/Core/Scene/CCharacterNode.cpp b/src/Core/Scene/CCharacterNode.cpp
index d59708a9..7be19959 100644
--- a/src/Core/Scene/CCharacterNode.cpp
+++ b/src/Core/Scene/CCharacterNode.cpp
@@ -63,7 +63,7 @@ void CCharacterNode::Draw(FRenderOptions Options, int ComponentIndex, ERenderCom
CGraphics::UpdateLightBlock();
CGraphics::sVertexBlock.COLOR0_Amb = CGraphics::skDefaultAmbientColor;
CGraphics::sPixelBlock.LightmapMultiplier = 1.f;
- CGraphics::sPixelBlock.TevColor = CColor::skWhite;
+ CGraphics::sPixelBlock.SetAllTevColors(CColor::skWhite);
CGraphics::sPixelBlock.TintColor = TintColor(rkViewInfo);
LoadModelMatrix();
diff --git a/src/Core/Scene/CModelNode.cpp b/src/Core/Scene/CModelNode.cpp
index 0b86f301..30be15e4 100644
--- a/src/Core/Scene/CModelNode.cpp
+++ b/src/Core/Scene/CModelNode.cpp
@@ -66,7 +66,7 @@ void CModelNode::Draw(FRenderOptions Options, int ComponentIndex, ERenderCommand
CGraphics::UpdateLightBlock();
CGraphics::sVertexBlock.COLOR0_Amb = CGraphics::skDefaultAmbientColor;
CGraphics::sPixelBlock.LightmapMultiplier = 1.f;
- CGraphics::sPixelBlock.TevColor = CColor::skWhite;
+ CGraphics::sPixelBlock.SetAllTevColors(CColor::skWhite);
}
else
{
@@ -75,7 +75,7 @@ void CModelNode::Draw(FRenderOptions Options, int ComponentIndex, ERenderCommand
if (IsLightingEnabled)
{
CGraphics::sNumLights = 0;
- CGraphics::sVertexBlock.COLOR0_Amb = CColor::skBlack;
+ CGraphics::sVertexBlock.COLOR0_Amb = CColor::skTransparentBlack;
CGraphics::sPixelBlock.LightmapMultiplier = 1.f;
CGraphics::UpdateLightBlock();
}
@@ -88,7 +88,7 @@ void CModelNode::Draw(FRenderOptions Options, int ComponentIndex, ERenderCommand
}
float Mul = CGraphics::sWorldLightMultiplier;
- CGraphics::sPixelBlock.TevColor = CColor(Mul,Mul,Mul);
+ CGraphics::sPixelBlock.SetAllTevColors(CColor(Mul,Mul,Mul));
}
CGraphics::sPixelBlock.TintColor = TintColor(rkViewInfo);
diff --git a/src/Core/Scene/CScriptAttachNode.cpp b/src/Core/Scene/CScriptAttachNode.cpp
index 8b6f9de7..8b5cec8e 100644
--- a/src/Core/Scene/CScriptAttachNode.cpp
+++ b/src/Core/Scene/CScriptAttachNode.cpp
@@ -93,7 +93,7 @@ void CScriptAttachNode::Draw(FRenderOptions Options, int /*ComponentIndex*/, ERe
CGraphics::UpdateVertexBlock();
CGraphics::sPixelBlock.TintColor = mpParent->TintColor(rkViewInfo);
- CGraphics::sPixelBlock.TevColor = CColor::skWhite;
+ CGraphics::sPixelBlock.SetAllTevColors(CColor::skWhite);
CGraphics::UpdatePixelBlock();
DrawModelParts(Model(), Options, 0, Command);
}
diff --git a/src/Core/Scene/CScriptNode.cpp b/src/Core/Scene/CScriptNode.cpp
index c4138e00..2c8964f6 100644
--- a/src/Core/Scene/CScriptNode.cpp
+++ b/src/Core/Scene/CScriptNode.cpp
@@ -180,7 +180,7 @@ void CScriptNode::Draw(FRenderOptions Options, int /*ComponentIndex*/, ERenderCo
if (CGraphics::sLightMode == CGraphics::ELightingMode::World && LightingOptions == eDisableWorldLighting)
{
CGraphics::sNumLights = 0;
- CGraphics::sVertexBlock.COLOR0_Amb = CColor::skBlack;
+ CGraphics::sVertexBlock.COLOR0_Amb = CColor::skTransparentBlack;
CGraphics::sPixelBlock.LightmapMultiplier = 1.f;
CGraphics::UpdateLightBlock();
}
@@ -207,8 +207,8 @@ void CScriptNode::Draw(FRenderOptions Options, int /*ComponentIndex*/, ERenderCo
{
if (pModel->IsSkinned()) CGraphics::LoadIdentityBoneTransforms();
- if (mpExtra) CGraphics::sPixelBlock.TevColor = mpExtra->TevColor();
- else CGraphics::sPixelBlock.TevColor = CColor::skWhite;
+ if (mpExtra) CGraphics::sPixelBlock.SetAllTevColors(mpExtra->TevColor());
+ else CGraphics::sPixelBlock.SetAllTevColors(CColor::skWhite);
CGraphics::sPixelBlock.TintColor = TintColor(rkViewInfo);
CGraphics::UpdatePixelBlock();
diff --git a/src/Core/Scene/CStaticNode.cpp b/src/Core/Scene/CStaticNode.cpp
index 7f6f5cdc..6993644a 100644
--- a/src/Core/Scene/CStaticNode.cpp
+++ b/src/Core/Scene/CStaticNode.cpp
@@ -62,7 +62,7 @@ void CStaticNode::Draw(FRenderOptions Options, int ComponentIndex, ERenderComman
if (IsLightingEnabled)
{
CGraphics::sNumLights = 0;
- CGraphics::sVertexBlock.COLOR0_Amb = UseWhiteAmbient ? CColor::skWhite : CColor::skBlack;
+ CGraphics::sVertexBlock.COLOR0_Amb = UseWhiteAmbient ? CColor::skWhite : CColor::skTransparentBlack;
CGraphics::sPixelBlock.LightmapMultiplier = 1.0f;
CGraphics::UpdateLightBlock();
}
@@ -75,7 +75,7 @@ void CStaticNode::Draw(FRenderOptions Options, int ComponentIndex, ERenderComman
}
float Mul = CGraphics::sWorldLightMultiplier;
- CGraphics::sPixelBlock.TevColor = CColor(Mul,Mul,Mul);
+ CGraphics::sPixelBlock.SetAllTevColors(CColor(Mul,Mul,Mul));
CGraphics::sPixelBlock.TintColor = TintColor(rkViewInfo);
LoadModelMatrix();
diff --git a/src/Core/ScriptExtra/CDoorExtra.cpp b/src/Core/ScriptExtra/CDoorExtra.cpp
index c3dd0e80..324e096d 100644
--- a/src/Core/ScriptExtra/CDoorExtra.cpp
+++ b/src/Core/ScriptExtra/CDoorExtra.cpp
@@ -79,7 +79,7 @@ void CDoorExtra::Draw(FRenderOptions Options, int /*ComponentIndex*/, ERenderCom
CColor Tint = mpParent->TintColor(rkViewInfo) * mShieldColor;
CGraphics::sPixelBlock.TintColor = Tint;
- CGraphics::sPixelBlock.TevColor = CColor::skWhite;
+ CGraphics::sPixelBlock.SetAllTevColors(CColor::skWhite);
CGraphics::UpdatePixelBlock();
DrawModelParts(mpShieldModel, Options, 0, Command);
}
diff --git a/src/Editor/CGizmo.cpp b/src/Editor/CGizmo.cpp
index fdd7f050..e2e90529 100644
--- a/src/Editor/CGizmo.cpp
+++ b/src/Editor/CGizmo.cpp
@@ -8,6 +8,7 @@
#include
#include
#include
+#include
CGizmo::CGizmo()
: mSelectedAxes(EAxis::None)
@@ -280,7 +281,7 @@ bool CGizmo::TransformFromInput(const CRay& rkRay, CCamera& rCamera)
// Calculate normalized cursor position
QPoint CursorPos = QCursor::pos();
- QRect Geom = QApplication::desktop()->screenGeometry();
+ QRect Geom = QApplication::screenAt(CursorPos)->geometry();
CVector2f MouseCoords(
(((2.f * CursorPos.x()) / Geom.width()) - 1.f),
(1.f - ((2.f * CursorPos.y()) / Geom.height()))
@@ -617,8 +618,8 @@ void CGizmo::UpdateTransform()
void CGizmo::WrapCursor()
{
- QRect Geom = QApplication::desktop()->screenGeometry();
QPoint CursorPos = QCursor::pos();
+ QRect Geom = QApplication::screenAt(CursorPos)->geometry();
// Horizontal
if (CursorPos.x() == Geom.width() - 1)
diff --git a/src/Editor/CTweakEditor.cpp b/src/Editor/CTweakEditor.cpp
index 221112f7..98c05f97 100644
--- a/src/Editor/CTweakEditor.cpp
+++ b/src/Editor/CTweakEditor.cpp
@@ -130,7 +130,7 @@ void CTweakEditor::OnProjectChanged(CGameProject* pNewProject)
// Sort in alphabetical order and create tabs
if (!mTweakAssets.isEmpty())
{
- qSort(mTweakAssets.begin(), mTweakAssets.end(), [](CTweakData* pLeft, CTweakData* pRight) -> bool {
+ std::sort(mTweakAssets.begin(), mTweakAssets.end(), [](CTweakData* pLeft, CTweakData* pRight) -> bool {
return pLeft->TweakName().ToUpper() < pRight->TweakName().ToUpper();
});
diff --git a/src/Editor/CharacterEditor/CCharacterEditorViewport.cpp b/src/Editor/CharacterEditor/CCharacterEditorViewport.cpp
index 23b464f2..fe60a388 100644
--- a/src/Editor/CharacterEditor/CCharacterEditorViewport.cpp
+++ b/src/Editor/CharacterEditor/CCharacterEditorViewport.cpp
@@ -6,7 +6,8 @@ CCharacterEditorViewport::CCharacterEditorViewport(QWidget *pParent /*= 0*/)
, mGridEnabled(true)
{
mpRenderer = new CRenderer();
- mpRenderer->SetViewportSize(width(), height());
+ qreal pixelRatio = devicePixelRatioF();
+ mpRenderer->SetViewportSize(width() * pixelRatio, height() * pixelRatio);
mpRenderer->SetClearColor(CColor(0.3f, 0.3f, 0.3f));
mpRenderer->ToggleGrid(true);
@@ -63,7 +64,8 @@ void CCharacterEditorViewport::Paint()
void CCharacterEditorViewport::OnResize()
{
- mpRenderer->SetViewportSize(width(), height());
+ qreal pixelRatio = devicePixelRatioF();
+ mpRenderer->SetViewportSize(width() * pixelRatio, height() * pixelRatio);
}
void CCharacterEditorViewport::OnMouseClick(QMouseEvent *pEvent)
diff --git a/src/Editor/CollisionEditor/CCollisionEditorViewport.cpp b/src/Editor/CollisionEditor/CCollisionEditorViewport.cpp
index ed942e2b..1635a0fb 100644
--- a/src/Editor/CollisionEditor/CCollisionEditorViewport.cpp
+++ b/src/Editor/CollisionEditor/CCollisionEditorViewport.cpp
@@ -6,7 +6,8 @@ CCollisionEditorViewport::CCollisionEditorViewport(QWidget* pParent /*= 0*/)
, mGridEnabled(true)
{
mpRenderer = std::make_unique();
- mpRenderer->SetViewportSize(width(), height());
+ qreal pixelRatio = devicePixelRatioF();
+ mpRenderer->SetViewportSize(width() * pixelRatio, height() * pixelRatio);
mpRenderer->SetClearColor(CColor(0.3f, 0.3f, 0.3f));
mpRenderer->ToggleGrid(true);
diff --git a/src/Editor/ModelEditor/CModelEditorViewport.cpp b/src/Editor/ModelEditor/CModelEditorViewport.cpp
index ad792090..f494ad62 100644
--- a/src/Editor/ModelEditor/CModelEditorViewport.cpp
+++ b/src/Editor/ModelEditor/CModelEditorViewport.cpp
@@ -9,7 +9,8 @@ CModelEditorViewport::CModelEditorViewport(QWidget *pParent)
, mGridEnabled(true)
{
mpRenderer = new CRenderer();
- mpRenderer->SetViewportSize(width(), height());
+ qreal pixelRatio = devicePixelRatioF();
+ mpRenderer->SetViewportSize(width() * pixelRatio, height() * pixelRatio);
mpRenderer->SetClearColor(CColor::skBlack);
mpRenderer->ToggleGrid(true);
@@ -109,5 +110,6 @@ void CModelEditorViewport::Paint()
void CModelEditorViewport::OnResize()
{
- mpRenderer->SetViewportSize(width(), height());
+ qreal pixelRatio = devicePixelRatioF();
+ mpRenderer->SetViewportSize(width() * pixelRatio, height() * pixelRatio);
}
diff --git a/src/Editor/PropertyEdit/CPropertyView.cpp b/src/Editor/PropertyEdit/CPropertyView.cpp
index 13f38aaa..b09691ae 100644
--- a/src/Editor/PropertyEdit/CPropertyView.cpp
+++ b/src/Editor/PropertyEdit/CPropertyView.cpp
@@ -241,7 +241,7 @@ void CPropertyView::ClosePersistentEditors(const QModelIndex& rkIndex)
for (uint32 iChild = 0; iChild < NumChildren; iChild++)
{
- QModelIndex ChildIndex = rkIndex.child(iChild, 1);
+ QModelIndex ChildIndex = mpModel->index(iChild, 1, rkIndex);
closePersistentEditor(ChildIndex);
if (mpModel->rowCount(ChildIndex) != 0)
diff --git a/src/Editor/ResourceBrowser/CResourceBrowser.cpp b/src/Editor/ResourceBrowser/CResourceBrowser.cpp
index 906d1069..17f13c61 100644
--- a/src/Editor/ResourceBrowser/CResourceBrowser.cpp
+++ b/src/Editor/ResourceBrowser/CResourceBrowser.cpp
@@ -268,7 +268,7 @@ void CResourceBrowser::CreateFilterCheckboxes()
mTypeList << SResourceType { pType, pCheck };
}
- qSort(mTypeList.begin(), mTypeList.end(), [](const SResourceType& rkLeft, const SResourceType& rkRight) -> bool {
+ std::sort(mTypeList.begin(), mTypeList.end(), [](const SResourceType& rkLeft, const SResourceType& rkRight) -> bool {
return rkLeft.pTypeInfo->TypeName().ToUpper() < rkRight.pTypeInfo->TypeName().ToUpper();
});
diff --git a/src/Editor/Undo/CDeleteLinksCommand.cpp b/src/Editor/Undo/CDeleteLinksCommand.cpp
index 8b246ccf..dc338935 100644
--- a/src/Editor/Undo/CDeleteLinksCommand.cpp
+++ b/src/Editor/Undo/CDeleteLinksCommand.cpp
@@ -53,7 +53,7 @@ void CDeleteLinksCommand::undo()
}
// Add to senders
- qSort(NewLinks.begin(), NewLinks.end(), [](SNewLink& rLinkA, SNewLink& rLinkB) { return rLinkA.pDelLink->SenderIndex < rLinkB.pDelLink->SenderIndex; });
+ std::sort(NewLinks.begin(), NewLinks.end(), [](SNewLink& rLinkA, SNewLink& rLinkB) { return rLinkA.pDelLink->SenderIndex < rLinkB.pDelLink->SenderIndex; });
for (int iLink = 0; iLink < NewLinks.size(); iLink++)
{
@@ -62,7 +62,7 @@ void CDeleteLinksCommand::undo()
}
// Add to receivers
- qSort(NewLinks.begin(), NewLinks.end(), [](SNewLink& rLinkA, SNewLink& rLinkB) { return rLinkA.pDelLink->ReceiverIndex < rLinkB.pDelLink->ReceiverIndex; });
+ std::sort(NewLinks.begin(), NewLinks.end(), [](SNewLink& rLinkA, SNewLink& rLinkB) { return rLinkA.pDelLink->ReceiverIndex < rLinkB.pDelLink->ReceiverIndex; });
for (int iLink = 0; iLink < NewLinks.size(); iLink++)
{
diff --git a/src/Editor/Undo/CDeleteSelectionCommand.cpp b/src/Editor/Undo/CDeleteSelectionCommand.cpp
index 61f88682..970983a6 100644
--- a/src/Editor/Undo/CDeleteSelectionCommand.cpp
+++ b/src/Editor/Undo/CDeleteSelectionCommand.cpp
@@ -111,7 +111,7 @@ void CDeleteSelectionCommand::undo()
}
// Sort links by sender index, add outgoing
- qSort(mDeletedLinks.begin(), mDeletedLinks.end(), [](SDeletedLink& rLeft, SDeletedLink& rRight) -> bool {
+ std::sort(mDeletedLinks.begin(), mDeletedLinks.end(), [](SDeletedLink& rLeft, SDeletedLink& rRight) -> bool {
return (rLeft.SenderIndex < rRight.SenderIndex);
});
@@ -128,7 +128,7 @@ void CDeleteSelectionCommand::undo()
}
// Sort links by receiver index, add incoming
- qSort(mDeletedLinks.begin(), mDeletedLinks.end(), [](SDeletedLink& rLeft, SDeletedLink& rRight) -> bool {
+ std::sort(mDeletedLinks.begin(), mDeletedLinks.end(), [](SDeletedLink& rLeft, SDeletedLink& rRight) -> bool {
return (rLeft.ReceiverIndex < rRight.ReceiverIndex);
});
diff --git a/src/Editor/Widgets/CFilteredResourceModel.h b/src/Editor/Widgets/CFilteredResourceModel.h
index 7df7f014..ff878bda 100644
--- a/src/Editor/Widgets/CFilteredResourceModel.h
+++ b/src/Editor/Widgets/CFilteredResourceModel.h
@@ -32,7 +32,7 @@ public:
}
}
- qSort(mEntries.begin(), mEntries.end(), [](CResourceEntry *pA, CResourceEntry *pB) -> bool {
+ std::sort(mEntries.begin(), mEntries.end(), [](CResourceEntry *pA, CResourceEntry *pB) -> bool {
return pA->UppercaseName() < pB->UppercaseName();
});
diff --git a/src/Editor/WorldEditor/CInstancesModel.cpp b/src/Editor/WorldEditor/CInstancesModel.cpp
index b7a31e61..1d90164e 100644
--- a/src/Editor/WorldEditor/CInstancesModel.cpp
+++ b/src/Editor/WorldEditor/CInstancesModel.cpp
@@ -581,7 +581,7 @@ void CInstancesModel::GenerateList()
mTemplateList << pTemp;
}
- qSort(mTemplateList.begin(), mTemplateList.end(), [](CScriptTemplate *pLeft, CScriptTemplate *pRight) -> bool {
+ std::sort(mTemplateList.begin(), mTemplateList.end(), [](CScriptTemplate *pLeft, CScriptTemplate *pRight) -> bool {
return (pLeft->Name() < pRight->Name());
});
}
diff --git a/src/Editor/WorldEditor/CStateMessageModel.h b/src/Editor/WorldEditor/CStateMessageModel.h
index 90621958..e6758d64 100644
--- a/src/Editor/WorldEditor/CStateMessageModel.h
+++ b/src/Editor/WorldEditor/CStateMessageModel.h
@@ -87,7 +87,7 @@ public:
}
}
- qSort(mEntries);
+ std::sort(mEntries.begin(), mEntries.end());
endResetModel();
}
diff --git a/src/Editor/WorldEditor/CTemplateListView.h b/src/Editor/WorldEditor/CTemplateListView.h
index 917d36c5..5887e0ec 100644
--- a/src/Editor/WorldEditor/CTemplateListView.h
+++ b/src/Editor/WorldEditor/CTemplateListView.h
@@ -67,7 +67,7 @@ public:
for (uint32 iTemp = 0; iTemp < mpGame->NumScriptTemplates(); iTemp++)
mTemplates << mpGame->TemplateByIndex(iTemp);
- qSort(mTemplates.begin(), mTemplates.end(), [](CScriptTemplate *pLeft, CScriptTemplate *pRight) -> bool {
+ std::sort(mTemplates.begin(), mTemplates.end(), [](CScriptTemplate *pLeft, CScriptTemplate *pRight) -> bool {
return pLeft->Name() < pRight->Name();
});
}
diff --git a/src/Editor/WorldEditor/CWorldTreeModel.cpp b/src/Editor/WorldEditor/CWorldTreeModel.cpp
index b8b52048..4f2c3140 100644
--- a/src/Editor/WorldEditor/CWorldTreeModel.cpp
+++ b/src/Editor/WorldEditor/CWorldTreeModel.cpp
@@ -257,7 +257,7 @@ void CWorldTreeModel::OnProjectChanged(CGameProject *pProj)
// Sort in alphabetical order for MP3
if (pProj->Game() >= EGame::Corruption)
{
- qSort(mWorldList.begin(), mWorldList.end(), [](const SWorldInfo& rkA, const SWorldInfo& rkB) -> bool {
+ std::sort(mWorldList.begin(), mWorldList.end(), [](const SWorldInfo& rkA, const SWorldInfo& rkB) -> bool {
return (rkA.WorldName.toUpper() < rkB.WorldName.toUpper());
});
}
@@ -333,7 +333,7 @@ void CWorldTreeModel::OnProjectChanged(CGameProject *pProj)
}
// Sort FrontEnd world
- qSort( pInfo->Areas.begin(), pInfo->Areas.end(), [](CResourceEntry *pA, CResourceEntry *pB) -> bool {
+ std::sort( pInfo->Areas.begin(), pInfo->Areas.end(), [](CResourceEntry *pA, CResourceEntry *pB) -> bool {
return pA->UppercaseName() < pB->UppercaseName();
});
}
diff --git a/src/Editor/WorldEditor/WInstancesTab.cpp b/src/Editor/WorldEditor/WInstancesTab.cpp
index 30d23b01..74cecfd4 100644
--- a/src/Editor/WorldEditor/WInstancesTab.cpp
+++ b/src/Editor/WorldEditor/WInstancesTab.cpp
@@ -347,7 +347,7 @@ void WInstancesTab::OnUnhideAll()
It->SetVisible(true);
// Unhide layers
- QModelIndex LayersRoot = mpLayersModel->index(0, 0, QModelIndex()).child(0, 0);
+ QModelIndex LayersRoot = mpLayersModel->index(0, 0, mpLayersModel->index(0, 0, QModelIndex()));
if (LayersRoot.isValid())
{
@@ -360,7 +360,7 @@ void WInstancesTab::OnUnhideAll()
}
// Unhide types
- QModelIndex TypesRoot = mpTypesModel->index(0, 0, QModelIndex()).child(0, 0);
+ QModelIndex TypesRoot = mpTypesModel->index(0, 0, mpTypesModel->index(0, 0, QModelIndex()));
if (TypesRoot.isValid())
{