Accurate MP3 material processing

This commit is contained in:
Jack Andersen 2019-11-06 16:52:45 -10:00
parent 79ec379c66
commit 6e3b23ec50
39 changed files with 1647 additions and 426 deletions

View File

@ -7,8 +7,15 @@
<option name="NAMESPACE_BRACE_PLACEMENT" value="2" /> <option name="NAMESPACE_BRACE_PLACEMENT" value="2" />
<option name="FUNCTION_BRACE_PLACEMENT" value="2" /> <option name="FUNCTION_BRACE_PLACEMENT" value="2" />
<option name="BLOCK_BRACE_PLACEMENT" value="2" /> <option name="BLOCK_BRACE_PLACEMENT" value="2" />
<option name="FUNCTION_NON_TOP_AFTER_RETURN_TYPE_WRAP" value="0" />
<option name="FUNCTION_TOP_AFTER_RETURN_TYPE_WRAP" value="0" />
<option name="SPACE_BEFORE_POINTER_IN_DECLARATION" value="false" />
<option name="SPACE_AFTER_POINTER_IN_DECLARATION" value="true" />
<option name="SPACE_BEFORE_REFERENCE_IN_DECLARATION" value="false" />
<option name="SPACE_AFTER_REFERENCE_IN_DECLARATION" value="true" />
</Objective-C> </Objective-C>
<codeStyleSettings language="ObjectiveC"> <codeStyleSettings language="ObjectiveC">
<option name="BLANK_LINES_AROUND_METHOD_IN_INTERFACE" value="0" />
<option name="BRACE_STYLE" value="2" /> <option name="BRACE_STYLE" value="2" />
<option name="CLASS_BRACE_STYLE" value="2" /> <option name="CLASS_BRACE_STYLE" value="2" />
</codeStyleSettings> </codeStyleSettings>

View File

@ -16,7 +16,7 @@ endif()
# Ensure submodules checked out # Ensure submodules checked out
if (NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/externals/LibCommon/CMakeLists.txt) 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() endif()
include(./dew.cmake) include(./dew.cmake)

2
externals/LibCommon vendored

@ -1 +1 @@
Subproject commit 8393432003b8e634cba4e89c27635fec0ae43a6f Subproject commit f914e4b9c422de49e573607a217b25152b3e6f20

View File

