diff --git a/hecl/blender/hecl/hmdl/__init__.py b/hecl/blender/hecl/hmdl/__init__.py index 1e87833b6..003421e72 100644 --- a/hecl/blender/hecl/hmdl/__init__.py +++ b/hecl/blender/hecl/hmdl/__init__.py @@ -31,6 +31,11 @@ def write_out_material(writebuf, mat, mesh_obj): transparent = True writebuf(struct.pack('b', int(transparent))) +# If this returns true, the material geometry will be split into contiguous faces +def should_split_into_contiguous_faces(mat): + return mat.game_settings.alpha_blend != 'OPAQUE' and \ + 'retro_depth_sort' in mat and mat['retro_depth_sort'] + # Takes a Blender 'Mesh' object (not the datablock) # and performs a one-shot conversion process to HMDL def cook(writebuf, mesh_obj, output_mode, max_skin_banks, use_luv=False): @@ -125,7 +130,7 @@ def cook(writebuf, mesh_obj, output_mode, max_skin_banks, use_luv=False): # Generate material meshes (if opaque) for mat_idx in sorted_material_idxs: mat = mesh_obj.data.materials[mat_idx] - if mat.game_settings.alpha_blend != 'OPAQUE': + if should_split_into_contiguous_faces(mat): continue mat_faces_rem = [] for face in bm_master.faces: @@ -161,7 +166,7 @@ def cook(writebuf, mesh_obj, output_mode, max_skin_banks, use_luv=False): # Generate island meshes (if transparent) for mat_idx in sorted_material_idxs: mat = mesh_obj.data.materials[mat_idx] - if mat.game_settings.alpha_blend == 'OPAQUE': + if not should_split_into_contiguous_faces(mat): continue mat_faces_rem = [] for face in bm_master.faces: diff --git a/hecl/include/hecl/Backend/GLSL.hpp b/hecl/include/hecl/Backend/GLSL.hpp index 8c5760c0b..a939577aa 100644 --- a/hecl/include/hecl/Backend/GLSL.hpp +++ b/hecl/include/hecl/Backend/GLSL.hpp @@ -16,10 +16,12 @@ struct GLSL : ProgrammableCommon const TextureInfo* extTexs, ReflectionType reflectionType) const; std::string makeFrag(size_t blockCount, const char** blockNames, bool alphaTest, ReflectionType reflectionType, + BlendFactor srcFactor, BlendFactor dstFactor, const Function& lighting=Function()) const; std::string makeFrag(size_t blockCount, const char** blockNames, bool alphaTest, ReflectionType reflectionType, + BlendFactor srcFactor, BlendFactor dstFactor, const Function& lighting, const Function& post, size_t extTexCount, const TextureInfo* extTexs) const; diff --git a/hecl/include/hecl/Backend/HLSL.hpp b/hecl/include/hecl/Backend/HLSL.hpp index d5c97da9c..a55106924 100644 --- a/hecl/include/hecl/Backend/HLSL.hpp +++ b/hecl/include/hecl/Backend/HLSL.hpp @@ -13,9 +13,11 @@ struct HLSL : ProgrammableCommon const TextureInfo* extTexs, ReflectionType reflectionType) const; std::string makeFrag(size_t blockCount, const char** blockNames, bool alphaTest, ReflectionType reflectionType, + BlendFactor srcFactor, BlendFactor dstFactor, const Function& lighting=Function()) const; std::string makeFrag(size_t blockCount, const char** blockNames, bool alphaTest, ReflectionType reflectionType, + BlendFactor srcFactor, BlendFactor dstFactor, const Function& lighting, const Function& post, size_t extTexCount, const TextureInfo* extTexs) const; diff --git a/hecl/include/hecl/Backend/Metal.hpp b/hecl/include/hecl/Backend/Metal.hpp index 49a1a0996..6b3074748 100644 --- a/hecl/include/hecl/Backend/Metal.hpp +++ b/hecl/include/hecl/Backend/Metal.hpp @@ -13,9 +13,12 @@ struct Metal : ProgrammableCommon const TextureInfo* extTexs, ReflectionType reflectionType) const; std::string makeFrag(size_t blockCount, const char** blockNames, bool alphaTest, ReflectionType reflectionType, + BlendFactor srcFactor, BlendFactor dstFactor, const Function& lighting=Function()) const; std::string makeFrag(size_t blockCount, const char** blockNames, bool alphaTest, - ReflectionType reflectionType, const Function& lighting, + ReflectionType reflectionType, + BlendFactor srcFactor, BlendFactor dstFactor, + const Function& lighting, const Function& post, size_t extTexCount, const TextureInfo* extTexs) const; diff --git a/hecl/include/hecl/Backend/ProgrammableCommon.hpp b/hecl/include/hecl/Backend/ProgrammableCommon.hpp index a058e6815..928a239c9 100644 --- a/hecl/include/hecl/Backend/ProgrammableCommon.hpp +++ b/hecl/include/hecl/Backend/ProgrammableCommon.hpp @@ -42,6 +42,8 @@ struct ProgrammableCommon : IBackend using IBackend::reset; void reset(const IR& ir, Diagnostics& diag, const char* backendName); + static const char* BlendFactorToDefine(BlendFactor factor, BlendFactor defaultFactor); + private: unsigned addTexCoordGen(TexGenSrc src, int uvIdx, int mtx, bool normalize); unsigned addTexSampling(unsigned mapIdx, unsigned tcgIdx); diff --git a/hecl/include/hecl/Pipeline.hpp b/hecl/include/hecl/Pipeline.hpp index 3d6a7f94e..6fa5bd859 100644 --- a/hecl/include/hecl/Pipeline.hpp +++ b/hecl/include/hecl/Pipeline.hpp @@ -79,7 +79,8 @@ public: { return m_backend.makeFrag(m_extension.blockCount, m_extension.blockNames, m_tag.getDepthWrite() && m_backend.m_blendDst == hecl::Backend::BlendFactor::InvSrcAlpha, - m_tag.getReflectionType(), m_extension.lighting, m_extension.post, + m_tag.getReflectionType(), m_backend.m_blendSrc, m_backend.m_blendDst, + m_extension.lighting, m_extension.post, m_extension.texCount, m_extension.texs); } const hecl::Backend::ShaderTag& getTag() const { return m_tag; } diff --git a/hecl/lib/Backend/GLSL.cpp b/hecl/lib/Backend/GLSL.cpp index 7586647c9..b4a64a152 100644 --- a/hecl/lib/Backend/GLSL.cpp +++ b/hecl/lib/Backend/GLSL.cpp @@ -221,7 +221,8 @@ std::string GLSL::makeVert(unsigned col, unsigned uv, unsigned w, } std::string GLSL::makeFrag(size_t blockCount, const char** blockNames, bool alphaTest, - ReflectionType reflectionType, const Function& lighting) const + ReflectionType reflectionType, BlendFactor srcFactor, BlendFactor dstFactor, + const Function& lighting) const { std::string lightingSrc; if (!lighting.m_source.empty()) @@ -246,6 +247,8 @@ std::string GLSL::makeFrag(size_t blockCount, const char** blockNames, bool alph std::string retval = std::string("#extension GL_ARB_shader_image_load_store: enable\n") + + "#define BLEND_SRC_" + BlendFactorToDefine(srcFactor, m_blendSrc) + "\n" + + "#define BLEND_DST_" + BlendFactorToDefine(dstFactor, m_blendDst) + "\n" + GenerateVertToFragStruct(0, reflectionType != ReflectionType::None) + (!alphaTest ? "#ifdef GL_ARB_shader_image_load_store\n" @@ -285,6 +288,7 @@ std::string GLSL::makeFrag(size_t blockCount, const char** blockNames, bool alph std::string GLSL::makeFrag(size_t blockCount, const char** blockNames, bool alphaTest, ReflectionType reflectionType, + BlendFactor srcFactor, BlendFactor dstFactor, const Function& lighting, const Function& post, size_t extTexCount, const TextureInfo* extTexs) const @@ -327,6 +331,8 @@ std::string GLSL::makeFrag(size_t blockCount, const char** blockNames, std::string retval = std::string("#extension GL_ARB_shader_image_load_store: enable\n") + + "#define BLEND_SRC_" + BlendFactorToDefine(srcFactor, m_blendSrc) + "\n" + + "#define BLEND_DST_" + BlendFactorToDefine(dstFactor, m_blendDst) + "\n" + GenerateVertToFragStruct(extTexCount, reflectionType != ReflectionType::None) + (!alphaTest ? "\n#ifdef GL_ARB_shader_image_load_store\n" diff --git a/hecl/lib/Backend/HLSL.cpp b/hecl/lib/Backend/HLSL.cpp index 5dd8dc22b..c63b6be5f 100644 --- a/hecl/lib/Backend/HLSL.cpp +++ b/hecl/lib/Backend/HLSL.cpp @@ -216,6 +216,7 @@ std::string HLSL::makeVert(unsigned col, unsigned uv, unsigned w, std::string HLSL::makeFrag(size_t blockCount, const char** blockNames, bool alphaTest, ReflectionType reflectionType, + BlendFactor srcFactor, BlendFactor dstFactor, const Function& lighting) const { std::string lightingSrc; @@ -238,6 +239,8 @@ std::string HLSL::makeFrag(size_t blockCount, const char** blockNames, texMapDecl += hecl::Format("Texture2D reflectionTex : register(t%u);\n", m_texMapEnd); std::string retval = + std::string("#define BLEND_SRC_") + BlendFactorToDefine(srcFactor, m_blendSrc) + "\n" + + "#define BLEND_DST_" + BlendFactorToDefine(dstFactor, m_blendDst) + "\n" + "SamplerState samp : register(s0);\n" "SamplerState clampSamp : register(s1);\n" "SamplerState reflectSamp : register(s2);\n" + @@ -275,6 +278,7 @@ std::string HLSL::makeFrag(size_t blockCount, const char** blockNames, std::string HLSL::makeFrag(size_t blockCount, const char** blockNames, bool alphaTest, ReflectionType reflectionType, + BlendFactor srcFactor, BlendFactor dstFactor, const Function& lighting, const Function& post, size_t extTexCount, const TextureInfo* extTexs) const @@ -315,6 +319,8 @@ std::string HLSL::makeFrag(size_t blockCount, const char** blockNames, } std::string retval = + std::string("#define BLEND_SRC_") + BlendFactorToDefine(srcFactor, m_blendSrc) + "\n" + + "#define BLEND_DST_" + BlendFactorToDefine(dstFactor, m_blendDst) + "\n" + "SamplerState samp : register(s0);\n" "SamplerState clampSamp : register(s1);\n" "SamplerState reflectSamp : register(s2);\n" + diff --git a/hecl/lib/Backend/Metal.cpp b/hecl/lib/Backend/Metal.cpp index 99a227f4c..2a8c5814d 100644 --- a/hecl/lib/Backend/Metal.cpp +++ b/hecl/lib/Backend/Metal.cpp @@ -222,7 +222,9 @@ std::string Metal::makeVert(unsigned col, unsigned uv, unsigned w, } std::string Metal::makeFrag(size_t blockCount, const char** blockNames, bool alphaTest, - ReflectionType reflectionType, const Function& lighting) const + ReflectionType reflectionType, + BlendFactor srcFactor, BlendFactor dstFactor, + const Function& lighting) const { std::string lightingSrc; if (!lighting.m_source.empty()) @@ -249,7 +251,9 @@ std::string Metal::makeFrag(size_t blockCount, const char** blockNames, bool alp blockCall += hecl::Format("block%" PRISize, i); } - std::string retval = "#include \nusing namespace metal;\n" + + std::string retval = std::string("#include \nusing namespace metal;\n") + + "#define BLEND_SRC_" + BlendFactorToDefine(srcFactor, m_blendSrc) + "\n" + + "#define BLEND_DST_" + BlendFactorToDefine(dstFactor, m_blendDst) + "\n" + GenerateVertToFragStruct(0, reflectionType != ReflectionType::None) + "\n" + GenerateFragOutStruct() + "\n" + lightingSrc + "\n" + @@ -301,7 +305,9 @@ std::string Metal::makeFrag(size_t blockCount, const char** blockNames, bool alp } std::string Metal::makeFrag(size_t blockCount, const char** blockNames, bool alphaTest, - ReflectionType reflectionType, const Function& lighting, + ReflectionType reflectionType, + BlendFactor srcFactor, BlendFactor dstFactor, + const Function& lighting, const Function& post, size_t extTexCount, const TextureInfo* extTexs) const { @@ -361,7 +367,9 @@ std::string Metal::makeFrag(size_t blockCount, const char** blockNames, bool alp blockCall += hecl::Format("block%" PRISize, i); } - std::string retval = "#include \nusing namespace metal;\n" + + std::string retval = std::string("#include \nusing namespace metal;\n") + + "#define BLEND_SRC_" + BlendFactorToDefine(srcFactor, m_blendSrc) + "\n" + + "#define BLEND_DST_" + BlendFactorToDefine(dstFactor, m_blendDst) + "\n" + GenerateVertToFragStruct(extTexCount, reflectionType != ReflectionType::None) + "\n" + GenerateFragOutStruct() + "\n" + lightingSrc + "\n" + diff --git a/hecl/lib/Backend/ProgrammableCommon.cpp b/hecl/lib/Backend/ProgrammableCommon.cpp index 540d91935..f516f6e76 100644 --- a/hecl/lib/Backend/ProgrammableCommon.cpp +++ b/hecl/lib/Backend/ProgrammableCommon.cpp @@ -4,6 +4,39 @@ namespace hecl::Backend { +const char* ProgrammableCommon::BlendFactorToDefine(BlendFactor factor, BlendFactor defaultFactor) +{ + switch (factor) + { + case BlendFactor::Zero: + return "ZERO"; + case BlendFactor::One: + return "ONE"; + case BlendFactor::SrcColor: + return "SRCCOLOR"; + case BlendFactor::InvSrcColor: + return "INVSRCCOLOR"; + case BlendFactor::DstColor: + return "DSTCOLOR"; + case BlendFactor::InvDstColor: + return "INVDSTCOLOR"; + case BlendFactor::SrcAlpha: + return "SRCALPHA"; + case BlendFactor::InvSrcAlpha: + return "INVSRCALPHA"; + case BlendFactor::DstAlpha: + return "DSTALPHA"; + case BlendFactor::InvDstAlpha: + return "INVDSTALPHA"; + case BlendFactor::SrcColor1: + return "SRCCOLOR1"; + case BlendFactor::InvSrcColor1: + return "INVSRCCOLOR1"; + default: + return BlendFactorToDefine(defaultFactor, BlendFactor::Zero); + } +} + unsigned ProgrammableCommon::addTexCoordGen(TexGenSrc src, int uvIdx, int mtx, bool normalize) { for (unsigned i=0 ; i