2
0
mirror of https://github.com/AxioDL/metaforce.git synced 2025-12-09 23:07:43 +00:00

Lots of initial CThermalColdFilter implementation

This commit is contained in:
Jack Andersen
2016-07-21 16:32:23 -10:00
parent 2ff1a2ee0b
commit a6477c635d
22 changed files with 607 additions and 136 deletions

View File

@@ -0,0 +1,82 @@
#include "CLineRendererShaders.hpp"
namespace urde
{
boo::IShaderPipeline* CLineRendererShaders::m_texAlpha = nullptr;
boo::IShaderPipeline* CLineRendererShaders::m_texAdditive = nullptr;
boo::IShaderPipeline* CLineRendererShaders::m_noTexAlpha = nullptr;
boo::IShaderPipeline* CLineRendererShaders::m_noTexAdditive = nullptr;
boo::IVertexFormat* CLineRendererShaders::m_texVtxFmt = nullptr;
boo::IVertexFormat* CLineRendererShaders::m_noTexVtxFmt = nullptr;
std::unique_ptr<CLineRendererShaders::IDataBindingFactory> CLineRendererShaders::m_bindFactory;
boo::GraphicsDataToken CLineRendererShaders::m_gfxToken;
void CLineRendererShaders::Initialize()
{
if (!CGraphics::g_BooFactory)
return;
m_gfxToken = CGraphics::CommitResources(
[&](boo::IGraphicsDataFactory::Context& ctx) -> bool
{
switch (ctx.platform())
{
case boo::IGraphicsDataFactory::Platform::OGL:
m_bindFactory.reset(Initialize(static_cast<boo::GLDataFactory::Context&>(ctx)));
break;
#if _WIN32
case boo::IGraphicsDataFactory::Platform::D3D11:
case boo::IGraphicsDataFactory::Platform::D3D12:
m_bindFactory.reset(Initialize(static_cast<boo::ID3DDataFactory::Context&>(ctx)));
break;
#endif
#if BOO_HAS_METAL
case boo::IGraphicsDataFactory::Platform::Metal:
m_bindFactory.reset(Initialize(static_cast<boo::MetalDataFactory::Context&>(ctx)));
break;
#endif
#if BOO_HAS_VULKAN
case boo::IGraphicsDataFactory::Platform::Vulkan:
m_bindFactory.reset(Initialize(static_cast<boo::VulkanDataFactory::Context&>(ctx)));
break;
#endif
default: break;
}
return true;
});
}
void CLineRendererShaders::Shutdown()
{
m_gfxToken.doDestroy();
}
void CLineRendererShaders::BuildShaderDataBinding(boo::IGraphicsDataFactory::Context& ctx,
CLineRenderer& renderer,
boo::ITexture* texture,
bool additive)
{
boo::IShaderPipeline* pipeline = nullptr;
if (texture)
{
if (additive)
pipeline = m_texAdditive;
else
pipeline = m_texAlpha;
}
else
{
if (additive)
pipeline = m_noTexAdditive;
else
pipeline = m_noTexAlpha;
}
m_bindFactory->BuildShaderDataBinding(ctx, renderer, pipeline, texture);
}
}

View File

@@ -0,0 +1,40 @@
#include "CModelShaders.hpp"
namespace urde
{
std::experimental::optional<CModelShaders> CModelShaders::g_ModelShaders;
hecl::Runtime::ShaderCacheExtensions
CModelShaders::GetShaderExtensions(boo::IGraphicsDataFactory::Platform plat)
{
switch (plat)
{
case boo::IGraphicsDataFactory::Platform::OGL:
case boo::IGraphicsDataFactory::Platform::Vulkan:
return GetShaderExtensionsGLSL(plat);
#if _WIN32
case boo::IGraphicsDataFactory::Platform::D3D11:
case boo::IGraphicsDataFactory::Platform::D3D12:
return GetShaderExtensionsHLSL(plat);
#endif
#if BOO_HAS_METAL
case boo::IGraphicsDataFactory::Platform::Metal:
return GetShaderExtensionsMetal(plat);
#endif
default:
return {boo::IGraphicsDataFactory::Platform::Null};
}
}
CModelShaders::CModelShaders(const hecl::Runtime::FileStoreManager& storeMgr,
boo::IGraphicsDataFactory* gfxFactory)
: m_shaderCache(storeMgr, gfxFactory, GetShaderExtensions(gfxFactory->platform())) {}
void CModelShaders::Initialize(const hecl::Runtime::FileStoreManager& storeMgr,
boo::IGraphicsDataFactory* gfxFactory)
{
g_ModelShaders.emplace(storeMgr, gfxFactory);
}
}