@ -172,7 +172,7 @@ void GenerateAssetNames(CGameProject *pProj)
for (uint32 iMat = 0; iMat < pSet->NumMaterials(); iMat++) 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++) for (uint32 iPass = 0; iPass < pMat->PassCount(); iPass++)
{ {
@ -239,7 +239,7 @@ void GenerateAssetNames(CGameProject *pProj)
for (uint32 iMat = 0; iMat < pMaterials->NumMaterials(); iMat++) for (uint32 iMat = 0; iMat < pMaterials->NumMaterials(); iMat++)
{ {
CMaterial *pMat = pMaterials->MaterialByIndex(iMat); CMaterial *pMat = pMaterials->MaterialByIndex(iMat, true);
bool FoundLightmap = false; bool FoundLightmap = false;
for (uint32 iPass = 0; iPass < pMat->PassCount(); iPass++) for (uint32 iPass = 0; iPass < pMat->PassCount(); iPass++)
@ -415,7 +415,7 @@ void GenerateAssetNames(CGameProject *pProj)
for (uint32 iMat = 0; iMat < pSet->NumMaterials(); iMat++) 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++) for (uint32 iPass = 0; iPass < pMat->PassCount(); iPass++)
{ {

View File

@ -366,6 +366,36 @@ bool CShaderGenerator::CreateVertexShader(const CMaterial& rkMat)
return mpShader->CompileVertexSource(ShaderCode.str().c_str()); 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) bool CShaderGenerator::CreatePixelShader(const CMaterial& rkMat)
{ {
std::stringstream ShaderCode; std::stringstream ShaderCode;
@ -391,7 +421,7 @@ bool CShaderGenerator::CreatePixelShader(const CMaterial& rkMat)
<< "\n" << "\n"
<< "layout(std140) uniform PixelBlock {\n" << "layout(std140) uniform PixelBlock {\n"
<< " vec4 KonstColors[4];\n" << " vec4 KonstColors[4];\n"
<< " vec4 TevColor;\n" << " vec4 TevColor[4];\n"
<< " vec4 TintColor;\n" << " vec4 TintColor;\n"
<< " float LightmapMultiplier;\n" << " float LightmapMultiplier;\n"
<< "};\n\n"; << "};\n\n";
@ -405,7 +435,7 @@ bool CShaderGenerator::CreatePixelShader(const CMaterial& rkMat)
ShaderCode << "void main()\n" ShaderCode << "void main()\n"
<< "{\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 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 Ras = vec4(0, 0, 0, 1), Tex = vec4(0, 0, 0, 0);\n"
<< " vec4 Konst = vec4(1, 1, 1, 1);\n"; << " vec4 Konst = vec4(1, 1, 1, 1);\n";
@ -430,7 +460,7 @@ bool CShaderGenerator::CreatePixelShader(const CMaterial& rkMat)
if (pPass->TexCoordSource() != 0xFF) if (pPass->TexCoordSource() != 0xFF)
ShaderCode << " TevCoord = (Tex" << iPass << ".z == 0.0 ? Tex" << iPass << ".xy : Tex" << iPass << ".xy / Tex" << iPass << ".z);\n"; 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)"; ShaderCode << " Tex = texture(Texture" << iPass << ", TevCoord)";
// A couple pass types require special swizzles to access different texture color channels as alpha // A couple pass types require special swizzles to access different texture color channels as alpha
@ -440,8 +470,9 @@ bool CShaderGenerator::CreatePixelShader(const CMaterial& rkMat)
ShaderCode << ".rgbg"; ShaderCode << ".rgbg";
// Apply lightmap multiplier // Apply lightmap multiplier
if ( (PassType == "DIFF") || bool UseLightmapMultiplier = (PassType == "DIFF") ||
(PassType == "CUST" && (rkMat.Options() & EMaterialOption::Lightmap) && iPass == 0) ) (PassType == "CUST" && (rkMat.Options() & EMaterialOption::Lightmap) && iPass == 0);
if (UseLightmapMultiplier && pPass->Texture())
ShaderCode << " * LightmapMultiplier"; ShaderCode << " * LightmapMultiplier";
ShaderCode << ";\n"; ShaderCode << ";\n";
@ -456,10 +487,13 @@ bool CShaderGenerator::CreatePixelShader(const CMaterial& rkMat)
char TevChar = iInput + 0x41; // the current stage number represented as an ASCII letter; eg 0 is 'A' char TevChar = iInput + 0x41; // the current stage number represented as an ASCII letter; eg 0 is 'A'
ShaderCode << " TevIn" << TevChar << " = vec4(" ShaderCode << " TevIn" << TevChar << " = vec4("
<< gkTevColor[pPass->ColorInput(iInput) & 0xF] << GetColorInputExpression(pPass, ETevColorInput(pPass->ColorInput(iInput) & 0xF))
<< ", " << ", "
<< gkTevAlpha[pPass->AlphaInput(iInput) & 0x7] << GetAlphaInputExpression(pPass, ETevAlphaInput(pPass->AlphaInput(iInput) & 0x7))
<< ");\n"; << ")";
if (UseLightmapMultiplier && !pPass->Texture() && iInput == 1)
ShaderCode << " * LightmapMultiplier";
ShaderCode << ";\n";
} }
ShaderCode << " // RGB Combine\n" ShaderCode << " // RGB Combine\n"
@ -467,8 +501,7 @@ bool CShaderGenerator::CreatePixelShader(const CMaterial& rkMat)
<< gkTevRigid[pPass->ColorOutput()] << gkTevRigid[pPass->ColorOutput()]
<< ".rgb = "; << ".rgb = ";
ShaderCode << "clamp(vec3(TevInD.rgb + ((1.0 - TevInC.rgb) * TevInA.rgb + TevInC.rgb * TevInB.rgb))"; ShaderCode << "clamp(vec3(TevInD.rgb + ((1.0 - TevInC.rgb) * TevInA.rgb + TevInC.rgb * TevInB.rgb)) * " << pPass->TevColorScale();
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 << ", vec3(0, 0, 0), vec3(1.0, 1.0, 1.0));\n"; ShaderCode << ", vec3(0, 0, 0), vec3(1.0, 1.0, 1.0));\n";
ShaderCode << " // Alpha Combine\n" ShaderCode << " // Alpha Combine\n"
@ -476,7 +509,7 @@ bool CShaderGenerator::CreatePixelShader(const CMaterial& rkMat)
<< gkTevRigid[pPass->AlphaOutput()] << gkTevRigid[pPass->AlphaOutput()]
<< ".a = "; << ".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) if (rkMat.Options() & EMaterialOption::Masked)

View File

@ -56,9 +56,15 @@ public:
struct SPixelBlock struct SPixelBlock
{ {
CColor Konst[4]; CColor Konst[4];
CColor TevColor; CColor TevColor[4];
CColor TintColor; CColor TintColor;
float LightmapMultiplier; float LightmapMultiplier;
float Padding[3];
void SetAllTevColors(const CColor& color)
{
std::fill(std::begin(TevColor), std::end(TevColor), color);
}
}; };
static SPixelBlock sPixelBlock; static SPixelBlock sPixelBlock;

View File

@ -270,7 +270,7 @@ void CRenderer::RenderSky(CModel *pSkyboxModel, const SViewInfo& rkViewInfo)
CGraphics::sMVPBlock.ModelMatrix = CMatrix4f::skIdentity; CGraphics::sMVPBlock.ModelMatrix = CMatrix4f::skIdentity;
CGraphics::sVertexBlock.COLOR0_Amb = CColor::skWhite; CGraphics::sVertexBlock.COLOR0_Amb = CColor::skWhite;
CGraphics::sPixelBlock.TevColor = CColor::skWhite; CGraphics::sPixelBlock.SetAllTevColors(CColor::skWhite);
CGraphics::sPixelBlock.TintColor = CColor::skWhite; CGraphics::sPixelBlock.TintColor = CColor::skWhite;
CGraphics::sNumLights = 0; CGraphics::sNumLights = 0;
CGraphics::UpdateVertexBlock(); CGraphics::UpdateVertexBlock();

View File

@ -79,7 +79,7 @@ void CGameArea::MergeTerrain()
for (uint32 iSurf = 0; iSurf < SubmeshCount; iSurf++) for (uint32 iSurf = 0; iSurf < SubmeshCount; iSurf++)
{ {
SSurface *pSurf = pMdl->GetSurface(iSurf); SSurface *pSurf = pMdl->GetSurface(iSurf);
CMaterial *pMat = mpMaterialSet->MaterialByIndex(pSurf->MaterialID); CMaterial *pMat = mpMaterialSet->MaterialByIndex(pSurf->MaterialID, false);
bool NewMat = true; bool NewMat = true;
for (std::vector<CStaticModel*>::iterator it = mStaticWorldModels.begin(); it != mStaticWorldModels.end(); it++) for (std::vector<CStaticModel*>::iterator it = mStaticWorldModels.begin(); it != mStaticWorldModels.end(); it++)

View File

@ -17,7 +17,6 @@ CMaterial::CMaterial()
: mpShader(nullptr) : mpShader(nullptr)
, mShaderStatus(EShaderStatus::NoShader) , mShaderStatus(EShaderStatus::NoShader)
, mRecalcHash(true) , mRecalcHash(true)
, mEnableBloom(false)
, mVersion(EGame::Invalid) , mVersion(EGame::Invalid)
, mOptions(EMaterialOption::None) , mOptions(EMaterialOption::None)
, mVtxDesc(EVertexAttribute::None) , mVtxDesc(EVertexAttribute::None)
@ -27,16 +26,16 @@ CMaterial::CMaterial()
, mEchoesUnknownA(0) , mEchoesUnknownA(0)
, mEchoesUnknownB(0) , mEchoesUnknownB(0)
, mpIndirectTexture(nullptr) , mpIndirectTexture(nullptr)
{ , mpNextDrawPassMaterial(nullptr)
} , mpBloomMaterial(nullptr)
{}
CMaterial::CMaterial(EGame Version, FVertexDescription VtxDesc) CMaterial::CMaterial(EGame Version, FVertexDescription VtxDesc)
: mpShader(nullptr) : mpShader(nullptr)
, mShaderStatus(EShaderStatus::NoShader) , mShaderStatus(EShaderStatus::NoShader)
, mRecalcHash(true) , mRecalcHash(true)
, mEnableBloom(Version == EGame::Corruption)
, mVersion(Version) , mVersion(Version)
, mOptions(EMaterialOption::DepthWrite) , mOptions(EMaterialOption::DepthWrite | EMaterialOption::ColorWrite)
, mVtxDesc(VtxDesc) , mVtxDesc(VtxDesc)
, mBlendSrcFac(GL_ONE) , mBlendSrcFac(GL_ONE)
, mBlendDstFac(GL_ZERO) , mBlendDstFac(GL_ZERO)
@ -44,27 +43,18 @@ CMaterial::CMaterial(EGame Version, FVertexDescription VtxDesc)
, mEchoesUnknownA(0) , mEchoesUnknownA(0)
, mEchoesUnknownB(0) , mEchoesUnknownB(0)
, mpIndirectTexture(nullptr) , mpIndirectTexture(nullptr)
{ , mpNextDrawPassMaterial(nullptr)
mpShader = nullptr; , mpBloomMaterial(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;
}
CMaterial::~CMaterial() CMaterial::~CMaterial()
{ {
for (uint32 iPass = 0; iPass < mPasses.size(); iPass++) for (uint32 iPass = 0; iPass < mPasses.size(); iPass++)
delete mPasses[iPass]; delete mPasses[iPass];
delete mpNextDrawPassMaterial;
delete mpBloomMaterial;
ClearShader(); ClearShader();
} }
@ -72,12 +62,13 @@ CMaterial* CMaterial::Clone()
{ {
CMaterial *pOut = new CMaterial(); CMaterial *pOut = new CMaterial();
pOut->mName = mName; pOut->mName = mName;
pOut->mEnableBloom = mEnableBloom;
pOut->mVersion = mVersion; pOut->mVersion = mVersion;
pOut->mOptions = mOptions; pOut->mOptions = mOptions;
pOut->mVtxDesc = mVtxDesc; pOut->mVtxDesc = mVtxDesc;
for (uint32 iKonst = 0; iKonst < 4; iKonst++) for (uint32 iKonst = 0; iKonst < 4; iKonst++)
pOut->mKonstColors[iKonst] = mKonstColors[iKonst]; pOut->mKonstColors[iKonst] = mKonstColors[iKonst];
for (uint32 iTev = 0; iTev < 4; iTev++)
pOut->mTevColors[iTev] = mTevColors[iTev];
pOut->mBlendSrcFac = mBlendSrcFac; pOut->mBlendSrcFac = mBlendSrcFac;
pOut->mBlendDstFac = mBlendDstFac; pOut->mBlendDstFac = mBlendDstFac;
pOut->mLightingEnabled = mLightingEnabled; pOut->mLightingEnabled = mLightingEnabled;
@ -89,6 +80,12 @@ CMaterial* CMaterial::Clone()
for (uint32 iPass = 0; iPass < mPasses.size(); iPass++) for (uint32 iPass = 0; iPass < mPasses.size(); iPass++)
pOut->mPasses[iPass] = mPasses[iPass]->Clone(pOut); pOut->mPasses[iPass] = mPasses[iPass]->Clone(pOut);
if (mpNextDrawPassMaterial)
pOut->mpNextDrawPassMaterial = mpNextDrawPassMaterial->Clone();
if (mpBloomMaterial)
pOut->mpBloomMaterial = mpBloomMaterial->Clone();
return pOut; return pOut;
} }
@ -179,15 +176,12 @@ bool CMaterial::SetCurrent(FRenderOptions Options)
dstRGB = mBlendDstFac; dstRGB = mBlendDstFac;
} }
// Set alpha blend equation if (mOptions & EMaterialOption::ZeroDestAlpha) {
bool AlphaBlended = ((mBlendSrcFac == GL_SRC_ALPHA) && (mBlendDstFac == GL_ONE_MINUS_SRC_ALPHA));
if ((mEnableBloom) && (Options & ERenderOption::EnableBloom) && (!AlphaBlended)) {
srcAlpha = mBlendSrcFac;
dstAlpha = mBlendDstFac;
} else {
srcAlpha = GL_ZERO; srcAlpha = GL_ZERO;
dstAlpha = GL_ZERO; dstAlpha = GL_ZERO;
} else {
srcAlpha = mBlendSrcFac;
dstAlpha = mBlendDstFac;
} }
glBlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha); glBlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha);
@ -196,6 +190,11 @@ bool CMaterial::SetCurrent(FRenderOptions Options)
for (uint32 iKonst = 0; iKonst < 4; iKonst++) for (uint32 iKonst = 0; iKonst < 4; iKonst++)
CGraphics::sPixelBlock.Konst[iKonst] = mKonstColors[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 // Set color channels
// COLOR0_Amb is initialized by the node instead of by the material // COLOR0_Amb is initialized by the node instead of by the material
CGraphics::sVertexBlock.COLOR0_Mat = CColor::skWhite; 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); if ((mOptions & EMaterialOption::DepthWrite) || (Options & ERenderOption::NoAlpha)) glDepthMask(GL_TRUE);
else glDepthMask(GL_FALSE); 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 // Load uniforms
for (uint32 iPass = 0; iPass < mPasses.size(); iPass++) for (uint32 iPass = 0; iPass < mPasses.size(); iPass++)
mPasses[iPass]->SetAnimCurrent(Options, iPass); mPasses[iPass]->SetAnimCurrent(Options, iPass);
@ -249,6 +253,7 @@ uint64 CMaterial::HashParameters()
Hash.HashLong(mOptions); Hash.HashLong(mOptions);
Hash.HashLong(mVtxDesc); Hash.HashLong(mVtxDesc);
Hash.HashData(mKonstColors, sizeof(CColor) * 4); Hash.HashData(mKonstColors, sizeof(CColor) * 4);
Hash.HashData(mTevColors, sizeof(CColor) * 4);
Hash.HashLong(mBlendSrcFac); Hash.HashLong(mBlendSrcFac);
Hash.HashLong(mBlendDstFac); Hash.HashLong(mBlendDstFac);
Hash.HashByte(mLightingEnabled); Hash.HashByte(mLightingEnabled);

View File

@ -31,10 +31,32 @@ enum class EMaterialOption
Lightmap = 0x800, Lightmap = 0x800,
ShortTexCoord = 0x2000, ShortTexCoord = 0x2000,
AllMP1Settings = 0x2FF8, AllMP1Settings = 0x2FF8,
ColorWrite = 0x10000,
AlphaWrite = 0x20000,
ZeroDestAlpha = 0x40000,
DrawWhiteAmbientDKCR = 0x80000 DrawWhiteAmbientDKCR = 0x80000
}; };
DECLARE_FLAGS_ENUMCLASS(EMaterialOption, FMaterialOptions) 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 class CMaterial
{ {
friend class CMaterialLoader; 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. 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. 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 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; 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 FVertexDescription mVtxDesc; // Descriptor of vertex attributes used by this material
CColor mKonstColors[4]; // Konst color values for TEV 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 mBlendSrcFac; // Source blend factor
GLenum mBlendDstFac; // Dest blend factor GLenum mBlendDstFac; // Dest blend factor
bool mLightingEnabled; // Color channel control flags; indicate whether lighting is enabled bool mLightingEnabled; // Color channel control flags; indicate whether lighting is enabled
@ -72,6 +94,16 @@ private:
std::vector<CMaterialPass*> mPasses; std::vector<CMaterialPass*> 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 // Reuse shaders between materials that have identical TEV setups
struct SMaterialShader struct SMaterialShader
{ {
@ -101,18 +133,22 @@ public:
inline GLenum BlendSrcFac() const { return mBlendSrcFac; } inline GLenum BlendSrcFac() const { return mBlendSrcFac; }
inline GLenum BlendDstFac() const { return mBlendDstFac; } inline GLenum BlendDstFac() const { return mBlendDstFac; }
inline CColor Konst(uint32 KIndex) const { return mKonstColors[KIndex]; } 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 CTexture* IndTexture() const { return mpIndirectTexture; }
inline bool IsLightingEnabled() const { return mLightingEnabled; } inline bool IsLightingEnabled() const { return mLightingEnabled; }
inline uint32 EchoesUnknownA() const { return mEchoesUnknownA; } inline uint32 EchoesUnknownA() const { return mEchoesUnknownA; }
inline uint32 EchoesUnknownB() const { return mEchoesUnknownB; } inline uint32 EchoesUnknownB() const { return mEchoesUnknownB; }
inline uint32 PassCount() const { return mPasses.size(); } inline uint32 PassCount() const { return mPasses.size(); }
inline CMaterialPass* Pass(uint32 PassIndex) const { return mPasses[PassIndex]; } 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 SetName(const TString& rkName) { mName = rkName; }
inline void SetOptions(FMaterialOptions Options) { mOptions = Options; Update(); } inline void SetOptions(FMaterialOptions Options) { mOptions = Options; Update(); }
inline void SetVertexDescription(FVertexDescription Desc) { mVtxDesc = Desc; Update(); } inline void SetVertexDescription(FVertexDescription Desc) { mVtxDesc = Desc; Update(); }
inline void SetBlendMode(GLenum SrcFac, GLenum DstFac) { mBlendSrcFac = SrcFac; mBlendDstFac = DstFac; mRecalcHash = true; } 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 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 SetIndTexture(CTexture *pTex) { mpIndirectTexture = pTex; }
inline void SetLightingEnabled(bool Enabled) { mLightingEnabled = Enabled; Update(); } inline void SetLightingEnabled(bool Enabled) { mLightingEnabled = Enabled; Update(); }

View File

@ -14,8 +14,11 @@ CMaterialPass::CMaterialPass(CMaterial *pParent)
, mKColorSel(kKonstOne) , mKColorSel(kKonstOne)
, mKAlphaSel(kKonstOne) , mKAlphaSel(kKonstOne)
, mRasSel(kRasColorNull) , mRasSel(kRasColorNull)
, mTevColorScale(1.f)
, mTevAlphaScale(1.f)
, mTexCoordSource(0xFF) , mTexCoordSource(0xFF)
, mAnimMode(EUVAnimMode::NoUVAnim) , mAnimMode(EUVAnimMode::NoUVAnim)
, mTexSwapComps{'r', 'g', 'b', 'a'}
{ {
for (uint32 iParam = 0; iParam < 4; iParam++) for (uint32 iParam = 0; iParam < 4; iParam++)
{ {
@ -46,13 +49,18 @@ CMaterialPass* CMaterialPass::Clone(CMaterial *pParent)
pOut->mKColorSel = mKColorSel; pOut->mKColorSel = mKColorSel;
pOut->mKAlphaSel = mKAlphaSel; pOut->mKAlphaSel = mKAlphaSel;
pOut->mRasSel = mRasSel; pOut->mRasSel = mRasSel;
pOut->mTevColorScale = mTevColorScale;
pOut->mTevAlphaScale = mTevAlphaScale;
pOut->mTexCoordSource = mTexCoordSource; pOut->mTexCoordSource = mTexCoordSource;
pOut->mpTexture = mpTexture; pOut->mpTexture = mpTexture;
pOut->mAnimMode = mAnimMode; pOut->mAnimMode = mAnimMode;
for (uint32 iParam = 0; iParam < 4; iParam++) for (uint32 iParam = 0; iParam < 8; iParam++)
pOut->mAnimParams[iParam] = mAnimParams[iParam]; pOut->mAnimParams[iParam] = mAnimParams[iParam];
for (uint32 iComp = 0; iComp < 4; iComp++)
pOut->mTexSwapComps[iComp] = mTexSwapComps[iComp];
pOut->mEnabled = mEnabled; pOut->mEnabled = mEnabled;
return pOut; return pOut;
@ -71,9 +79,12 @@ void CMaterialPass::HashParameters(CFNV1A& rHash)
rHash.HashLong(mKColorSel); rHash.HashLong(mKColorSel);
rHash.HashLong(mKAlphaSel); rHash.HashLong(mKAlphaSel);
rHash.HashLong(mRasSel); rHash.HashLong(mRasSel);
rHash.HashLong(mTevColorScale);
rHash.HashLong(mTevAlphaScale);
rHash.HashLong(mTexCoordSource); rHash.HashLong(mTexCoordSource);
rHash.HashLong((uint) mAnimMode); 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); rHash.HashByte(mEnabled);
} }
} }
@ -295,6 +306,18 @@ void CMaterialPass::SetRasSel(ETevRasSel Sel)
mpParentMat->Update(); 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) void CMaterialPass::SetTexCoordSource(uint32 Source)
{ {
mTexCoordSource = Source; mTexCoordSource = Source;
@ -317,6 +340,11 @@ void CMaterialPass::SetAnimParam(uint32 ParamIndex, float Value)
mAnimParams[ParamIndex] = Value; mAnimParams[ParamIndex] = Value;
} }
void CMaterialPass::SetTexSwapComp(uint32 Comp, char Value)
{
mTexSwapComps[Comp] = Value;
}
void CMaterialPass::SetEnabled(bool Enabled) void CMaterialPass::SetEnabled(bool Enabled)
{ {
mEnabled = Enabled; mEnabled = Enabled;

View File

@ -13,7 +13,8 @@ class CMaterial;
enum class EPassSettings enum class EPassSettings
{ {
None = 0x0, None = 0x0,
EmissiveBloom = 0x4, BloomContribution = 0x4,
ModulateIncandecenceMap = 0x8,
InvertOpacityMap = 0x10 InvertOpacityMap = 0x10
}; };
DECLARE_FLAGS_ENUMCLASS(EPassSettings, FPassSettings) DECLARE_FLAGS_ENUMCLASS(EPassSettings, FPassSettings)
@ -34,11 +35,14 @@ class CMaterialPass
ETevKSel mKColorSel; ETevKSel mKColorSel;
ETevKSel mKAlphaSel; ETevKSel mKAlphaSel;
ETevRasSel mRasSel; ETevRasSel mRasSel;
float mTevColorScale;
float mTevAlphaScale;
uint32 mTexCoordSource; // Should maybe be an enum but worried about conflicts with EVertexDescriptionn uint32 mTexCoordSource; // Should maybe be an enum but worried about conflicts with EVertexDescriptionn
TResPtr<CTexture> mpTexture; TResPtr<CTexture> mpTexture;
EUVAnimMode mAnimMode; EUVAnimMode mAnimMode;
EUVConvolutedModeBType mAnimConvolutedModeBType; EUVConvolutedModeBType mAnimConvolutedModeBType;
float mAnimParams[8]; float mAnimParams[8];
char mTexSwapComps[4];
bool mEnabled; bool mEnabled;
public: public:
@ -58,10 +62,13 @@ public:
void SetKColorSel(ETevKSel Sel); void SetKColorSel(ETevKSel Sel);
void SetKAlphaSel(ETevKSel Sel); void SetKAlphaSel(ETevKSel Sel);
void SetRasSel(ETevRasSel Sel); void SetRasSel(ETevRasSel Sel);
void SetTevColorScale(float Scale);
void SetTevAlphaScale(float Scale);
void SetTexCoordSource(uint32 Source); void SetTexCoordSource(uint32 Source);
void SetTexture(CTexture *pTex); void SetTexture(CTexture *pTex);
void SetAnimMode(EUVAnimMode Mode); void SetAnimMode(EUVAnimMode Mode);
void SetAnimParam(uint32 ParamIndex, float Value); void SetAnimParam(uint32 ParamIndex, float Value);
void SetTexSwapComp(uint32 Comp, char Value);
void SetEnabled(bool Enabled); void SetEnabled(bool Enabled);
// Getters // Getters
@ -74,10 +81,13 @@ public:
inline ETevKSel KColorSel() const { return mKColorSel; } inline ETevKSel KColorSel() const { return mKColorSel; }
inline ETevKSel KAlphaSel() const { return mKAlphaSel; } inline ETevKSel KAlphaSel() const { return mKAlphaSel; }
inline ETevRasSel RasSel() const { return mRasSel; } 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 uint32 TexCoordSource() const { return mTexCoordSource; }
inline CTexture* Texture() const { return mpTexture; } inline CTexture* Texture() const { return mpTexture; }
inline EUVAnimMode AnimMode() const { return mAnimMode; } inline EUVAnimMode AnimMode() const { return mAnimMode; }
inline float AnimParam(uint32 ParamIndex) const { return mAnimParams[ParamIndex]; } inline float AnimParam(uint32 ParamIndex) const { return mAnimParams[ParamIndex]; }
inline char TexSwapComp(uint32 Comp) const { return mTexSwapComps[Comp]; }
inline bool IsEnabled() const { return mEnabled; } inline bool IsEnabled() const { return mEnabled; }
// Static // Static

View File

@ -38,10 +38,13 @@ public:
return mMaterials.size(); return mMaterials.size();
} }
CMaterial* MaterialByIndex(uint32 Index) CMaterial* MaterialByIndex(uint32 Index, bool TryBloom)
{ {
if (Index >= NumMaterials()) return nullptr; 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) CMaterial* MaterialByName(const TString& rkName)

View File

@ -1,6 +1,8 @@
#ifndef ETEVENUMS #ifndef ETEVENUMS
#define ETEVENUMS #define ETEVENUMS
#include <Common/BasicTypes.h>
enum ETevColorInput enum ETevColorInput
{ {
kPrevRGB = 0x0, kPrevRGB = 0x0,
@ -103,6 +105,20 @@ enum class EUVAnimMode
NoUVAnim = -1 NoUVAnim = -1
}; };
enum class EUVAnimUVSource : uint16
{
Position,
Normal,
UV
};
enum class EUVAnimMatrixConfig : uint16
{
NoMtxNoPost,
MtxNoPost,
NoMtxPost,
MtxPost
};
enum class EUVConvolutedModeBType { enum class EUVConvolutedModeBType {
Zero, Zero,
One, One,

File diff suppressed because it is too large Load Diff

View File

@ -8,6 +8,105 @@
#include <Common/FileIO.h> #include <Common/FileIO.h>
#include <assimp/scene.h> #include <assimp/scene.h>
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<CTexture> 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<PASS> mPASSes[14];
const std::optional<PASS>& 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 class CMaterialLoader
{ {
// Material data // Material data
@ -15,13 +114,10 @@ class CMaterialLoader
IInputStream *mpFile; IInputStream *mpFile;
EGame mVersion; EGame mVersion;
std::vector<TResPtr<CTexture>> mTextures; std::vector<TResPtr<CTexture>> mTextures;
bool mHasOPAC;
bool mHas0x400;
CColor mCorruptionColors[4]; CColor mCorruptionColors[4];
uint8 mCorruptionInts[5]; uint8 mCorruptionInts[5];
uint32 mCorruptionFlags; uint32 mCorruptionFlags;
std::vector<uint32> mPassOffsets;
CMaterialLoader(); CMaterialLoader();
~CMaterialLoader(); ~CMaterialLoader();
@ -33,7 +129,59 @@ class CMaterialLoader
void ReadCorruptionMatSet(); void ReadCorruptionMatSet();
CMaterial* ReadCorruptionMaterial(); 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); CMaterial* LoadAssimpMaterial(const aiMaterial *pAiMat);

View File

@ -128,7 +128,7 @@ SSurface* CModelLoader::LoadSurface(IInputStream& rModel)
LoadSurfaceHeaderDKCR(rModel, pSurf); LoadSurfaceHeaderDKCR(rModel, pSurf);
bool HasAABB = (pSurf->AABox != CAABox::skInfinite); bool HasAABB = (pSurf->AABox != CAABox::skInfinite);
CMaterial *pMat = mMaterials[0]->MaterialByIndex(pSurf->MaterialID); CMaterial *pMat = mMaterials[0]->MaterialByIndex(pSurf->MaterialID, false);
// Primitive table // Primitive table
uint8 Flag = rModel.ReadByte(); uint8 Flag = rModel.ReadByte();
@ -282,7 +282,7 @@ void CModelLoader::LoadSurfaceHeaderDKCR(IInputStream& rModel, SSurface *pSurf)
SSurface* CModelLoader::LoadAssimpMesh(const aiMesh *pkMesh, CMaterialSet *pSet) SSurface* CModelLoader::LoadAssimpMesh(const aiMesh *pkMesh, CMaterialSet *pSet)
{ {
// Create vertex description and assign it to material // 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(); FVertexDescription Desc = pMat->VtxDesc();
if (Desc == (FVertexDescription) EVertexAttribute::None) if (Desc == (FVertexDescription) EVertexAttribute::None)

View File

@ -108,8 +108,8 @@ void CModel::GenerateMaterialShaders()
for (uint32 iMat = 0; iMat < pSet->NumMaterials(); iMat++) for (uint32 iMat = 0; iMat < pSet->NumMaterials(); iMat++)
{ {
CMaterial *pMat = pSet->MaterialByIndex(iMat); pSet->MaterialByIndex(iMat, false)->GenerateShader(false);
pMat->GenerateShader(false); pSet->MaterialByIndex(iMat, true)->GenerateShader(false);
} }
} }
} }
@ -136,18 +136,8 @@ void CModel::DrawSurface(FRenderOptions Options, uint32 Surface, uint32 MatSet)
if (MatSet >= mMaterialSets.size()) if (MatSet >= mMaterialSets.size())
MatSet = mMaterialSets.size() - 1; MatSet = mMaterialSets.size() - 1;
// Bind material auto DoDraw = [this, Surface]()
if ((Options & ERenderOption::NoMaterialSetup) == 0)
{ {
SSurface *pSurf = mSurfaces[Surface];
CMaterial *pMat = mMaterialSets[MatSet]->MaterialByIndex(pSurf->MaterialID);
if (!Options.HasFlag(ERenderOption::EnableOccluders) && pMat->Options().HasFlag(EMaterialOption::Occluder))
return;
pMat->SetCurrent(Options);
}
// Draw IBOs // Draw IBOs
mVBO.Bind(); mVBO.Bind();
glLineWidth(1.f); glLineWidth(1.f);
@ -159,6 +149,27 @@ void CModel::DrawSurface(FRenderOptions Options, uint32 Surface, uint32 MatSet)
} }
mVBO.Unbind(); mVBO.Unbind();
};
// Bind material
if ((Options & ERenderOption::NoMaterialSetup) == 0)
{
SSurface *pSurf = mSurfaces[Surface];
CMaterial *pMat = mMaterialSets[MatSet]->MaterialByIndex(pSurf->MaterialID, Options.HasFlag(ERenderOption::EnableBloom));
if (!Options.HasFlag(ERenderOption::EnableOccluders) && pMat->Options().HasFlag(EMaterialOption::Occluder))
return;
for (CMaterial* passMat = pMat; passMat; passMat = passMat->GetNextDrawPass())
{
passMat->SetCurrent(Options);
DoDraw();
}
}
else
{
DoDraw();
}
} }
void CModel::DrawWireframe(FRenderOptions Options, CColor WireColor /*= CColor::skWhite*/) void CModel::DrawWireframe(FRenderOptions Options, CColor WireColor /*= CColor::skWhite*/)
@ -206,7 +217,9 @@ void CModel::SetSkin(CSkin *pSkin)
for (uint32 iMat = 0; iMat < pSet->NumMaterials(); iMat++) for (uint32 iMat = 0; iMat < pSet->NumMaterials(); iMat++)
{ {
CMaterial *pMat = pSet->MaterialByIndex(iMat); for (bool iBloom = false; !iBloom; iBloom = true)
{
CMaterial *pMat = pSet->MaterialByIndex(iMat, iBloom);
FVertexDescription VtxDesc = pMat->VtxDesc(); FVertexDescription VtxDesc = pMat->VtxDesc();
if (pSkin && !VtxDesc.HasAllFlags(kBoneFlags)) if (pSkin && !VtxDesc.HasAllFlags(kBoneFlags))
@ -224,6 +237,7 @@ void CModel::SetSkin(CSkin *pSkin)
} }
} }
} }
}
uint32 CModel::GetMatSetCount() uint32 CModel::GetMatSetCount()
{ {
@ -249,7 +263,7 @@ CMaterial* CModel::GetMaterialByIndex(uint32 MatSet, uint32 Index)
if (GetMatCount() == 0) if (GetMatCount() == 0)
return nullptr; return nullptr;
return mMaterialSets[MatSet]->MaterialByIndex(Index); return mMaterialSets[MatSet]->MaterialByIndex(Index, false);
} }
CMaterial* CModel::GetMaterialBySurface(uint32 MatSet, uint32 Surface) CMaterial* CModel::GetMaterialBySurface(uint32 MatSet, uint32 Surface)
@ -263,7 +277,7 @@ bool CModel::HasTransparency(uint32 MatSet)
MatSet = mMaterialSets.size() - 1; MatSet = mMaterialSets.size() - 1;
for (uint32 iMat = 0; iMat < mMaterialSets[MatSet]->NumMaterials(); iMat++) 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; return false;
} }
@ -274,7 +288,7 @@ bool CModel::IsSurfaceTransparent(uint32 Surface, uint32 MatSet)
MatSet = mMaterialSets.size() - 1; MatSet = mMaterialSets.size() - 1;
uint32 matID = mSurfaces[Surface]->MaterialID; 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 bool CModel::IsLightmapped() const
@ -285,7 +299,7 @@ bool CModel::IsLightmapped() const
for (uint32 iMat = 0; iMat < pSet->NumMaterials(); iMat++) 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)) if (pMat->Options().HasFlag(EMaterialOption::Lightmap))
return true; return true;
} }

View File

@ -63,7 +63,7 @@ void CCharacterNode::Draw(FRenderOptions Options, int ComponentIndex, ERenderCom
CGraphics::UpdateLightBlock(); CGraphics::UpdateLightBlock();
CGraphics::sVertexBlock.COLOR0_Amb = CGraphics::skDefaultAmbientColor; CGraphics::sVertexBlock.COLOR0_Amb = CGraphics::skDefaultAmbientColor;
CGraphics::sPixelBlock.LightmapMultiplier = 1.f; CGraphics::sPixelBlock.LightmapMultiplier = 1.f;
CGraphics::sPixelBlock.TevColor = CColor::skWhite; CGraphics::sPixelBlock.SetAllTevColors(CColor::skWhite);
CGraphics::sPixelBlock.TintColor = TintColor(rkViewInfo); CGraphics::sPixelBlock.TintColor = TintColor(rkViewInfo);
LoadModelMatrix(); LoadModelMatrix();

View File

@ -66,7 +66,7 @@ void CModelNode::Draw(FRenderOptions Options, int ComponentIndex, ERenderCommand
CGraphics::UpdateLightBlock(); CGraphics::UpdateLightBlock();
CGraphics::sVertexBlock.COLOR0_Amb = CGraphics::skDefaultAmbientColor; CGraphics::sVertexBlock.COLOR0_Amb = CGraphics::skDefaultAmbientColor;
CGraphics::sPixelBlock.LightmapMultiplier = 1.f; CGraphics::sPixelBlock.LightmapMultiplier = 1.f;
CGraphics::sPixelBlock.TevColor = CColor::skWhite; CGraphics::sPixelBlock.SetAllTevColors(CColor::skWhite);
} }
else else
{ {
@ -88,7 +88,7 @@ void CModelNode::Draw(FRenderOptions Options, int ComponentIndex, ERenderCommand
} }
float Mul = CGraphics::sWorldLightMultiplier; float Mul = CGraphics::sWorldLightMultiplier;
CGraphics::sPixelBlock.TevColor = CColor(Mul,Mul,Mul); CGraphics::sPixelBlock.SetAllTevColors(CColor(Mul,Mul,Mul));
} }
CGraphics::sPixelBlock.TintColor = TintColor(rkViewInfo); CGraphics::sPixelBlock.TintColor = TintColor(rkViewInfo);

