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

@ -91,3 +91,4 @@ list(APPEND SPECTER_SOURCES
atdna_FontCache.cpp) atdna_FontCache.cpp)
add_library(specter ${SPECTER_SOURCES} ${SPECTER_HEADERS}) add_library(specter ${SPECTER_SOURCES} ${SPECTER_HEADERS})
add_dependencies(specter hecl-light)

View File

@ -8,14 +8,28 @@ namespace specter
class Control; class Control;
class Button; class Button;
enum class ControlType
{
Button,
Float,
Int,
String,
CVar
};
struct IControlBinding struct IControlBinding
{ {
virtual ControlType type() const = 0;
virtual std::string_view name(const Control* control) const=0; virtual std::string_view name(const Control* control) const=0;
virtual std::string_view help(const Control* control) const {return {};} virtual std::string_view help(const Control* control) const {return {};}
}; };
struct IButtonBinding : IControlBinding struct IButtonBinding : IControlBinding
{ {
ControlType type() const { return ControlType::Button; }
static IButtonBinding* castTo(IControlBinding* bind)
{ return bind->type() == ControlType::Button ? static_cast<IButtonBinding*>(bind) : nullptr; }
/** Pressed/Released while Hovering action, /** Pressed/Released while Hovering action,
* cancellable by holding the button and releasing outside */ * cancellable by holding the button and releasing outside */
virtual void activated(const Button* button, const boo::SWindowCoord& coord) {} virtual void activated(const Button* button, const boo::SWindowCoord& coord) {}
@ -43,6 +57,9 @@ struct IButtonBinding : IControlBinding
struct IFloatBinding : IControlBinding struct IFloatBinding : IControlBinding
{ {
ControlType type() const { return ControlType::Float; }
static IFloatBinding* castTo(IControlBinding* bind)
{ return bind->type() == ControlType::Float ? static_cast<IFloatBinding*>(bind) : nullptr; }
virtual float getDefault(const Control* control) const {return 0.0;} virtual float getDefault(const Control* control) const {return 0.0;}
virtual std::pair<float,float> getBounds(const Control* control) const {return std::make_pair(FLT_MIN, FLT_MAX);} virtual std::pair<float,float> getBounds(const Control* control) const {return std::make_pair(FLT_MIN, FLT_MAX);}
virtual void changed(const Control* control, float val)=0; virtual void changed(const Control* control, float val)=0;
@ -50,6 +67,9 @@ struct IFloatBinding : IControlBinding
struct IIntBinding : IControlBinding struct IIntBinding : IControlBinding
{ {
ControlType type() const { return ControlType::Int; }
static IIntBinding* castTo(IControlBinding* bind)
{ return bind->type() == ControlType::Int ? static_cast<IIntBinding*>(bind) : nullptr; }
virtual int getDefault(const Control* control) const {return 0;} virtual int getDefault(const Control* control) const {return 0;}
virtual std::pair<int,int> getBounds(const Control* control) const {return std::make_pair(INT_MIN, INT_MAX);} virtual std::pair<int,int> getBounds(const Control* control) const {return std::make_pair(INT_MIN, INT_MAX);}
virtual void changed(const Control* control, int val)=0; virtual void changed(const Control* control, int val)=0;
@ -57,6 +77,9 @@ struct IIntBinding : IControlBinding
struct IStringBinding : IControlBinding struct IStringBinding : IControlBinding
{ {
ControlType type() const { return ControlType::String; }
static IStringBinding* castTo(IControlBinding* bind)
{ return bind->type() == ControlType::String ? static_cast<IStringBinding*>(bind) : nullptr; }
virtual std::string getDefault(const Control* control) const {return "";} virtual std::string getDefault(const Control* control) const {return "";}
virtual void changed(const Control* control, std::string_view val)=0; virtual void changed(const Control* control, std::string_view val)=0;
}; };
@ -66,6 +89,9 @@ struct CVarControlBinding : IControlBinding
hecl::CVar* m_cvar; hecl::CVar* m_cvar;
CVarControlBinding(hecl::CVar* cvar) CVarControlBinding(hecl::CVar* cvar)
: m_cvar(cvar) {} : m_cvar(cvar) {}
ControlType type() const { return ControlType::CVar; }
static CVarControlBinding* castTo(IControlBinding* bind)
{ return bind->type() == ControlType::CVar ? static_cast<CVarControlBinding*>(bind) : nullptr; }
std::string_view name(const Control* control) const {return m_cvar->name();} std::string_view name(const Control* control) const {return m_cvar->name();}
std::string_view help(const Control* control) const {return m_cvar->rawHelp();} std::string_view help(const Control* control) const {return m_cvar->rawHelp();}
}; };

View File

@ -8,6 +8,7 @@
#include <hecl/Runtime.hpp> #include <hecl/Runtime.hpp>
#include <athena/FileReader.hpp> #include <athena/FileReader.hpp>
#include <athena/FileWriter.hpp> #include <athena/FileWriter.hpp>
#include <athena/DNA.hpp>
namespace specter namespace specter
{ {

View File

@ -17,7 +17,6 @@ class NumericField : public View
boo::IGraphicsBufferD* m_bBlockBuf; boo::IGraphicsBufferD* m_bBlockBuf;
boo::IGraphicsBufferD* m_bVertsBuf; boo::IGraphicsBufferD* m_bVertsBuf;
boo::IVertexFormat* m_bVtxFmt; /* OpenGL only */
boo::IShaderDataBinding* m_bShaderBinding; boo::IShaderDataBinding* m_bShaderBinding;
int m_nomWidth, m_nomHeight; int m_nomWidth, m_nomHeight;

View File

@ -74,7 +74,10 @@ public:
if (m_toolbar.m_view) if (m_toolbar.m_view)
m_toolbar.m_view->setMultiplyColor(color); m_toolbar.m_view->setMultiplyColor(color);
} }
bool isSpace() const { return true; }
}; };
inline Space* View::castToSpace() { return isSpace() ? static_cast<Space*>(this) : nullptr; }
} }

View File

@ -112,7 +112,10 @@ public:
if (m_views[1].m_view) if (m_views[1].m_view)
m_views[1].m_view->setMultiplyColor(color); m_views[1].m_view->setMultiplyColor(color);
} }
bool isSplitView() const { return true; }
}; };
inline SplitView* View::castToSplitView() { return isSplitView() ? static_cast<SplitView*>(this) : nullptr; }
} }

View File

@ -2,10 +2,7 @@
#define SPECTER_TEXTVIEW_HPP #define SPECTER_TEXTVIEW_HPP
#include "View.hpp" #include "View.hpp"
#include <boo/graphicsdev/GL.hpp> #include "boo/graphicsdev/IGraphicsDataFactory.hpp"
#include <boo/graphicsdev/D3D.hpp>
#include <boo/graphicsdev/Metal.hpp>
#include <boo/graphicsdev/Vulkan.hpp>
#include "FontCache.hpp" #include "FontCache.hpp"
@ -62,7 +59,6 @@ private:
size_t m_capacity; size_t m_capacity;
size_t m_curSize = 0; size_t m_curSize = 0;
hecl::VertexBufferPool<RenderGlyph>::Token m_glyphBuf; hecl::VertexBufferPool<RenderGlyph>::Token m_glyphBuf;
boo::ObjToken<boo::IVertexFormat> m_vtxFmt; /* OpenGL only */
boo::ObjToken<boo::IShaderDataBinding> m_shaderBinding; boo::ObjToken<boo::IShaderDataBinding> m_shaderBinding;
const FontAtlas& m_fontAtlas; const FontAtlas& m_fontAtlas;
Alignment m_align; Alignment m_align;
@ -90,27 +86,14 @@ public:
FontCache* m_fcache = nullptr; FontCache* m_fcache = nullptr;
boo::ObjToken<boo::IShaderPipeline> m_regular; boo::ObjToken<boo::IShaderPipeline> m_regular;
boo::ObjToken<boo::IShaderPipeline> m_subpixel; boo::ObjToken<boo::IShaderPipeline> m_subpixel;
boo::ObjToken<boo::IVertexFormat> m_vtxFmt; /* Not OpenGL */
#if BOO_HAS_GL void init(boo::IGraphicsDataFactory::Context& ctx, FontCache* fcache);
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 destroy() void destroy()
{ {
m_glyphPool.doDestroy(); m_glyphPool.doDestroy();
m_regular.reset(); m_regular.reset();
m_subpixel.reset(); m_subpixel.reset();
m_vtxFmt.reset();
} }
}; };

