macOS decal rendering support

This commit is contained in:
Jack Andersen 2018-03-16 17:41:01 -10:00
parent 08569104c2
commit 7100ed437f
22 changed files with 1613 additions and 105 deletions

View File

@ -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"

View File

@ -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"

View File

@ -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];
}

View File

@ -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);

View File

@ -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

View File

@ -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)
}

View File

@ -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__

View File

@ -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
}

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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())

View File

@ -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;

View File

@ -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;
}
}
}

View File

@ -9,12 +9,9 @@
namespace urde
{
class CDecal
struct SQuadDescr;
struct CQuadDecal
{
friend class CDecalManager;
public:
struct CQuadDecal
{
union
{
struct
@ -25,22 +22,31 @@ public:
};
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;
}
};
private:
static bool sMoveRedToAphaBuffer;
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;
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);

View File

@ -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)
{

View File

@ -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);

View File

@ -10,11 +10,9 @@
namespace urde
{
class CDecalDescription
struct SQuadDescr
{
public:
struct SQuadDescr
{
std::unique_ptr<CIntElement> x0_LFT;
std::unique_ptr<CRealElement> x4_SZE;
std::unique_ptr<CRealElement> x8_ROT;
@ -22,10 +20,12 @@ public:
std::unique_ptr<CColorElement> x10_CLR;
std::unique_ptr<CUVElement> x14_TEX;
bool x18_ADD = false;
};
};
SQuadDescr x0_Quad;
SQuadDescr x1c_Quad;
class CDecalDescription
{
public:
SQuadDescr x0_Quads[2];
SParticleModel x38_DMDL;
std::unique_ptr<CIntElement> x48_DLFT;
std::unique_ptr<CVectorElement> x4c_DMOP;

View File

@ -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);
}
}

View File

@ -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);
};
}

View File

@ -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()
{

View File

@ -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__

View File

@ -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)