View File

@ -93,7 +93,7 @@ void CScriptAttachNode::Draw(FRenderOptions Options, int /*ComponentIndex*/, ERe
CGraphics::UpdateVertexBlock(); CGraphics::UpdateVertexBlock();
CGraphics::sPixelBlock.TintColor = mpParent->TintColor(rkViewInfo); CGraphics::sPixelBlock.TintColor = mpParent->TintColor(rkViewInfo);
CGraphics::sPixelBlock.TevColor = CColor::skWhite; CGraphics::sPixelBlock.SetAllTevColors(CColor::skWhite);
CGraphics::UpdatePixelBlock(); CGraphics::UpdatePixelBlock();
DrawModelParts(Model(), Options, 0, Command); DrawModelParts(Model(), Options, 0, Command);
} }

View File

@ -207,8 +207,8 @@ void CScriptNode::Draw(FRenderOptions Options, int /*ComponentIndex*/, ERenderCo
{ {
if (pModel->IsSkinned()) CGraphics::LoadIdentityBoneTransforms(); if (pModel->IsSkinned()) CGraphics::LoadIdentityBoneTransforms();
if (mpExtra) CGraphics::sPixelBlock.TevColor = mpExtra->TevColor(); if (mpExtra) CGraphics::sPixelBlock.SetAllTevColors(mpExtra->TevColor());
else CGraphics::sPixelBlock.TevColor = CColor::skWhite; else CGraphics::sPixelBlock.SetAllTevColors(CColor::skWhite);
CGraphics::sPixelBlock.TintColor = TintColor(rkViewInfo); CGraphics::sPixelBlock.TintColor = TintColor(rkViewInfo);
CGraphics::UpdatePixelBlock(); CGraphics::UpdatePixelBlock();

View File

@ -75,7 +75,7 @@ void CStaticNode::Draw(FRenderOptions Options, int ComponentIndex, ERenderComman
} }
float Mul = CGraphics::sWorldLightMultiplier; float Mul = CGraphics::sWorldLightMultiplier;
CGraphics::sPixelBlock.TevColor = CColor(Mul,Mul,Mul); CGraphics::sPixelBlock.SetAllTevColors(CColor(Mul,Mul,Mul));
CGraphics::sPixelBlock.TintColor = TintColor(rkViewInfo); CGraphics::sPixelBlock.TintColor = TintColor(rkViewInfo);
LoadModelMatrix(); LoadModelMatrix();

View File

@ -79,7 +79,7 @@ void CDoorExtra::Draw(FRenderOptions Options, int /*ComponentIndex*/, ERenderCom
CColor Tint = mpParent->TintColor(rkViewInfo) * mShieldColor; CColor Tint = mpParent->TintColor(rkViewInfo) * mShieldColor;
CGraphics::sPixelBlock.TintColor = Tint; CGraphics::sPixelBlock.TintColor = Tint;
CGraphics::sPixelBlock.TevColor = CColor::skWhite; CGraphics::sPixelBlock.SetAllTevColors(CColor::skWhite);
CGraphics::UpdatePixelBlock(); CGraphics::UpdatePixelBlock();
DrawModelParts(mpShieldModel, Options, 0, Command); DrawModelParts(mpShieldModel, Options, 0, Command);
} }

View File

@ -8,6 +8,7 @@
#include <iostream> #include <iostream>
#include <QApplication> #include <QApplication>
#include <QDesktopWidget> #include <QDesktopWidget>
#include <QScreen>
CGizmo::CGizmo() CGizmo::CGizmo()
: mSelectedAxes(EAxis::None) : mSelectedAxes(EAxis::None)
@ -280,7 +281,7 @@ bool CGizmo::TransformFromInput(const CRay& rkRay, CCamera& rCamera)
// Calculate normalized cursor position // Calculate normalized cursor position
QPoint CursorPos = QCursor::pos(); QPoint CursorPos = QCursor::pos();
QRect Geom = QApplication::desktop()->screenGeometry(); QRect Geom = QApplication::screenAt(CursorPos)->geometry();
CVector2f MouseCoords( CVector2f MouseCoords(
(((2.f * CursorPos.x()) / Geom.width()) - 1.f), (((2.f * CursorPos.x()) / Geom.width()) - 1.f),
(1.f - ((2.f * CursorPos.y()) / Geom.height())) (1.f - ((2.f * CursorPos.y()) / Geom.height()))
@ -617,8 +618,8 @@ void CGizmo::UpdateTransform()
void CGizmo::WrapCursor() void CGizmo::WrapCursor()
{ {
QRect Geom = QApplication::desktop()->screenGeometry();
QPoint CursorPos = QCursor::pos(); QPoint CursorPos = QCursor::pos();
QRect Geom = QApplication::screenAt(CursorPos)->geometry();
// Horizontal // Horizontal
if (CursorPos.x() == Geom.width() - 1) if (CursorPos.x() == Geom.width() - 1)

View File

@ -130,7 +130,7 @@ void CTweakEditor::OnProjectChanged(CGameProject* pNewProject)
// Sort in alphabetical order and create tabs // Sort in alphabetical order and create tabs
if (!mTweakAssets.isEmpty()) 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(); return pLeft->TweakName().ToUpper() < pRight->TweakName().ToUpper();
}); });

View File

@ -6,7 +6,8 @@ CCharacterEditorViewport::CCharacterEditorViewport(QWidget *pParent /*= 0*/)
, mGridEnabled(true) , mGridEnabled(true)
{ {
mpRenderer = new CRenderer(); 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->SetClearColor(CColor(0.3f, 0.3f, 0.3f));
mpRenderer->ToggleGrid(true); mpRenderer->ToggleGrid(true);
@ -63,7 +64,8 @@ void CCharacterEditorViewport::Paint()
void CCharacterEditorViewport::OnResize() void CCharacterEditorViewport::OnResize()
{ {
mpRenderer->SetViewportSize(width(), height()); qreal pixelRatio = devicePixelRatioF();
mpRenderer->SetViewportSize(width() * pixelRatio, height() * pixelRatio);
} }
void CCharacterEditorViewport::OnMouseClick(QMouseEvent *pEvent) void CCharacterEditorViewport::OnMouseClick(QMouseEvent *pEvent)

View File

@ -6,7 +6,8 @@ CCollisionEditorViewport::CCollisionEditorViewport(QWidget* pParent /*= 0*/)
, mGridEnabled(true) , mGridEnabled(true)
{ {
mpRenderer = std::make_unique<CRenderer>(); mpRenderer = std::make_unique<CRenderer>();
mpRenderer->SetViewportSize(width(), height()); qreal pixelRatio = devicePixelRatioF();
mpRenderer->SetViewportSize(width() * pixelRatio, height() * pixelRatio);
mpRenderer->SetClearColor(CColor(0.3f, 0.3f, 0.3f)); mpRenderer->SetClearColor(CColor(0.3f, 0.3f, 0.3f));
mpRenderer->ToggleGrid(true); mpRenderer->ToggleGrid(true);

View File

@ -9,7 +9,8 @@ CModelEditorViewport::CModelEditorViewport(QWidget *pParent)
, mGridEnabled(true) , mGridEnabled(true)
{ {
mpRenderer = new CRenderer(); mpRenderer = new CRenderer();
mpRenderer->SetViewportSize(width(), height()); qreal pixelRatio = devicePixelRatioF();
mpRenderer->SetViewportSize(width() * pixelRatio, height() * pixelRatio);
mpRenderer->SetClearColor(CColor::skBlack); mpRenderer->SetClearColor(CColor::skBlack);
mpRenderer->ToggleGrid(true); mpRenderer->ToggleGrid(true);
@ -109,5 +110,6 @@ void CModelEditorViewport::Paint()
void CModelEditorViewport::OnResize() void CModelEditorViewport::OnResize()
{ {
mpRenderer->SetViewportSize(width(), height()); qreal pixelRatio = devicePixelRatioF();
mpRenderer->SetViewportSize(width() * pixelRatio, height() * pixelRatio);
} }

View File

@ -241,7 +241,7 @@ void CPropertyView::ClosePersistentEditors(const QModelIndex& rkIndex)
for (uint32 iChild = 0; iChild < NumChildren; iChild++) for (uint32 iChild = 0; iChild < NumChildren; iChild++)
{ {
QModelIndex ChildIndex = rkIndex.child(iChild, 1); QModelIndex ChildIndex = mpModel->index(iChild, 1, rkIndex);
closePersistentEditor(ChildIndex); closePersistentEditor(ChildIndex);
if (mpModel->rowCount(ChildIndex) != 0) if (mpModel->rowCount(ChildIndex) != 0)

View File

@ -268,7 +268,7 @@ void CResourceBrowser::CreateFilterCheckboxes()
mTypeList << SResourceType { pType, pCheck }; 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(); return rkLeft.pTypeInfo->TypeName().ToUpper() < rkRight.pTypeInfo->TypeName().ToUpper();
}); });

View File

@ -53,7 +53,7 @@ void CDeleteLinksCommand::undo()
} }
// Add to senders // 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++) for (int iLink = 0; iLink < NewLinks.size(); iLink++)
{ {
@ -62,7 +62,7 @@ void CDeleteLinksCommand::undo()
} }
// Add to receivers // 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++) for (int iLink = 0; iLink < NewLinks.size(); iLink++)
{ {

View File

@ -111,7 +111,7 @@ void CDeleteSelectionCommand::undo()
} }
// Sort links by sender index, add outgoing // 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); return (rLeft.SenderIndex < rRight.SenderIndex);
}); });
@ -128,7 +128,7 @@ void CDeleteSelectionCommand::undo()
} }
// Sort links by receiver index, add incoming // 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); return (rLeft.ReceiverIndex < rRight.ReceiverIndex);
}); });