View File

@@ -13,7 +13,9 @@ namespace urde
class CModelShaders
{
friend class CModel;
hecl::Runtime::ShaderCacheManager m_shaderCache;
static std::experimental::optional<CModelShaders> g_ModelShaders;
static hecl::Runtime::ShaderCacheExtensions GetShaderExtensions(boo::IGraphicsDataFactory::Platform plat);
static hecl::Runtime::ShaderCacheExtensions GetShaderExtensionsGLSL(boo::IGraphicsDataFactory::Platform plat);
static hecl::Runtime::ShaderCacheExtensions GetShaderExtensionsHLSL(boo::IGraphicsDataFactory::Platform plat);

View File

@@ -0,0 +1,66 @@
#include "CThermalColdFilter.hpp"
#include "Graphics/CGraphics.hpp"
namespace urde
{
CThermalColdFilter::CThermalColdFilter()
{
m_token = CGraphics::g_BooFactory->commitTransaction([&](boo::IGraphicsDataFactory::Context& ctx) -> bool
{
m_shiftTex = ctx.newDynamicTexture(8, 8, boo::TextureFormat::RGBA8);
m_vbo = ctx.newDynamicBuffer(boo::BufferUse::Vertex, 32, 1);
m_uniBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(Uniform), 1);
m_dataBind = TFilterShader<CThermalColdFilter>::BuildShaderDataBinding(ctx, *this);
return true;
});
struct Vert
{
zeus::CVector2f m_pos;
zeus::CVector2f m_uv;
} verts[4] =
{
{{-1.0, -1.0}, {0.0, 0.0}},
{{-1.0, 1.0}, {0.0, 1.0}},
{{ 1.0, 1.0}, {1.0, 1.0}},
{{ 1.0, -1.0}, {1.0, 0.0}}
};
m_vbo->load(verts, sizeof(verts));
setShift(0);
}
void CThermalColdFilter::setShift(unsigned shift)
{
shift = std::min(shift, 31u);
for (unsigned y=0 ; y<4 ; ++y)
{
unsigned bx = y * 8;
for (unsigned x=0 ; x<8 ; ++x)
{
unsigned px = bx + x;
unsigned spx = px + shift;
unsigned ny = spx / 8;
if (ny > 3)
ny = 3;
unsigned nx = spx % 8;
m_shiftTexture[y][x][0] = nx / 7.f;
m_shiftTexture[y][x][1] = ny / 3.f;
}
}
m_shiftTex->load(m_shiftTexture[0][0], sizeof(m_shiftTexture));
}
void CThermalColdFilter::draw()
{
m_uniform.m_shiftTexMtx[0][0] = 80.f * CGraphics::g_ProjAspect;
m_uniform.m_shiftTexMtx[1][1] = 120.f;
m_uniBuf->load(&m_uniform, sizeof(m_uniform));
CGraphics::g_BooMainCommandQueue->setShaderDataBinding(m_dataBind);
CGraphics::g_BooMainCommandQueue->draw(0, 4);
}
URDE_SPECIALIZE_FILTER(CThermalColdFilter)
}

View File