View File

@ -1,7 +1,7 @@
#ifndef SPECTER_VIEW_HPP #ifndef SPECTER_VIEW_HPP
#define SPECTER_VIEW_HPP #define SPECTER_VIEW_HPP
#include <boo/boo.hpp> #include "boo/boo.hpp"
#include "optional.hpp" #include "optional.hpp"
#include "zeus/CVector3f.hpp" #include "zeus/CVector3f.hpp"
#include "zeus/CMatrix4f.hpp" #include "zeus/CMatrix4f.hpp"
@ -11,11 +11,6 @@
#include "hecl/UniformBufferPool.hpp" #include "hecl/UniformBufferPool.hpp"
#include "hecl/VertexBufferPool.hpp" #include "hecl/VertexBufferPool.hpp"
#include <boo/graphicsdev/GL.hpp>
#include <boo/graphicsdev/D3D.hpp>
#include <boo/graphicsdev/Metal.hpp>
#include <boo/graphicsdev/Vulkan.hpp>
namespace specter namespace specter
{ {
class IThemeData; class IThemeData;
@ -81,6 +76,8 @@ public:
} }
}; };
class Space;
class SplitView;
class View class View
{ {
public: public:
@ -111,7 +108,6 @@ public:
struct VertexBufferBinding struct VertexBufferBinding
{ {
typename hecl::VertexBufferPool<VertStruct>::Token m_vertsBuf; typename hecl::VertexBufferPool<VertStruct>::Token m_vertsBuf;
boo::ObjToken<boo::IVertexFormat> m_vtxFmt; /* OpenGL only */
boo::ObjToken<boo::IShaderDataBinding> m_shaderBinding; boo::ObjToken<boo::IShaderDataBinding> m_shaderBinding;
void load(const VertStruct* data, size_t count) void load(const VertStruct* data, size_t count)
@ -165,24 +161,6 @@ private:
protected: protected:
ViewBlock m_viewVertBlock; 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<ViewBlock>::Token m_viewVertBlockBuf; hecl::UniformBufferPool<ViewBlock>::Token m_viewVertBlockBuf;
public: public:
@ -200,23 +178,9 @@ public:
} }
boo::ObjToken<boo::IShaderPipeline> m_solidShader; boo::ObjToken<boo::IShaderPipeline> m_solidShader;
boo::ObjToken<boo::IVertexFormat> m_solidVtxFmt; /* Not OpenGL */
boo::ObjToken<boo::IShaderPipeline> m_texShader; boo::ObjToken<boo::IShaderPipeline> m_texShader;
boo::ObjToken<boo::IVertexFormat> m_texVtxFmt; /* Not OpenGL */
#if BOO_HAS_GL void init(boo::IGraphicsDataFactory::Context& ctx, const IThemeData& theme);
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 destroy() void destroy()
{ {
@ -225,9 +189,7 @@ public:
m_texPool.doDestroy(); m_texPool.doDestroy();
m_solidShader.reset(); m_solidShader.reset();
m_solidVtxFmt.reset();
m_texShader.reset(); m_texShader.reset();
m_texVtxFmt.reset();
} }
}; };
@ -292,6 +254,11 @@ public:
const boo::SWindowRect& scissor) {resized(root, sub);} const boo::SWindowRect& scissor) {resized(root, sub);}
virtual void think() {} virtual void think() {}
virtual void draw(boo::IGraphicsCommandQueue* gfxQ); virtual void draw(boo::IGraphicsCommandQueue* gfxQ);
virtual bool isSpace() const { return false; }
virtual bool isSplitView() const { return false; }
Space* castToSpace();
SplitView* castToSplitView();
}; };
template <class ViewPtrType> template <class ViewPtrType>

View File