View File

@ -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(); return pA->UppercaseName() < pB->UppercaseName();
}); });

View File

@ -581,7 +581,7 @@ void CInstancesModel::GenerateList()
mTemplateList << pTemp; 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()); return (pLeft->Name() < pRight->Name());
}); });
} }

View File

@ -87,7 +87,7 @@ public:
} }
} }
qSort(mEntries); std::sort(mEntries.begin(), mEntries.end());
endResetModel(); endResetModel();
} }

View File

@ -67,7 +67,7 @@ public:
for (uint32 iTemp = 0; iTemp < mpGame->NumScriptTemplates(); iTemp++) for (uint32 iTemp = 0; iTemp < mpGame->NumScriptTemplates(); iTemp++)
mTemplates << mpGame->TemplateByIndex(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(); return pLeft->Name() < pRight->Name();
}); });
} }

View File

@ -257,7 +257,7 @@ void CWorldTreeModel::OnProjectChanged(CGameProject *pProj)
// Sort in alphabetical order for MP3 // Sort in alphabetical order for MP3
if (pProj->Game() >= EGame::Corruption) 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()); return (rkA.WorldName.toUpper() < rkB.WorldName.toUpper());
}); });
} }
@ -333,7 +333,7 @@ void CWorldTreeModel::OnProjectChanged(CGameProject *pProj)
} }
// Sort FrontEnd world // 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(); return pA->UppercaseName() < pB->UppercaseName();
}); });
} }

View File

@ -347,7 +347,7 @@ void WInstancesTab::OnUnhideAll()
It->SetVisible(true); It->SetVisible(true);
// Unhide layers // 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()) if (LayersRoot.isValid())
{ {
@ -360,7 +360,7 @@ void WInstancesTab::OnUnhideAll()
} }
// Unhide types // 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()) if (TypesRoot.isValid())
{ {