Accurate MP3 material processing
This commit is contained in:
parent
79ec379c66
commit
6e3b23ec50
|
@ -7,8 +7,15 @@
|
|||
<option name="NAMESPACE_BRACE_PLACEMENT" value="2" />
|
||||
<option name="FUNCTION_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>
|
||||
<codeStyleSettings language="ObjectiveC">
|
||||
<option name="BLANK_LINES_AROUND_METHOD_IN_INTERFACE" value="0" />
|
||||
<option name="BRACE_STYLE" value="2" />
|
||||
<option name="CLASS_BRACE_STYLE" value="2" />
|
||||
</codeStyleSettings>
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 8393432003b8e634cba4e89c27635fec0ae43a6f
|
||||
Subproject commit f914e4b9c422de49e573607a217b25152b3e6f20
|
|
@ -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++)
|
||||
{
|
||||
|
|
|
@ -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,7 +460,7 @@ 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
|
||||
|
@ -440,8 +470,9 @@ bool CShaderGenerator::CreatePixelShader(const CMaterial& rkMat)
|
|||
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 +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'
|
||||
|
||||
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 +501,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 +509,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)
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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<CStaticModel*>::iterator it = mStaticWorldModels.begin(); it != mStaticWorldModels.end(); it++)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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<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
|
||||
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(); }
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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<CTexture> 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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#ifndef ETEVENUMS
|
||||
#define ETEVENUMS
|
||||
|
||||
#include <Common/BasicTypes.h>
|
||||
|
||||
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,
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -8,6 +8,105 @@
|
|||
#include <Common/FileIO.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
|
||||
{
|
||||
// Material data
|
||||
|
@ -15,13 +114,10 @@ class CMaterialLoader
|
|||
IInputStream *mpFile;
|
||||
EGame mVersion;
|
||||
std::vector<TResPtr<CTexture>> mTextures;
|
||||
bool mHasOPAC;
|
||||
bool mHas0x400;
|
||||
|
||||
CColor mCorruptionColors[4];
|
||||
uint8 mCorruptionInts[5];
|
||||
uint32 mCorruptionFlags;
|
||||
std::vector<uint32> mPassOffsets;
|
||||
|
||||
CMaterialLoader();
|
||||
~CMaterialLoader();
|
||||
|
@ -33,7 +129,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);
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <iostream>
|
||||
#include <QApplication>
|
||||
#include <QDesktopWidget>
|
||||
#include <QScreen>
|
||||
|
||||
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)
|
||||
|
|
|
@ -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();
|
||||
});
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -6,7 +6,8 @@ CCollisionEditorViewport::CCollisionEditorViewport(QWidget* pParent /*= 0*/)
|
|||
, mGridEnabled(true)
|
||||
{
|
||||
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->ToggleGrid(true);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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();
|
||||
});
|
||||
|
||||
|
|
|
@ -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++)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
|
||||
|
|
|
@ -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();
|
||||
});
|
||||
|
||||
|
|
|
@ -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());
|
||||
});
|
||||
}
|
||||
|
|
|
@ -87,7 +87,7 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
qSort(mEntries);
|
||||
std::sort(mEntries.begin(), mEntries.end());
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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())
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue