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

Huge shader refactor

This commit is contained in:
Jack Andersen
2018-10-06 16:58:28 -10:00
parent 38cc803486
commit 4600ff4454
20 changed files with 533 additions and 777 deletions

View File

@@ -2,6 +2,7 @@
#include "specter/TextView.hpp"
#include "specter/ViewResources.hpp"
#include "utf8proc.h"
#include "hecl/Pipeline.hpp"
#include <freetype/internal/internal.h>
#include <freetype/internal/ftobjs.h>
@@ -10,291 +11,12 @@ namespace specter
{
static logvisor::Module Log("specter::TextView");
#if BOO_HAS_GL
static const char* GLSLVS =
"#version 330\n"
BOO_GLSL_BINDING_HEAD
"layout(location=0) in vec3 posIn[4];\n"
"layout(location=4) in mat4 mvMtx;\n"
"layout(location=8) in vec3 uvIn[4];\n"
"layout(location=12) in vec4 colorIn;\n"
SPECTER_GLSL_VIEW_VERT_BLOCK
"struct VertToFrag\n"
"{\n"
" vec3 uv;\n"
" vec4 color;\n"
"};\n"
"SBINDING(0) out VertToFrag vtf;\n"
"void main()\n"
"{\n"
" vec3 pos = posIn[gl_VertexID];\n"
" vtf.uv = uvIn[gl_VertexID];\n"
" vtf.color = colorIn * mulColor;\n"
" gl_Position = mv * mvMtx * vec4(pos, 1.0);\n"
" gl_Position = FLIPFROMGL(gl_Position);\n"
"}\n";
static const char* GLSLFSReg =
"#version 330\n"
BOO_GLSL_BINDING_HEAD
"TBINDING0 uniform sampler2DArray fontTex;\n"
"struct VertToFrag\n"
"{\n"
" vec3 uv;\n"
" vec4 color;\n"
"};\n"
"SBINDING(0) in VertToFrag vtf;\n"
"layout(location=0) out vec4 colorOut;\n"
"void main()\n"
"{\n"
" colorOut = vtf.color;\n"
" colorOut.a *= texture(fontTex, vtf.uv).r;\n"
"}\n";
static const char* GLSLFSSubpixel =
"#version 330\n"
BOO_GLSL_BINDING_HEAD
"TBINDING0 uniform sampler2DArray fontTex;\n"
"struct VertToFrag\n"
"{\n"
" vec3 uv;\n"
" vec4 color;\n"
"};\n"
"SBINDING(0) in VertToFrag vtf;\n"
"layout(location=0, index=0) out vec4 colorOut;\n"
"layout(location=0, index=1) out vec4 blendOut;\n"
"void main()\n"
"{\n"
" colorOut = vtf.color;\n"
" blendOut = colorOut.a * texture(fontTex, vtf.uv);\n"
"}\n";
static const char* BlockNames[] = {"SpecterViewBlock"};
static const char* TexNames[] = {"fontTex"};
void TextView::Resources::init(boo::GLDataFactory::Context& ctx, FontCache* fcache)
void TextView::Resources::init(boo::IGraphicsDataFactory::Context& ctx, FontCache* fcache)
{
m_fcache = fcache;
m_regular =
ctx.newShaderPipeline(GLSLVS, GLSLFSReg, 1, TexNames, 1, BlockNames,
boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha,
boo::Primitive::TriStrips, boo::ZTest::None, false, true, false, boo::CullMode::None);
m_subpixel =
ctx.newShaderPipeline(GLSLVS, GLSLFSSubpixel, 1, TexNames, 1, BlockNames,
boo::BlendFactor::SrcColor1, boo::BlendFactor::InvSrcColor1,
boo::Primitive::TriStrips, boo::ZTest::None, false, true, false, boo::CullMode::None);
m_regular = hecl::conv->convert(ctx, Shader_SpecterTextViewShader{});
m_subpixel = hecl::conv->convert(ctx, Shader_SpecterTextViewShaderSubpixel{});
}
#endif
#if _WIN32
void TextView::Resources::init(boo::D3DDataFactory::Context& ctx, FontCache* fcache)
{
m_fcache = fcache;
static const char* VS =
"struct VertData\n"
"{\n"
" float3 posIn[4] : POSITION;\n"
" float4x4 mvMtx : MODELVIEW;\n"
" float3 uvIn[4] : UV;\n"
" float4 colorIn : COLOR;\n"
"};\n"
SPECTER_HLSL_VIEW_VERT_BLOCK
"struct VertToFrag\n"
"{\n"
" float4 position : SV_Position;\n"
" float3 uv : UV;\n"
" float4 color : COLOR;\n"
"};\n"
"VertToFrag main(in VertData v, in uint vertId : SV_VertexID)\n"
"{\n"
" VertToFrag vtf;\n"
" vtf.uv = v.uvIn[vertId];\n"
" vtf.color = v.colorIn * mulColor;\n"
" vtf.position = mul(mv, mul(v.mvMtx, float4(v.posIn[vertId], 1.0)));\n"
" return vtf;\n"
"}\n";
static const char* FSReg =
"Texture2DArray fontTex : register(t0);\n"
"SamplerState samp : register(s0);\n"
"struct VertToFrag\n"
"{\n"
" float4 position : SV_Position;\n"
" float3 uv : UV;\n"
" float4 color : COLOR;\n"
"};\n"
"float4 main(in VertToFrag vtf) : SV_Target0\n"
"{\n"
" float4 colorOut = vtf.color;\n"
" colorOut.a *= fontTex.Sample(samp, vtf.uv).r;\n"
" return colorOut;\n"
"}\n";
static const char* FSSubpixel =
"Texture2DArray fontTex : register(t0);\n"
"SamplerState samp : register(s0);\n"
"struct VertToFrag\n"
"{\n"
" float4 position : SV_Position;\n"
" float3 uv : UV;\n"
" float4 color : COLOR;\n"
"};\n"
"struct BlendOut\n"
"{\n"
" float4 colorOut : SV_Target0;\n"
" float4 blendOut : SV_Target1;\n"
"};\n"
"BlendOut main(in VertToFrag vtf)\n"
"{\n"
" BlendOut ret;\n"
" ret.colorOut = vtf.color;\n"
" ret.blendOut = ret.colorOut.a * fontTex.Sample(samp, vtf.uv);\n"
" return ret;\n"
"}\n";
boo::VertexElementDescriptor vdescs[] =
{
{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::ModelView | boo::VertexSemantic::Instanced, 0},
{nullptr, nullptr, boo::VertexSemantic::ModelView | boo::VertexSemantic::Instanced, 1},
{nullptr, nullptr, boo::VertexSemantic::ModelView | boo::VertexSemantic::Instanced, 2},
{nullptr, nullptr, boo::VertexSemantic::ModelView | boo::VertexSemantic::Instanced, 3},
{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::Color | boo::VertexSemantic::Instanced}
};
m_vtxFmt = ctx.newVertexFormat(13, vdescs);
m_regular =
ctx.newShaderPipeline(VS, FSReg, nullptr, nullptr, nullptr, m_vtxFmt,
boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha,
boo::Primitive::TriStrips, boo::ZTest::None, false, true, true, boo::CullMode::None);
m_subpixel =
ctx.newShaderPipeline(VS, FSSubpixel, nullptr, nullptr, nullptr, m_vtxFmt,
boo::BlendFactor::SrcColor1, boo::BlendFactor::InvSrcColor1,
boo::Primitive::TriStrips, boo::ZTest::None, false, true, true, boo::CullMode::None);
}
#endif
#if BOO_HAS_METAL
void TextView::Resources::init(boo::MetalDataFactory::Context& ctx, FontCache* fcache)
{
m_fcache = fcache;
static const char* VS =
"#include <metal_stdlib>\n"
"using namespace metal;\n"
"struct VertData\n"
"{\n"
" float3 posIn[4];\n"
" float4x4 mvMtx;\n"
" float3 uvIn[4];\n"
" float4 colorIn;\n"
"};\n"
SPECTER_METAL_VIEW_VERT_BLOCK
"struct VertToFrag\n"
"{\n"
" float4 position [[ position ]];\n"
" float3 uv;\n"
" float4 color;\n"
"};\n"
"vertex VertToFrag vmain(constant VertData* va [[ buffer(1) ]],\n"
" uint vertId [[ vertex_id ]], uint instId [[ instance_id ]],\n"
" constant SpecterViewBlock& view [[ buffer(2) ]])\n"
"{\n"
" VertToFrag vtf;\n"
" constant VertData& v = va[instId];\n"
" vtf.uv = v.uvIn[vertId];\n"
" vtf.color = v.colorIn * view.mulColor;\n"
" vtf.position = view.mv * v.mvMtx * float4(v.posIn[vertId], 1.0);\n"
" return vtf;\n"
"}\n";
static const char* FSReg =
"#include <metal_stdlib>\n"
"using namespace metal;\n"
"struct VertToFrag\n"
"{\n"
" float4 position [[ position ]];\n"
" float3 uv;\n"
" float4 color;\n"
"};\n"
"fragment float4 fmain(VertToFrag vtf [[ stage_in ]],\n"
" sampler samp [[ sampler(0) ]],\n"
" texture2d_array<float> fontTex [[ texture(0) ]])\n"
"{\n"
" float4 colorOut = vtf.color;\n"
" colorOut.a *= fontTex.sample(samp, vtf.uv.xy, vtf.uv.z).r;\n"
" return colorOut;\n"
"}\n";
boo::VertexElementDescriptor vdescs[] =
{
{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::ModelView | boo::VertexSemantic::Instanced, 0},
{nullptr, nullptr, boo::VertexSemantic::ModelView | boo::VertexSemantic::Instanced, 1},
{nullptr, nullptr, boo::VertexSemantic::ModelView | boo::VertexSemantic::Instanced, 2},
{nullptr, nullptr, boo::VertexSemantic::ModelView | boo::VertexSemantic::Instanced, 3},
{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::Color | boo::VertexSemantic::Instanced}
};
m_vtxFmt = ctx.newVertexFormat(13, vdescs);
m_regular =
ctx.newShaderPipeline(VS, FSReg, nullptr, nullptr, m_vtxFmt,
boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha,
boo::Primitive::TriStrips, boo::ZTest::None, false, true, false, boo::CullMode::None);
}
#endif
#if BOO_HAS_VULKAN
void TextView::Resources::init(boo::VulkanDataFactory::Context& ctx, FontCache* fcache)
{
m_fcache = fcache;
boo::VertexElementDescriptor vdescs[] =
{
{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::ModelView | boo::VertexSemantic::Instanced, 0},
{nullptr, nullptr, boo::VertexSemantic::ModelView | boo::VertexSemantic::Instanced, 1},
{nullptr, nullptr, boo::VertexSemantic::ModelView | boo::VertexSemantic::Instanced, 2},
{nullptr, nullptr, boo::VertexSemantic::ModelView | boo::VertexSemantic::Instanced, 3},
{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::Color | boo::VertexSemantic::Instanced}
};
m_vtxFmt = ctx.newVertexFormat(13, vdescs);
m_regular =
ctx.newShaderPipeline(GLSLVS, GLSLFSReg, m_vtxFmt,
boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha,
boo::Primitive::TriStrips,boo::ZTest::None, false, true, true, boo::CullMode::None);
}
#endif
void TextView::_commitResources(size_t capacity)
{
@@ -321,37 +43,9 @@ void TextView::_commitResources(size_t capacity)
size_t uBufSizes[] = {sizeof(ViewBlock)};
boo::ObjToken<boo::ITexture> texs[] = {fontTex.get()};
if (!res.m_textRes.m_vtxFmt)
{
boo::VertexElementDescriptor vdescs[] =
{
{vBufInfo.first.get(), nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 0},
{vBufInfo.first.get(), nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 1},
{vBufInfo.first.get(), nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 2},
{vBufInfo.first.get(), nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 3},
{vBufInfo.first.get(), nullptr, boo::VertexSemantic::ModelView | boo::VertexSemantic::Instanced, 0},
{vBufInfo.first.get(), nullptr, boo::VertexSemantic::ModelView | boo::VertexSemantic::Instanced, 1},
{vBufInfo.first.get(), nullptr, boo::VertexSemantic::ModelView | boo::VertexSemantic::Instanced, 2},
{vBufInfo.first.get(), nullptr, boo::VertexSemantic::ModelView | boo::VertexSemantic::Instanced, 3},
{vBufInfo.first.get(), nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 0},
{vBufInfo.first.get(), nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 1},
{vBufInfo.first.get(), nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 2},
{vBufInfo.first.get(), nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 3},
{vBufInfo.first.get(), nullptr, boo::VertexSemantic::Color | boo::VertexSemantic::Instanced}
};
m_vtxFmt = ctx.newVertexFormat(13, vdescs, 0, vBufInfo.second);
m_shaderBinding = ctx.newShaderDataBinding(shader, m_vtxFmt,
nullptr, vBufInfo.first.get(), nullptr, 1,
uBufs, nullptr, uBufOffs, uBufSizes,
1, texs, nullptr, nullptr, 0, vBufInfo.second);
}
else
{
m_shaderBinding = ctx.newShaderDataBinding(shader, res.m_textRes.m_vtxFmt,
nullptr, vBufInfo.first.get(), nullptr, 1,
uBufs, nullptr, uBufOffs, uBufSizes,
1, texs, nullptr, nullptr, 0, vBufInfo.second);
}
m_shaderBinding = ctx.newShaderDataBinding(shader, {}, vBufInfo.first.get(), nullptr, 1,
uBufs, nullptr, uBufOffs, uBufSizes,
1, texs, nullptr, nullptr, 0, vBufInfo.second);
}
return true;
});