diff --git a/specter/MathLib b/specter/MathLib index 9885d3442..3d6218a9d 160000 --- a/specter/MathLib +++ b/specter/MathLib @@ -1 +1 @@ -Subproject commit 9885d34420ec70ba52d8270b4e0a9ddc22663dea +Subproject commit 3d6218a9d246c07cc974397f91d9f94b15fa3e85 diff --git a/specter/include/Specter/MultiLineTextView.hpp b/specter/include/Specter/MultiLineTextView.hpp index 7cb886a56..3f1506753 100644 --- a/specter/include/Specter/MultiLineTextView.hpp +++ b/specter/include/Specter/MultiLineTextView.hpp @@ -11,7 +11,7 @@ namespace Specter class MultiLineTextView : public View { ViewSystem& m_viewSystem; - std::vector m_lines; + std::vector> m_lines; const FontAtlas& m_fontAtlas; size_t m_lineCapacity; float m_lineHeight; diff --git a/specter/include/Specter/RootView.hpp b/specter/include/Specter/RootView.hpp index 0c300dfc6..909b40aba 100644 --- a/specter/include/Specter/RootView.hpp +++ b/specter/include/Specter/RootView.hpp @@ -14,12 +14,13 @@ class RootView : public View, public boo::IWindowCallback { boo::IWindow* m_window = nullptr; boo::ITextureR* m_renderTex = nullptr; - MultiLineTextView m_textView; boo::SWindowRect m_rootRect; bool m_resizeRTDirty = false; bool m_destroyed = false; public: + RootView(ViewSystem& system, boo::IWindow* window); + void destroyed(); bool isDestroyed() const {return m_destroyed;} @@ -44,10 +45,88 @@ public: void modKeyUp(boo::EModifierKey mod); void draw(boo::IGraphicsCommandQueue* gfxQ); - - RootView(ViewSystem& system, boo::IWindow* window); - const boo::SWindowRect& rootRect() const {return m_rootRect;} + + boo::IWindow* window() const {return m_window;} + + class SplitView : public View + { + public: + class System + { + friend class ViewSystem; + friend class SplitView; + boo::ITextureS* m_shadingTex; + + void init(boo::IGraphicsDataFactory* factory); + }; + + enum class Axis + { + Horizontal, + Vertical + }; + private: + Axis m_axis; + float m_slide = 0.5; + bool m_dragging = false; + + void setSlide(float slide) + { + m_slide = std::min(std::max(slide, 0.0f), 1.0f); + updateSize(); + } + + std::unique_ptr m_views[2]; + VertexBlock m_splitBlock; + boo::IGraphicsBufferD* m_splitBlockBuf; + struct SplitVert + { + Zeus::CVector3f m_pos; + Zeus::CVector2f m_uv; + } m_splitVerts[4]; + + void setHorizontalVerts(int width) + { + m_splitVerts[0].m_pos.assign(0, 1, 0); + m_splitVerts[0].m_uv.assign(0, 0); + m_splitVerts[1].m_pos.assign(0, -1, 0); + m_splitVerts[1].m_uv.assign(1, 0); + m_splitVerts[2].m_pos.assign(width, 1, 0); + m_splitVerts[2].m_uv.assign(0, 0); + m_splitVerts[3].m_pos.assign(width, -1, 0); + m_splitVerts[3].m_uv.assign(1, 0); + } + + void setVerticalVerts(int height) + { + m_splitVerts[0].m_pos.assign(-1, height, 0); + m_splitVerts[0].m_uv.assign(0, 0); + m_splitVerts[1].m_pos.assign(-1, 0, 0); + m_splitVerts[1].m_uv.assign(0, 0); + m_splitVerts[2].m_pos.assign(1, height, 0); + m_splitVerts[2].m_uv.assign(1, 0); + m_splitVerts[3].m_pos.assign(1, 0, 0); + m_splitVerts[3].m_uv.assign(1, 0); + } + + boo::IGraphicsBufferD* m_splitVertsBuf; + boo::IVertexFormat* m_splitVtxFmt; /* OpenGL only */ + boo::IShaderDataBinding* m_splitShaderBinding; + int m_splitValidSlots = 0; + public: + SplitView(ViewSystem& system, View& parentView, Axis axis); + void setContentView(int slot, std::unique_ptr&& view); + std::unique_ptr releaseContentView(int slot); + void mouseDown(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey); + void mouseUp(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey); + void mouseMove(const boo::SWindowCoord&); + void resized(const boo::SWindowRect& root, const boo::SWindowRect& sub); + void draw(boo::IGraphicsCommandQueue* gfxQ); + }; + +private: + std::unique_ptr m_splitView; }; } diff --git a/specter/include/Specter/View.hpp b/specter/include/Specter/View.hpp index 7162b4a36..8707d80f0 100644 --- a/specter/include/Specter/View.hpp +++ b/specter/include/Specter/View.hpp @@ -28,6 +28,7 @@ class View Zeus::CVector3f m_bgRect[4]; Zeus::CColor m_bgColor; int m_bgValidSlots = 0; + std::unique_ptr m_gfxData; friend class RootView; void buildResources(ViewSystem& system); @@ -63,12 +64,13 @@ protected: boo::IGraphicsBufferD* m_viewVertBlockBuf; public: - class System + struct System { - friend class ViewSystem; - friend class View; boo::IShaderPipeline* m_solidShader = nullptr; - boo::IVertexFormat* m_vtxFmt = nullptr; /* Not OpenGL */ + boo::IVertexFormat* m_solidVtxFmt = nullptr; /* Not OpenGL */ + + boo::IShaderPipeline* m_texShader = nullptr; + boo::IVertexFormat* m_texVtxFmt = nullptr; /* Not OpenGL */ void init(boo::GLDataFactory* factory); #if _WIN32 @@ -80,15 +82,24 @@ public: protected: View(ViewSystem& system, View& parentView); + void commitResources(ViewSystem& system); public: + virtual ~View() {} View() = delete; + View(const View& other) = delete; + View& operator=(const View& other) = delete; View& parent() {return m_parentView;} RootView& root() {return m_rootView;} + const boo::SWindowRect& subRect() const {return m_subRect;} void updateSize(); void setBackground(Zeus::CColor color) {m_bgColor = color; m_bgValidSlots = 0;} + + virtual void mouseDown(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey) {} + virtual void mouseUp(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey) {} + virtual void mouseMove(const boo::SWindowCoord&) {} virtual void resized(const boo::SWindowRect &root, const boo::SWindowRect& sub); virtual void draw(boo::IGraphicsCommandQueue* gfxQ); }; diff --git a/specter/include/Specter/ViewSystem.hpp b/specter/include/Specter/ViewSystem.hpp index fca48876d..f7a18a51b 100644 --- a/specter/include/Specter/ViewSystem.hpp +++ b/specter/include/Specter/ViewSystem.hpp @@ -2,6 +2,7 @@ #define SPECTER_VIEWSYSTEM_HPP #include "TextView.hpp" +#include "RootView.hpp" namespace Specter { @@ -12,12 +13,15 @@ class ViewSystem { m_viewSystem.init(factory); m_textSystem.init(factory, fcache); + m_splitViewSystem.init(factory); } public: boo::IGraphicsDataFactory* m_factory = nullptr; View::System m_viewSystem; TextView::System m_textSystem; + RootView::SplitView::System m_splitViewSystem; + std::unique_ptr m_sysData; Specter::FontTag m_mainFont; Specter::FontTag m_monoFont; diff --git a/specter/lib/MultiLineTextView.cpp b/specter/lib/MultiLineTextView.cpp index 3601de7b1..6f1bc0116 100644 --- a/specter/lib/MultiLineTextView.cpp +++ b/specter/lib/MultiLineTextView.cpp @@ -14,7 +14,10 @@ MultiLineTextView::MultiLineTextView(ViewSystem& system, m_viewSystem(system), m_fontAtlas(font), m_lineCapacity(lineCapacity), - m_lineHeight(lineHeight) {} + m_lineHeight(lineHeight) +{ + commitResources(system); +} MultiLineTextView::MultiLineTextView(ViewSystem& system, View& parentView, @@ -58,8 +61,8 @@ void MultiLineTextView::typesetGlyphs(const std::string& str, utf8proc_ssize_t sz = utf8proc_iterate(it, -1, &ch); if (ch == '\n' || ch == '\0') { - m_lines.emplace_back(m_viewSystem, *this, m_fontAtlas, m_lineCapacity); - m_lines.back().typesetGlyphs(std::string((char*)beginIt, it - beginIt), defaultColor); + m_lines.emplace_back(new TextView(m_viewSystem, *this, m_fontAtlas, m_lineCapacity)); + m_lines.back()->typesetGlyphs(std::string((char*)beginIt, it - beginIt), defaultColor); beginIt = it + 1; } rem -= sz; @@ -94,8 +97,8 @@ void MultiLineTextView::typesetGlyphs(const std::wstring& str, { if (*it == L'\n' || *it == L'\0') { - m_lines.emplace_back(m_viewSystem, *this, m_fontAtlas, m_lineCapacity); - m_lines.back().typesetGlyphs(std::wstring(beginIt, it), defaultColor); + m_lines.emplace_back(new TextView(m_viewSystem, *this, m_fontAtlas, m_lineCapacity)); + m_lines.back()->typesetGlyphs(std::wstring(beginIt, it), defaultColor); beginIt = it + 1; } --rem; @@ -113,18 +116,18 @@ void MultiLineTextView::resized(const boo::SWindowRect& root, const boo::SWindow boo::SWindowRect tsub = sub; tsub.location[1] += decumHeight; tsub.size[1] = 10; - for (TextView& tv : m_lines) + for (std::unique_ptr& tv : m_lines) { tsub.location[1] -= lHeight; - tv.resized(root, tsub); + tv->resized(root, tsub); } } void MultiLineTextView::draw(boo::IGraphicsCommandQueue* gfxQ) { View::draw(gfxQ); - for (TextView& tv : m_lines) - tv.draw(gfxQ); + for (std::unique_ptr& tv : m_lines) + tv->draw(gfxQ); } } diff --git a/specter/lib/RootView.cpp b/specter/lib/RootView.cpp index 14b9cfeae..9b5a07d7f 100644 --- a/specter/lib/RootView.cpp +++ b/specter/lib/RootView.cpp @@ -3,18 +3,26 @@ namespace Specter { +static LogVisor::LogModule Log("Specter::RootView"); RootView::RootView(ViewSystem& system, boo::IWindow* window) -: View(system, *this), m_window(window), m_textView(system, *this, system.m_mainFont) +: View(system, *this), m_window(window) { window->setCallback(this); boo::SWindowRect rect = window->getWindowFrame(); m_renderTex = system.m_factory->newRenderTexture(rect.size[0], rect.size[1], 1); - system.m_factory->commit(); + commitResources(system); + m_splitView.reset(new SplitView(system, *this, SplitView::Axis::Horizontal)); + MultiLineTextView* textView1 = new MultiLineTextView(system, *this, system.m_mainFont); + MultiLineTextView* textView2 = new MultiLineTextView(system, *this, system.m_mainFont); + m_splitView->setContentView(0, std::unique_ptr(textView1)); + m_splitView->setContentView(1, std::unique_ptr(textView2)); resized(rect); - m_textView.typesetGlyphs("Hello, World!\nこんにちは世界!\n\n", Zeus::CColor::skWhite); + textView1->typesetGlyphs("Hello, World!\n\n", Zeus::CColor::skWhite); + textView2->typesetGlyphs("こんにちは世界!\n\n", Zeus::CColor::skWhite); Zeus::CColor transBlack(0.f, 0.f, 0.f, 0.5f); - m_textView.setBackground(transBlack); + textView1->setBackground(transBlack); + textView2->setBackground(transBlack); setBackground(Zeus::CColor::skGrey); } @@ -34,29 +42,23 @@ void RootView::resized(const boo::SWindowRect& root, const boo::SWindowRect&) m_rootRect.location[0] = 0; m_rootRect.location[1] = 0; View::resized(m_rootRect, m_rootRect); - - boo::SWindowRect textRect = m_rootRect; - textRect.location[0] = 10; - textRect.location[1] = 10; - textRect.size[0] -= 20; - if (textRect.size[0] < 0) - textRect.size[0] = 0; - textRect.size[1] = 100; - m_textView.resized(m_rootRect, textRect); - + m_splitView->resized(m_rootRect, m_rootRect); m_resizeRTDirty = true; } void RootView::mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mods) { + m_splitView->mouseDown(coord, button, mods); } void RootView::mouseUp(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mods) { + m_splitView->mouseUp(coord, button, mods); } void RootView::mouseMove(const boo::SWindowCoord& coord) { + m_splitView->mouseMove(coord); } void RootView::mouseEnter(const boo::SWindowCoord& coord) @@ -118,8 +120,164 @@ void RootView::draw(boo::IGraphicsCommandQueue* gfxQ) gfxQ->setViewport(m_rootRect); gfxQ->setScissor(m_rootRect); View::draw(gfxQ); - m_textView.draw(gfxQ); + m_splitView->draw(gfxQ); gfxQ->resolveDisplay(m_renderTex); } +void RootView::SplitView::System::init(boo::IGraphicsDataFactory* factory) +{ + static const Zeus::RGBA32 tex[3] = + { + {0,0,0,64}, + {0,0,0,255}, + {255,255,255,64} + }; + m_shadingTex = factory->newStaticTexture(3, 1, 1, boo::TextureFormat::RGBA8, tex, 12); +} + +RootView::SplitView::SplitView(ViewSystem& system, View& parentView, Axis axis) +: View(system, parentView), m_axis(axis) +{ + m_splitBlockBuf = system.m_factory->newDynamicBuffer(boo::BufferUse::Uniform, sizeof(VertexBlock), 1); + m_splitVertsBuf = system.m_factory->newDynamicBuffer(boo::BufferUse::Vertex, sizeof(SplitVert), 4); + + if (!system.m_viewSystem.m_texVtxFmt) + { + boo::VertexElementDescriptor vdescs[] = + { + {m_splitVertsBuf, nullptr, boo::VertexSemantic::Position4}, + {m_splitVertsBuf, nullptr, boo::VertexSemantic::UV4} + }; + m_splitVtxFmt = system.m_factory->newVertexFormat(2, vdescs); + boo::IGraphicsBuffer* bufs[] = {m_splitBlockBuf}; + boo::ITexture* texs[] = {system.m_splitViewSystem.m_shadingTex}; + m_splitShaderBinding = system.m_factory->newShaderDataBinding(system.m_viewSystem.m_texShader, + m_splitVtxFmt, m_splitVertsBuf, nullptr, + nullptr, 1, bufs, 1, texs); + } + else + { + boo::IGraphicsBuffer* bufs[] = {m_splitBlockBuf}; + boo::ITexture* texs[] = {system.m_splitViewSystem.m_shadingTex}; + m_splitShaderBinding = system.m_factory->newShaderDataBinding(system.m_viewSystem.m_texShader, + system.m_viewSystem.m_texVtxFmt, + m_splitVertsBuf, nullptr, + nullptr, 1, bufs, 1, texs); + } + + commitResources(system); +} + +void RootView::SplitView::setContentView(int slot, std::unique_ptr&& view) +{ + if (slot < 0 || slot > 1) + Log.report(LogVisor::FatalError, "out-of-range slot to RootView::SplitView::setContentView"); + m_views[slot] = std::move(view); + updateSize(); +} + +std::unique_ptr RootView::SplitView::releaseContentView(int slot) +{ + if (slot < 0 || slot > 1) + Log.report(LogVisor::FatalError, "out-of-range slot to RootView::SplitView::releaseContentView"); + std::unique_ptr ret; + m_views[slot].swap(ret); + updateSize(); + return ret; +} + +void RootView::SplitView::mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod) +{ + if (button == boo::EMouseButton::Primary) + { + m_dragging = true; + if (m_axis == Axis::Horizontal) + setSlide(coord.pixel[1] / float(subRect().size[1])); + else if (m_axis == Axis::Vertical) + setSlide(coord.pixel[0] / float(subRect().size[0])); + } +} + +void RootView::SplitView::mouseUp(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod) +{ + if (button == boo::EMouseButton::Primary) + m_dragging = false; +} + +void RootView::SplitView::mouseMove(const boo::SWindowCoord& coord) +{ + if (m_axis == Axis::Horizontal) + { + if (m_dragging) + setSlide(coord.pixel[1] / float(subRect().size[1])); + int slidePx = subRect().size[1] * m_slide; + if (abs(int(coord.pixel[1]) - slidePx) < 4) + root().window()->setCursor(boo::EMouseCursor::VerticalArrow); + else + root().window()->setCursor(boo::EMouseCursor::Pointer); + } + else if (m_axis == Axis::Vertical) + { + if (m_dragging) + setSlide(coord.pixel[0] / float(subRect().size[0])); + int slidePx = subRect().size[0] * m_slide; + if (abs(int(coord.pixel[0]) - slidePx) < 4) + root().window()->setCursor(boo::EMouseCursor::HorizontalArrow); + else + root().window()->setCursor(boo::EMouseCursor::Pointer); + } +} + +void RootView::SplitView::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub) +{ + View::resized(root, sub); + if (m_axis == Axis::Horizontal) + { + boo::SWindowRect ssub = sub; + ssub.size[1] *= m_slide; + if (m_views[0]) + m_views[0]->resized(root, ssub); + ssub.location[1] += ssub.size[1]; + ssub.size[1] = sub.size[1] - ssub.size[1]; + if (m_views[1]) + m_views[1]->resized(root, ssub); + m_splitBlock.setViewRect(root, ssub); + setHorizontalVerts(ssub.size[0]); + } + else if (m_axis == Axis::Vertical) + { + boo::SWindowRect ssub = sub; + ssub.size[0] *= m_slide; + if (m_views[0]) + m_views[0]->resized(root, ssub); + ssub.location[0] += ssub.size[0]; + ssub.size[0] = sub.size[0] - ssub.size[0]; + if (m_views[1]) + m_views[1]->resized(root, ssub); + m_splitBlock.setViewRect(root, ssub); + setVerticalVerts(ssub.size[1]); + } + m_splitValidSlots = 0; +} + +void RootView::SplitView::draw(boo::IGraphicsCommandQueue* gfxQ) +{ + View::draw(gfxQ); + if (m_views[0]) + m_views[0]->draw(gfxQ); + if (m_views[1]) + m_views[1]->draw(gfxQ); + + int pendingSlot = 1 << gfxQ->pendingDynamicSlot(); + if ((m_splitValidSlots & pendingSlot) == 0) + { + m_splitBlockBuf->load(&m_splitBlock, sizeof(VertexBlock)); + m_splitVertsBuf->load(m_splitVerts, sizeof(SplitVert) * 4); + m_splitValidSlots |= pendingSlot; + } + gfxQ->setShaderDataBinding(m_splitShaderBinding); + gfxQ->draw(0, 4); + +} + } diff --git a/specter/lib/Specter.cpp b/specter/lib/Specter.cpp index af5d5a5a7..ca64581a5 100644 --- a/specter/lib/Specter.cpp +++ b/specter/lib/Specter.cpp @@ -28,6 +28,7 @@ void ViewSystem::init(boo::IGraphicsDataFactory* factory, FontCache* fcache) Log.report(LogVisor::FatalError, _S("unable to init view system for %s"), factory->platformName()); } fcache->closeBuiltinFonts(); + m_sysData.reset(factory->commit()); } } diff --git a/specter/lib/TextView.cpp b/specter/lib/TextView.cpp index 5d59a3e54..c151e371f 100644 --- a/specter/lib/TextView.cpp +++ b/specter/lib/TextView.cpp @@ -309,6 +309,7 @@ TextView::TextView(ViewSystem& system, View& parentView, const FontAtlas& font, } m_glyphs.reserve(capacity); + commitResources(system); } TextView::TextView(ViewSystem& system, View& parentView, FontTag font, size_t capacity) diff --git a/specter/lib/View.cpp b/specter/lib/View.cpp index e428441c6..d1a4eff17 100644 --- a/specter/lib/View.cpp +++ b/specter/lib/View.cpp @@ -7,7 +7,7 @@ namespace Specter void View::System::init(boo::GLDataFactory* factory) { - static const char* VS = + static const char* SolidVS = "#version 330\n" "layout(location=0) in vec3 posIn;\n" "layout(location=1) in vec4 colorIn;\n" @@ -23,7 +23,7 @@ void View::System::init(boo::GLDataFactory* factory) " gl_Position = mv * vec4(posIn, 1.0);\n" "}\n"; - static const char* FS = + static const char* SolidFS = "#version 330\n" "struct VertToFrag\n" "{\n" @@ -36,18 +36,52 @@ void View::System::init(boo::GLDataFactory* factory) " colorOut = vtf.color;\n" "}\n"; + static const char* TexVS = + "#version 330\n" + "layout(location=0) in vec3 posIn;\n" + "layout(location=1) in vec2 uvIn;\n" + SPECTER_VIEW_VERT_BLOCK_GLSL + "struct VertToFrag\n" + "{\n" + " vec2 uv;\n" + "};\n" + "out VertToFrag vtf;\n" + "void main()\n" + "{\n" + " vtf.uv = uvIn;\n" + " gl_Position = mv * vec4(posIn, 1.0);\n" + "}\n"; + + static const char* TexFS = + "#version 330\n" + "struct VertToFrag\n" + "{\n" + " vec2 uv;\n" + "};\n" + "in VertToFrag vtf;\n" + "uniform sampler2D tex;\n" + "layout(location=0) out vec4 colorOut;\n" + "void main()\n" + "{\n" + " colorOut = texture(tex, vtf.uv);\n" + "}\n"; + static const char* BlockNames[] = {"SpecterViewBlock"}; - m_solidShader = factory->newShaderPipeline(VS, FS, 0, nullptr, 1, BlockNames, + m_solidShader = factory->newShaderPipeline(SolidVS, SolidFS, 0, nullptr, 1, BlockNames, boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha, false, false, false); + + m_texShader = factory->newShaderPipeline(TexVS, TexFS, 1, "tex", 1, BlockNames, + boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha, + false, false, false); } #if _WIN32 void View::System::init(boo::ID3DDataFactory* factory) { - static const char* VS = + static const char* SolidVS = "struct VertData\n" "{\n" " float3 posIn : POSITION;\n" @@ -67,7 +101,7 @@ void View::System::init(boo::ID3DDataFactory* factory) " return vtf;\n" "}\n"; - static const char* FS = + static const char* SolidFS = "struct VertToFrag\n" "{\n" " float4 position : SV_Position;\n" @@ -78,17 +112,64 @@ void View::System::init(boo::ID3DDataFactory* factory) " return vtf.color;\n" "}\n"; + static const char* TexVS = + "struct VertData\n" + "{\n" + " float3 posIn : POSITION;\n" + " float2 uvIn : UV;\n" + "};\n" + SPECTER_VIEW_VERT_BLOCK_HLSL + "struct VertToFrag\n" + "{\n" + " float4 position : SV_Position;\n" + " float2 uv : UV;\n" + "};\n" + "VertToFrag main(in VertData v)\n" + "{\n" + " VertToFrag vtf;\n" + " vtf.uv = v.uvIn;\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" + " 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);\n" + "}\n"; + boo::VertexElementDescriptor vdescs[] = { {nullptr, nullptr, boo::VertexSemantic::Position4}, {nullptr, nullptr, boo::VertexSemantic::Color | boo::VertexSemantic::Instanced} }; - m_vtxFmt = factory->newVertexFormat(2, vdescs); + m_solidVtxFmt = factory->newVertexFormat(2, vdescs); ComPtr vertBlob; ComPtr fragBlob; ComPtr pipeBlob; - m_solidShader = factory->newShaderPipeline(VS, FS, vertBlob, fragBlob, pipeBlob, m_vtxFmt, + m_solidShader = factory->newShaderPipeline(SolidVS, SolidFS, vertBlob, fragBlob, pipeBlob, m_solidVtxFmt, + boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha, + false, false, false); + + boo::VertexElementDescriptor vdescs[] = + { + {nullptr, nullptr, boo::VertexSemantic::Position4}, + {nullptr, nullptr, boo::VertexSemantic::UV4} + }; + m_texVtxFmt = factory->newVertexFormat(2, vdescs); + + vertBlob.Reset(); + fragBlob.Reset(); + pipeBlob.Reset(); + m_solidShader = factory->newShaderPipeline(TexVS, TexFS, vertBlob, fragBlob, pipeBlob, m_texVtxFmt, boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha, false, false, false); } @@ -97,7 +178,7 @@ void View::System::init(boo::ID3DDataFactory* factory) void View::System::init(boo::MetalDataFactory* factory) { - static const char* VS = + static const char* SolidVS = "#include \n" "using namespace metal;\n" "struct VertData\n" @@ -119,7 +200,7 @@ void View::System::init(boo::MetalDataFactory* factory) " return vtf;\n" "}\n"; - static const char* FS = + static const char* SolidFS = "#include \n" "using namespace metal;\n" "struct VertToFrag\n" @@ -131,17 +212,64 @@ void View::System::init(boo::MetalDataFactory* factory) "{\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_VIEW_VERT_BLOCK_METAL + "struct VertToFrag\n" + "{\n" + " float4 position [[ position ]];\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.position = view.mv * float4(v.posIn, 1.0);\n" + " return vtf;\n" + "}\n"; + + static const char* TexFS = + "#include \n" + "using namespace metal;\n" + "constexpr sampler samp(address::repeat);\n" + "struct VertToFrag\n" + "{\n" + " float4 position [[ position ]];\n" + " float2 uv;\n" + "};\n" + "fragment float4 fmain(VertToFrag vtf [[ stage_in ]], texture2d tex [[ texture(0) ]])\n" + "{\n" + " return tex.sample(samp, vtf.uv);\n" + "}\n"; boo::VertexElementDescriptor vdescs[] = { {nullptr, nullptr, boo::VertexSemantic::Position4}, {nullptr, nullptr, boo::VertexSemantic::Color | boo::VertexSemantic::Instanced} }; - m_vtxFmt = factory->newVertexFormat(2, vdescs); + m_solidVtxFmt = factory->newVertexFormat(2, vdescs); - m_solidShader = factory->newShaderPipeline(VS, FS, m_vtxFmt, 1, + m_solidShader = factory->newShaderPipeline(SolidVS, SolidFS, m_solidVtxFmt, 1, boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha, false, false, false); + + boo::VertexElementDescriptor vdescs[] = + { + {nullptr, nullptr, boo::VertexSemantic::Position4}, + {nullptr, nullptr, boo::VertexSemantic::UV4} + }; + m_texVtxFmt = factory->newVertexFormat(2, vdescs); + + m_texShader = factory->newShaderPipeline(TexVS, TexFS, m_texVtxFmt, 1, + boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha, + false, false, false); } #endif @@ -162,7 +290,7 @@ void View::buildResources(ViewSystem& system) system.m_factory->newDynamicBuffer(boo::BufferUse::Uniform, sizeof(VertexBlock), 1); - if (!system.m_viewSystem.m_vtxFmt) + if (!system.m_viewSystem.m_solidVtxFmt) { boo::VertexElementDescriptor vdescs[] = { @@ -179,7 +307,7 @@ void View::buildResources(ViewSystem& system) else { m_bgShaderBinding = - system.m_factory->newShaderDataBinding(system.m_viewSystem.m_solidShader, system.m_viewSystem.m_vtxFmt, + system.m_factory->newShaderDataBinding(system.m_viewSystem.m_solidShader, system.m_viewSystem.m_solidVtxFmt, m_bgVertBuf, m_bgInstBuf, nullptr, 1, (boo::IGraphicsBuffer**)&m_viewVertBlockBuf, 0, nullptr); @@ -231,4 +359,9 @@ void View::draw(boo::IGraphicsCommandQueue* gfxQ) gfxQ->draw(0, 4); } +void View::commitResources(ViewSystem& system) +{ + m_gfxData.reset(system.m_factory->commit()); +} + }