@@ -0,0 +1,50 @@
#ifndef __URDE_CTHERMALCOLDFILTER_HPP__
#define __URDE_CTHERMALCOLDFILTER_HPP__
#include "TFilterShader.hpp"
#include "zeus/CMatrix4f.hpp"
#include "zeus/CColor.hpp"
namespace urde
{
class CThermalColdFilter
{
friend struct CThermalColdFilterGLDataBindingFactory;
friend struct CThermalColdFilterVulkanDataBindingFactory;
struct Uniform
{
zeus::CMatrix4f m_shiftTexMtx;
zeus::CMatrix4f m_indMtx;
zeus::CColor m_colorRegs[3];
};
u8 m_shiftTexture[4][8][4] = {};
boo::GraphicsDataToken m_token;
boo::ITextureD* m_shiftTex = nullptr;
boo::IGraphicsBufferD* m_vbo;
boo::IGraphicsBufferD* m_uniBuf;
boo::IShaderDataBinding* m_dataBind = nullptr;
Uniform m_uniform;
public:
CThermalColdFilter();
void setShift(unsigned shift);
void setColorA(const zeus::CColor& color) {m_uniform.m_colorRegs[0] = color;}
void setColorB(const zeus::CColor& color) {m_uniform.m_colorRegs[1] = color;}
void setColorC(const zeus::CColor& color) {m_uniform.m_colorRegs[2] = color;}
void setScale(float scale)
{
scale = 0.1f * (1.f - scale);
m_uniform.m_indMtx[0][0] = scale;
m_uniform.m_indMtx[1][1] = scale;
}
void draw();
using _CLS = CThermalColdFilter;
#include "TFilterDecl.hpp"
};
}
#endif // __URDE_CTHERMALCOLDFILTER_HPP__

View File

@@ -0,0 +1,138 @@
#include "CThermalColdFilter.hpp"
namespace urde
{
static const char* VS_GLSL_TEX =
"#version 330\n"
BOO_GLSL_BINDING_HEAD
"layout(location=0) in vec4 posIn;\n"
"layout(location=1) in vec4 uvIn;\n"
"\n"
"UBINDING0 uniform ThermalColdUniform\n"
"{\n"
" mat4 shiftMtx;\n"
" mat4 indMtx;\n"
" vec4 colorReg0;\n"
" vec4 colorReg1;\n"
" vec4 colorReg2;\n"
"};\n"
"\n"
"struct VertToFrag\n"
"{\n"
" mat3 indMtx;\n"
" vec4 colorReg0;\n"
" vec4 colorReg1;\n"
" vec4 colorReg2;\n"
" vec2 sceneUv;\n"
" vec2 shiftUv;\n"
"};\n"
"\n"
"SBINDING(0) out VertToFrag vtf;\n"
"void main()\n"
"{\n"
" vtf.indMtx = mat3(indMtx);\n"
" vtf.colorReg0 = colorReg0;\n"
" vtf.colorReg1 = colorReg1;\n"
" vtf.colorReg2 = colorReg2;\n"
" vtf.sceneUv = uvIn.xy;\n"
" vtf.shiftUv = shiftMtx * uvIn;\n"
" gl_Position = FLIPFROMGL(posIn);\n"
"}\n";
static const char* FS_GLSL_TEX =
"#version 330\n"
BOO_GLSL_BINDING_HEAD
"struct VertToFrag\n"
"{\n"
" mat3 indMtx;\n"
" vec4 colorReg0;\n"
" vec4 colorReg1;\n"
" vec4 colorReg2;\n"
" vec2 sceneUv;\n"
" vec2 shiftUv;\n"
" vec2 shiftDelta;\n"
"};\n"
"\n"
"SBINDING(0) in VertToFrag vtf;\n"
"layout(location=0) out vec4 colorOut;\n"
"TBINDING0 uniform sampler2D sceneTex;\n"
"TBINDING1 uniform sampler2D shiftTex;\n"
"const vec4 kRGBToYPrime = vec4(0.299, 0.587, 0.114, 0.0);\n"
"void main()\n"
"{\n"
" vec2 shiftCoord = vtf.sceneUv + texture(shiftTex, vtf.shiftUv).xy;\n"
" float shiftScene0 = dot(texture(sceneTex, shiftCoord - vec2(0.5)), kRGBToYPrime);\n"
" float shiftScene1 = dot(texture(sceneTex, shiftCoord - vec2(0.5, 0.4984375)), kRGBToYPrime);\n"
" vec2 indCoord = (indMtx * vec3(shiftScene0, shiftScene1, 1.0)).xy;\n"
" float indScene = dot(texture(sceneTex, vtf.sceneUv + indCoord), kRGBToYPrime);\n"
" colorOut = vtf.colorReg0 * indScene + vtf.colorReg1 * shiftScene0 + vtf.colorReg2;\n"
"}\n";
URDE_DECL_SPECIALIZE_FILTER(CThermalColdFilter)
struct CThermalColdFilterGLDataBindingFactory : TFilterShader<CThermalColdFilter>::IDataBindingFactory
{
boo::IShaderDataBinding* BuildShaderDataBinding(boo::IGraphicsDataFactory::Context& ctx, CThermalColdFilter& filter)
{
boo::GLDataFactory::Context& cctx = static_cast<boo::GLDataFactory::Context&>(ctx);
const boo::VertexElementDescriptor VtxVmt[] =
{
{filter.m_vbo, nullptr, boo::VertexSemantic::Position4},
{filter.m_vbo, nullptr, boo::VertexSemantic::UV4}
};
boo::IGraphicsBuffer* bufs[] = {filter.m_uniBuf};
boo::PipelineStage stages[] = {boo::PipelineStage::Vertex};
boo::ITexture* texs[] = {CGraphics::g_SpareTexture, filter.m_shiftTex};
return cctx.newShaderDataBinding(TFilterShader<CThermalColdFilter>::m_pipeline,
ctx.newVertexFormat(3, VtxVmt), filter.m_vbo, nullptr, nullptr,
1, bufs, stages, nullptr, nullptr, 2, texs);
}
};
#if BOO_HAS_VULKAN
struct CThermalColdFilterVulkanDataBindingFactory : TFilterShader<CThermalColdFilter>::IDataBindingFactory
{
boo::IShaderDataBinding* BuildShaderDataBinding(boo::IGraphicsDataFactory::Context& ctx, CThermalColdFilter& filter)
{
boo::VulkanDataFactory::Context& cctx = static_cast<boo::VulkanDataFactory::Context&>(ctx);
boo::IGraphicsBuffer* bufs[] = {filter.m_uniBuf};
boo::ITexture* texs[] = {CGraphics::g_SpareTexture, filter.m_shiftTex};
return cctx.newShaderDataBinding(TFilterShader<CThermalColdFilter>::m_pipeline,
TFilterShader<CThermalColdFilter>::m_vtxFmt,
filter.m_vbo, nullptr, nullptr, 1, bufs,
nullptr, nullptr, nullptr, 2, texs);
}
};
#endif
TFilterShader<CThermalColdFilter>::IDataBindingFactory* CThermalColdFilter::Initialize(boo::GLDataFactory::Context& ctx,
boo::IShaderPipeline*& pipeOut)
{
const char* texNames[] = {"sceneTex", "shiftTex"};
const char* uniNames[] = {"ThermalColdUniform"};
pipeOut = ctx.newShaderPipeline(VS_GLSL_TEX, FS_GLSL_TEX, 2, texNames, 1, uniNames, boo::BlendFactor::One,
boo::BlendFactor::Zero, boo::Primitive::TriStrips, false, false, false);
return new CThermalColdFilterGLDataBindingFactory;
}
#if BOO_HAS_VULKAN
TFilterShader<CThermalColdFilter>::IDataBindingFactory* CThermalColdFilter::Initialize(boo::VulkanDataFactory::Context& ctx,
boo::IShaderPipeline*& pipeOut,
boo::IVertexFormat*& vtxFmtOut)
{
const boo::VertexElementDescriptor VtxVmt[] =
{
{nullptr, nullptr, boo::VertexSemantic::Position4},
{nullptr, nullptr, boo::VertexSemantic::UV4}
};
vtxFmtOut = ctx.newVertexFormat(2, VtxVmt);
pipeOut = ctx.newShaderPipeline(VS_GLSL_TEX, FS_GLSL_TEX, vtxFmtOut, boo::BlendFactor::One,
boo::BlendFactor::Zero, boo::Primitive::TriStrips, false, false, false);
return new CThermalColdFilterVulkanDataBindingFactory;
}
#endif
}

View File

@@ -0,0 +1,13 @@
#include "CThermalColdFilter.hpp"
namespace urde
{
TFilterShader<CThermalColdFilter>::IDataBindingFactory* CThermalColdFilter::Initialize(boo::ID3DDataFactory::Context& ctx,
boo::IShaderPipeline*& pipeOut,
boo::IVertexFormat*& vtxFmtOut)
{
return nullptr;
}
}

View File

@@ -0,0 +1,13 @@
#include "CThermalColdFilter.hpp"
namespace urde
{
TFilterShader<CThermalColdFilter>::IDataBindingFactory* CThermalColdFilter::Initialize(boo::MetalDataFactory::Context& ctx,
boo::IShaderPipeline*& pipeOut,
boo::IVertexFormat*& vtxFmtOut)
{
return nullptr;
}
}

View File

@@ -0,0 +1,17 @@
static TFilterShader<_CLS>::IDataBindingFactory* Initialize(boo::GLDataFactory::Context& ctx,
boo::IShaderPipeline*& pipeOut);
#if _WIN32
static TFilterShader<_CLS>::IDataBindingFactory* Initialize(boo::ID3DDataFactory::Context& ctx,
boo::IShaderPipeline*& pipeOut,
boo::IVertexFormat*& vtxFmtOut);
#endif
#if BOO_HAS_METAL
static TFilterShader<_CLS>::IDataBindingFactory* Initialize(boo::MetalDataFactory::Context& ctx,
boo::IShaderPipeline*& pipeOut,
boo::IVertexFormat*& vtxFmtOut);
#endif
#if BOO_HAS_VULKAN
static TFilterShader<_CLS>::IDataBindingFactory* Initialize(boo::VulkanDataFactory::Context& ctx,
boo::IShaderPipeline*& pipeOut,
boo::IVertexFormat*& vtxFmtOut);
#endif

View File

@@ -0,0 +1,99 @@
#ifndef __URDE_TFILTERSHADER_HPP__
#define __URDE_TFILTERSHADER_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
{
template <class FilterImp>
class TFilterShader
{
public:
struct IDataBindingFactory
{
virtual boo::IShaderDataBinding* BuildShaderDataBinding(boo::IGraphicsDataFactory::Context& ctx, FilterImp& filter)=0;
};
static boo::IShaderPipeline* m_pipeline;
static boo::IVertexFormat* m_vtxFmt; /* No OpenGL */
static std::unique_ptr<IDataBindingFactory> m_bindFactory;
static boo::GraphicsDataToken m_gfxToken;
static void Initialize()
{
if (!CGraphics::g_BooFactory)
return;
m_gfxToken = CGraphics::CommitResources(
[&](boo::IGraphicsDataFactory::Context& ctx) -> bool
{
switch (ctx.platform())
{
case boo::IGraphicsDataFactory::Platform::OGL:
m_bindFactory.reset(FilterImp::Initialize(static_cast<boo::GLDataFactory::Context&>(ctx),
m_pipeline));
break;
#if _WIN32
case boo::IGraphicsDataFactory::Platform::D3D11:
case boo::IGraphicsDataFactory::Platform::D3D12:
m_bindFactory.reset(FilterImp::Initialize(static_cast<boo::ID3DDataFactory::Context&>(ctx),
m_pipeline, m_vtxFmt));
break;
#endif
#if BOO_HAS_METAL
case boo::IGraphicsDataFactory::Platform::Metal:
m_bindFactory.reset(FilterImp::Initialize(static_cast<boo::MetalDataFactory::Context&>(ctx),
m_pipeline, m_vtxFmt));
break;
#endif
#if BOO_HAS_VULKAN
case boo::IGraphicsDataFactory::Platform::Vulkan:
m_bindFactory.reset(FilterImp::Initialize(static_cast<boo::VulkanDataFactory::Context&>(ctx),
m_pipeline, m_vtxFmt));
break;
#endif
default: break;
}
return true;
});
}
static void Shutdown()
{
m_gfxToken.doDestroy();
}
static boo::IShaderDataBinding* BuildShaderDataBinding(boo::IGraphicsDataFactory::Context& ctx, FilterImp& filter)
{
return m_bindFactory->BuildShaderDataBinding(ctx, filter);
}
};
#define URDE_DECL_SPECIALIZE_FILTER(cls) \
template <> boo::IShaderPipeline* \
TFilterShader<cls>::m_pipeline; \
template <> boo::IVertexFormat* \
TFilterShader<cls>::m_vtxFmt;
#define URDE_SPECIALIZE_FILTER(cls) \
template <> boo::IShaderPipeline* \
TFilterShader<cls>::m_pipeline = nullptr; \
template <> boo::IVertexFormat* \
TFilterShader<cls>::m_vtxFmt = nullptr; \
\
template <> std::unique_ptr<TFilterShader<cls>::IDataBindingFactory> \
TFilterShader<cls>::m_bindFactory; \
template <> boo::GraphicsDataToken \
TFilterShader<cls>::m_gfxToken; \
\
template class TFilterShader<cls>;
}
#endif // __URDE_TFILTERSHADER_HPP__