diff --git a/specter/CMakeLists.txt b/specter/CMakeLists.txt index d5f72e9db..9513471ef 100644 --- a/specter/CMakeLists.txt +++ b/specter/CMakeLists.txt @@ -91,3 +91,4 @@ list(APPEND SPECTER_SOURCES atdna_FontCache.cpp) add_library(specter ${SPECTER_SOURCES} ${SPECTER_HEADERS}) +add_dependencies(specter hecl-light) diff --git a/specter/include/specter/Control.hpp b/specter/include/specter/Control.hpp index 88ba7b5f3..e9f861bc8 100644 --- a/specter/include/specter/Control.hpp +++ b/specter/include/specter/Control.hpp @@ -8,14 +8,28 @@ namespace specter class Control; class Button; +enum class ControlType +{ + Button, + Float, + Int, + String, + CVar +}; + struct IControlBinding { + virtual ControlType type() const = 0; virtual std::string_view name(const Control* control) const=0; virtual std::string_view help(const Control* control) const {return {};} }; struct IButtonBinding : IControlBinding { + ControlType type() const { return ControlType::Button; } + static IButtonBinding* castTo(IControlBinding* bind) + { return bind->type() == ControlType::Button ? static_cast(bind) : nullptr; } + /** Pressed/Released while Hovering action, * cancellable by holding the button and releasing outside */ virtual void activated(const Button* button, const boo::SWindowCoord& coord) {} @@ -43,6 +57,9 @@ struct IButtonBinding : IControlBinding struct IFloatBinding : IControlBinding { + ControlType type() const { return ControlType::Float; } + static IFloatBinding* castTo(IControlBinding* bind) + { return bind->type() == ControlType::Float ? static_cast(bind) : nullptr; } virtual float getDefault(const Control* control) const {return 0.0;} virtual std::pair getBounds(const Control* control) const {return std::make_pair(FLT_MIN, FLT_MAX);} virtual void changed(const Control* control, float val)=0; @@ -50,6 +67,9 @@ struct IFloatBinding : IControlBinding struct IIntBinding : IControlBinding { + ControlType type() const { return ControlType::Int; } + static IIntBinding* castTo(IControlBinding* bind) + { return bind->type() == ControlType::Int ? static_cast(bind) : nullptr; } virtual int getDefault(const Control* control) const {return 0;} virtual std::pair getBounds(const Control* control) const {return std::make_pair(INT_MIN, INT_MAX);} virtual void changed(const Control* control, int val)=0; @@ -57,6 +77,9 @@ struct IIntBinding : IControlBinding struct IStringBinding : IControlBinding { + ControlType type() const { return ControlType::String; } + static IStringBinding* castTo(IControlBinding* bind) + { return bind->type() == ControlType::String ? static_cast(bind) : nullptr; } virtual std::string getDefault(const Control* control) const {return "";} virtual void changed(const Control* control, std::string_view val)=0; }; @@ -66,6 +89,9 @@ struct CVarControlBinding : IControlBinding hecl::CVar* m_cvar; CVarControlBinding(hecl::CVar* cvar) : m_cvar(cvar) {} + ControlType type() const { return ControlType::CVar; } + static CVarControlBinding* castTo(IControlBinding* bind) + { return bind->type() == ControlType::CVar ? static_cast(bind) : nullptr; } std::string_view name(const Control* control) const {return m_cvar->name();} std::string_view help(const Control* control) const {return m_cvar->rawHelp();} }; diff --git a/specter/include/specter/FontCache.hpp b/specter/include/specter/FontCache.hpp index f77acfd77..b19263d0b 100644 --- a/specter/include/specter/FontCache.hpp +++ b/specter/include/specter/FontCache.hpp @@ -8,6 +8,7 @@ #include #include #include +#include namespace specter { diff --git a/specter/include/specter/NumericField.hpp b/specter/include/specter/NumericField.hpp index 277a687bc..194fb015a 100644 --- a/specter/include/specter/NumericField.hpp +++ b/specter/include/specter/NumericField.hpp @@ -17,7 +17,6 @@ class NumericField : public View boo::IGraphicsBufferD* m_bBlockBuf; boo::IGraphicsBufferD* m_bVertsBuf; - boo::IVertexFormat* m_bVtxFmt; /* OpenGL only */ boo::IShaderDataBinding* m_bShaderBinding; int m_nomWidth, m_nomHeight; diff --git a/specter/include/specter/Space.hpp b/specter/include/specter/Space.hpp index 17a806411..d3af85ddd 100644 --- a/specter/include/specter/Space.hpp +++ b/specter/include/specter/Space.hpp @@ -74,7 +74,10 @@ public: if (m_toolbar.m_view) m_toolbar.m_view->setMultiplyColor(color); } + + bool isSpace() const { return true; } }; +inline Space* View::castToSpace() { return isSpace() ? static_cast(this) : nullptr; } } diff --git a/specter/include/specter/SplitView.hpp b/specter/include/specter/SplitView.hpp index fcd7bdafe..1ce93961f 100644 --- a/specter/include/specter/SplitView.hpp +++ b/specter/include/specter/SplitView.hpp @@ -112,7 +112,10 @@ public: if (m_views[1].m_view) m_views[1].m_view->setMultiplyColor(color); } + + bool isSplitView() const { return true; } }; +inline SplitView* View::castToSplitView() { return isSplitView() ? static_cast(this) : nullptr; } } diff --git a/specter/include/specter/TextView.hpp b/specter/include/specter/TextView.hpp index 7a6a58c66..09d9abaeb 100644 --- a/specter/include/specter/TextView.hpp +++ b/specter/include/specter/TextView.hpp @@ -2,10 +2,7 @@ #define SPECTER_TEXTVIEW_HPP #include "View.hpp" -#include -#include -#include -#include +#include "boo/graphicsdev/IGraphicsDataFactory.hpp" #include "FontCache.hpp" @@ -62,7 +59,6 @@ private: size_t m_capacity; size_t m_curSize = 0; hecl::VertexBufferPool::Token m_glyphBuf; - boo::ObjToken m_vtxFmt; /* OpenGL only */ boo::ObjToken m_shaderBinding; const FontAtlas& m_fontAtlas; Alignment m_align; @@ -90,27 +86,14 @@ public: FontCache* m_fcache = nullptr; boo::ObjToken m_regular; boo::ObjToken m_subpixel; - boo::ObjToken m_vtxFmt; /* Not OpenGL */ -#if BOO_HAS_GL - void init(boo::GLDataFactory::Context& ctx, FontCache* fcache); -#endif -#if _WIN32 - void init(boo::D3DDataFactory::Context& ctx, FontCache* fcache); -#endif -#if BOO_HAS_METAL - void init(boo::MetalDataFactory::Context& ctx, FontCache* fcache); -#endif -#if BOO_HAS_VULKAN - void init(boo::VulkanDataFactory::Context& ctx, FontCache* fcache); -#endif + void init(boo::IGraphicsDataFactory::Context& ctx, FontCache* fcache); void destroy() { m_glyphPool.doDestroy(); m_regular.reset(); m_subpixel.reset(); - m_vtxFmt.reset(); } }; diff --git a/specter/include/specter/View.hpp b/specter/include/specter/View.hpp index 061f14c97..ed2f39c7b 100644 --- a/specter/include/specter/View.hpp +++ b/specter/include/specter/View.hpp @@ -1,7 +1,7 @@ #ifndef SPECTER_VIEW_HPP #define SPECTER_VIEW_HPP -#include +#include "boo/boo.hpp" #include "optional.hpp" #include "zeus/CVector3f.hpp" #include "zeus/CMatrix4f.hpp" @@ -11,11 +11,6 @@ #include "hecl/UniformBufferPool.hpp" #include "hecl/VertexBufferPool.hpp" -#include -#include -#include -#include - namespace specter { class IThemeData; @@ -81,6 +76,8 @@ public: } }; +class Space; +class SplitView; class View { public: @@ -111,7 +108,6 @@ public: struct VertexBufferBinding { typename hecl::VertexBufferPool::Token m_vertsBuf; - boo::ObjToken m_vtxFmt; /* OpenGL only */ boo::ObjToken m_shaderBinding; void load(const VertStruct* data, size_t count) @@ -165,24 +161,6 @@ private: protected: ViewBlock m_viewVertBlock; -#define SPECTER_GLSL_VIEW_VERT_BLOCK\ - "UBINDING0 uniform SpecterViewBlock\n"\ - "{\n"\ - " mat4 mv;\n"\ - " vec4 mulColor;\n"\ - "};\n" -#define SPECTER_HLSL_VIEW_VERT_BLOCK\ - "cbuffer SpecterViewBlock : register(b0)\n"\ - "{\n"\ - " float4x4 mv;\n"\ - " float4 mulColor;\n"\ - "};\n" -#define SPECTER_METAL_VIEW_VERT_BLOCK\ - "struct SpecterViewBlock\n"\ - "{\n"\ - " float4x4 mv;\n"\ - " float4 mulColor;\n"\ - "};\n" hecl::UniformBufferPool::Token m_viewVertBlockBuf; public: @@ -200,23 +178,9 @@ public: } boo::ObjToken m_solidShader; - boo::ObjToken m_solidVtxFmt; /* Not OpenGL */ - boo::ObjToken m_texShader; - boo::ObjToken m_texVtxFmt; /* Not OpenGL */ -#if BOO_HAS_GL - void init(boo::GLDataFactory::Context& ctx, const IThemeData& theme); -#endif -#if _WIN32 - void init(boo::D3DDataFactory::Context& ctx, const IThemeData& theme); -#endif -#if BOO_HAS_METAL - void init(boo::MetalDataFactory::Context& ctx, const IThemeData& theme); -#endif -#if BOO_HAS_VULKAN - void init(boo::VulkanDataFactory::Context& ctx, const IThemeData& theme); -#endif + void init(boo::IGraphicsDataFactory::Context& ctx, const IThemeData& theme); void destroy() { @@ -225,9 +189,7 @@ public: m_texPool.doDestroy(); m_solidShader.reset(); - m_solidVtxFmt.reset(); m_texShader.reset(); - m_texVtxFmt.reset(); } }; @@ -292,6 +254,11 @@ public: const boo::SWindowRect& scissor) {resized(root, sub);} virtual void think() {} virtual void draw(boo::IGraphicsCommandQueue* gfxQ); + + virtual bool isSpace() const { return false; } + virtual bool isSplitView() const { return false; } + Space* castToSpace(); + SplitView* castToSplitView(); }; template diff --git a/specter/include/specter/ViewResources.hpp b/specter/include/specter/ViewResources.hpp index df12a1fcc..03055ec01 100644 --- a/specter/include/specter/ViewResources.hpp +++ b/specter/include/specter/ViewResources.hpp @@ -149,8 +149,7 @@ public: class ViewResources { - template - void init(FactoryCtx& factory, const IThemeData& theme, FontCache* fcache) + void init(boo::IGraphicsDataFactory::Context& factory, const IThemeData& theme, FontCache* fcache) { m_viewRes.init(factory, theme); m_textRes.init(factory, fcache); diff --git a/specter/lib/RootView.cpp b/specter/lib/RootView.cpp index b9f22ed2b..d7dad8315 100644 --- a/specter/lib/RootView.cpp +++ b/specter/lib/RootView.cpp @@ -320,7 +320,7 @@ void RootView::SplitMenuSystem::mouseUp(const boo::SWindowCoord& coord, boo::EMo { m_interactiveDown = false; m_phase = Phase::Inactive; - Space* space = dynamic_cast(m_splitView->m_views[m_interactiveSlot].m_view); + Space* space = m_splitView->m_views[m_interactiveSlot].m_view->castToSpace(); if (space && space->m_controller.spaceSplitAllowed()) { ISplitSpaceController* ss = space->m_controller.spaceSplit(axis, 0); @@ -337,7 +337,7 @@ SplitView* RootView::recursiveTestSplitHover(SplitView* sv, const boo::SWindowCo return sv; for (int i=0 ; i<2 ; ++i) { - SplitView* child = dynamic_cast(sv->m_views[i].m_view); + SplitView* child = sv->m_views[i].m_view->castToSplitView(); if (child) { SplitView* res = recursiveTestSplitHover(child, coord); @@ -391,7 +391,7 @@ void RootView::mouseMove(const boo::SWindowCoord& coord) { for (View* v : m_views) { - SplitView* sv = dynamic_cast(v); + SplitView* sv = v->castToSplitView(); if (sv) sv = recursiveTestSplitHover(sv, coord); if (sv) diff --git a/specter/lib/Space.cpp b/specter/lib/Space.cpp index b8a76648d..2861de04b 100644 --- a/specter/lib/Space.cpp +++ b/specter/lib/Space.cpp @@ -267,7 +267,7 @@ void Space::CornerView::mouseLeave(const boo::SWindowCoord& coord) SplitView* Space::findSplitViewOnSide(SplitView::Axis axis, int side) { - SplitView* ret = dynamic_cast(&parentView()); + SplitView* ret = parentView().castToSplitView(); View* test = this; while (ret) { @@ -277,7 +277,7 @@ SplitView* Space::findSplitViewOnSide(SplitView::Axis axis, int side) return ret; else if (ret->m_views[side].m_view == test) test = ret; - ret = dynamic_cast(&ret->parentView()); + ret = ret->parentView().castToSplitView(); } return nullptr; } diff --git a/specter/lib/SplitView.cpp b/specter/lib/SplitView.cpp index a8368b7e8..5ad014d36 100644 --- a/specter/lib/SplitView.cpp +++ b/specter/lib/SplitView.cpp @@ -123,7 +123,7 @@ bool SplitView::testJoinArrowHover(const boo::SWindowCoord& coord, int& origSlot dirOut = ArrowDir::Up; if (m_views[1].m_view) { - SplitView* chSplit = dynamic_cast(m_views[1].m_view); + SplitView* chSplit = m_views[1].m_view->castToSplitView(); if (chSplit && chSplit->m_axis == Axis::Horizontal) return chSplit->testJoinArrowHover(coord, origDummy, splitOut, slotOut, rectOut, dirDummy, 0); } @@ -140,7 +140,7 @@ bool SplitView::testJoinArrowHover(const boo::SWindowCoord& coord, int& origSlot dirOut = ArrowDir::Down; if (m_views[0].m_view) { - SplitView* chSplit = dynamic_cast(m_views[0].m_view); + SplitView* chSplit = m_views[0].m_view->castToSplitView(); if (chSplit && chSplit->m_axis == Axis::Horizontal) return chSplit->testJoinArrowHover(coord, origDummy, splitOut, slotOut, rectOut, dirDummy, 1); } @@ -160,7 +160,7 @@ bool SplitView::testJoinArrowHover(const boo::SWindowCoord& coord, int& origSlot dirOut = ArrowDir::Right; if (m_views[1].m_view) { - SplitView* chSplit = dynamic_cast(m_views[1].m_view); + SplitView* chSplit = m_views[1].m_view->castToSplitView(); if (chSplit && chSplit->m_axis == Axis::Vertical) return chSplit->testJoinArrowHover(coord, origDummy, splitOut, slotOut, rectOut, dirDummy, 0); } @@ -177,7 +177,7 @@ bool SplitView::testJoinArrowHover(const boo::SWindowCoord& coord, int& origSlot dirOut = ArrowDir::Left; if (m_views[0].m_view) { - SplitView* chSplit = dynamic_cast(m_views[0].m_view); + SplitView* chSplit = m_views[0].m_view->castToSplitView(); if (chSplit && chSplit->m_axis == Axis::Vertical) return chSplit->testJoinArrowHover(coord, origDummy, splitOut, slotOut, rectOut, dirDummy, 1); } @@ -199,7 +199,7 @@ void SplitView::getJoinArrowHover(int slot, boo::SWindowRect& rectOut, ArrowDir& { if (m_views[1].m_view) { - SplitView* chSplit = dynamic_cast(m_views[1].m_view); + SplitView* chSplit = m_views[1].m_view->castToSplitView(); if (chSplit && chSplit->m_axis == Axis::Horizontal) return chSplit->getJoinArrowHover(0, rectOut, dirOut); } @@ -212,7 +212,7 @@ void SplitView::getJoinArrowHover(int slot, boo::SWindowRect& rectOut, ArrowDir& { if (m_views[0].m_view) { - SplitView* chSplit = dynamic_cast(m_views[0].m_view); + SplitView* chSplit = m_views[0].m_view->castToSplitView(); if (chSplit && chSplit->m_axis == Axis::Horizontal) return chSplit->getJoinArrowHover(1, rectOut, dirOut); } @@ -228,7 +228,7 @@ void SplitView::getJoinArrowHover(int slot, boo::SWindowRect& rectOut, ArrowDir& { if (m_views[1].m_view) { - SplitView* chSplit = dynamic_cast(m_views[1].m_view); + SplitView* chSplit = m_views[1].m_view->castToSplitView(); if (chSplit && chSplit->m_axis == Axis::Vertical) return chSplit->getJoinArrowHover(0, rectOut, dirOut); } @@ -241,7 +241,7 @@ void SplitView::getJoinArrowHover(int slot, boo::SWindowRect& rectOut, ArrowDir& { if (m_views[0].m_view) { - SplitView* chSplit = dynamic_cast(m_views[0].m_view); + SplitView* chSplit = m_views[0].m_view->castToSplitView(); if (chSplit && chSplit->m_axis == Axis::Vertical) return chSplit->getJoinArrowHover(1, rectOut, dirOut); } @@ -265,7 +265,7 @@ bool SplitView::testSplitLineHover(const boo::SWindowCoord& coord, int& slotOut, { if (m_views[1].m_view) { - SplitView* chSplit = dynamic_cast(m_views[1].m_view); + SplitView* chSplit = m_views[1].m_view->castToSplitView(); if (chSplit && chSplit->m_axis == Axis::Horizontal) return chSplit->testSplitLineHover(coord, slotOut, rectOut, splitOut, axisOut); } @@ -281,7 +281,7 @@ bool SplitView::testSplitLineHover(const boo::SWindowCoord& coord, int& slotOut, { if (m_views[0].m_view) { - SplitView* chSplit = dynamic_cast(m_views[0].m_view); + SplitView* chSplit = m_views[0].m_view->castToSplitView(); if (chSplit && chSplit->m_axis == Axis::Horizontal) return chSplit->testSplitLineHover(coord, slotOut, rectOut, splitOut, axisOut); } @@ -300,7 +300,7 @@ bool SplitView::testSplitLineHover(const boo::SWindowCoord& coord, int& slotOut, { if (m_views[1].m_view) { - SplitView* chSplit = dynamic_cast(m_views[1].m_view); + SplitView* chSplit = m_views[1].m_view->castToSplitView(); if (chSplit && chSplit->m_axis == Axis::Vertical) return chSplit->testSplitLineHover(coord, slotOut, rectOut, splitOut, axisOut); } @@ -316,7 +316,7 @@ bool SplitView::testSplitLineHover(const boo::SWindowCoord& coord, int& slotOut, { if (m_views[0].m_view) { - SplitView* chSplit = dynamic_cast(m_views[0].m_view); + SplitView* chSplit = m_views[0].m_view->castToSplitView(); if (chSplit && chSplit->m_axis == Axis::Vertical) return chSplit->testSplitLineHover(coord, slotOut, rectOut, splitOut, axisOut); } @@ -339,7 +339,7 @@ void SplitView::getSplitLineHover(int slot, boo::SWindowRect& rectOut, Axis& axi { if (m_views[1].m_view) { - SplitView* chSplit = dynamic_cast(m_views[1].m_view); + SplitView* chSplit = m_views[1].m_view->castToSplitView(); if (chSplit && chSplit->m_axis == Axis::Horizontal) return chSplit->getSplitLineHover(0, rectOut, axisOut); } @@ -352,7 +352,7 @@ void SplitView::getSplitLineHover(int slot, boo::SWindowRect& rectOut, Axis& axi { if (m_views[0].m_view) { - SplitView* chSplit = dynamic_cast(m_views[0].m_view); + SplitView* chSplit = m_views[0].m_view->castToSplitView(); if (chSplit && chSplit->m_axis == Axis::Horizontal) return chSplit->getSplitLineHover(1, rectOut, axisOut); } @@ -368,7 +368,7 @@ void SplitView::getSplitLineHover(int slot, boo::SWindowRect& rectOut, Axis& axi { if (m_views[1].m_view) { - SplitView* chSplit = dynamic_cast(m_views[1].m_view); + SplitView* chSplit = m_views[1].m_view->castToSplitView(); if (chSplit && chSplit->m_axis == Axis::Vertical) return chSplit->getSplitLineHover(0, rectOut, axisOut); } @@ -381,7 +381,7 @@ void SplitView::getSplitLineHover(int slot, boo::SWindowRect& rectOut, Axis& axi { if (m_views[0].m_view) { - SplitView* chSplit = dynamic_cast(m_views[0].m_view); + SplitView* chSplit = m_views[0].m_view->castToSplitView(); if (chSplit && chSplit->m_axis == Axis::Vertical) return chSplit->getSplitLineHover(1, rectOut, axisOut); } diff --git a/specter/lib/TextField.cpp b/specter/lib/TextField.cpp index b48dc790f..698c8449e 100644 --- a/specter/lib/TextField.cpp +++ b/specter/lib/TextField.cpp @@ -33,8 +33,9 @@ void TextField::_setText() m_textStr = m_deferredTextStr; m_text->typesetGlyphs(m_textStr, m_error ? rootView().themeData().uiText() : rootView().themeData().fieldText()); - if (m_controlBinding && dynamic_cast(m_controlBinding)) - static_cast(*m_controlBinding).changed(this, m_textStr); + if (m_controlBinding) + if (IStringBinding* strBind = IStringBinding::castTo(m_controlBinding)) + strBind->changed(this, m_textStr); m_hasTextSet = false; if (m_deferredMarkStr.size()) m_hasMarkSet = true; diff --git a/specter/lib/TextView.cpp b/specter/lib/TextView.cpp index b2103c598..43784f456 100644 --- a/specter/lib/TextView.cpp +++ b/specter/lib/TextView.cpp @@ -2,6 +2,7 @@ #include "specter/TextView.hpp" #include "specter/ViewResources.hpp" #include "utf8proc.h" +#include "hecl/Pipeline.hpp" #include #include @@ -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 \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 \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 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 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; }); diff --git a/specter/lib/View.cpp b/specter/lib/View.cpp index 400477cda..19de26055 100644 --- a/specter/lib/View.cpp +++ b/specter/lib/View.cpp @@ -1,323 +1,17 @@ #include "specter/View.hpp" #include "specter/ViewResources.hpp" #include "specter/RootView.hpp" +#include "hecl/Pipeline.hpp" namespace specter { static logvisor::Module Log("specter::View"); -#if BOO_HAS_GL -static const char* GLSLSolidVS = -"#version 330\n" -BOO_GLSL_BINDING_HEAD -"layout(location=0) in vec3 posIn;\n" -"layout(location=1) in vec4 colorIn;\n" -SPECTER_GLSL_VIEW_VERT_BLOCK -"struct VertToFrag\n" -"{\n" -" vec4 color;\n" -"};\n" -"SBINDING(0) out VertToFrag vtf;\n" -"void main()\n" -"{\n" -" vtf.color = colorIn * mulColor;\n" -" gl_Position = mv * vec4(posIn, 1.0);\n" -" gl_Position = FLIPFROMGL(gl_Position);\n" -"}\n"; - -static const char* GLSLSolidFS = -"#version 330\n" -BOO_GLSL_BINDING_HEAD -"struct VertToFrag\n" -"{\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" -"}\n"; - -static const char* GLSLTexVS = -"#version 330\n" -BOO_GLSL_BINDING_HEAD -"layout(location=0) in vec3 posIn;\n" -"layout(location=1) in vec2 uvIn;\n" -SPECTER_GLSL_VIEW_VERT_BLOCK -"struct VertToFrag\n" -"{\n" -" vec4 color;\n" -" vec4 uv;\n" -"};\n" -"SBINDING(0) out VertToFrag vtf;\n" -"void main()\n" -"{\n" -" vtf.uv.xy = uvIn;\n" -" vtf.color = mulColor;\n" -" gl_Position = mv * vec4(posIn, 1.0);\n" -" gl_Position = FLIPFROMGL(gl_Position);\n" -"}\n"; - -static const char* GLSLTexFS = -"#version 330\n" -BOO_GLSL_BINDING_HEAD -"struct VertToFrag\n" -"{\n" -" vec4 color;\n" -" vec4 uv;\n" -"};\n" -"SBINDING(0) in VertToFrag vtf;\n" -"TBINDING0 uniform sampler2D tex;\n" -"layout(location=0) out vec4 colorOut;\n" -"void main()\n" -"{\n" -" colorOut = texture(tex, vtf.uv.xy) * vtf.color;\n" -"}\n"; - -static const char* BlockNames[] = {"SpecterViewBlock"}; -static const char* TexNames[] = {"tex"}; - -void View::Resources::init(boo::GLDataFactory::Context& ctx, const IThemeData& theme) +void View::Resources::init(boo::IGraphicsDataFactory::Context& ctx, const IThemeData& theme) { - m_solidShader = ctx.newShaderPipeline(GLSLSolidVS, GLSLSolidFS, 0, nullptr, 1, BlockNames, - boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha, - boo::Primitive::TriStrips, boo::ZTest::None, false, true, false, - boo::CullMode::None); - - m_texShader = ctx.newShaderPipeline(GLSLTexVS, GLSLTexFS, 1, TexNames, 1, BlockNames, - boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha, - boo::Primitive::TriStrips, boo::ZTest::None, false, true, false, - boo::CullMode::None); + m_solidShader = hecl::conv->convert(ctx, Shader_SpecterViewShaderSolid{}); + m_texShader = hecl::conv->convert(ctx, Shader_SpecterViewShaderTex{}); } -#endif - -#if _WIN32 - -void View::Resources::init(boo::D3DDataFactory::Context& ctx, const IThemeData& theme) -{ - static const char* SolidVS = - "struct VertData\n" - "{\n" - " float3 posIn : POSITION;\n" - " float4 colorIn : COLOR;\n" - "};\n" - SPECTER_HLSL_VIEW_VERT_BLOCK - "struct VertToFrag\n" - "{\n" - " float4 position : SV_Position;\n" - " float4 color : COLOR;\n" - "};\n" - "VertToFrag main(in VertData v)\n" - "{\n" - " VertToFrag vtf;\n" - " vtf.color = v.colorIn * mulColor;\n" - " vtf.position = mul(mv, float4(v.posIn, 1.0));\n" - " return vtf;\n" - "}\n"; - - static const char* SolidFS = - "struct VertToFrag\n" - "{\n" - " float4 position : SV_Position;\n" - " float4 color : COLOR;\n" - "};\n" - "float4 main(in VertToFrag vtf) : SV_Target0\n" - "{\n" - " return vtf.color;\n" - "}\n"; - - static const char* TexVS = - "struct VertData\n" - "{\n" - " float3 posIn : POSITION;\n" - " float2 uvIn : UV;\n" - "};\n" - SPECTER_HLSL_VIEW_VERT_BLOCK - "struct VertToFrag\n" - "{\n" - " float4 position : SV_Position;\n" - " float4 color : COLOR;\n" - " float2 uv : UV;\n" - "};\n" - "VertToFrag main(in VertData v)\n" - "{\n" - " VertToFrag vtf;\n" - " vtf.uv = v.uvIn;\n" - " vtf.color = mulColor;\n" - " vtf.position = mul(mv, float4(v.posIn, 1.0));\n" - " return vtf;\n" - "}\n"; - - static const char* TexFS = - "struct VertToFrag\n" - "{\n" - " float4 position : SV_Position;\n" - " float4 color : COLOR;\n" - " float2 uv : UV;\n" - "};\n" - "Texture2D tex : register(t0);\n" - "SamplerState samp : register(s0);\n" - "float4 main(in VertToFrag vtf) : SV_Target0\n" - "{\n" - " return tex.Sample(samp, vtf.uv) * vtf.color;\n" - "}\n"; - - boo::VertexElementDescriptor solidvdescs[] = - { - {nullptr, nullptr, boo::VertexSemantic::Position4}, - {nullptr, nullptr, boo::VertexSemantic::Color} - }; - m_solidVtxFmt = ctx.newVertexFormat(2, solidvdescs); - - m_solidShader = ctx.newShaderPipeline(SolidVS, SolidFS, nullptr, nullptr, nullptr, m_solidVtxFmt, - boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha, - boo::Primitive::TriStrips, boo::ZTest::None, false, true, true, boo::CullMode::None); - - boo::VertexElementDescriptor texvdescs[] = - { - {nullptr, nullptr, boo::VertexSemantic::Position4}, - {nullptr, nullptr, boo::VertexSemantic::UV4} - }; - m_texVtxFmt = ctx.newVertexFormat(2, texvdescs); - - m_texShader = ctx.newShaderPipeline(TexVS, TexFS, nullptr, nullptr, nullptr, m_texVtxFmt, - boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha, - boo::Primitive::TriStrips, boo::ZTest::None, false, true, true, boo::CullMode::None); -} - -#endif -#if BOO_HAS_METAL - -void View::Resources::init(boo::MetalDataFactory::Context& ctx, const IThemeData& theme) -{ - static const char* SolidVS = - "#include \n" - "using namespace metal;\n" - "struct VertData\n" - "{\n" - " float3 posIn [[ attribute(0) ]];\n" - " float4 colorIn [[ attribute(1) ]];\n" - "};\n" - SPECTER_METAL_VIEW_VERT_BLOCK - "struct VertToFrag\n" - "{\n" - " float4 position [[ position ]];\n" - " float4 color;\n" - "};\n" - "vertex VertToFrag vmain(VertData v [[ stage_in ]], constant SpecterViewBlock& view [[ buffer(2) ]])\n" - "{\n" - " VertToFrag vtf;\n" - " vtf.color = v.colorIn * view.mulColor;\n" - " vtf.position = view.mv * float4(v.posIn, 1.0);\n" - " return vtf;\n" - "}\n"; - - static const char* SolidFS = - "#include \n" - "using namespace metal;\n" - "struct VertToFrag\n" - "{\n" - " float4 position [[ position ]];\n" - " float4 color;\n" - "};\n" - "fragment float4 fmain(VertToFrag vtf [[ stage_in ]])\n" - "{\n" - " return vtf.color;\n" - "}\n"; - - static const char* TexVS = - "#include \n" - "using namespace metal;\n" - "struct VertData\n" - "{\n" - " float3 posIn [[ attribute(0) ]];\n" - " float2 uvIn [[ attribute(1) ]];\n" - "};\n" - SPECTER_METAL_VIEW_VERT_BLOCK - "struct VertToFrag\n" - "{\n" - " float4 position [[ position ]];\n" - " float4 color;\n" - " float2 uv;\n" - "};\n" - "vertex VertToFrag vmain(VertData v [[ stage_in ]], constant SpecterViewBlock& view [[ buffer(2) ]])\n" - "{\n" - " VertToFrag vtf;\n" - " vtf.uv = v.uvIn;\n" - " vtf.color = view.mulColor;\n" - " vtf.position = view.mv * float4(v.posIn, 1.0);\n" - " return vtf;\n" - "}\n"; - - static const char* TexFS = - "#include \n" - "using namespace metal;\n" - "struct VertToFrag\n" - "{\n" - " float4 position [[ position ]];\n" - " float4 color;\n" - " float2 uv;\n" - "};\n" - "fragment float4 fmain(VertToFrag vtf [[ stage_in ]],\n" - " sampler samp [[ sampler(0) ]],\n" - " texture2d tex [[ texture(0) ]])\n" - "{\n" - " return tex.sample(samp, vtf.uv) * vtf.color;\n" - "}\n"; - - boo::VertexElementDescriptor solidvdescs[] = - { - {nullptr, nullptr, boo::VertexSemantic::Position4}, - {nullptr, nullptr, boo::VertexSemantic::Color} - }; - m_solidVtxFmt = ctx.newVertexFormat(2, solidvdescs); - - m_solidShader = ctx.newShaderPipeline(SolidVS, SolidFS, nullptr, nullptr, m_solidVtxFmt, - boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha, - boo::Primitive::TriStrips, boo::ZTest::None, false, true, false, boo::CullMode::None); - - boo::VertexElementDescriptor texvdescs[] = - { - {nullptr, nullptr, boo::VertexSemantic::Position4}, - {nullptr, nullptr, boo::VertexSemantic::UV4} - }; - m_texVtxFmt = ctx.newVertexFormat(2, texvdescs); - - m_texShader = ctx.newShaderPipeline(TexVS, TexFS, nullptr, nullptr, m_texVtxFmt, - boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha, - boo::Primitive::TriStrips, boo::ZTest::None, false, true, false, boo::CullMode::None); -} - -#endif -#if BOO_HAS_VULKAN - -void View::Resources::init(boo::VulkanDataFactory::Context& ctx, const IThemeData& theme) -{ - boo::VertexElementDescriptor solidvdescs[] = - { - {nullptr, nullptr, boo::VertexSemantic::Position4}, - {nullptr, nullptr, boo::VertexSemantic::Color} - }; - m_solidVtxFmt = ctx.newVertexFormat(2, solidvdescs); - - m_solidShader = ctx.newShaderPipeline(GLSLSolidVS, GLSLSolidFS, m_solidVtxFmt, - boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha, - boo::Primitive::TriStrips, boo::ZTest::None, false, true, true, boo::CullMode::None); - - boo::VertexElementDescriptor texvdescs[] = - { - {nullptr, nullptr, boo::VertexSemantic::Position4}, - {nullptr, nullptr, boo::VertexSemantic::UV4} - }; - m_texVtxFmt = ctx.newVertexFormat(2, texvdescs); - - m_texShader = ctx.newShaderPipeline(GLSLTexVS, GLSLTexFS, m_texVtxFmt, - boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha, - boo::Primitive::TriStrips, boo::ZTest::None, false, true, true, boo::CullMode::None); -} - -#endif void View::buildResources(boo::IGraphicsDataFactory::Context& ctx, ViewResources& res) { @@ -389,27 +83,10 @@ void View::VertexBufferBindingSolid::init(boo::IGraphicsDataFactory::Context& ct size_t bufOffs[] = {size_t(uBufInfo.second)}; size_t bufSizes[] = {sizeof(ViewBlock)}; - if (!res.m_viewRes.m_solidVtxFmt) - { - boo::VertexElementDescriptor vdescs[] = - { - {vBufInfo.first.get(), nullptr, boo::VertexSemantic::Position4}, - {vBufInfo.first.get(), nullptr, boo::VertexSemantic::Color} - }; - m_vtxFmt = ctx.newVertexFormat(2, vdescs, vBufInfo.second); - m_shaderBinding = ctx.newShaderDataBinding(res.m_viewRes.m_solidShader, - m_vtxFmt, vBufInfo.first.get(), nullptr, - nullptr, 1, bufs, nullptr, bufOffs, - bufSizes, 0, nullptr, nullptr, nullptr, vBufInfo.second); - } - else - { - m_shaderBinding = ctx.newShaderDataBinding(res.m_viewRes.m_solidShader, - res.m_viewRes.m_solidVtxFmt, - vBufInfo.first.get(), nullptr, - nullptr, 1, bufs, nullptr, bufOffs, - bufSizes, 0, nullptr, nullptr, nullptr, vBufInfo.second); - } + m_shaderBinding = ctx.newShaderDataBinding(res.m_viewRes.m_solidShader, + vBufInfo.first.get(), nullptr, + nullptr, 1, bufs, nullptr, bufOffs, + bufSizes, 0, nullptr, nullptr, nullptr, vBufInfo.second); } void View::VertexBufferBindingTex::init(boo::IGraphicsDataFactory::Context& ctx, @@ -426,27 +103,10 @@ void View::VertexBufferBindingTex::init(boo::IGraphicsDataFactory::Context& ctx, size_t bufSizes[] = {sizeof(ViewBlock)}; boo::ObjToken tex[] = {texture}; - if (!res.m_viewRes.m_texVtxFmt) - { - boo::VertexElementDescriptor vdescs[] = - { - {vBufInfo.first.get(), nullptr, boo::VertexSemantic::Position4}, - {vBufInfo.first.get(), nullptr, boo::VertexSemantic::UV4} - }; - m_vtxFmt = ctx.newVertexFormat(2, vdescs, vBufInfo.second); - m_shaderBinding = ctx.newShaderDataBinding(res.m_viewRes.m_texShader, - m_vtxFmt, vBufInfo.first.get(), nullptr, - nullptr, 1, bufs, nullptr, bufOffs, - bufSizes, 1, tex, nullptr, nullptr, vBufInfo.second); - } - else - { - m_shaderBinding = ctx.newShaderDataBinding(res.m_viewRes.m_texShader, - res.m_viewRes.m_texVtxFmt, - vBufInfo.first.get(), nullptr, - nullptr, 1, bufs, nullptr, bufOffs, - bufSizes, 1, tex, nullptr, nullptr, vBufInfo.second); - } + m_shaderBinding = ctx.newShaderDataBinding(res.m_viewRes.m_texShader, + vBufInfo.first.get(), nullptr, + nullptr, 1, bufs, nullptr, bufOffs, + bufSizes, 1, tex, nullptr, nullptr, vBufInfo.second); } diff --git a/specter/lib/ViewResources.cpp b/specter/lib/ViewResources.cpp index 8e3d1c19c..ba92f63d3 100644 --- a/specter/lib/ViewResources.cpp +++ b/specter/lib/ViewResources.cpp @@ -17,31 +17,7 @@ void ViewResources::init(boo::IGraphicsDataFactory* factory, FontCache* fcache, m_curveFont = fcache->prepCurvesFont(AllCharFilter, false, 8.f, dpi); factory->commitTransaction([&](boo::IGraphicsDataFactory::Context& ctx) { - switch (ctx.platform()) - { -#if BOO_HAS_GL - case boo::IGraphicsDataFactory::Platform::OpenGL: - init(static_cast(ctx), *theme, fcache); - break; -#endif -#if _WIN32 - case boo::IGraphicsDataFactory::Platform::D3D11: - init(static_cast(ctx), *theme, fcache); - break; -#endif -#if BOO_HAS_METAL - case boo::IGraphicsDataFactory::Platform::Metal: - init(static_cast(ctx), *theme, fcache); - break; -#endif -#if BOO_HAS_VULKAN - case boo::IGraphicsDataFactory::Platform::Vulkan: - init(static_cast(ctx), *theme, fcache); - break; -#endif - default: - Log.report(logvisor::Fatal, _S("unable to init view system for %s"), ctx.platformName()); - } + init(ctx, *theme, fcache); return true; } BooTrace); } diff --git a/specter/shaders/CMakeLists.txt b/specter/shaders/CMakeLists.txt new file mode 100644 index 000000000..47bdccc92 --- /dev/null +++ b/specter/shaders/CMakeLists.txt @@ -0,0 +1,5 @@ +include_directories(../../hecl/include + ../../hecl/extern/boo/include + ../../hecl/extern/boo/logvisor/include) +add_shader(SpecterViewShaders) +add_shader(SpecterTextViewShaders) diff --git a/specter/shaders/SpecterCommon.shader b/specter/shaders/SpecterCommon.shader new file mode 100644 index 000000000..a588c801d --- /dev/null +++ b/specter/shaders/SpecterCommon.shader @@ -0,0 +1,18 @@ +#define SPECTER_GLSL_VIEW_VERT_BLOCK\ + UBINDING0 uniform SpecterViewBlock\ + {\ + mat4 mv;\ + vec4 mulColor;\ + }; +#define SPECTER_HLSL_VIEW_VERT_BLOCK\ + cbuffer SpecterViewBlock : register(b0)\ + {\ + float4x4 mv;\ + float4 mulColor;\ + }; +#define SPECTER_METAL_VIEW_VERT_BLOCK\ + struct SpecterViewBlock\ + {\ + float4x4 mv;\ + float4 mulColor;\ + }; \ No newline at end of file diff --git a/specter/shaders/SpecterTextViewShaders.shader b/specter/shaders/SpecterTextViewShaders.shader new file mode 100644 index 000000000..bcc5a76c2 --- /dev/null +++ b/specter/shaders/SpecterTextViewShaders.shader @@ -0,0 +1,205 @@ +#include "SpecterCommon.shader" + +#shader SpecterTextViewShader +#instattribute position4 0 +#instattribute position4 1 +#instattribute position4 2 +#instattribute position4 3 +#instattribute modelview 0 +#instattribute modelview 1 +#instattribute modelview 2 +#instattribute modelview 3 +#instattribute uv4 0 +#instattribute uv4 1 +#instattribute uv4 2 +#instattribute uv4 3 +#instattribute color +#srcfac srcalpha +#dstfac invsrcalpha +#primitive tristrips +#depthtest none +#depthwrite false +#culling none + +#vertex glsl +layout(location=0) in vec3 posIn[4]; +layout(location=4) in mat4 mvMtx; +layout(location=8) in vec3 uvIn[4]; +layout(location=12) in vec4 colorIn; +SPECTER_GLSL_VIEW_VERT_BLOCK +struct VertToFrag +{ + vec3 uv; + vec4 color; +}; +SBINDING(0) out VertToFrag vtf; +void main() +{ + vec3 pos = posIn[gl_VertexID]; + vtf.uv = uvIn[gl_VertexID]; + vtf.color = colorIn * mulColor; + gl_Position = mv * mvMtx * vec4(pos, 1.0); + gl_Position = FLIPFROMGL(gl_Position); +} + +#fragment glsl +TBINDING0 uniform sampler2DArray fontTex; +struct VertToFrag +{ + vec3 uv; + vec4 color; +}; +SBINDING(0) in VertToFrag vtf; +layout(location=0) out vec4 colorOut; +void main() +{ + colorOut = vtf.color; + colorOut.a *= texture(fontTex, vtf.uv).r; +} + +#vertex hlsl +struct VertData +{ + float3 posIn[4] : POSITION; + float4x4 mvMtx : MODELVIEW; + float3 uvIn[4] : UV; + float4 colorIn : COLOR; +}; +SPECTER_HLSL_VIEW_VERT_BLOCK +struct VertToFrag +{ + float4 position : SV_Position; + float3 uv : UV; + float4 color : COLOR; +}; +VertToFrag main(in VertData v, in uint vertId : SV_VertexID) +{ + VertToFrag vtf; + vtf.uv = v.uvIn[vertId]; + vtf.color = v.colorIn * mulColor; + vtf.position = mul(mv, mul(v.mvMtx, float4(v.posIn[vertId], 1.0))); + return vtf; +} + +#fragment hlsl +Texture2DArray fontTex : register(t0); +SamplerState samp : register(s0); +struct VertToFrag +{ + float4 position : SV_Position; + float3 uv : UV; + float4 color : COLOR; +}; +float4 main(in VertToFrag vtf) : SV_Target0 +{ + float4 colorOut = vtf.color; + colorOut.a *= fontTex.Sample(samp, vtf.uv).r; + return colorOut; +} + +#vertex metal +struct VertData +{ + float3 posIn[4]; + float4x4 mvMtx; + float3 uvIn[4]; + float4 colorIn; +}; +SPECTER_METAL_VIEW_VERT_BLOCK +struct VertToFrag +{ + float4 position [[ position ]]; + float3 uv; + float4 color; +}; +vertex VertToFrag vmain(constant VertData* va [[ buffer(1) ]], + uint vertId [[ vertex_id ]], uint instId [[ instance_id ]], + constant SpecterViewBlock& view [[ buffer(2) ]]) +{ + VertToFrag vtf; + constant VertData& v = va[instId]; + vtf.uv = v.uvIn[vertId]; + vtf.color = v.colorIn * view.mulColor; + vtf.position = view.mv * v.mvMtx * float4(v.posIn[vertId], 1.0); + return vtf; +} + +#fragment metal +struct VertToFrag +{ + float4 position [[ position ]]; + float3 uv; + float4 color; +}; +fragment float4 fmain(VertToFrag vtf [[ stage_in ]], + sampler samp [[ sampler(0) ]], + texture2d_array fontTex [[ texture(0) ]]) +{ + float4 colorOut = vtf.color; + colorOut.a *= fontTex.sample(samp, vtf.uv.xy, vtf.uv.z).r; + return colorOut; +} + +#shader SpecterTextViewShaderSubpixel : SpecterTextViewShader +#srcfac srccolor1 +#dstfac invsrccolor1 + +#fragment glsl +TBINDING0 uniform sampler2DArray fontTex; +struct VertToFrag +{ + vec3 uv; + vec4 color; +}; +SBINDING(0) in VertToFrag vtf; +layout(location=0, index=0) out vec4 colorOut; +layout(location=0, index=1) out vec4 blendOut; +void main() +{ + colorOut = vtf.color; + blendOut = colorOut.a * texture(fontTex, vtf.uv); +} + +#fragment hlsl +Texture2DArray fontTex : register(t0); +SamplerState samp : register(s0); +struct VertToFrag +{ + float4 position : SV_Position; + float3 uv : UV; + float4 color : COLOR; +}; +struct BlendOut +{ + float4 colorOut : SV_Target0; + float4 blendOut : SV_Target1; +}; +BlendOut main(in VertToFrag vtf) +{ + BlendOut ret; + ret.colorOut = vtf.color; + ret.blendOut = ret.colorOut.a * fontTex.Sample(samp, vtf.uv); + return ret; +} + +#fragment metal +struct VertToFrag +{ + float4 position [[ position ]]; + float3 uv; + float4 color; +}; +struct BlendOut +{ + float4 colorOut : [[ color(0), index(0) ]]; + float4 blendOut : [[ color(0), index(1) ]]; +}; +fragment BlendOut fmain(VertToFrag vtf [[ stage_in ]], + sampler samp [[ sampler(0) ]], + texture2d_array fontTex [[ texture(0) ]]) +{ + BlendOut ret; + ret.colorOut = vtf.color; + ret.blendOut = ret.colorOut.a * fontTex.sample(samp, vtf.uv.xy, vtf.uv.z); + return ret; +} diff --git a/specter/shaders/SpecterViewShaders.shader b/specter/shaders/SpecterViewShaders.shader new file mode 100644 index 000000000..aa86e3bd1 --- /dev/null +++ b/specter/shaders/SpecterViewShaders.shader @@ -0,0 +1,215 @@ +#include "SpecterCommon.shader" + +#shader SpecterViewShaderSolid +#attribute position4 +#attribute color +#srcfac srcalpha +#dstfac invsrcalpha +#primitive tristrips +#depthtest none +#depthwrite false +#culling none + +#vertex glsl +layout(location=0) in vec3 posIn; +layout(location=1) in vec4 colorIn; +SPECTER_GLSL_VIEW_VERT_BLOCK +struct VertToFrag +{ + vec4 color; +}; +SBINDING(0) out VertToFrag vtf; +void main() +{ + vtf.color = colorIn * mulColor; + gl_Position = mv * vec4(posIn, 1.0); + gl_Position = FLIPFROMGL(gl_Position); +} + +#fragment glsl +struct VertToFrag +{ + vec4 color; +}; +SBINDING(0) in VertToFrag vtf; +layout(location=0) out vec4 colorOut; +void main() +{ + colorOut = vtf.color; +} + +#vertex hlsl +struct VertData +{ + float3 posIn : POSITION; + float4 colorIn : COLOR; +}; +SPECTER_HLSL_VIEW_VERT_BLOCK +struct VertToFrag +{ + float4 position : SV_Position; + float4 color : COLOR; +}; +VertToFrag main(in VertData v) +{ + VertToFrag vtf; + vtf.color = v.colorIn * mulColor; + vtf.position = mul(mv, float4(v.posIn, 1.0)); + return vtf; +} + +#fragment hlsl +struct VertToFrag +{ + float4 position : SV_Position; + float4 color : COLOR; +}; +float4 main(in VertToFrag vtf) : SV_Target0 +{ + return vtf.color; +} + +#vertex metal +struct VertData +{ + float3 posIn [[ attribute(0) ]]; + float4 colorIn [[ attribute(1) ]]; +}; +SPECTER_METAL_VIEW_VERT_BLOCK +struct VertToFrag +{ + float4 position [[ position ]]; + float4 color; +}; +vertex VertToFrag vmain(VertData v [[ stage_in ]], constant SpecterViewBlock& view [[ buffer(2) ]]) +{ + VertToFrag vtf; + vtf.color = v.colorIn * view.mulColor; + vtf.position = view.mv * float4(v.posIn, 1.0); + return vtf; +} + +#fragment metal +struct VertToFrag +{ + float4 position [[ position ]]; + float4 color; +}; +fragment float4 fmain(VertToFrag vtf [[ stage_in ]]) +{ + return vtf.color; +} + +#shader SpecterViewShaderTex +#attribute position4 +#attribute uv4 +#srcfac srcalpha +#dstfac invsrcalpha +#primitive tristrips +#depthtest none +#depthwrite false +#culling none + +#vertex glsl +layout(location=0) in vec3 posIn; +layout(location=1) in vec2 uvIn; +SPECTER_GLSL_VIEW_VERT_BLOCK +struct VertToFrag +{ + vec4 color; + vec4 uv; +}; +SBINDING(0) out VertToFrag vtf; +void main() +{ + vtf.uv.xy = uvIn; + vtf.color = mulColor; + gl_Position = mv * vec4(posIn, 1.0); + gl_Position = FLIPFROMGL(gl_Position); +} + +#fragment glsl +struct VertToFrag +{ + vec4 color; + vec4 uv; +}; +SBINDING(0) in VertToFrag vtf; +TBINDING0 uniform sampler2D tex; +layout(location=0) out vec4 colorOut; +void main() +{ + colorOut = texture(tex, vtf.uv.xy) * vtf.color; +} + +#vertex hlsl +struct VertData +{ + float3 posIn : POSITION; + float2 uvIn : UV; +}; +SPECTER_HLSL_VIEW_VERT_BLOCK +struct VertToFrag +{ + float4 position : SV_Position; + float4 color : COLOR; + float2 uv : UV; +}; +VertToFrag main(in VertData v) +{ + VertToFrag vtf; + vtf.uv = v.uvIn; + vtf.color = mulColor; + vtf.position = mul(mv, float4(v.posIn, 1.0)); + return vtf; +} + +#fragment hlsl +struct VertToFrag +{ + float4 position : SV_Position; + float4 color : COLOR; + float2 uv : UV; +}; +Texture2D tex : register(t0); +SamplerState samp : register(s0); +float4 main(in VertToFrag vtf) : SV_Target0 +{ + return tex.Sample(samp, vtf.uv) * vtf.color; +} + +#vertex metal +struct VertData +{ + float3 posIn [[ attribute(0) ]]; + float2 uvIn [[ attribute(1) ]]; +}; +SPECTER_METAL_VIEW_VERT_BLOCK +struct VertToFrag +{ + float4 position [[ position ]]; + float4 color; + float2 uv; +}; +vertex VertToFrag vmain(VertData v [[ stage_in ]], constant SpecterViewBlock& view [[ buffer(2) ]]) +{ + VertToFrag vtf; + vtf.uv = v.uvIn; + vtf.color = view.mulColor; + vtf.position = view.mv * float4(v.posIn, 1.0); + return vtf; +} + +#fragment metal +struct VertToFrag +{ + float4 position [[ position ]]; + float4 color; + float2 uv; +}; +fragment float4 fmain(VertToFrag vtf [[ stage_in ]], + sampler samp [[ sampler(0) ]], + texture2d tex [[ texture(0) ]]) +{ + return tex.sample(samp, vtf.uv) * vtf.color; +}