@ -149,8 +149,7 @@ public:
class ViewResources class ViewResources
{ {
template <class FactoryCtx> void init(boo::IGraphicsDataFactory::Context& factory, const IThemeData& theme, FontCache* fcache)
void init(FactoryCtx& factory, const IThemeData& theme, FontCache* fcache)
{ {
m_viewRes.init(factory, theme); m_viewRes.init(factory, theme);
m_textRes.init(factory, fcache); m_textRes.init(factory, fcache);

View File

@ -320,7 +320,7 @@ void RootView::SplitMenuSystem::mouseUp(const boo::SWindowCoord& coord, boo::EMo
{ {
m_interactiveDown = false; m_interactiveDown = false;
m_phase = Phase::Inactive; m_phase = Phase::Inactive;
Space* space = dynamic_cast<Space*>(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()) if (space && space->m_controller.spaceSplitAllowed())
{ {
ISplitSpaceController* ss = space->m_controller.spaceSplit(axis, 0); ISplitSpaceController* ss = space->m_controller.spaceSplit(axis, 0);
@ -337,7 +337,7 @@ SplitView* RootView::recursiveTestSplitHover(SplitView* sv, const boo::SWindowCo
return sv; return sv;
for (int i=0 ; i<2 ; ++i) for (int i=0 ; i<2 ; ++i)
{ {
SplitView* child = dynamic_cast<SplitView*>(sv->m_views[i].m_view); SplitView* child = sv->m_views[i].m_view->castToSplitView();
if (child) if (child)
{ {
SplitView* res = recursiveTestSplitHover(child, coord); SplitView* res = recursiveTestSplitHover(child, coord);
@ -391,7 +391,7 @@ void RootView::mouseMove(const boo::SWindowCoord& coord)
{ {
for (View* v : m_views) for (View* v : m_views)
{ {
SplitView* sv = dynamic_cast<SplitView*>(v); SplitView* sv = v->castToSplitView();
if (sv) if (sv)
sv = recursiveTestSplitHover(sv, coord); sv = recursiveTestSplitHover(sv, coord);
if (sv) if (sv)

View File

@ -267,7 +267,7 @@ void Space::CornerView::mouseLeave(const boo::SWindowCoord& coord)
SplitView* Space::findSplitViewOnSide(SplitView::Axis axis, int side) SplitView* Space::findSplitViewOnSide(SplitView::Axis axis, int side)
{ {
SplitView* ret = dynamic_cast<SplitView*>(&parentView()); SplitView* ret = parentView().castToSplitView();
View* test = this; View* test = this;
while (ret) while (ret)
{ {
@ -277,7 +277,7 @@ SplitView* Space::findSplitViewOnSide(SplitView::Axis axis, int side)
return ret; return ret;
else if (ret->m_views[side].m_view == test) else if (ret->m_views[side].m_view == test)
test = ret; test = ret;
ret = dynamic_cast<SplitView*>(&ret->parentView()); ret = ret->parentView().castToSplitView();
} }
return nullptr; return nullptr;
} }

View File

@ -123,7 +123,7 @@ bool SplitView::testJoinArrowHover(const boo::SWindowCoord& coord, int& origSlot
dirOut = ArrowDir::Up; dirOut = ArrowDir::Up;
if (m_views[1].m_view) if (m_views[1].m_view)
{ {
SplitView* chSplit = dynamic_cast<SplitView*>(m_views[1].m_view); SplitView* chSplit = m_views[1].m_view->castToSplitView();
if (chSplit && chSplit->m_axis == Axis::Horizontal) if (chSplit && chSplit->m_axis == Axis::Horizontal)
return chSplit->testJoinArrowHover(coord, origDummy, splitOut, slotOut, rectOut, dirDummy, 0); 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; dirOut = ArrowDir::Down;
if (m_views[0].m_view) if (m_views[0].m_view)
{ {
SplitView* chSplit = dynamic_cast<SplitView*>(m_views[0].m_view); SplitView* chSplit = m_views[0].m_view->castToSplitView();
if (chSplit && chSplit->m_axis == Axis::Horizontal) if (chSplit && chSplit->m_axis == Axis::Horizontal)
return chSplit->testJoinArrowHover(coord, origDummy, splitOut, slotOut, rectOut, dirDummy, 1); 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; dirOut = ArrowDir::Right;
if (m_views[1].m_view) if (m_views[1].m_view)
{ {
SplitView* chSplit = dynamic_cast<SplitView*>(m_views[1].m_view); SplitView* chSplit = m_views[1].m_view->castToSplitView();
if (chSplit && chSplit->m_axis == Axis::Vertical) if (chSplit && chSplit->m_axis == Axis::Vertical)
return chSplit->testJoinArrowHover(coord, origDummy, splitOut, slotOut, rectOut, dirDummy, 0); 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; dirOut = ArrowDir::Left;
if (m_views[0].m_view) if (m_views[0].m_view)
{ {
SplitView* chSplit = dynamic_cast<SplitView*>(m_views[0].m_view); SplitView* chSplit = m_views[0].m_view->castToSplitView();
if (chSplit && chSplit->m_axis == Axis::Vertical) if (chSplit && chSplit->m_axis == Axis::Vertical)
return chSplit->testJoinArrowHover(coord, origDummy, splitOut, slotOut, rectOut, dirDummy, 1); 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) if (m_views[1].m_view)
{ {
SplitView* chSplit = dynamic_cast<SplitView*>(m_views[1].m_view); SplitView* chSplit = m_views[1].m_view->castToSplitView();
if (chSplit && chSplit->m_axis == Axis::Horizontal) if (chSplit && chSplit->m_axis == Axis::Horizontal)
return chSplit->getJoinArrowHover(0, rectOut, dirOut); 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) if (m_views[0].m_view)
{ {
SplitView* chSplit = dynamic_cast<SplitView*>(m_views[0].m_view); SplitView* chSplit = m_views[0].m_view->castToSplitView();
if (chSplit && chSplit->m_axis == Axis::Horizontal) if (chSplit && chSplit->m_axis == Axis::Horizontal)
return chSplit->getJoinArrowHover(1, rectOut, dirOut); 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) if (m_views[1].m_view)
{ {
SplitView* chSplit = dynamic_cast<SplitView*>(m_views[1].m_view); SplitView* chSplit = m_views[1].m_view->castToSplitView();
if (chSplit && chSplit->m_axis == Axis::Vertical) if (chSplit && chSplit->m_axis == Axis::Vertical)
return chSplit->getJoinArrowHover(0, rectOut, dirOut); 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) if (m_views[0].m_view)
{ {
SplitView* chSplit = dynamic_cast<SplitView*>(m_views[0].m_view); SplitView* chSplit = m_views[0].m_view->castToSplitView();
if (chSplit && chSplit->m_axis == Axis::Vertical) if (chSplit && chSplit->m_axis == Axis::Vertical)
return chSplit->getJoinArrowHover(1, rectOut, dirOut); 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) if (m_views[1].m_view)
{ {
SplitView* chSplit = dynamic_cast<SplitView*>(m_views[1].m_view); SplitView* chSplit = m_views[1].m_view->castToSplitView();
if (chSplit && chSplit->m_axis == Axis::Horizontal) if (chSplit && chSplit->m_axis == Axis::Horizontal)
return chSplit->testSplitLineHover(coord, slotOut, rectOut, splitOut, axisOut); 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) if (m_views[0].m_view)
{ {
SplitView* chSplit = dynamic_cast<SplitView*>(m_views[0].m_view); SplitView* chSplit = m_views[0].m_view->castToSplitView();
if (chSplit && chSplit->m_axis == Axis::Horizontal) if (chSplit && chSplit->m_axis == Axis::Horizontal)
return chSplit->testSplitLineHover(coord, slotOut, rectOut, splitOut, axisOut); 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) if (m_views[1].m_view)
{ {
SplitView* chSplit = dynamic_cast<SplitView*>(m_views[1].m_view); SplitView* chSplit = m_views[1].m_view->castToSplitView();
if (chSplit && chSplit->m_axis == Axis::Vertical) if (chSplit && chSplit->m_axis == Axis::Vertical)
return chSplit->testSplitLineHover(coord, slotOut, rectOut, splitOut, axisOut); 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) if (m_views[0].m_view)
{ {
SplitView* chSplit = dynamic_cast<SplitView*>(m_views[0].m_view); SplitView* chSplit = m_views[0].m_view->castToSplitView();
if (chSplit && chSplit->m_axis == Axis::Vertical) if (chSplit && chSplit->m_axis == Axis::Vertical)
return chSplit->testSplitLineHover(coord, slotOut, rectOut, splitOut, axisOut); 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) if (m_views[1].m_view)
{ {
SplitView* chSplit = dynamic_cast<SplitView*>(m_views[1].m_view); SplitView* chSplit = m_views[1].m_view->castToSplitView();
if (chSplit && chSplit->m_axis == Axis::Horizontal) if (chSplit && chSplit->m_axis == Axis::Horizontal)
return chSplit->getSplitLineHover(0, rectOut, axisOut); 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) if (m_views[0].m_view)
{ {
SplitView* chSplit = dynamic_cast<SplitView*>(m_views[0].m_view); SplitView* chSplit = m_views[0].m_view->castToSplitView();
if (chSplit && chSplit->m_axis == Axis::Horizontal) if (chSplit && chSplit->m_axis == Axis::Horizontal)
return chSplit->getSplitLineHover(1, rectOut, axisOut); 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) if (m_views[1].m_view)
{ {
SplitView* chSplit = dynamic_cast<SplitView*>(m_views[1].m_view); SplitView* chSplit = m_views[1].m_view->castToSplitView();
if (chSplit && chSplit->m_axis == Axis::Vertical) if (chSplit && chSplit->m_axis == Axis::Vertical)
return chSplit->getSplitLineHover(0, rectOut, axisOut); 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) if (m_views[0].m_view)
{ {
SplitView* chSplit = dynamic_cast<SplitView*>(m_views[0].m_view); SplitView* chSplit = m_views[0].m_view->castToSplitView();
if (chSplit && chSplit->m_axis == Axis::Vertical) if (chSplit && chSplit->m_axis == Axis::Vertical)
return chSplit->getSplitLineHover(1, rectOut, axisOut); return chSplit->getSplitLineHover(1, rectOut, axisOut);
} }

View File

@ -33,8 +33,9 @@ void TextField::_setText()
m_textStr = m_deferredTextStr; m_textStr = m_deferredTextStr;
m_text->typesetGlyphs(m_textStr, m_error ? rootView().themeData().uiText() : m_text->typesetGlyphs(m_textStr, m_error ? rootView().themeData().uiText() :
rootView().themeData().fieldText()); rootView().themeData().fieldText());
if (m_controlBinding && dynamic_cast<IStringBinding*>(m_controlBinding)) if (m_controlBinding)
static_cast<IStringBinding&>(*m_controlBinding).changed(this, m_textStr); if (IStringBinding* strBind = IStringBinding::castTo(m_controlBinding))
strBind->changed(this, m_textStr);
m_hasTextSet = false; m_hasTextSet = false;
if (m_deferredMarkStr.size()) if (m_deferredMarkStr.size())
m_hasMarkSet = true; m_hasMarkSet = true;

View File

@ -2,6 +2,7 @@
#include "specter/TextView.hpp" #include "specter/TextView.hpp"
#include "specter/ViewResources.hpp" #include "specter/ViewResources.hpp"
#include "utf8proc.h" #include "utf8proc.h"
#include "hecl/Pipeline.hpp"
#include <freetype/internal/internal.h> #include <freetype/internal/internal.h>
#include <freetype/internal/ftobjs.h> #include <freetype/internal/ftobjs.h>
@ -10,291 +11,12 @@ namespace specter
{ {
static logvisor::Module Log("specter::TextView"); static logvisor::Module Log("specter::TextView");
#if BOO_HAS_GL void TextView::Resources::init(boo::IGraphicsDataFactory::Context& ctx, FontCache* fcache)
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)
{ {
m_fcache = fcache; m_fcache = fcache;
m_regular = hecl::conv->convert(ctx, Shader_SpecterTextViewShader{});
m_regular = m_subpixel = hecl::conv->convert(ctx, Shader_SpecterTextViewShaderSubpixel{});
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);
} }
#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) void TextView::_commitResources(size_t capacity)
{ {
@ -321,38 +43,10 @@ void TextView::_commitResources(size_t capacity)
size_t uBufSizes[] = {sizeof(ViewBlock)}; size_t uBufSizes[] = {sizeof(ViewBlock)};
boo::ObjToken<boo::ITexture> texs[] = {fontTex.get()}; boo::ObjToken<boo::ITexture> texs[] = {fontTex.get()};
if (!res.m_textRes.m_vtxFmt) m_shaderBinding = ctx.newShaderDataBinding(shader, {}, vBufInfo.first.get(), nullptr, 1,
{
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, uBufs, nullptr, uBufOffs, uBufSizes,
1, texs, nullptr, nullptr, 0, vBufInfo.second); 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);
}
}
return true; return true;
}); });
} }

View File

@ -1,323 +1,17 @@
#include "specter/View.hpp" #include "specter/View.hpp"
#include "specter/ViewResources.hpp" #include "specter/ViewResources.hpp"
#include "specter/RootView.hpp" #include "specter/RootView.hpp"
#include "hecl/Pipeline.hpp"
namespace specter namespace specter
{ {
static logvisor::Module Log("specter::View"); static logvisor::Module Log("specter::View");
#if BOO_HAS_GL void View::Resources::init(boo::IGraphicsDataFactory::Context& ctx, const IThemeData& theme)
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)
{ {
m_solidShader = ctx.newShaderPipeline(GLSLSolidVS, GLSLSolidFS, 0, nullptr, 1, BlockNames, m_solidShader = hecl::conv->convert(ctx, Shader_SpecterViewShaderSolid{});
boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha, m_texShader = hecl::conv->convert(ctx, Shader_SpecterViewShaderTex{});
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);
} }
#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 <metal_stdlib>\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 <metal_stdlib>\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 <metal_stdlib>\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 <metal_stdlib>\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<float> 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) 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 bufOffs[] = {size_t(uBufInfo.second)};
size_t bufSizes[] = {sizeof(ViewBlock)}; 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_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, vBufInfo.first.get(), nullptr,
nullptr, 1, bufs, nullptr, bufOffs, nullptr, 1, bufs, nullptr, bufOffs,
bufSizes, 0, nullptr, nullptr, nullptr, vBufInfo.second); bufSizes, 0, nullptr, nullptr, nullptr, vBufInfo.second);
}
} }
void View::VertexBufferBindingTex::init(boo::IGraphicsDataFactory::Context& ctx, 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)}; size_t bufSizes[] = {sizeof(ViewBlock)};
boo::ObjToken<boo::ITexture> tex[] = {texture}; boo::ObjToken<boo::ITexture> 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_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, vBufInfo.first.get(), nullptr,
nullptr, 1, bufs, nullptr, bufOffs, nullptr, 1, bufs, nullptr, bufOffs,
bufSizes, 1, tex, nullptr, nullptr, vBufInfo.second); bufSizes, 1, tex, nullptr, nullptr, vBufInfo.second);
}
} }

View File

@ -17,31 +17,7 @@ void ViewResources::init(boo::IGraphicsDataFactory* factory, FontCache* fcache,
m_curveFont = fcache->prepCurvesFont(AllCharFilter, false, 8.f, dpi); m_curveFont = fcache->prepCurvesFont(AllCharFilter, false, 8.f, dpi);
factory->commitTransaction([&](boo::IGraphicsDataFactory::Context& ctx) { factory->commitTransaction([&](boo::IGraphicsDataFactory::Context& ctx) {
switch (ctx.platform()) init(ctx, *theme, fcache);
{
#if BOO_HAS_GL
case boo::IGraphicsDataFactory::Platform::OpenGL:
init<boo::GLDataFactory::Context>(static_cast<boo::GLDataFactory::Context&>(ctx), *theme, fcache);
break;
#endif
#if _WIN32
case boo::IGraphicsDataFactory::Platform::D3D11:
init<boo::D3DDataFactory::Context>(static_cast<boo::D3DDataFactory::Context&>(ctx), *theme, fcache);
break;
#endif
#if BOO_HAS_METAL
case boo::IGraphicsDataFactory::Platform::Metal:
init<boo::MetalDataFactory::Context>(static_cast<boo::MetalDataFactory::Context&>(ctx), *theme, fcache);
break;
#endif
#if BOO_HAS_VULKAN
case boo::IGraphicsDataFactory::Platform::Vulkan:
init<boo::VulkanDataFactory::Context>(static_cast<boo::VulkanDataFactory::Context&>(ctx), *theme, fcache);
break;
#endif
default:
Log.report(logvisor::Fatal, _S("unable to init view system for %s"), ctx.platformName());
}
return true; return true;
} BooTrace); } BooTrace);
} }

View File

@ -0,0 +1,5 @@
include_directories(../../hecl/include
../../hecl/extern/boo/include
../../hecl/extern/boo/logvisor/include)
add_shader(SpecterViewShaders)
add_shader(SpecterTextViewShaders)

View File

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

View File

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

View File

@ -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<float> tex [[ texture(0) ]])
{
return tex.sample(samp, vtf.uv) * vtf.color;
}