mirror of https://github.com/AxioDL/metaforce.git
macOS decal rendering support
This commit is contained in:
parent
08569104c2
commit
7100ed437f
|
@ -51,7 +51,7 @@ void DeafBabe::BlenderInit(hecl::blender::PyOutStream& os)
|
|||
"bpy.types.Material.retro_half_pipe = bpy.props.BoolProperty(name='Retro: Half Pipe (H)')\n"
|
||||
"bpy.types.Material.retro_surface_mud = bpy.props.BoolProperty(name='Retro Surface: Mud')\n"
|
||||
"bpy.types.Material.retro_surface_glass = bpy.props.BoolProperty(name='Retro Surface: Glass')\n"
|
||||
"bpy.types.Material.retro_surface_shield = bpy.props.BoolProperty(name='Retro Surface: Sheild')\n"
|
||||
"bpy.types.Material.retro_surface_shield = bpy.props.BoolProperty(name='Retro Surface: Shield')\n"
|
||||
"bpy.types.Material.retro_surface_sand = bpy.props.BoolProperty(name='Retro Surface: Sand')\n"
|
||||
"bpy.types.Material.retro_projectile_passthrough = bpy.props.BoolProperty(name='Retro: Projectile Passthrough (P)')\n"
|
||||
"bpy.types.Material.retro_solid = bpy.props.BoolProperty(name='Retro: Solid (K)')\n"
|
||||
|
|
|
@ -53,7 +53,7 @@ void DeafBabe::BlenderInit(hecl::blender::PyOutStream& os)
|
|||
"bpy.types.Material.retro_unused4 = bpy.props.BoolProperty(description='Retro: Unused 4 (U)')\n"
|
||||
"bpy.types.Material.retro_surface_mud = bpy.props.BoolProperty(description='Retro Surface: Mud')\n"
|
||||
"bpy.types.Material.retro_surface_glass = bpy.props.BoolProperty(description='Retro Surface: Glass')\n"
|
||||
"bpy.types.Material.retro_surface_shield = bpy.props.BoolProperty(description='Retro Surface: Sheild')\n"
|
||||
"bpy.types.Material.retro_surface_shield = bpy.props.BoolProperty(description='Retro Surface: Shield')\n"
|
||||
"bpy.types.Material.retro_surface_sand = bpy.props.BoolProperty(description='Retro Surface: Sand')\n"
|
||||
"bpy.types.Material.retro_surface_moth_or_seed_organics = bpy.props.BoolProperty(description='Retro Surface: Moth/Seed Organics')\n"
|
||||
"bpy.types.Material.retro_surface_web = bpy.props.BoolProperty(description='Retro Surface: Web')\n"
|
||||
|
|
|
@ -182,6 +182,32 @@ CCollisionResponseData::CCollisionResponseData(CInputStream& in, CSimplePool* re
|
|||
const rstl::optional_object<TLockedToken<CGenDescription>>&
|
||||
CCollisionResponseData::GetParticleDescription(EWeaponCollisionResponseTypes type) const
|
||||
{
|
||||
if (x0_generators[u32(type)])
|
||||
return x0_generators[u32(type)];
|
||||
|
||||
bool foundType = false;
|
||||
if (ResponseTypeIsEnemyNormal(type))
|
||||
{
|
||||
type = EWeaponCollisionResponseTypes::EnemyNormal;
|
||||
foundType = true;
|
||||
}
|
||||
else if (ResponseTypeIsEnemySpecial(type))
|
||||
{
|
||||
type = EWeaponCollisionResponseTypes::EnemySpecial;
|
||||
foundType = true;
|
||||
}
|
||||
else if (ResponseTypeIsEnemyShielded(type))
|
||||
{
|
||||
type = EWeaponCollisionResponseTypes::EnemyShielded;
|
||||
foundType = true;
|
||||
}
|
||||
|
||||
if (foundType && !x0_generators[u32(type)])
|
||||
type = EWeaponCollisionResponseTypes::EnemyNormal;
|
||||
|
||||
if (!x0_generators[u32(type)] && type != EWeaponCollisionResponseTypes::None)
|
||||
type = EWeaponCollisionResponseTypes::Default;
|
||||
|
||||
return x0_generators[u32(type)];
|
||||
}
|
||||
|
||||
|
@ -210,9 +236,8 @@ s32 CCollisionResponseData::GetSoundEffectId(EWeaponCollisionResponseTypes type)
|
|||
|
||||
EWeaponCollisionResponseTypes CCollisionResponseData::GetWorldCollisionResponseType(s32 id)
|
||||
{
|
||||
if (id < 0 || id >= s32(EWeaponCollisionResponseTypes::Unknown32))
|
||||
if (id < 0 || id >= 32)
|
||||
return EWeaponCollisionResponseTypes::Default;
|
||||
|
||||
return skWorldMaterialTable[id];
|
||||
}
|
||||
|
||||
|
|
|
@ -1039,7 +1039,8 @@ void CBooRenderer::AddPlaneObject(const void*, const zeus::CAABox&, const zeus::
|
|||
|
||||
}
|
||||
|
||||
void CBooRenderer::AddDrawable(const void* obj, const zeus::CVector3f& pos, const zeus::CAABox& aabb, int mode, EDrawableSorting sorting)
|
||||
void CBooRenderer::AddDrawable(const void* obj, const zeus::CVector3f& pos, const zeus::CAABox& aabb,
|
||||
int mode, EDrawableSorting sorting)
|
||||
{
|
||||
if (sorting == EDrawableSorting::UnsortedCallback)
|
||||
xa8_drawableCallback(obj, xac_callbackContext, mode);
|
||||
|
|
|
@ -19,6 +19,7 @@ if(WIN32)
|
|||
Shaders/CScanLinesFilterHLSL.cpp
|
||||
Shaders/CRandomStaticFilterHLSL.cpp
|
||||
Shaders/CElementGenShadersHLSL.cpp
|
||||
Shaders/CDecalShadersHLSL.cpp
|
||||
Shaders/CParticleSwooshShadersHLSL.cpp
|
||||
Shaders/CFluidPlaneShaderHLSL.cpp
|
||||
Shaders/CAABoxShaderHLSL.cpp
|
||||
|
@ -44,6 +45,7 @@ elseif(BOO_HAS_METAL)
|
|||
Shaders/CScanLinesFilterMetal.cpp
|
||||
Shaders/CRandomStaticFilterMetal.cpp
|
||||
Shaders/CElementGenShadersMetal.cpp
|
||||
Shaders/CDecalShadersMetal.cpp
|
||||
Shaders/CParticleSwooshShadersMetal.cpp
|
||||
Shaders/CFluidPlaneShaderMetal.cpp
|
||||
Shaders/CAABoxShaderMetal.cpp
|
||||
|
@ -71,6 +73,7 @@ if(NOT WINDOWS_STORE)
|
|||
Shaders/CScanLinesFilterGLSL.cpp
|
||||
Shaders/CRandomStaticFilterGLSL.cpp
|
||||
Shaders/CElementGenShadersGLSL.cpp
|
||||
Shaders/CDecalShadersGLSL.cpp
|
||||
Shaders/CParticleSwooshShadersGLSL.cpp
|
||||
Shaders/CFluidPlaneShaderGLSL.cpp
|
||||
Shaders/CAABoxShaderGLSL.cpp
|
||||
|
@ -119,6 +122,7 @@ set(GRAPHICS_SOURCES
|
|||
Shaders/CScanLinesFilter.hpp Shaders/CScanLinesFilter.cpp
|
||||
Shaders/CRandomStaticFilter.hpp Shaders/CRandomStaticFilter.cpp
|
||||
Shaders/CElementGenShaders.hpp Shaders/CElementGenShaders.cpp
|
||||
Shaders/CDecalShaders.hpp Shaders/CDecalShaders.cpp
|
||||
Shaders/CParticleSwooshShaders.hpp Shaders/CParticleSwooshShaders.cpp
|
||||
Shaders/CFluidPlaneShader.hpp Shaders/CFluidPlaneShader.cpp
|
||||
Shaders/CAABoxShader.hpp Shaders/CAABoxShader.cpp
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
#include "CDecalShaders.hpp"
|
||||
#include "Particle/CDecal.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
|
||||
boo::ObjToken<boo::IShaderPipeline> CDecalShaders::m_texZTestNoZWrite;
|
||||
boo::ObjToken<boo::IShaderPipeline> CDecalShaders::m_texAdditiveZTest;
|
||||
boo::ObjToken<boo::IShaderPipeline> CDecalShaders::m_texRedToAlphaZTest;
|
||||
|
||||
boo::ObjToken<boo::IShaderPipeline> CDecalShaders::m_noTexZTestNoZWrite;
|
||||
boo::ObjToken<boo::IShaderPipeline> CDecalShaders::m_noTexAdditiveZTest;
|
||||
|
||||
boo::ObjToken<boo::IVertexFormat> CDecalShaders::m_vtxFormatTex;
|
||||
boo::ObjToken<boo::IVertexFormat> CDecalShaders::m_vtxFormatNoTex;
|
||||
|
||||
void CDecalShaders::BuildShaderDataBinding(boo::IGraphicsDataFactory::Context& ctx, CQuadDecal& decal)
|
||||
{
|
||||
boo::ObjToken<boo::IShaderPipeline> regPipeline;
|
||||
boo::ObjToken<boo::IShaderPipeline> redToAlphaPipeline;
|
||||
|
||||
if (decal.m_desc->x14_TEX)
|
||||
{
|
||||
if (decal.m_desc->x18_ADD)
|
||||
regPipeline = m_texAdditiveZTest;
|
||||
else
|
||||
regPipeline = m_texZTestNoZWrite;
|
||||
redToAlphaPipeline = m_texRedToAlphaZTest;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (decal.m_desc->x18_ADD)
|
||||
regPipeline = m_noTexAdditiveZTest;
|
||||
else
|
||||
regPipeline = m_noTexZTestNoZWrite;
|
||||
}
|
||||
|
||||
CDecalShaders shad(decal, regPipeline, redToAlphaPipeline);
|
||||
TShader<CDecalShaders>::BuildShaderDataBinding(ctx, shad);
|
||||
}
|
||||
|
||||
URDE_SPECIALIZE_SHADER(CDecalShaders)
|
||||
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
#ifndef __URDE_CDECALSHADERS_HPP__
|
||||
#define __URDE_CDECALSHADERS_HPP__
|
||||
|
||||
#include "TShader.hpp"
|
||||
#include "Graphics/CGraphics.hpp"
|
||||
#include "boo/graphicsdev/GL.hpp"
|
||||
#include "boo/graphicsdev/D3D.hpp"
|
||||
#include "boo/graphicsdev/Metal.hpp"
|
||||
#include "boo/graphicsdev/Vulkan.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
class CQuadDecal;
|
||||
|
||||
class CDecalShaders
|
||||
{
|
||||
friend struct OGLDecalDataBindingFactory;
|
||||
friend struct VulkanDecalDataBindingFactory;
|
||||
friend struct D3DDecalDataBindingFactory;
|
||||
friend struct MetalDecalDataBindingFactory;
|
||||
|
||||
private:
|
||||
static boo::ObjToken<boo::IShaderPipeline> m_texZTestNoZWrite;
|
||||
static boo::ObjToken<boo::IShaderPipeline> m_texAdditiveZTest;
|
||||
static boo::ObjToken<boo::IShaderPipeline> m_texRedToAlphaZTest;
|
||||
|
||||
static boo::ObjToken<boo::IShaderPipeline> m_noTexZTestNoZWrite;
|
||||
static boo::ObjToken<boo::IShaderPipeline> m_noTexAdditiveZTest;
|
||||
|
||||
static boo::ObjToken<boo::IVertexFormat> m_vtxFormatTex; /* No OpenGL */
|
||||
static boo::ObjToken<boo::IVertexFormat> m_vtxFormatNoTex; /* No OpenGL */
|
||||
|
||||
CQuadDecal& m_decal;
|
||||
boo::ObjToken<boo::IShaderPipeline> m_regPipeline;
|
||||
boo::ObjToken<boo::IShaderPipeline> m_redToAlphaPipeline;
|
||||
CDecalShaders(CQuadDecal& decal,
|
||||
const boo::ObjToken<boo::IShaderPipeline>& regPipeline,
|
||||
const boo::ObjToken<boo::IShaderPipeline>& redToAlphaPipeline)
|
||||
: m_decal(decal), m_regPipeline(regPipeline), m_redToAlphaPipeline(redToAlphaPipeline) {}
|
||||
|
||||
public:
|
||||
static void BuildShaderDataBinding(boo::IGraphicsDataFactory::Context& ctx, CQuadDecal& decal);
|
||||
|
||||
using _CLS = CDecalShaders;
|
||||
#include "TShaderDecl.hpp"
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // __URDE_CDECALSHADERS_HPP__
|
|
@ -0,0 +1,439 @@
|
|||
#include "CDecalShaders.hpp"
|
||||
#include "Particle/CDecal.hpp"
|
||||
#include "Graphics/CModel.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
|
||||
static const char* VS_GLSL_TEX =
|
||||
"#version 330\n"
|
||||
BOO_GLSL_BINDING_HEAD
|
||||
"layout(location=0) in vec4 posIn[4];\n"
|
||||
"layout(location=4) in vec4 colorIn;\n"
|
||||
"layout(location=5) in vec4 uvsIn[4];\n"
|
||||
"\n"
|
||||
"UBINDING0 uniform DecalUniform\n"
|
||||
"{\n"
|
||||
" mat4 mvp;\n"
|
||||
" vec4 moduColor;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"struct VertToFrag\n"
|
||||
"{\n"
|
||||
" vec4 color;\n"
|
||||
" vec2 uv;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"SBINDING(0) out VertToFrag vtf;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" vtf.color = colorIn * moduColor;\n"
|
||||
" vtf.uv = uvsIn[gl_VertexID].xy;\n"
|
||||
" gl_Position = mvp * posIn[gl_VertexID];\n"
|
||||
"}\n";
|
||||
|
||||
static const char* FS_GLSL_TEX =
|
||||
"#version 330\n"
|
||||
BOO_GLSL_BINDING_HEAD
|
||||
"struct VertToFrag\n"
|
||||
"{\n"
|
||||
" vec4 color;\n"
|
||||
" vec2 uv;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"SBINDING(0) in VertToFrag vtf;\n"
|
||||
"layout(location=0) out vec4 colorOut;\n"
|
||||
"TBINDING0 uniform sampler2D tex;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" colorOut = vtf.color * texture(tex, vtf.uv);\n"
|
||||
"}\n";
|
||||
|
||||
static const char* FS_GLSL_TEX_REDTOALPHA =
|
||||
"#version 330\n"
|
||||
BOO_GLSL_BINDING_HEAD
|
||||
"struct VertToFrag\n"
|
||||
"{\n"
|
||||
" vec4 color;\n"
|
||||
" vec2 uv;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"SBINDING(0) in VertToFrag vtf;\n"
|
||||
"layout(location=0) out vec4 colorOut;\n"
|
||||
"TBINDING0 uniform sampler2D tex;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" colorOut = vtf.color;\n"
|
||||
" colorOut.a = texture(tex, vtf.uv).r;\n"
|
||||
"}\n";
|
||||
|
||||
static const char* VS_GLSL_NOTEX =
|
||||
"#version 330\n"
|
||||
BOO_GLSL_BINDING_HEAD
|
||||
"layout(location=0) in vec4 posIn[4];\n"
|
||||
"layout(location=4) in vec4 colorIn;\n"
|
||||
"\n"
|
||||
"UBINDING0 uniform DecalUniform\n"
|
||||
"{\n"
|
||||
" mat4 mvp;\n"
|
||||
" vec4 moduColor;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"struct VertToFrag\n"
|
||||
"{\n"
|
||||
" vec4 color;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"SBINDING(0) out VertToFrag vtf;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" vtf.color = colorIn * moduColor;\n"
|
||||
" gl_Position = mvp * posIn[gl_VertexID];\n"
|
||||
"}\n";
|
||||
|
||||
static const char* FS_GLSL_NOTEX =
|
||||
"#version 330\n"
|
||||
BOO_GLSL_BINDING_HEAD
|
||||
"struct VertToFrag\n"
|
||||
"{\n"
|
||||
" vec4 color;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"SBINDING(0) in VertToFrag vtf;\n"
|
||||
"layout(location=0) out vec4 colorOut;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" colorOut = vtf.color;\n"
|
||||
"}\n";
|
||||
|
||||
struct OGLDecalDataBindingFactory : TShader<CDecalShaders>::IDataBindingFactory
|
||||
{
|
||||
boo::ObjToken<boo::IShaderDataBinding> BuildShaderDataBinding(boo::IGraphicsDataFactory::Context& ctx,
|
||||
CDecalShaders& shaders)
|
||||
{
|
||||
CQuadDecal& decal = shaders.m_decal;
|
||||
const SQuadDescr* desc = decal.m_desc;
|
||||
|
||||
boo::ObjToken<boo::IVertexFormat> vtxFmt;
|
||||
CUVElement* texr = desc->x14_TEX.get();
|
||||
int texCount = 0;
|
||||
boo::ObjToken<boo::ITexture> textures[1];
|
||||
|
||||
if (texr)
|
||||
{
|
||||
textures[0] = texr->GetValueTexture(0).GetObj()->GetBooTexture();
|
||||
texCount = 1;
|
||||
if (decal.m_instBuf)
|
||||
{
|
||||
const boo::VertexElementDescriptor TexFmtTex[] =
|
||||
{
|
||||
{decal.m_instBuf.get(), nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 0},
|
||||
{decal.m_instBuf.get(), nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 1},
|
||||
{decal.m_instBuf.get(), nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 2},
|
||||
{decal.m_instBuf.get(), nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 3},
|
||||
{decal.m_instBuf.get(), nullptr, boo::VertexSemantic::Color | boo::VertexSemantic::Instanced},
|
||||
{decal.m_instBuf.get(), nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 0},
|
||||
{decal.m_instBuf.get(), nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 1},
|
||||
{decal.m_instBuf.get(), nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 2},
|
||||
{decal.m_instBuf.get(), nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 3}
|
||||
};
|
||||
vtxFmt = ctx.newVertexFormat(9, TexFmtTex);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (decal.m_instBuf)
|
||||
{
|
||||
const boo::VertexElementDescriptor TexFmtNoTex[] =
|
||||
{
|
||||
{decal.m_instBuf.get(), nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 0},
|
||||
{decal.m_instBuf.get(), nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 1},
|
||||
{decal.m_instBuf.get(), nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 2},
|
||||
{decal.m_instBuf.get(), nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 3},
|
||||
{decal.m_instBuf.get(), nullptr, boo::VertexSemantic::Color | boo::VertexSemantic::Instanced}
|
||||
};
|
||||
vtxFmt = ctx.newVertexFormat(5, TexFmtNoTex);
|
||||
}
|
||||
}
|
||||
|
||||
if (decal.m_instBuf)
|
||||
{
|
||||
boo::ObjToken<boo::IGraphicsBuffer> uniforms[] = {decal.m_uniformBuf.get()};
|
||||
|
||||
if (shaders.m_regPipeline)
|
||||
decal.m_normalDataBind = ctx.newShaderDataBinding(shaders.m_regPipeline, vtxFmt, nullptr,
|
||||
decal.m_instBuf.get(), nullptr, 1, uniforms,
|
||||
nullptr, texCount, textures, nullptr, nullptr);
|
||||
if (shaders.m_redToAlphaPipeline)
|
||||
decal.m_redToAlphaDataBind = ctx.newShaderDataBinding(shaders.m_redToAlphaPipeline, vtxFmt, nullptr,
|
||||
decal.m_instBuf.get(), nullptr, 1, uniforms,
|
||||
nullptr, texCount, textures, nullptr, nullptr);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
static const char* UniNames[] = {"DecalUniform"};
|
||||
static const char* TexNames[] = {"tex"};
|
||||
|
||||
TShader<CDecalShaders>::IDataBindingFactory* CDecalShaders::Initialize(boo::GLDataFactory::Context& ctx)
|
||||
{
|
||||
m_texZTestNoZWrite = ctx.newShaderPipeline(VS_GLSL_TEX, FS_GLSL_TEX, 1, TexNames, 1, UniNames,
|
||||
boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha,
|
||||
boo::Primitive::TriStrips, boo::ZTest::LEqual, false,
|
||||
true, false, boo::CullMode::None);
|
||||
|
||||
m_texAdditiveZTest = ctx.newShaderPipeline(VS_GLSL_TEX, FS_GLSL_TEX, 1, TexNames, 1, UniNames,
|
||||
boo::BlendFactor::SrcAlpha, boo::BlendFactor::One,
|
||||
boo::Primitive::TriStrips, boo::ZTest::LEqual, false,
|
||||
true, false, boo::CullMode::None);
|
||||
|
||||
m_texRedToAlphaZTest = ctx.newShaderPipeline(VS_GLSL_TEX, FS_GLSL_TEX_REDTOALPHA, 1, TexNames, 1, UniNames,
|
||||
boo::BlendFactor::One, boo::BlendFactor::One,
|
||||
boo::Primitive::TriStrips, boo::ZTest::LEqual, false,
|
||||
true, false, boo::CullMode::None);
|
||||
|
||||
m_noTexZTestNoZWrite = ctx.newShaderPipeline(VS_GLSL_NOTEX, FS_GLSL_NOTEX, 0, nullptr, 1, UniNames,
|
||||
boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha,
|
||||
boo::Primitive::TriStrips, boo::ZTest::LEqual, false,
|
||||
true, false, boo::CullMode::None);
|
||||
|
||||
m_noTexAdditiveZTest = ctx.newShaderPipeline(VS_GLSL_NOTEX, FS_GLSL_NOTEX, 0, nullptr, 1, UniNames,
|
||||
boo::BlendFactor::SrcAlpha, boo::BlendFactor::One,
|
||||
boo::Primitive::TriStrips, boo::ZTest::LEqual, false,
|
||||
true, false, boo::CullMode::None);
|
||||
|
||||
return new struct OGLDecalDataBindingFactory;
|
||||
}
|
||||
|
||||
template <>
|
||||
void CDecalShaders::Shutdown<boo::GLDataFactory>()
|
||||
{
|
||||
m_texZTestNoZWrite.reset();
|
||||
m_texAdditiveZTest.reset();
|
||||
m_texRedToAlphaZTest.reset();
|
||||
|
||||
m_noTexZTestNoZWrite.reset();
|
||||
m_noTexAdditiveZTest.reset();
|
||||
}
|
||||
|
||||
#if BOO_HAS_VULKAN
|
||||
struct VulkanDecalDataBindingFactory : TShader<CElementGenShaders>::IDataBindingFactory
|
||||
{
|
||||
boo::ObjToken<boo::IShaderDataBinding>
|
||||
BuildShaderDataBinding(boo::IGraphicsDataFactory::Context& ctx,
|
||||
CElementGenShaders& shaders)
|
||||
{
|
||||
CElementGen& gen = shaders.m_gen;
|
||||
CGenDescription* desc = gen.GetDesc();
|
||||
|
||||
CUVElement* texr = desc->x54_x40_TEXR.get();
|
||||
CUVElement* tind = desc->x58_x44_TIND.get();
|
||||
int texCount = 0;
|
||||
boo::ObjToken<boo::ITexture> textures[3];
|
||||
|
||||
if (texr)
|
||||
{
|
||||
textures[0] = texr->GetValueTexture(0).GetObj()->GetBooTexture();
|
||||
texCount = 1;
|
||||
if (tind)
|
||||
{
|
||||
textures[1] = CGraphics::g_SpareTexture.get();
|
||||
textures[2] = tind->GetValueTexture(0).GetObj()->GetBooTexture();
|
||||
texCount = 3;
|
||||
}
|
||||
}
|
||||
|
||||
if (gen.m_instBuf)
|
||||
{
|
||||
boo::ObjToken<boo::IGraphicsBuffer> uniforms[] = {gen.m_uniformBuf.get()};
|
||||
|
||||
if (shaders.m_regPipeline)
|
||||
gen.m_normalDataBind = ctx.newShaderDataBinding(shaders.m_regPipeline, nullptr, nullptr,
|
||||
gen.m_instBuf.get(), nullptr, 1, uniforms,
|
||||
nullptr, texCount, textures, nullptr, nullptr);
|
||||
if (shaders.m_regPipelineSub)
|
||||
gen.m_normalSubDataBind = ctx.newShaderDataBinding(shaders.m_regPipelineSub, nullptr, nullptr,
|
||||
gen.m_instBuf.get(), nullptr, 1, uniforms,
|
||||
nullptr, texCount, textures, nullptr, nullptr);
|
||||
if (shaders.m_redToAlphaPipeline)
|
||||
gen.m_redToAlphaDataBind = ctx.newShaderDataBinding(shaders.m_redToAlphaPipeline, nullptr, nullptr,
|
||||
gen.m_instBuf.get(), nullptr, 1, uniforms,
|
||||
nullptr, texCount, textures, nullptr, nullptr);
|
||||
if (shaders.m_redToAlphaPipelineSub)
|
||||
gen.m_redToAlphaSubDataBind = ctx.newShaderDataBinding(shaders.m_redToAlphaPipelineSub, nullptr, nullptr,
|
||||
gen.m_instBuf.get(), nullptr, 1, uniforms,
|
||||
nullptr, texCount, textures, nullptr, nullptr);
|
||||
|
||||
}
|
||||
|
||||
if (gen.m_instBufPmus)
|
||||
{
|
||||
boo::ObjToken<boo::IGraphicsBuffer> uniforms[] = {gen.m_uniformBufPmus.get()};
|
||||
texCount = std::min(texCount, 1);
|
||||
|
||||
if (shaders.m_regPipelinePmus)
|
||||
gen.m_normalDataBindPmus = ctx.newShaderDataBinding(shaders.m_regPipelinePmus, nullptr, nullptr,
|
||||
gen.m_instBufPmus.get(), nullptr, 1, uniforms,
|
||||
nullptr, texCount, textures, nullptr, nullptr);
|
||||
if (shaders.m_redToAlphaPipelinePmus)
|
||||
gen.m_redToAlphaDataBindPmus = ctx.newShaderDataBinding(shaders.m_redToAlphaPipelinePmus, nullptr, nullptr,
|
||||
gen.m_instBufPmus.get(), nullptr, 1, uniforms,
|
||||
nullptr, texCount, textures, nullptr, nullptr);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
TShader<CElementGenShaders>::IDataBindingFactory* CElementGenShaders::Initialize(boo::VulkanDataFactory::Context& ctx)
|
||||
{
|
||||
static const boo::VertexElementDescriptor TexFmtTex[] =
|
||||
{
|
||||
{nullptr, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 0},
|
||||
{nullptr, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 1},
|
||||
{nullptr, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 2},
|
||||
{nullptr, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 3},
|
||||
{nullptr, nullptr, boo::VertexSemantic::Color | boo::VertexSemantic::Instanced},
|
||||
{nullptr, nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 0},
|
||||
{nullptr, nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 1},
|
||||
{nullptr, nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 2},
|
||||
{nullptr, nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 3}
|
||||
};
|
||||
m_vtxFormatTex = ctx.newVertexFormat(9, TexFmtTex);
|
||||
|
||||
static const boo::VertexElementDescriptor TexFmtNoTex[] =
|
||||
{
|
||||
{nullptr, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 0},
|
||||
{nullptr, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 1},
|
||||
{nullptr, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 2},
|
||||
{nullptr, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 3},
|
||||
{nullptr, nullptr, boo::VertexSemantic::Color | boo::VertexSemantic::Instanced}
|
||||
};
|
||||
m_vtxFormatNoTex = ctx.newVertexFormat(5, TexFmtNoTex);
|
||||
|
||||
m_texZTestZWrite = ctx.newShaderPipeline(VS_GLSL_TEX, FS_GLSL_TEX, m_vtxFormatTex,
|
||||
boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha,
|
||||
boo::Primitive::TriStrips, boo::ZTest::LEqual, true,
|
||||
true, false, boo::CullMode::None);
|
||||
m_texNoZTestZWrite = ctx.newShaderPipeline(VS_GLSL_TEX, FS_GLSL_TEX, m_vtxFormatTex,
|
||||
boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha,
|
||||
boo::Primitive::TriStrips, boo::ZTest::None, true,
|
||||
true, false, boo::CullMode::None);
|
||||
m_texZTestNoZWrite = ctx.newShaderPipeline(VS_GLSL_TEX, FS_GLSL_TEX, m_vtxFormatTex,
|
||||
boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha,
|
||||
boo::Primitive::TriStrips, boo::ZTest::LEqual, false,
|
||||
true, false, boo::CullMode::None);
|
||||
m_texNoZTestNoZWrite = ctx.newShaderPipeline(VS_GLSL_TEX, FS_GLSL_TEX, m_vtxFormatTex,
|
||||
boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha,
|
||||
boo::Primitive::TriStrips, boo::ZTest::None, false,
|
||||
true, false, boo::CullMode::None);
|
||||
|
||||
m_texAdditiveZTest = ctx.newShaderPipeline(VS_GLSL_TEX, FS_GLSL_TEX, m_vtxFormatTex,
|
||||
boo::BlendFactor::SrcAlpha, boo::BlendFactor::One,
|
||||
boo::Primitive::TriStrips, boo::ZTest::LEqual, false,
|
||||
true, false, boo::CullMode::None);
|
||||
m_texAdditiveNoZTest = ctx.newShaderPipeline(VS_GLSL_TEX, FS_GLSL_TEX, m_vtxFormatTex,
|
||||
boo::BlendFactor::SrcAlpha, boo::BlendFactor::One,
|
||||
boo::Primitive::TriStrips, boo::ZTest::None, false,
|
||||
true, false, boo::CullMode::None);
|
||||
|
||||
m_texRedToAlphaZTest = ctx.newShaderPipeline(VS_GLSL_TEX, FS_GLSL_TEX_REDTOALPHA, m_vtxFormatTex,
|
||||
boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha,
|
||||
boo::Primitive::TriStrips, boo::ZTest::LEqual, false,
|
||||
true, false, boo::CullMode::None);
|
||||
m_texRedToAlphaNoZTest = ctx.newShaderPipeline(VS_GLSL_TEX, FS_GLSL_TEX_REDTOALPHA, m_vtxFormatTex,
|
||||
boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha,
|
||||
boo::Primitive::TriStrips, boo::ZTest::None, false,
|
||||
true, false, boo::CullMode::None);
|
||||
|
||||
m_texZTestNoZWriteSub = ctx.newShaderPipeline(VS_GLSL_TEX, FS_GLSL_TEX, m_vtxFormatTex,
|
||||
boo::BlendFactor::Subtract, boo::BlendFactor::Subtract,
|
||||
boo::Primitive::TriStrips, boo::ZTest::LEqual, false,
|
||||
true, false, boo::CullMode::None);
|
||||
m_texNoZTestNoZWriteSub = ctx.newShaderPipeline(VS_GLSL_TEX, FS_GLSL_TEX, m_vtxFormatTex,
|
||||
boo::BlendFactor::Subtract, boo::BlendFactor::Subtract,
|
||||
boo::Primitive::TriStrips, boo::ZTest::None, false,
|
||||
true, false, boo::CullMode::None);
|
||||
|
||||
m_texRedToAlphaZTestSub = ctx.newShaderPipeline(VS_GLSL_TEX, FS_GLSL_TEX_REDTOALPHA, m_vtxFormatTex,
|
||||
boo::BlendFactor::Subtract, boo::BlendFactor::Subtract,
|
||||
boo::Primitive::TriStrips, boo::ZTest::LEqual, false,
|
||||
true, false, boo::CullMode::None);
|
||||
m_texRedToAlphaNoZTestSub = ctx.newShaderPipeline(VS_GLSL_TEX, FS_GLSL_TEX_REDTOALPHA, m_vtxFormatTex,
|
||||
boo::BlendFactor::Subtract, boo::BlendFactor::Subtract,
|
||||
boo::Primitive::TriStrips, boo::ZTest::None, false,
|
||||
true, false, boo::CullMode::None);
|
||||
|
||||
m_indTexZWrite = ctx.newShaderPipeline(VS_GLSL_INDTEX, FS_GLSL_INDTEX, m_vtxFormatIndTex,
|
||||
boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha,
|
||||
boo::Primitive::TriStrips, boo::ZTest::LEqual, true,
|
||||
true, false, boo::CullMode::None);
|
||||
m_indTexNoZWrite = ctx.newShaderPipeline(VS_GLSL_INDTEX, FS_GLSL_INDTEX, m_vtxFormatIndTex,
|
||||
boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha,
|
||||
boo::Primitive::TriStrips, boo::ZTest::LEqual, false,
|
||||
true, false, boo::CullMode::None);
|
||||
m_indTexAdditive = ctx.newShaderPipeline(VS_GLSL_INDTEX, FS_GLSL_INDTEX, m_vtxFormatIndTex,
|
||||
boo::BlendFactor::SrcAlpha, boo::BlendFactor::One,
|
||||
boo::Primitive::TriStrips, boo::ZTest::LEqual, true,
|
||||
true, false, boo::CullMode::None);
|
||||
|
||||
m_cindTexZWrite = ctx.newShaderPipeline(VS_GLSL_INDTEX, FS_GLSL_CINDTEX, m_vtxFormatIndTex,
|
||||
boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha,
|
||||
boo::Primitive::TriStrips, boo::ZTest::LEqual, true,
|
||||
true, false, boo::CullMode::None);
|
||||
m_cindTexNoZWrite = ctx.newShaderPipeline(VS_GLSL_INDTEX, FS_GLSL_CINDTEX, m_vtxFormatIndTex,
|
||||
boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha,
|
||||
boo::Primitive::TriStrips, boo::ZTest::LEqual, false,
|
||||
true, false, boo::CullMode::None);
|
||||
m_cindTexAdditive = ctx.newShaderPipeline(VS_GLSL_INDTEX, FS_GLSL_CINDTEX, m_vtxFormatIndTex,
|
||||
boo::BlendFactor::SrcAlpha, boo::BlendFactor::One,
|
||||
boo::Primitive::TriStrips, boo::ZTest::LEqual, true,
|
||||
true, false, boo::CullMode::None);
|
||||
|
||||
m_noTexZTestZWrite = ctx.newShaderPipeline(VS_GLSL_NOTEX, FS_GLSL_NOTEX, m_vtxFormatNoTex,
|
||||
boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha,
|
||||
boo::Primitive::TriStrips, boo::ZTest::LEqual, true,
|
||||
true, false, boo::CullMode::None);
|
||||
m_noTexNoZTestZWrite = ctx.newShaderPipeline(VS_GLSL_NOTEX, FS_GLSL_NOTEX, m_vtxFormatNoTex,
|
||||
boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha,
|
||||
boo::Primitive::TriStrips, boo::ZTest::None, true,
|
||||
true, false, boo::CullMode::None);
|
||||
m_noTexZTestNoZWrite = ctx.newShaderPipeline(VS_GLSL_NOTEX, FS_GLSL_NOTEX, m_vtxFormatNoTex,
|
||||
boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha,
|
||||
boo::Primitive::TriStrips, boo::ZTest::LEqual, false,
|
||||
true, false, boo::CullMode::None);
|
||||
m_noTexNoZTestNoZWrite = ctx.newShaderPipeline(VS_GLSL_NOTEX, FS_GLSL_NOTEX, m_vtxFormatNoTex,
|
||||
boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha,
|
||||
boo::Primitive::TriStrips, boo::ZTest::None, false,
|
||||
true, false, boo::CullMode::None);
|
||||
|
||||
m_noTexAdditiveZTest = ctx.newShaderPipeline(VS_GLSL_NOTEX, FS_GLSL_NOTEX, m_vtxFormatNoTex,
|
||||
boo::BlendFactor::SrcAlpha, boo::BlendFactor::One,
|
||||
boo::Primitive::TriStrips, boo::ZTest::LEqual, false,
|
||||
true, false, boo::CullMode::None);
|
||||
m_noTexAdditiveNoZTest = ctx.newShaderPipeline(VS_GLSL_NOTEX, FS_GLSL_NOTEX, m_vtxFormatNoTex,
|
||||
boo::BlendFactor::SrcAlpha, boo::BlendFactor::One,
|
||||
boo::Primitive::TriStrips, boo::ZTest::None, false,
|
||||
true, false, boo::CullMode::None);
|
||||
|
||||
return new struct VulkanDecalDataBindingFactory;
|
||||
}
|
||||
|
||||
template <>
|
||||
void CElementGenShaders::Shutdown<boo::VulkanDataFactory>()
|
||||
{
|
||||
m_vtxFormatTex.reset();
|
||||
m_vtxFormatNoTex.reset();
|
||||
|
||||
m_texZTestNoZWrite.reset();
|
||||
m_texAdditiveZTest.reset();
|
||||
m_texRedToAlphaZTest.reset();
|
||||
|
||||
m_noTexZTestNoZWrite.reset();
|
||||
m_noTexAdditiveZTest.reset();
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
|
@ -0,0 +1,389 @@
|
|||
#include "CDecalShaders.hpp"
|
||||
#include "Particle/CDecal.hpp"
|
||||
#include "Graphics/CModel.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
|
||||
static const char* VS_HLSL_TEX =
|
||||
"struct VertData\n"
|
||||
"{\n"
|
||||
" float4 posIn[4] : POSITION;\n"
|
||||
" float4 colorIn : COLOR;\n"
|
||||
" float4 uvsIn[4] : UV;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"cbuffer DecalUniform : register(b0)\n"
|
||||
"{\n"
|
||||
" float4x4 mvp;\n"
|
||||
" float4 moduColor;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"struct VertToFrag\n"
|
||||
"{\n"
|
||||
" float4 position : SV_Position;\n"
|
||||
" float4 color : COLOR;\n"
|
||||
" float2 uv : UV;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"VertToFrag main(in VertData v, in uint vertId : SV_VertexID)\n"
|
||||
"{\n"
|
||||
" VertToFrag vtf;\n"
|
||||
" vtf.color = v.colorIn * moduColor;\n"
|
||||
" vtf.uv = v.uvsIn[vertId].xy;\n"
|
||||
" vtf.position = mul(mvp, v.posIn[vertId]);\n"
|
||||
" return vtf;\n"
|
||||
"}\n";
|
||||
|
||||
static const char* FS_HLSL_TEX =
|
||||
"SamplerState samp : register(s0);\n"
|
||||
"Texture2D tex0 : register(t0);\n"
|
||||
"struct VertToFrag\n"
|
||||
"{\n"
|
||||
" float4 position : SV_Position;\n"
|
||||
" float4 color : COLOR;\n"
|
||||
" float2 uv : UV;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"float4 main(in VertToFrag vtf) : SV_Target0\n"
|
||||
"{\n"
|
||||
" return vtf.color * tex0.Sample(samp, vtf.uv);\n"
|
||||
"}\n";
|
||||
|
||||
static const char* FS_HLSL_TEX_REDTOALPHA =
|
||||
"SamplerState samp : register(s0);\n"
|
||||
"Texture2D tex0 : register(t0);\n"
|
||||
"struct VertToFrag\n"
|
||||
"{\n"
|
||||
" float4 position : SV_Position;\n"
|
||||
" float4 color : COLOR;\n"
|
||||
" float2 uv : UV;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"float4 main(in VertToFrag vtf) : SV_Target0\n"
|
||||
"{\n"
|
||||
" return float4(vtf.color.rgb, tex0.Sample(samp, vtf.uv).r);\n"
|
||||
"}\n";
|
||||
|
||||
static const char* VS_HLSL_NOTEX =
|
||||
"struct VertData\n"
|
||||
"{\n"
|
||||
" float4 posIn[4] : POSITION;\n"
|
||||
" float4 colorIn : COLOR;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"cbuffer DecalUniform : register(b0)\n"
|
||||
"{\n"
|
||||
" float4x4 mvp;\n"
|
||||
" float4 moduColor;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"struct VertToFrag\n"
|
||||
"{\n"
|
||||
" float4 position : SV_Position;\n"
|
||||
" float4 color : COLOR;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"VertToFrag main(in VertData v, in uint vertId : SV_VertexID)\n"
|
||||
"{\n"
|
||||
" VertToFrag vtf;\n"
|
||||
" vtf.color = v.colorIn * moduColor;\n"
|
||||
" vtf.position = mul(mvp, v.posIn[vertId]);\n"
|
||||
" return vtf;\n"
|
||||
"}\n";
|
||||
|
||||
static const char* FS_HLSL_NOTEX =
|
||||
"struct VertToFrag\n"
|
||||
"{\n"
|
||||
" float4 position : SV_Position;\n"
|
||||
" float4 color : COLOR;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"float4 main(in VertToFrag vtf) : SV_Target0\n"
|
||||
"{\n"
|
||||
" return vtf.color;\n"
|
||||
"}\n";
|
||||
|
||||
struct D3DElementDataBindingFactory : TShader<CElementGenShaders>::IDataBindingFactory
|
||||
{
|
||||
boo::ObjToken<boo::IShaderDataBinding>
|
||||
BuildShaderDataBinding(boo::IGraphicsDataFactory::Context& ctx,
|
||||
CElementGenShaders& shaders)
|
||||
{
|
||||
CElementGen& gen = shaders.m_gen;
|
||||
CGenDescription* desc = gen.GetDesc();
|
||||
|
||||
CUVElement* texr = desc->x54_x40_TEXR.get();
|
||||
CUVElement* tind = desc->x58_x44_TIND.get();
|
||||
int texCount = 0;
|
||||
boo::ObjToken<boo::ITexture> textures[3];
|
||||
|
||||
if (texr)
|
||||
{
|
||||
textures[0] = texr->GetValueTexture(0).GetObj()->GetBooTexture();
|
||||
texCount = 1;
|
||||
if (tind)
|
||||
{
|
||||
textures[1] = CGraphics::g_SpareTexture.get();
|
||||
textures[2] = tind->GetValueTexture(0).GetObj()->GetBooTexture();
|
||||
texCount = 3;
|
||||
}
|
||||
}
|
||||
|
||||
if (gen.m_instBuf)
|
||||
{
|
||||
boo::ObjToken<boo::IGraphicsBuffer> uniforms[] = {gen.m_uniformBuf.get()};
|
||||
|
||||
if (shaders.m_regPipeline)
|
||||
gen.m_normalDataBind = ctx.newShaderDataBinding(shaders.m_regPipeline, nullptr, nullptr,
|
||||
gen.m_instBuf.get(), nullptr, 1, uniforms,
|
||||
nullptr, texCount, textures,
|
||||
nullptr, nullptr);
|
||||
if (shaders.m_regPipelineSub)
|
||||
gen.m_normalSubDataBind = ctx.newShaderDataBinding(shaders.m_regPipelineSub, nullptr, nullptr,
|
||||
gen.m_instBuf.get(), nullptr, 1, uniforms,
|
||||
nullptr, texCount, textures,
|
||||
nullptr, nullptr);
|
||||
if (shaders.m_redToAlphaPipeline)
|
||||
gen.m_redToAlphaDataBind = ctx.newShaderDataBinding(shaders.m_redToAlphaPipeline, nullptr, nullptr,
|
||||
gen.m_instBuf.get(), nullptr, 1, uniforms,
|
||||
nullptr, texCount, textures,
|
||||
nullptr, nullptr);
|
||||
if (shaders.m_redToAlphaPipelineSub)
|
||||
gen.m_redToAlphaSubDataBind = ctx.newShaderDataBinding(shaders.m_redToAlphaPipelineSub, nullptr, nullptr,
|
||||
gen.m_instBuf.get(), nullptr, 1, uniforms,
|
||||
nullptr, texCount, textures,
|
||||
nullptr, nullptr);
|
||||
}
|
||||
|
||||
if (gen.m_instBufPmus)
|
||||
{
|
||||
boo::ObjToken<boo::IGraphicsBuffer> uniforms[] = {gen.m_uniformBufPmus.get()};
|
||||
texCount = std::min(texCount, 1);
|
||||
|
||||
if (shaders.m_regPipelinePmus)
|
||||
gen.m_normalDataBindPmus = ctx.newShaderDataBinding(shaders.m_regPipelinePmus, nullptr, nullptr,
|
||||
gen.m_instBuf.get(), nullptr, 1, uniforms,
|
||||
nullptr, texCount, textures,
|
||||
nullptr, nullptr);
|
||||
if (shaders.m_redToAlphaPipelinePmus)
|
||||
gen.m_redToAlphaDataBindPmus = ctx.newShaderDataBinding(shaders.m_redToAlphaPipelinePmus, nullptr, nullptr,
|
||||
gen.m_instBuf.get(), nullptr, 1, uniforms,
|
||||
nullptr, texCount, textures,
|
||||
nullptr, nullptr);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
TShader<CElementGenShaders>::IDataBindingFactory* CElementGenShaders::Initialize(boo::ID3DDataFactory::Context& ctx)
|
||||
{
|
||||
static const boo::VertexElementDescriptor TexFmtTex[] =
|
||||
{
|
||||
{nullptr, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 0},
|
||||
{nullptr, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 1},
|
||||
{nullptr, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 2},
|
||||
{nullptr, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 3},
|
||||
{nullptr, nullptr, boo::VertexSemantic::Color | boo::VertexSemantic::Instanced},
|
||||
{nullptr, nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 0},
|
||||
{nullptr, nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 1},
|
||||
{nullptr, nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 2},
|
||||
{nullptr, nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 3}
|
||||
};
|
||||
m_vtxFormatTex = ctx.newVertexFormat(9, TexFmtTex);
|
||||
|
||||
static const boo::VertexElementDescriptor TexFmtIndTex[] =
|
||||
{
|
||||
{nullptr, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 0},
|
||||
{nullptr, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 1},
|
||||
{nullptr, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 2},
|
||||
{nullptr, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 3},
|
||||
{nullptr, nullptr, boo::VertexSemantic::Color | boo::VertexSemantic::Instanced},
|
||||
{nullptr, nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 0},
|
||||
{nullptr, nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 1},
|
||||
{nullptr, nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 2},
|
||||
{nullptr, nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 3},
|
||||
{nullptr, nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 4}
|
||||
};
|
||||
m_vtxFormatIndTex = ctx.newVertexFormat(10, TexFmtIndTex);
|
||||
|
||||
static const boo::VertexElementDescriptor TexFmtNoTex[] =
|
||||
{
|
||||
{nullptr, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 0},
|
||||
{nullptr, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 1},
|
||||
{nullptr, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 2},
|
||||
{nullptr, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 3},
|
||||
{nullptr, nullptr, boo::VertexSemantic::Color | boo::VertexSemantic::Instanced}
|
||||
};
|
||||
m_vtxFormatNoTex = ctx.newVertexFormat(5, TexFmtNoTex);
|
||||
|
||||
m_texZTestZWrite = ctx.newShaderPipeline(VS_HLSL_TEX, FS_HLSL_TEX, nullptr, nullptr,
|
||||
nullptr, m_vtxFormatTex,
|
||||
boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha,
|
||||
boo::Primitive::TriStrips, boo::ZTest::LEqual, true,
|
||||
true, false, boo::CullMode::None);
|
||||
m_texNoZTestZWrite = ctx.newShaderPipeline(VS_HLSL_TEX, FS_HLSL_TEX, nullptr, nullptr,
|
||||
nullptr, m_vtxFormatTex,
|
||||
boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha,
|
||||
boo::Primitive::TriStrips, boo::ZTest::None, true,
|
||||
true, false, boo::CullMode::None);
|
||||
m_texZTestNoZWrite = ctx.newShaderPipeline(VS_HLSL_TEX, FS_HLSL_TEX, nullptr, nullptr,
|
||||
nullptr, m_vtxFormatTex,
|
||||
boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha,
|
||||
boo::Primitive::TriStrips, boo::ZTest::LEqual, false,
|
||||
true, false, boo::CullMode::None);
|
||||
m_texNoZTestNoZWrite = ctx.newShaderPipeline(VS_HLSL_TEX, FS_HLSL_TEX, nullptr, nullptr,
|
||||
nullptr, m_vtxFormatTex,
|
||||
boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha,
|
||||
boo::Primitive::TriStrips, boo::ZTest::None, false,
|
||||
true, false, boo::CullMode::None);
|
||||
|
||||
m_texAdditiveZTest = ctx.newShaderPipeline(VS_HLSL_TEX, FS_HLSL_TEX, nullptr, nullptr,
|
||||
nullptr, m_vtxFormatTex,
|
||||
boo::BlendFactor::SrcAlpha, boo::BlendFactor::One,
|
||||
boo::Primitive::TriStrips, boo::ZTest::LEqual, false,
|
||||
true, false, boo::CullMode::None);
|
||||
m_texAdditiveNoZTest = ctx.newShaderPipeline(VS_HLSL_TEX, FS_HLSL_TEX, nullptr, nullptr,
|
||||
nullptr, m_vtxFormatTex,
|
||||
boo::BlendFactor::SrcAlpha, boo::BlendFactor::One,
|
||||
boo::Primitive::TriStrips, boo::ZTest::None, false,
|
||||
true, false, boo::CullMode::None);
|
||||
|
||||
m_texRedToAlphaZTest = ctx.newShaderPipeline(VS_HLSL_TEX, FS_HLSL_TEX_REDTOALPHA, nullptr, nullptr,
|
||||
nullptr, m_vtxFormatTex,
|
||||
boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha,
|
||||
boo::Primitive::TriStrips, boo::ZTest::LEqual, false,
|
||||
true, false, boo::CullMode::None);
|
||||
m_texRedToAlphaNoZTest = ctx.newShaderPipeline(VS_HLSL_TEX, FS_HLSL_TEX_REDTOALPHA, nullptr, nullptr,
|
||||
nullptr, m_vtxFormatTex,
|
||||
boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha,
|
||||
boo::Primitive::TriStrips, boo::ZTest::None, false,
|
||||
true, false, boo::CullMode::None);
|
||||
|
||||
m_texZTestNoZWriteSub = ctx.newShaderPipeline(VS_HLSL_TEX, FS_HLSL_TEX, nullptr, nullptr,
|
||||
nullptr, m_vtxFormatTex,
|
||||
boo::BlendFactor::Subtract, boo::BlendFactor::Subtract,
|
||||
boo::Primitive::TriStrips, boo::ZTest::LEqual, false,
|
||||
true, false, boo::CullMode::None);
|
||||
m_texNoZTestNoZWriteSub = ctx.newShaderPipeline(VS_HLSL_TEX, FS_HLSL_TEX, nullptr, nullptr,
|
||||
nullptr, m_vtxFormatTex,
|
||||
boo::BlendFactor::Subtract, boo::BlendFactor::Subtract,
|
||||
boo::Primitive::TriStrips, boo::ZTest::None, false,
|
||||
true, false, boo::CullMode::None);
|
||||
|
||||
m_texRedToAlphaZTestSub = ctx.newShaderPipeline(VS_HLSL_TEX, FS_HLSL_TEX_REDTOALPHA, nullptr, nullptr,
|
||||
nullptr, m_vtxFormatTex,
|
||||
boo::BlendFactor::Subtract, boo::BlendFactor::Subtract,
|
||||
boo::Primitive::TriStrips, boo::ZTest::LEqual, false,
|
||||
true, false, boo::CullMode::None);
|
||||
m_texRedToAlphaNoZTestSub = ctx.newShaderPipeline(VS_HLSL_TEX, FS_HLSL_TEX_REDTOALPHA, nullptr, nullptr,
|
||||
nullptr, m_vtxFormatTex,
|
||||
boo::BlendFactor::Subtract, boo::BlendFactor::Subtract,
|
||||
boo::Primitive::TriStrips, boo::ZTest::None, false,
|
||||
true, false, boo::CullMode::None);
|
||||
|
||||
m_indTexZWrite = ctx.newShaderPipeline(VS_HLSL_INDTEX, FS_HLSL_INDTEX, nullptr, nullptr,
|
||||
nullptr, m_vtxFormatIndTex,
|
||||
boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha,
|
||||
boo::Primitive::TriStrips, boo::ZTest::None, true,
|
||||
true, false, boo::CullMode::None);
|
||||
m_indTexNoZWrite = ctx.newShaderPipeline(VS_HLSL_INDTEX, FS_HLSL_INDTEX, nullptr, nullptr,
|
||||
nullptr, m_vtxFormatIndTex,
|
||||
boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha,
|
||||
boo::Primitive::TriStrips, boo::ZTest::None, false,
|
||||
true, false, boo::CullMode::None);
|
||||
m_indTexAdditive = ctx.newShaderPipeline(VS_HLSL_INDTEX, FS_HLSL_INDTEX, nullptr, nullptr,
|
||||
nullptr, m_vtxFormatIndTex,
|
||||
boo::BlendFactor::SrcAlpha, boo::BlendFactor::One,
|
||||
boo::Primitive::TriStrips, boo::ZTest::None, true,
|
||||
true, false, boo::CullMode::None);
|
||||
|
||||
m_cindTexZWrite = ctx.newShaderPipeline(VS_HLSL_INDTEX, FS_HLSL_CINDTEX, nullptr, nullptr,
|
||||
nullptr, m_vtxFormatIndTex,
|
||||
boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha,
|
||||
boo::Primitive::TriStrips, boo::ZTest::None, true,
|
||||
true, false, boo::CullMode::None);
|
||||
m_cindTexNoZWrite = ctx.newShaderPipeline(VS_HLSL_INDTEX, FS_HLSL_CINDTEX, nullptr, nullptr,
|
||||
nullptr, m_vtxFormatIndTex,
|
||||
boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha,
|
||||
boo::Primitive::TriStrips, boo::ZTest::None, false,
|
||||
true, false, boo::CullMode::None);
|
||||
m_cindTexAdditive = ctx.newShaderPipeline(VS_HLSL_INDTEX, FS_HLSL_CINDTEX, nullptr, nullptr,
|
||||
nullptr, m_vtxFormatIndTex,
|
||||
boo::BlendFactor::SrcAlpha, boo::BlendFactor::One,
|
||||
boo::Primitive::TriStrips, boo::ZTest::None, true,
|
||||
true, false, boo::CullMode::None);
|
||||
|
||||
m_noTexZTestZWrite = ctx.newShaderPipeline(VS_HLSL_NOTEX, FS_HLSL_NOTEX, nullptr, nullptr,
|
||||
nullptr, m_vtxFormatNoTex,
|
||||
boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha,
|
||||
boo::Primitive::TriStrips, boo::ZTest::LEqual, true,
|
||||
true, false, boo::CullMode::None);
|
||||
m_noTexNoZTestZWrite = ctx.newShaderPipeline(VS_HLSL_NOTEX, FS_HLSL_NOTEX, nullptr, nullptr,
|
||||
nullptr, m_vtxFormatNoTex,
|
||||
boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha,
|
||||
boo::Primitive::TriStrips, boo::ZTest::None, true,
|
||||
true, false, boo::CullMode::None);
|
||||
m_noTexZTestNoZWrite = ctx.newShaderPipeline(VS_HLSL_NOTEX, FS_HLSL_NOTEX, nullptr, nullptr,
|
||||
nullptr, m_vtxFormatNoTex,
|
||||
boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha,
|
||||
boo::Primitive::TriStrips, boo::ZTest::LEqual, false,
|
||||
true, false, boo::CullMode::None);
|
||||
m_noTexNoZTestNoZWrite = ctx.newShaderPipeline(VS_HLSL_NOTEX, FS_HLSL_NOTEX, nullptr, nullptr,
|
||||
nullptr, m_vtxFormatNoTex,
|
||||
boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha,
|
||||
boo::Primitive::TriStrips, boo::ZTest::None, false,
|
||||
true, false, boo::CullMode::None);
|
||||
|
||||
m_noTexAdditiveZTest = ctx.newShaderPipeline(VS_HLSL_NOTEX, FS_HLSL_NOTEX, nullptr, nullptr,
|
||||
nullptr, m_vtxFormatNoTex,
|
||||
boo::BlendFactor::SrcAlpha, boo::BlendFactor::One,
|
||||
boo::Primitive::TriStrips, boo::ZTest::LEqual, true,
|
||||
true, false, boo::CullMode::None);
|
||||
m_noTexAdditiveNoZTest = ctx.newShaderPipeline(VS_HLSL_NOTEX, FS_HLSL_NOTEX, nullptr, nullptr,
|
||||
nullptr, m_vtxFormatNoTex,
|
||||
boo::BlendFactor::SrcAlpha, boo::BlendFactor::One,
|
||||
boo::Primitive::TriStrips, boo::ZTest::None, true,
|
||||
true, false, boo::CullMode::None);
|
||||
|
||||
return new struct D3DElementDataBindingFactory;
|
||||
}
|
||||
|
||||
template <>
|
||||
void CElementGenShaders::Shutdown<boo::ID3DDataFactory>()
|
||||
{
|
||||
m_vtxFormatTex.reset();
|
||||
m_vtxFormatIndTex.reset();
|
||||
m_vtxFormatNoTex.reset();
|
||||
|
||||
m_texZTestZWrite.reset();
|
||||
m_texNoZTestZWrite.reset();
|
||||
m_texZTestNoZWrite.reset();
|
||||
m_texNoZTestNoZWrite.reset();
|
||||
m_texAdditiveZTest.reset();
|
||||
m_texAdditiveNoZTest.reset();
|
||||
m_texRedToAlphaZTest.reset();
|
||||
m_texRedToAlphaNoZTest.reset();
|
||||
m_texZTestNoZWriteSub.reset();
|
||||
m_texNoZTestNoZWriteSub.reset();
|
||||
m_texRedToAlphaZTestSub.reset();
|
||||
m_texRedToAlphaNoZTestSub.reset();
|
||||
|
||||
m_indTexZWrite.reset();
|
||||
m_indTexNoZWrite.reset();
|
||||
m_indTexAdditive.reset();
|
||||
|
||||
m_cindTexZWrite.reset();
|
||||
m_cindTexNoZWrite.reset();
|
||||
m_cindTexAdditive.reset();
|
||||
|
||||
m_noTexZTestZWrite.reset();
|
||||
m_noTexNoZTestZWrite.reset();
|
||||
m_noTexZTestNoZWrite.reset();
|
||||
m_noTexNoZTestNoZWrite.reset();
|
||||
m_noTexAdditiveZTest.reset();
|
||||
m_noTexAdditiveNoZTest.reset();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,221 @@
|
|||
#include "CDecalShaders.hpp"
|
||||
#include "Particle/CDecal.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
|
||||
static const char* VS_METAL_TEX =
|
||||
"#include <metal_stdlib>\n"
|
||||
"using namespace metal;\n"
|
||||
"struct VertData\n"
|
||||
"{\n"
|
||||
" float4 posIn[4];\n"
|
||||
" float4 colorIn;\n"
|
||||
" float4 uvsIn[4];\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"struct DecalUniform\n"
|
||||
"{\n"
|
||||
" float4x4 mvp;\n"
|
||||
" float4 moduColor;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"struct VertToFrag\n"
|
||||
"{\n"
|
||||
" float4 position [[ position ]];\n"
|
||||
" float4 color;\n"
|
||||
" float2 uv;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"vertex VertToFrag vmain(constant VertData* va [[ buffer(1) ]],\n"
|
||||
" uint vertId [[ vertex_id ]], uint instId [[ instance_id ]],\n"
|
||||
" constant DecalUniform& decal [[ buffer(2) ]])\n"
|
||||
"{\n"
|
||||
" VertToFrag vtf;\n"
|
||||
" constant VertData& v = va[instId];\n"
|
||||
" vtf.color = v.colorIn * decal.moduColor;\n"
|
||||
" vtf.uv = v.uvsIn[vertId].xy;\n"
|
||||
" vtf.position = decal.mvp * v.posIn[vertId];\n"
|
||||
" return vtf;\n"
|
||||
"}\n";
|
||||
|
||||
static const char* FS_METAL_TEX =
|
||||
"#include <metal_stdlib>\n"
|
||||
"using namespace metal;\n"
|
||||
"struct VertToFrag\n"
|
||||
"{\n"
|
||||
" float4 position [[ position ]];\n"
|
||||
" float4 color;\n"
|
||||
" float2 uv;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"fragment float4 fmain(VertToFrag vtf [[ stage_in ]],\n"
|
||||
" sampler samp [[ sampler(0) ]],\n"
|
||||
" texture2d<float> tex0 [[ texture(0) ]])\n"
|
||||
"{\n"
|
||||
" return vtf.color * tex0.sample(samp, vtf.uv);\n"
|
||||
"}\n";
|
||||
|
||||
static const char* FS_METAL_TEX_REDTOALPHA =
|
||||
"#include <metal_stdlib>\n"
|
||||
"using namespace metal;\n"
|
||||
"struct VertToFrag\n"
|
||||
"{\n"
|
||||
" float4 position [[ position ]];\n"
|
||||
" float4 color;\n"
|
||||
" float2 uv;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"fragment float4 fmain(VertToFrag vtf [[ stage_in ]],\n"
|
||||
" sampler samp [[ sampler(0) ]],\n"
|
||||
" texture2d<float> tex0 [[ texture(0) ]])\n"
|
||||
"{\n"
|
||||
" return float4(vtf.color.rgb, tex0.sample(samp, vtf.uv).r);\n"
|
||||
"}\n";
|
||||
|
||||
static const char* VS_METAL_NOTEX =
|
||||
"#include <metal_stdlib>\n"
|
||||
"using namespace metal;\n"
|
||||
"struct VertData\n"
|
||||
"{\n"
|
||||
" float4 posIn[4];\n"
|
||||
" float4 colorIn;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"struct DecalUniform\n"
|
||||
"{\n"
|
||||
" float4x4 mvp;\n"
|
||||
" float4 moduColor;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"struct VertToFrag\n"
|
||||
"{\n"
|
||||
" float4 position [[ position ]];\n"
|
||||
" float4 color;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"vertex VertToFrag vmain(constant VertData* va [[ buffer(1) ]],\n"
|
||||
" uint vertId [[ vertex_id ]], uint instId [[ instance_id ]],\n"
|
||||
" constant DecalUniform& decal [[ buffer(2) ]])\n"
|
||||
"{\n"
|
||||
" VertToFrag vtf;\n"
|
||||
" constant VertData& v = va[instId];\n"
|
||||
" vtf.color = v.colorIn * decal.moduColor;\n"
|
||||
" vtf.position = decal.mvp * v.posIn[vertId];\n"
|
||||
" return vtf;\n"
|
||||
"}\n";
|
||||
|
||||
static const char* FS_METAL_NOTEX =
|
||||
"#include <metal_stdlib>\n"
|
||||
"using namespace metal;\n"
|
||||
"struct VertToFrag\n"
|
||||
"{\n"
|
||||
" float4 position [[ position ]];\n"
|
||||
" float4 color;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"fragment float4 fmain(VertToFrag vtf [[ stage_in ]])\n"
|
||||
"{\n"
|
||||
" return vtf.color;\n"
|
||||
"}\n";
|
||||
|
||||
struct MetalDecalDataBindingFactory : TShader<CDecalShaders>::IDataBindingFactory
|
||||
{
|
||||
boo::ObjToken<boo::IShaderDataBinding> BuildShaderDataBinding(boo::IGraphicsDataFactory::Context& ctx,
|
||||
CDecalShaders& shader)
|
||||
{
|
||||
CQuadDecal& decal = shader.m_decal;
|
||||
const SQuadDescr* desc = decal.m_desc;
|
||||
|
||||
CUVElement* texr = desc->x14_TEX.get();
|
||||
int texCount = 0;
|
||||
boo::ObjToken<boo::ITexture> textures[1];
|
||||
|
||||
if (texr)
|
||||
{
|
||||
textures[0] = texr->GetValueTexture(0).GetObj()->GetBooTexture();
|
||||
texCount = 1;
|
||||
}
|
||||
|
||||
if (decal.m_instBuf)
|
||||
{
|
||||
boo::ObjToken<boo::IGraphicsBuffer> uniforms[] = {decal.m_uniformBuf.get()};
|
||||
|
||||
if (shader.m_regPipeline)
|
||||
decal.m_normalDataBind = ctx.newShaderDataBinding(shader.m_regPipeline, nullptr, nullptr,
|
||||
decal.m_instBuf.get(), nullptr, 1, uniforms,
|
||||
nullptr, texCount, textures, nullptr, nullptr);
|
||||
if (shader.m_redToAlphaPipeline)
|
||||
decal.m_redToAlphaDataBind = ctx.newShaderDataBinding(shader.m_redToAlphaPipeline, nullptr, nullptr,
|
||||
decal.m_instBuf.get(), nullptr, 1, uniforms,
|
||||
nullptr, texCount, textures, nullptr, nullptr);
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
};
|
||||
|
||||
TShader<CDecalShaders>::IDataBindingFactory* CDecalShaders::Initialize(boo::MetalDataFactory::Context& ctx)
|
||||
{
|
||||
static const boo::VertexElementDescriptor TexFmtTex[] =
|
||||
{
|
||||
{nullptr, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 0},
|
||||
{nullptr, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 1},
|
||||
{nullptr, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 2},
|
||||
{nullptr, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 3},
|
||||
{nullptr, nullptr, boo::VertexSemantic::Color | boo::VertexSemantic::Instanced},
|
||||
{nullptr, nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 0},
|
||||
{nullptr, nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 1},
|
||||
{nullptr, nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 2},
|
||||
{nullptr, nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 3}
|
||||
};
|
||||
m_vtxFormatTex = ctx.newVertexFormat(9, TexFmtTex);
|
||||
|
||||
static const boo::VertexElementDescriptor TexFmtNoTex[] =
|
||||
{
|
||||
{nullptr, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 0},
|
||||
{nullptr, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 1},
|
||||
{nullptr, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 2},
|
||||
{nullptr, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 3},
|
||||
{nullptr, nullptr, boo::VertexSemantic::Color | boo::VertexSemantic::Instanced}
|
||||
};
|
||||
m_vtxFormatNoTex = ctx.newVertexFormat(5, TexFmtNoTex);
|
||||
|
||||
m_texZTestNoZWrite = ctx.newShaderPipeline(VS_METAL_TEX, FS_METAL_TEX, nullptr, nullptr, m_vtxFormatTex,
|
||||
boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha,
|
||||
boo::Primitive::TriStrips, boo::ZTest::LEqual, false, true, false, boo::CullMode::None);
|
||||
|
||||
m_texAdditiveZTest = ctx.newShaderPipeline(VS_METAL_TEX, FS_METAL_TEX, nullptr, nullptr, m_vtxFormatTex,
|
||||
boo::BlendFactor::SrcAlpha, boo::BlendFactor::One,
|
||||
boo::Primitive::TriStrips, boo::ZTest::LEqual, false, true, false, boo::CullMode::None);
|
||||
|
||||
m_texRedToAlphaZTest = ctx.newShaderPipeline(VS_METAL_TEX, FS_METAL_TEX_REDTOALPHA, nullptr, nullptr, m_vtxFormatTex,
|
||||
boo::BlendFactor::One, boo::BlendFactor::One,
|
||||
boo::Primitive::TriStrips, boo::ZTest::LEqual, false, true, true, boo::CullMode::None);
|
||||
|
||||
m_noTexZTestNoZWrite = ctx.newShaderPipeline(VS_METAL_NOTEX, FS_METAL_NOTEX, nullptr, nullptr, m_vtxFormatNoTex,
|
||||
boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha,
|
||||
boo::Primitive::TriStrips, boo::ZTest::LEqual, false, true, false, boo::CullMode::None);
|
||||
|
||||
m_noTexAdditiveZTest = ctx.newShaderPipeline(VS_METAL_NOTEX, FS_METAL_NOTEX, nullptr, nullptr, m_vtxFormatNoTex,
|
||||
boo::BlendFactor::SrcAlpha, boo::BlendFactor::One,
|
||||
boo::Primitive::TriStrips, boo::ZTest::LEqual, false, true, false, boo::CullMode::None);
|
||||
|
||||
return new struct MetalDecalDataBindingFactory;
|
||||
}
|
||||
|
||||
template <>
|
||||
void CDecalShaders::Shutdown<boo::MetalDataFactory>()
|
||||
{
|
||||
m_texZTestNoZWrite.reset();
|
||||
m_texAdditiveZTest.reset();
|
||||
m_texRedToAlphaZTest.reset();
|
||||
|
||||
m_noTexZTestNoZWrite.reset();
|
||||
m_noTexAdditiveZTest.reset();
|
||||
|
||||
m_vtxFormatTex.reset();
|
||||
m_vtxFormatNoTex.reset();
|
||||
}
|
||||
|
||||
}
|
|
@ -19,6 +19,14 @@ CMFGame::CMFGame(const std::weak_ptr<CStateManager>& stateMgr, const std::weak_p
|
|||
static_cast<CMain&>(*g_Main).SetMFGameBuilt(true);
|
||||
}
|
||||
|
||||
CMFGame::~CMFGame()
|
||||
{
|
||||
CMain& main = static_cast<CMain&>(*g_Main);
|
||||
main.SetMFGameBuilt(false);
|
||||
main.SetScreenFading(false);
|
||||
CDecalManager::Reinitialize();
|
||||
}
|
||||
|
||||
CIOWin::EMessageReturn CMFGame::OnMessage(const CArchitectureMessage& msg, CArchitectureQueue& queue)
|
||||
{
|
||||
switch (msg.GetType())
|
||||
|
|
|
@ -50,6 +50,7 @@ class CMFGame : public CMFGameBase
|
|||
public:
|
||||
CMFGame(const std::weak_ptr<CStateManager>& stateMgr, const std::weak_ptr<CInGameGuiManager>& guiMgr,
|
||||
const CArchitectureQueue&);
|
||||
~CMFGame();
|
||||
CIOWin::EMessageReturn OnMessage(const CArchitectureMessage& msg, CArchitectureQueue& queue);
|
||||
void Touch();
|
||||
void Draw() const;
|
||||
|
|
|
@ -1,38 +1,56 @@
|
|||
#include "CDecal.hpp"
|
||||
#include "CParticleGlobals.hpp"
|
||||
#include "Graphics/Shaders/CDecalShaders.hpp"
|
||||
#include "Graphics/CModel.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
CRandom16 CDecal::sDecalRandom(99);
|
||||
bool CDecal::sMoveRedToAphaBuffer = false;
|
||||
bool CDecal::sMoveRedToAlphaBuffer = false;
|
||||
|
||||
CDecal::CDecal(const TToken<CDecalDescription>& desc, const zeus::CTransform& xf)
|
||||
: x0_description(desc),
|
||||
xc_transform(xf),
|
||||
x3c_decalQuad1(0, 0.f),
|
||||
x48_decalQuad2(0, 0.f)
|
||||
: x0_description(desc),
|
||||
xc_transform(xf)
|
||||
{
|
||||
CGlobalRandom gr(sDecalRandom);
|
||||
|
||||
x5c_31_quad1Invalid = InitQuad(x3c_decalQuad1, x0_description.GetObj()->x0_Quad);
|
||||
x5c_30_quad2Invalid = InitQuad(x48_decalQuad2, x0_description.GetObj()->x1c_Quad);
|
||||
CDecalDescription& desco = *x0_description;
|
||||
x5c_31_quad1Invalid = InitQuad(x3c_decalQuads[0], desco.x0_Quads[0]);
|
||||
x5c_30_quad2Invalid = InitQuad(x3c_decalQuads[1], desco.x0_Quads[1]);
|
||||
|
||||
CDecalDescription* d = x0_description.GetObj();
|
||||
if (d->x38_DMDL)
|
||||
{
|
||||
if (d->x48_DLFT)
|
||||
d->x48_DLFT->GetValue(0, x54_lifetime);
|
||||
d->x48_DLFT->GetValue(0, x54_modelLifetime);
|
||||
else
|
||||
x54_lifetime = 0x7FFFFF;
|
||||
x54_modelLifetime = 0x7FFFFF;
|
||||
|
||||
if (d->x50_DMRT)
|
||||
d->x50_DMRT->GetValue(0, x60_rotation);
|
||||
}
|
||||
else
|
||||
x5c_29_modelInvalid = true;
|
||||
|
||||
CGraphics::CommitResources([this](boo::IGraphicsDataFactory::Context& ctx)
|
||||
{
|
||||
for (int i=0 ; i<2 ; ++i)
|
||||
{
|
||||
CQuadDecal& decal = x3c_decalQuads[i];
|
||||
if (decal.m_desc->x14_TEX)
|
||||
decal.m_instBuf = ctx.newDynamicBuffer(boo::BufferUse::Vertex, sizeof(SParticleInstanceTex), 1);
|
||||
else
|
||||
decal.m_instBuf = ctx.newDynamicBuffer(boo::BufferUse::Vertex, sizeof(SParticleInstanceNoTex), 1);
|
||||
decal.m_uniformBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(SParticleUniforms), 1);
|
||||
CDecalShaders::BuildShaderDataBinding(ctx, decal);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
bool CDecal::InitQuad(CDecal::CQuadDecal& quad, const CDecalDescription::SQuadDescr& desc)
|
||||
bool CDecal::InitQuad(CQuadDecal& quad, const SQuadDescr& desc)
|
||||
{
|
||||
quad.m_desc = &desc;
|
||||
if (desc.x14_TEX)
|
||||
{
|
||||
if (desc.x0_LFT)
|
||||
|
@ -70,11 +88,237 @@ void CDecal::SetGlobalSeed(u16 seed)
|
|||
|
||||
void CDecal::SetMoveRedToAlphaBuffer(bool move)
|
||||
{
|
||||
sMoveRedToAphaBuffer = move;
|
||||
sMoveRedToAlphaBuffer = move;
|
||||
}
|
||||
|
||||
void CDecal::RenderQuad(CQuadDecal& decal, const SQuadDescr& desc) const
|
||||
{
|
||||
zeus::CColor color = zeus::CColor::skWhite;
|
||||
float size = 1.f;
|
||||
zeus::CVector3f offset;
|
||||
if (CColorElement* clr = desc.x10_CLR.get())
|
||||
clr->GetValue(x58_frameIdx, color);
|
||||
if (CRealElement* sze = desc.x4_SZE.get())
|
||||
{
|
||||
sze->GetValue(x58_frameIdx, size);
|
||||
size *= 0.5f;
|
||||
}
|
||||
if (CRealElement* rot = desc.x8_ROT.get())
|
||||
rot->GetValue(x58_frameIdx, decal.x8_rotation);
|
||||
if (CVectorElement* off = desc.xc_OFF.get())
|
||||
{
|
||||
off->GetValue(x58_frameIdx, offset);
|
||||
offset.y = 0.f;
|
||||
}
|
||||
zeus::CTransform modXf = xc_transform;
|
||||
modXf.origin += offset;
|
||||
CGraphics::SetModelMatrix(modXf);
|
||||
|
||||
SParticleUniforms uniformData =
|
||||
{
|
||||
CGraphics::GetPerspectiveProjectionMatrix(true) * CGraphics::g_GXModelView.toMatrix4f(),
|
||||
{1.f, 1.f, 1.f, 1.f}
|
||||
};
|
||||
decal.m_uniformBuf->load(&uniformData, sizeof(SParticleUniforms));
|
||||
|
||||
bool redToAlpha = sMoveRedToAlphaBuffer && desc.x18_ADD && desc.x14_TEX;
|
||||
|
||||
SUVElementSet uvSet = {0.f, 1.f, 0.f, 1.f};
|
||||
if (CUVElement* tex = desc.x14_TEX.get())
|
||||
{
|
||||
TLockedToken<CTexture> texObj = tex->GetValueTexture(x58_frameIdx);
|
||||
if (!texObj.IsLoaded())
|
||||
return;
|
||||
tex->GetValueUV(x58_frameIdx, uvSet);
|
||||
if (redToAlpha)
|
||||
CGraphics::SetShaderDataBinding(decal.m_redToAlphaDataBind);
|
||||
else
|
||||
CGraphics::SetShaderDataBinding(decal.m_normalDataBind);
|
||||
|
||||
g_instTexData.clear();
|
||||
g_instTexData.reserve(1);
|
||||
|
||||
g_instTexData.emplace_back();
|
||||
SParticleInstanceTex& inst = g_instTexData.back();
|
||||
if (decal.x8_rotation == 0.f)
|
||||
{
|
||||
inst.pos[0] = zeus::CVector3f(-size, 0.001f, size);
|
||||
inst.pos[1] = zeus::CVector3f(size, 0.001f, size);
|
||||
inst.pos[2] = zeus::CVector3f(-size, 0.001f, -size);
|
||||
inst.pos[3] = zeus::CVector3f(size, 0.001f, -size);
|
||||
}
|
||||
else
|
||||
{
|
||||
float ang = zeus::degToRad(decal.x8_rotation);
|
||||
float sinSize = std::sin(ang) * size;
|
||||
float cosSize = std::cos(ang) * size;
|
||||
inst.pos[0] = zeus::CVector3f(sinSize - cosSize, 0.001f, cosSize + sinSize);
|
||||
inst.pos[1] = zeus::CVector3f(cosSize + sinSize, 0.001f, cosSize - sinSize);
|
||||
inst.pos[2] = zeus::CVector3f(-(cosSize + sinSize), 0.001f, -(cosSize - sinSize));
|
||||
inst.pos[3] = zeus::CVector3f(-sinSize + cosSize, 0.001f, -cosSize - sinSize);
|
||||
}
|
||||
inst.color = color;
|
||||
inst.uvs[0] = zeus::CVector2f(uvSet.xMin, uvSet.yMin);
|
||||
inst.uvs[1] = zeus::CVector2f(uvSet.xMax, uvSet.yMin);
|
||||
inst.uvs[2] = zeus::CVector2f(uvSet.xMin, uvSet.yMax);
|
||||
inst.uvs[3] = zeus::CVector2f(uvSet.xMax, uvSet.yMax);
|
||||
|
||||
decal.m_instBuf->load(g_instTexData.data(), g_instTexData.size() * sizeof(SParticleInstanceTex));
|
||||
CGraphics::DrawInstances(0, 4, g_instTexData.size());
|
||||
}
|
||||
else
|
||||
{
|
||||
g_instNoTexData.clear();
|
||||
g_instNoTexData.reserve(1);
|
||||
|
||||
g_instNoTexData.emplace_back();
|
||||
SParticleInstanceNoTex& inst = g_instNoTexData.back();
|
||||
if (decal.x8_rotation == 0.f)
|
||||
{
|
||||
inst.pos[0] = zeus::CVector3f(-size, 0.001f, size);
|
||||
inst.pos[1] = zeus::CVector3f(size, 0.001f, size);
|
||||
inst.pos[2] = zeus::CVector3f(-size, 0.001f, -size);
|
||||
inst.pos[3] = zeus::CVector3f(size, 0.001f, -size);
|
||||
}
|
||||
else
|
||||
{
|
||||
float ang = zeus::degToRad(decal.x8_rotation);
|
||||
float sinSize = std::sin(ang) * size;
|
||||
float cosSize = std::cos(ang) * size;
|
||||
inst.pos[0] = zeus::CVector3f(sinSize - cosSize, 0.001f, cosSize + sinSize);
|
||||
inst.pos[1] = zeus::CVector3f(cosSize + sinSize, 0.001f, cosSize - sinSize);
|
||||
inst.pos[2] = zeus::CVector3f(-(cosSize + sinSize), 0.001f, -(cosSize - sinSize));
|
||||
inst.pos[3] = zeus::CVector3f(-sinSize + cosSize, 0.001f, -cosSize - sinSize);
|
||||
}
|
||||
inst.color = color;
|
||||
|
||||
decal.m_instBuf->load(g_instNoTexData.data(), g_instNoTexData.size() * sizeof(SParticleInstanceNoTex));
|
||||
CGraphics::DrawInstances(0, 4, g_instNoTexData.size());
|
||||
}
|
||||
}
|
||||
|
||||
void CDecal::RenderMdl() const
|
||||
{
|
||||
const CDecalDescription& desc = *x0_description;
|
||||
zeus::CColor color = zeus::CColor::skWhite;
|
||||
zeus::CVector3f dmop;
|
||||
zeus::CTransform rotXf;
|
||||
|
||||
if (!desc.x5c_25_DMOO)
|
||||
rotXf = xc_transform.getRotation();
|
||||
|
||||
bool dmrtIsConst = false;
|
||||
if (CVectorElement* dmrt = desc.x50_DMRT.get())
|
||||
dmrtIsConst = dmrt->IsFastConstant();
|
||||
|
||||
zeus::CTransform dmrtXf;
|
||||
if (dmrtIsConst)
|
||||
{
|
||||
desc.x50_DMRT->GetValue(x58_frameIdx, const_cast<zeus::CVector3f&>(x60_rotation));
|
||||
dmrtXf = zeus::CTransform::RotateZ(zeus::degToRad(x60_rotation.z));
|
||||
dmrtXf.rotateLocalY(zeus::degToRad(x60_rotation.y));
|
||||
dmrtXf.rotateLocalX(zeus::degToRad(x60_rotation.x));
|
||||
}
|
||||
|
||||
dmrtXf = rotXf * dmrtXf;
|
||||
|
||||
if (CVectorElement* dmopo = desc.x4c_DMOP.get())
|
||||
dmopo->GetValue(x58_frameIdx, dmop);
|
||||
|
||||
zeus::CTransform worldXf = zeus::CTransform::Translate(rotXf * dmop + xc_transform.origin);
|
||||
|
||||
if (dmrtIsConst)
|
||||
{
|
||||
worldXf = worldXf * dmrtXf;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (CVectorElement* dmrt = desc.x50_DMRT.get())
|
||||
{
|
||||
zeus::CVector3f dmrtVec;
|
||||
dmrt->GetValue(x58_frameIdx, dmrtVec);
|
||||
dmrtXf = zeus::CTransform::RotateZ(zeus::degToRad(dmrtVec.z));
|
||||
dmrtXf.rotateLocalY(zeus::degToRad(dmrtVec.y));
|
||||
dmrtXf.rotateLocalX(zeus::degToRad(dmrtVec.x));
|
||||
worldXf = worldXf * rotXf * dmrtXf;
|
||||
}
|
||||
else
|
||||
{
|
||||
worldXf = worldXf * dmrtXf;
|
||||
}
|
||||
}
|
||||
|
||||
if (CVectorElement* dmsc = desc.x54_DMSC.get())
|
||||
{
|
||||
zeus::CVector3f dmscVec;
|
||||
dmsc->GetValue(x58_frameIdx, dmscVec);
|
||||
worldXf = worldXf * zeus::CTransform::Scale(dmscVec);
|
||||
}
|
||||
|
||||
if (CColorElement* dmcl = desc.x58_DMCL.get())
|
||||
dmcl->GetValue(x58_frameIdx, color);
|
||||
|
||||
CGraphics::SetModelMatrix(worldXf);
|
||||
|
||||
if (desc.x5c_24_DMAB)
|
||||
{
|
||||
CModelFlags flags(7, 0, 1, color);
|
||||
desc.x38_DMDL.m_token->Draw(flags);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (color.a == 1.f)
|
||||
{
|
||||
CModelFlags flags(0, 0, 3, zeus::CColor::skWhite);
|
||||
desc.x38_DMDL.m_token->Draw(flags);
|
||||
}
|
||||
else
|
||||
{
|
||||
CModelFlags flags(5, 0, 1, color);
|
||||
desc.x38_DMDL.m_token->Draw(flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CDecal::Render() const
|
||||
{
|
||||
CGlobalRandom gr(sDecalRandom);
|
||||
if (x5c_29_modelInvalid && x5c_30_quad2Invalid && x5c_31_quad1Invalid)
|
||||
return;
|
||||
|
||||
CGraphics::DisableAllLights();
|
||||
CParticleGlobals::SetEmitterTime(x58_frameIdx);
|
||||
|
||||
const CDecalDescription& desc = *x0_description;
|
||||
if (desc.x0_Quads[0].x14_TEX && !x5c_31_quad1Invalid)
|
||||
{
|
||||
CParticleGlobals::SetParticleLifetime(x3c_decalQuads[0].x4_lifetime);
|
||||
CParticleGlobals::UpdateParticleLifetimeTweenValues(x58_frameIdx);
|
||||
RenderQuad(const_cast<CQuadDecal&>(x3c_decalQuads[0]), desc.x0_Quads[0]);
|
||||
}
|
||||
if (desc.x0_Quads[1].x14_TEX && !x5c_30_quad2Invalid)
|
||||
{
|
||||
CParticleGlobals::SetParticleLifetime(x3c_decalQuads[1].x4_lifetime);
|
||||
CParticleGlobals::UpdateParticleLifetimeTweenValues(x58_frameIdx);
|
||||
RenderQuad(const_cast<CQuadDecal&>(x3c_decalQuads[1]), desc.x0_Quads[1]);
|
||||
}
|
||||
if (desc.x38_DMDL && !x5c_29_modelInvalid)
|
||||
{
|
||||
CParticleGlobals::SetParticleLifetime(x54_modelLifetime);
|
||||
CParticleGlobals::UpdateParticleLifetimeTweenValues(x58_frameIdx);
|
||||
RenderMdl();
|
||||
}
|
||||
}
|
||||
|
||||
void CDecal::Update(float dt)
|
||||
{
|
||||
if (x58_frameIdx >= x3c_decalQuads[0].x4_lifetime)
|
||||
x5c_31_quad1Invalid = true;
|
||||
if (x58_frameIdx >= x3c_decalQuads[1].x4_lifetime)
|
||||
x5c_30_quad2Invalid = true;
|
||||
if (x58_frameIdx >= x54_modelLifetime)
|
||||
x5c_29_modelInvalid = true;
|
||||
++x58_frameIdx;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,38 +9,44 @@
|
|||
|
||||
namespace urde
|
||||
{
|
||||
struct SQuadDescr;
|
||||
struct CQuadDecal
|
||||
{
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
bool x0_24_invalid : 1;
|
||||
};
|
||||
u32 _dummy = 0;
|
||||
};
|
||||
s32 x4_lifetime = 0;
|
||||
float x8_rotation = 0.f;
|
||||
const SQuadDescr* m_desc = nullptr;
|
||||
CQuadDecal() = default;
|
||||
CQuadDecal(s32 i, float f)
|
||||
: x4_lifetime(i),
|
||||
x8_rotation(f)
|
||||
{
|
||||
x0_24_invalid = true;
|
||||
}
|
||||
|
||||
boo::ObjToken<boo::IGraphicsBufferD> m_instBuf;
|
||||
boo::ObjToken<boo::IGraphicsBufferD> m_uniformBuf;
|
||||
boo::ObjToken<boo::IShaderDataBinding> m_normalDataBind;
|
||||
boo::ObjToken<boo::IShaderDataBinding> m_redToAlphaDataBind;
|
||||
};
|
||||
|
||||
class CDecal
|
||||
{
|
||||
friend class CDecalManager;
|
||||
public:
|
||||
struct CQuadDecal
|
||||
{
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
bool x0_24_invalid : 1;
|
||||
};
|
||||
u32 _dummy = 0;
|
||||
};
|
||||
s32 x4_lifetime = 0;
|
||||
float x8_rotation = 0.f;
|
||||
CQuadDecal(s32 i, float f)
|
||||
: x4_lifetime(i),
|
||||
x8_rotation(f)
|
||||
{
|
||||
x0_24_invalid = true;
|
||||
}
|
||||
};
|
||||
private:
|
||||
static bool sMoveRedToAphaBuffer;
|
||||
static bool sMoveRedToAlphaBuffer;
|
||||
static CRandom16 sDecalRandom;
|
||||
|
||||
TLockedToken<CDecalDescription> x0_description;
|
||||
zeus::CTransform xc_transform;
|
||||
CQuadDecal x3c_decalQuad1;
|
||||
CQuadDecal x48_decalQuad2;
|
||||
s32 x54_lifetime = 0;
|
||||
CQuadDecal x3c_decalQuads[2];
|
||||
s32 x54_modelLifetime = 0;
|
||||
s32 x58_frameIdx = 0;
|
||||
union
|
||||
{
|
||||
|
@ -53,16 +59,13 @@ private:
|
|||
u32 x5c_dummy = 0;
|
||||
};
|
||||
zeus::CVector3f x60_rotation;
|
||||
bool InitQuad(CQuadDecal&, const CDecalDescription::SQuadDescr&);
|
||||
bool InitQuad(CQuadDecal& quad, const SQuadDescr& desc);
|
||||
public:
|
||||
CDecal(const TToken<CDecalDescription>&, const zeus::CTransform&);
|
||||
bool IsDone() const;
|
||||
void RenderQuad(CQuadDecal&, const CDecalDescription::SQuadDescr&) const;
|
||||
CDecal(const TToken<CDecalDescription>& desc, const zeus::CTransform& xf);
|
||||
void RenderQuad(CQuadDecal& decal, const SQuadDescr& desc) const;
|
||||
void RenderMdl() const;
|
||||
void Render() const;
|
||||
void ProcessQuad(CQuadDecal&, const CDecalDescription::SQuadDescr&, s32) const;
|
||||
void Update(float);
|
||||
void CheckTime(s32, s32);
|
||||
void Update(float dt);
|
||||
|
||||
static void SetGlobalSeed(u16);
|
||||
static void SetMoveRedToAlphaBuffer(bool);
|
||||
|
|
|
@ -58,9 +58,9 @@ bool CDecalDataFactory::CreateDPSM(CDecalDescription* desc, CInputStream& in, CS
|
|||
case SBIG('2TEX'):
|
||||
case SBIG('2ADD'):
|
||||
if (loadFirstDesc)
|
||||
GetQuadDecalInfo(in, resPool, clsId, desc->x0_Quad);
|
||||
GetQuadDecalInfo(in, resPool, clsId, desc->x0_Quads[0]);
|
||||
else
|
||||
GetQuadDecalInfo(in, resPool, clsId, desc->x1c_Quad);
|
||||
GetQuadDecalInfo(in, resPool, clsId, desc->x0_Quads[1]);
|
||||
break;
|
||||
|
||||
case SBIG('DMDL'):
|
||||
|
@ -100,8 +100,7 @@ bool CDecalDataFactory::CreateDPSM(CDecalDescription* desc, CInputStream& in, CS
|
|||
return true;
|
||||
}
|
||||
|
||||
void CDecalDataFactory::GetQuadDecalInfo(CInputStream& in, CSimplePool* resPool, FourCC clsId,
|
||||
CDecalDescription::SQuadDescr& quad)
|
||||
void CDecalDataFactory::GetQuadDecalInfo(CInputStream& in, CSimplePool* resPool, FourCC clsId, SQuadDescr& quad)
|
||||
{
|
||||
switch (clsId)
|
||||
{
|
||||
|
|
|
@ -16,8 +16,7 @@ class CDecalDataFactory
|
|||
{
|
||||
static bool CreateDPSM(CDecalDescription* desc, CInputStream& in, CSimplePool* resPool);
|
||||
static CDecalDescription* CreateGeneratorDescription(CInputStream& in, CSimplePool* resPool);
|
||||
static void GetQuadDecalInfo(CInputStream& in, CSimplePool* resPool, FourCC clsId,
|
||||
CDecalDescription::SQuadDescr& quad);
|
||||
static void GetQuadDecalInfo(CInputStream& in, CSimplePool* resPool, FourCC clsId, SQuadDescr& quad);
|
||||
|
||||
public:
|
||||
static CDecalDescription* GetGeneratorDesc(CInputStream& in, CSimplePool* resPool);
|
||||
|
|
|
@ -10,22 +10,22 @@
|
|||
|
||||
namespace urde
|
||||
{
|
||||
|
||||
struct SQuadDescr
|
||||
{
|
||||
std::unique_ptr<CIntElement> x0_LFT;
|
||||
std::unique_ptr<CRealElement> x4_SZE;
|
||||
std::unique_ptr<CRealElement> x8_ROT;
|
||||
std::unique_ptr<CVectorElement> xc_OFF;
|
||||
std::unique_ptr<CColorElement> x10_CLR;
|
||||
std::unique_ptr<CUVElement> x14_TEX;
|
||||
bool x18_ADD = false;
|
||||
};
|
||||
|
||||
class CDecalDescription
|
||||
{
|
||||
public:
|
||||
struct SQuadDescr
|
||||
{
|
||||
std::unique_ptr<CIntElement> x0_LFT;
|
||||
std::unique_ptr<CRealElement> x4_SZE;
|
||||
std::unique_ptr<CRealElement> x8_ROT;
|
||||
std::unique_ptr<CVectorElement> xc_OFF;
|
||||
std::unique_ptr<CColorElement> x10_CLR;
|
||||
std::unique_ptr<CUVElement> x14_TEX;
|
||||
bool x18_ADD = false;
|
||||
};
|
||||
|
||||
SQuadDescr x0_Quad;
|
||||
SQuadDescr x1c_Quad;
|
||||
SQuadDescr x0_Quads[2];
|
||||
SParticleModel x38_DMDL;
|
||||
std::unique_ptr<CIntElement> x48_DLFT;
|
||||
std::unique_ptr<CVectorElement> x4c_DMOP;
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "CStateManager.hpp"
|
||||
#include "Graphics/CBooRenderer.hpp"
|
||||
#include "GameGlobalObjects.hpp"
|
||||
#include "Graphics/Shaders/CDecalShaders.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
|
@ -15,24 +16,46 @@ CAssetId CDecalManager::m_LastDecalCreatedAssetId = -1;
|
|||
rstl::reserved_vector<CDecalManager::SDecal, 64> CDecalManager::m_DecalPool;
|
||||
rstl::reserved_vector<s32, 64> CDecalManager::m_ActiveIndexList;
|
||||
|
||||
URDE_DECL_SPECIALIZE_SHADER(CDecalShaders)
|
||||
|
||||
void CDecalManager::Initialize()
|
||||
{
|
||||
if (m_PoolInitialized)
|
||||
return;
|
||||
|
||||
m_DecalPool.clear();
|
||||
m_DecalPool.resize(64);
|
||||
for (int i=0 ; i<64 ; ++i)
|
||||
m_DecalPool.emplace_back(std::experimental::optional<CDecal>{}, 0, i-1, false);
|
||||
|
||||
m_FreeIndex = 63;
|
||||
m_PoolInitialized = true;
|
||||
m_DeltaTimeSinceLastDecalCreation = 0.f;
|
||||
m_LastDecalCreatedIndex = -1;
|
||||
m_LastDecalCreatedAssetId = -1;
|
||||
|
||||
/* Compile shaders */
|
||||
TShader<CDecalShaders>::Initialize();
|
||||
}
|
||||
|
||||
void CDecalManager::Reinitialize()
|
||||
{
|
||||
if (!m_PoolInitialized)
|
||||
Initialize();
|
||||
|
||||
m_DecalPool.clear();
|
||||
for (int i=0 ; i<64 ; ++i)
|
||||
m_DecalPool.emplace_back(std::experimental::optional<CDecal>{}, 0, i-1, false);
|
||||
|
||||
m_ActiveIndexList.clear();
|
||||
|
||||
m_FreeIndex = 63;
|
||||
}
|
||||
|
||||
void CDecalManager::Shutdown()
|
||||
{
|
||||
|
||||
m_ActiveIndexList.clear();
|
||||
m_DecalPool.clear();
|
||||
TShader<CDecalShaders>::Shutdown();
|
||||
}
|
||||
|
||||
void CDecalManager::AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr)
|
||||
|
@ -40,7 +63,7 @@ void CDecalManager::AddToRenderer(const zeus::CFrustum& frustum, const CStateMan
|
|||
for (s32 idx : m_ActiveIndexList)
|
||||
{
|
||||
CDecalManager::SDecal& decal = m_DecalPool[idx];
|
||||
if (decal.x75_flags & 0x2 || mgr.GetThermalDrawFlag() != EThermalDrawFlag::Hot)
|
||||
if (decal.x75_24_notIce || mgr.GetThermalDrawFlag() != EThermalDrawFlag::Hot)
|
||||
{
|
||||
const zeus::CVector3f& point = decal.x0_decal->xc_transform.origin;
|
||||
zeus::CAABox aabb(point, point);
|
||||
|
@ -50,15 +73,61 @@ void CDecalManager::AddToRenderer(const zeus::CFrustum& frustum, const CStateMan
|
|||
}
|
||||
}
|
||||
|
||||
rstl::reserved_vector<s32, 64>::iterator
|
||||
CDecalManager::RemoveFromActiveList(rstl::reserved_vector<s32, 64>::iterator it, s32 idx)
|
||||
{
|
||||
it = m_ActiveIndexList.erase(it);
|
||||
m_DecalPool[idx].x74_index = u8(m_FreeIndex);
|
||||
m_FreeIndex = idx;
|
||||
if (m_LastDecalCreatedIndex == m_FreeIndex)
|
||||
m_LastDecalCreatedIndex = -1;
|
||||
return it;
|
||||
}
|
||||
|
||||
void CDecalManager::Update(float dt, CStateManager& mgr)
|
||||
{
|
||||
|
||||
m_DeltaTimeSinceLastDecalCreation += dt;
|
||||
for (auto it = m_ActiveIndexList.begin() ; it != m_ActiveIndexList.end() ;)
|
||||
{
|
||||
SDecal& decal = m_DecalPool[*it];
|
||||
if (decal.x70_areaId != mgr.GetNextAreaId() ||
|
||||
(decal.x0_decal->x5c_29_modelInvalid &&
|
||||
decal.x0_decal->x5c_30_quad2Invalid &&
|
||||
decal.x0_decal->x5c_31_quad1Invalid))
|
||||
{
|
||||
it = RemoveFromActiveList(it, *it);
|
||||
continue;
|
||||
}
|
||||
decal.x0_decal->Update(dt);
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
void CDecalManager::AddDecal(const TToken<CDecalDescription>& decal, const zeus::CTransform& xf,
|
||||
bool b1, CStateManager& mgr)
|
||||
bool notIce, CStateManager& mgr)
|
||||
{
|
||||
if (m_LastDecalCreatedIndex != -1 && m_DeltaTimeSinceLastDecalCreation < 0.75f &&
|
||||
m_LastDecalCreatedAssetId == decal.GetObjectTag()->id)
|
||||
{
|
||||
SDecal& existingDecal = m_DecalPool[m_LastDecalCreatedIndex];
|
||||
if ((existingDecal.x0_decal->xc_transform.origin - xf.origin).magSquared() < 0.01f)
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_FreeIndex == -1)
|
||||
RemoveFromActiveList(m_ActiveIndexList.begin(), m_ActiveIndexList[0]);
|
||||
|
||||
s32 thisIndex = m_FreeIndex;
|
||||
SDecal& freeDecal = m_DecalPool[thisIndex];
|
||||
m_FreeIndex = freeDecal.x74_index;
|
||||
freeDecal.x0_decal.emplace(decal, xf);
|
||||
|
||||
freeDecal.x70_areaId = mgr.GetNextAreaId();
|
||||
freeDecal.x75_24_notIce = notIce;
|
||||
m_DeltaTimeSinceLastDecalCreation = 0.f;
|
||||
m_LastDecalCreatedIndex = thisIndex;
|
||||
m_LastDecalCreatedAssetId = decal.GetObjectTag()->id;
|
||||
m_ActiveIndexList.push_back(thisIndex);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -18,8 +18,10 @@ class CDecalManager
|
|||
{
|
||||
std::experimental::optional<CDecal> x0_decal;
|
||||
TAreaId x70_areaId;
|
||||
u8 x74_index;
|
||||
u8 x75_flags : 2;
|
||||
s8 x74_index;
|
||||
bool x75_24_notIce : 1;
|
||||
SDecal(const std::experimental::optional<CDecal>& decal, TAreaId aid, s8 idx, bool notIce)
|
||||
: x0_decal(decal), x70_areaId(aid), x74_index(idx) { x75_24_notIce = notIce; }
|
||||
};
|
||||
|
||||
static bool m_PoolInitialized;
|
||||
|
@ -29,13 +31,16 @@ class CDecalManager
|
|||
static CAssetId m_LastDecalCreatedAssetId;
|
||||
static rstl::reserved_vector<SDecal, 64> m_DecalPool;
|
||||
static rstl::reserved_vector<s32, 64> m_ActiveIndexList;
|
||||
static rstl::reserved_vector<s32, 64>::iterator
|
||||
RemoveFromActiveList(rstl::reserved_vector<s32, 64>::iterator it, s32 idx);
|
||||
public:
|
||||
static void Initialize();
|
||||
static void Reinitialize();
|
||||
static void Shutdown();
|
||||
static void AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr);
|
||||
static void Update(float dt, CStateManager& mgr);
|
||||
static void AddDecal(const TToken<CDecalDescription>& decal, const zeus::CTransform& xf,
|
||||
bool b1, CStateManager& mgr);
|
||||
bool notIce, CStateManager& mgr);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -26,35 +26,9 @@ bool CElementGen::g_ParticleSystemInitialized = false;
|
|||
bool CElementGen::sMoveRedToAlphaBuffer = false;
|
||||
CParticle* CElementGen::g_currentParticle = nullptr;
|
||||
|
||||
struct SParticleInstanceTex
|
||||
{
|
||||
zeus::CVector4f pos[4];
|
||||
zeus::CColor color;
|
||||
zeus::CVector2f uvs[4];
|
||||
};
|
||||
static std::vector<SParticleInstanceTex> g_instTexData;
|
||||
|
||||
struct SParticleInstanceIndTex
|
||||
{
|
||||
zeus::CVector4f pos[4];
|
||||
zeus::CColor color;
|
||||
zeus::CVector4f texrTindUVs[4];
|
||||
zeus::CVector4f sceneUVs;
|
||||
};
|
||||
static std::vector<SParticleInstanceIndTex> g_instIndTexData;
|
||||
|
||||
struct SParticleInstanceNoTex
|
||||
{
|
||||
zeus::CVector4f pos[4];
|
||||
zeus::CColor color;
|
||||
};
|
||||
static std::vector<SParticleInstanceNoTex> g_instNoTexData;
|
||||
|
||||
struct SParticleUniforms
|
||||
{
|
||||
zeus::CMatrix4f mvp;
|
||||
zeus::CColor moduColor;
|
||||
};
|
||||
std::vector<SParticleInstanceTex> g_instTexData;
|
||||
std::vector<SParticleInstanceIndTex> g_instIndTexData;
|
||||
std::vector<SParticleInstanceNoTex> g_instNoTexData;
|
||||
|
||||
void CElementGen::Initialize()
|
||||
{
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
#define __URDE_CPARTICLEGLOBALS_HPP__
|
||||
|
||||
#include "zeus/CVector3f.hpp"
|
||||
#include "zeus/CVector4f.hpp"
|
||||
#include "zeus/CMatrix4f.hpp"
|
||||
#include "zeus/CColor.hpp"
|
||||
#include "RetroTypes.hpp"
|
||||
#include <array>
|
||||
|
@ -50,6 +52,36 @@ public:
|
|||
static SParticleSystem* g_currentParticleSystem;
|
||||
};
|
||||
|
||||
struct SParticleInstanceTex
|
||||
{
|
||||
zeus::CVector4f pos[4];
|
||||
zeus::CColor color;
|
||||
zeus::CVector2f uvs[4];
|
||||
};
|
||||
extern std::vector<SParticleInstanceTex> g_instTexData;
|
||||
|
||||
struct SParticleInstanceIndTex
|
||||
{
|
||||
zeus::CVector4f pos[4];
|
||||
zeus::CColor color;
|
||||
zeus::CVector4f texrTindUVs[4];
|
||||
zeus::CVector4f sceneUVs;
|
||||
};
|
||||
extern std::vector<SParticleInstanceIndTex> g_instIndTexData;
|
||||
|
||||
struct SParticleInstanceNoTex
|
||||
{
|
||||
zeus::CVector4f pos[4];
|
||||
zeus::CColor color;
|
||||
};
|
||||
extern std::vector<SParticleInstanceNoTex> g_instNoTexData;
|
||||
|
||||
struct SParticleUniforms
|
||||
{
|
||||
zeus::CMatrix4f mvp;
|
||||
zeus::CColor moduColor;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // __URDE_CPARTICLEGLOBALS_HPP__
|
||||
|
|
|
@ -338,6 +338,7 @@ bool CEnergyProjectile::Explode(const zeus::CVector3f& pos, const zeus::CVector3
|
|||
if (auto particle = x170_projectile.CollisionOccured(type, !done, retargetPlayer, offsetPos, normal, targetPos))
|
||||
{
|
||||
zeus::CTransform particleXf = zeus::lookAt(zeus::CVector3f::skZero, normal);
|
||||
particleXf.origin = offsetPos;
|
||||
if (xf0_weaponType != EWeaponType::Power ||
|
||||
!xf8_filter.GetExcludeList().HasMaterial(EMaterialTypes::Player) ||
|
||||
!x2e4_27_inWater)
|
||||
|
|
Loading…
Reference in New Issue