Merge branch 'master' into fontdebug

This commit is contained in:
Jack Andersen 2015-12-01 15:43:54 -10:00
commit b55e10ea22
7 changed files with 306 additions and 43 deletions

View File

@ -27,11 +27,12 @@ add_subdirectory(resources/fonts)
include_directories(include ${HECL_INCLUDE_DIR} ${BOO_INCLUDE_DIR} include_directories(include ${HECL_INCLUDE_DIR} ${BOO_INCLUDE_DIR}
${LOG_VISOR_INCLUDE_DIR} ${ATHENA_INCLUDE_DIR} ${LOG_VISOR_INCLUDE_DIR} ${ATHENA_INCLUDE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/freetype2/include ${CMAKE_CURRENT_SOURCE_DIR}/freetype2/include
${MATHLIB_INCLUDE_DIR}) ${MATHLIB_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR})
list(APPEND SPECTER_HEADERS list(APPEND SPECTER_HEADERS
include/Specter/Specter.hpp include/Specter/Specter.hpp
include/Specter/ViewResources.hpp include/Specter/ViewResources.hpp
include/Specter/DeferredWindowEvents.hpp
include/Specter/View.hpp include/Specter/View.hpp
include/Specter/RootView.hpp include/Specter/RootView.hpp
include/Specter/SplitView.hpp include/Specter/SplitView.hpp

View File

@ -0,0 +1,262 @@
#ifndef SPECTER_DEFERREDWINDOWEVENTS_HPP
#define SPECTER_DEFERREDWINDOWEVENTS_HPP
#include <boo/boo.hpp>
namespace Specter
{
template <class Receiver>
struct DeferredWindowEvents : public boo::IWindowCallback
{
Receiver& m_rec;
std::mutex m_mt;
DeferredWindowEvents(Receiver& rec) : m_rec(rec) {}
bool m_destroyed = false;
void destroyed()
{
m_destroyed = true;
}
bool m_hasResize = false;
boo::SWindowRect m_latestResize;
void resized(const boo::SWindowRect& rect)
{
std::unique_lock<std::mutex> lk(m_mt);
m_latestResize = rect;
m_hasResize = true;
}
struct Command
{
enum class Type
{
MouseDown,
MouseUp,
MouseMove,
MouseEnter,
MouseLeave,
Scroll,
TouchDown,
TouchUp,
TouchMove,
CharKeyDown,
CharKeyUp,
SpecialKeyDown,
SpecialKeyUp,
ModKeyDown,
ModKeyUp
} m_type;
boo::SWindowCoord m_coord;
boo::EMouseButton m_button;
boo::EModifierKey m_mods;
boo::SScrollDelta m_scroll;
boo::STouchCoord m_tCoord;
uintptr_t m_tid;
unsigned long m_charcode;
boo::ESpecialKey m_special;
bool m_isRepeat;
void dispatch(Receiver& rec) const
{
switch (m_type)
{
case Type::MouseDown:
rec.mouseDown(m_coord, m_button, m_mods);
break;
case Type::MouseUp:
rec.mouseUp(m_coord, m_button, m_mods);
break;
case Type::MouseMove:
rec.mouseMove(m_coord);
break;
case Type::MouseEnter:
rec.mouseEnter(m_coord);
break;
case Type::MouseLeave:
rec.mouseLeave(m_coord);
break;
case Type::Scroll:
rec.scroll(m_coord, m_scroll);
break;
case Type::TouchDown:
rec.touchDown(m_tCoord, m_tid);
break;
case Type::TouchUp:
rec.touchUp(m_tCoord, m_tid);
break;
case Type::TouchMove:
rec.touchMove(m_tCoord, m_tid);
break;
case Type::CharKeyDown:
rec.charKeyDown(m_charcode, m_mods, m_isRepeat);
break;
case Type::CharKeyUp:
rec.charKeyUp(m_charcode, m_mods);
break;
case Type::SpecialKeyDown:
rec.specialKeyDown(m_special, m_mods, m_isRepeat);
break;
case Type::SpecialKeyUp:
rec.specialKeyUp(m_special, m_mods);
break;
case Type::ModKeyDown:
rec.modKeyDown(m_mods, m_isRepeat);
break;
case Type::ModKeyUp:
rec.modKeyUp(m_mods);
break;
default: break;
}
}
Command(Type tp) : m_type(tp) {}
};
std::vector<Command> m_cmds;
void mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mods)
{
std::unique_lock<std::mutex> lk(m_mt);
m_cmds.emplace_back(Command::Type::MouseDown);
m_cmds.back().m_coord = coord;
m_cmds.back().m_button = button;
m_cmds.back().m_mods = mods;
}
void mouseUp(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mods)
{
std::unique_lock<std::mutex> lk(m_mt);
m_cmds.emplace_back(Command::Type::MouseUp);
m_cmds.back().m_coord = coord;
m_cmds.back().m_button = button;
m_cmds.back().m_mods = mods;
}
void mouseMove(const boo::SWindowCoord& coord)
{
std::unique_lock<std::mutex> lk(m_mt);
m_cmds.emplace_back(Command::Type::MouseMove);
m_cmds.back().m_coord = coord;
}
void mouseEnter(const boo::SWindowCoord& coord)
{
std::unique_lock<std::mutex> lk(m_mt);
m_cmds.emplace_back(Command::Type::MouseEnter);
m_cmds.back().m_coord = coord;
}
void mouseLeave(const boo::SWindowCoord& coord)
{
std::unique_lock<std::mutex> lk(m_mt);
m_cmds.emplace_back(Command::Type::MouseLeave);
m_cmds.back().m_coord = coord;
}
void scroll(const boo::SWindowCoord& coord, const boo::SScrollDelta& scroll)
{
std::unique_lock<std::mutex> lk(m_mt);
m_cmds.emplace_back(Command::Type::Scroll);
m_cmds.back().m_coord = coord;
m_cmds.back().m_scroll = scroll;
}
void touchDown(const boo::STouchCoord& coord, uintptr_t tid)
{
std::unique_lock<std::mutex> lk(m_mt);
m_cmds.emplace_back(Command::Type::TouchDown);
m_cmds.back().m_tCoord = coord;
m_cmds.back().m_tid = tid;
}
void touchUp(const boo::STouchCoord& coord, uintptr_t tid)
{
std::unique_lock<std::mutex> lk(m_mt);
m_cmds.emplace_back(Command::Type::TouchUp);
m_cmds.back().m_tCoord = coord;
m_cmds.back().m_tid = tid;
}
void touchMove(const boo::STouchCoord& coord, uintptr_t tid)
{
std::unique_lock<std::mutex> lk(m_mt);
m_cmds.emplace_back(Command::Type::TouchMove);
m_cmds.back().m_tCoord = coord;
m_cmds.back().m_tid = tid;
}
void charKeyDown(unsigned long charCode, boo::EModifierKey mods, bool isRepeat)
{
std::unique_lock<std::mutex> lk(m_mt);
m_cmds.emplace_back(Command::Type::CharKeyDown);
m_cmds.back().m_charcode = charCode;
m_cmds.back().m_mods = mods;
m_cmds.back().m_isRepeat = isRepeat;
}
void charKeyUp(unsigned long charCode, boo::EModifierKey mods)
{
std::unique_lock<std::mutex> lk(m_mt);
m_cmds.emplace_back(Command::Type::CharKeyUp);
m_cmds.back().m_charcode = charCode;
m_cmds.back().m_mods = mods;
}
void specialKeyDown(boo::ESpecialKey key, boo::EModifierKey mods, bool isRepeat)
{
std::unique_lock<std::mutex> lk(m_mt);
m_cmds.emplace_back(Command::Type::SpecialKeyDown);
m_cmds.back().m_special = key;
m_cmds.back().m_mods = mods;
m_cmds.back().m_isRepeat = isRepeat;
}
void specialKeyUp(boo::ESpecialKey key, boo::EModifierKey mods)
{
std::unique_lock<std::mutex> lk(m_mt);
m_cmds.emplace_back(Command::Type::SpecialKeyUp);
m_cmds.back().m_special = key;
m_cmds.back().m_mods = mods;
}
void modKeyDown(boo::EModifierKey mod, bool isRepeat)
{
std::unique_lock<std::mutex> lk(m_mt);
m_cmds.emplace_back(Command::Type::ModKeyDown);
m_cmds.back().m_mods = mod;
m_cmds.back().m_isRepeat = isRepeat;
}
void modKeyUp(boo::EModifierKey mod)
{
std::unique_lock<std::mutex> lk(m_mt);
m_cmds.emplace_back(Command::Type::ModKeyUp);
m_cmds.back().m_mods = mod;
}
void dispatchEvents()
{
std::unique_lock<std::mutex> lk(m_mt);
if (m_destroyed)
{
m_rec.destroyed();
return;
}
if (m_hasResize)
{
m_rec.resized(m_latestResize, m_latestResize);
m_hasResize = false;
}
for (const Command& cmd : m_cmds)
cmd.dispatch(m_rec);
m_cmds.clear();
}
};
}
#endif // SPECTER_DEFERREDWINDOWEVENTS_HPP

View File

@ -5,27 +5,29 @@
#include "MultiLineTextView.hpp" #include "MultiLineTextView.hpp"
#include "SplitView.hpp" #include "SplitView.hpp"
#include "FontCache.hpp" #include "FontCache.hpp"
#include "DeferredWindowEvents.hpp"
#include <boo/boo.hpp> #include <boo/boo.hpp>
namespace Specter namespace Specter
{ {
class ViewResources; class ViewResources;
class RootView : public View, public boo::IWindowCallback class RootView : public View
{ {
boo::IWindow* m_window = nullptr; boo::IWindow* m_window = nullptr;
boo::ITextureR* m_renderTex = nullptr; boo::ITextureR* m_renderTex = nullptr;
boo::SWindowRect m_rootRect; boo::SWindowRect m_rootRect = {};
bool m_resizeRTDirty = false; bool m_resizeRTDirty = false;
bool m_destroyed = false; bool m_destroyed = false;
DeferredWindowEvents<RootView> m_events;
public: public:
RootView(ViewResources& res, boo::IWindow* window); RootView(ViewResources& res, boo::IWindow* window);
void destroyed(); void destroyed();
bool isDestroyed() const {return m_destroyed;} bool isDestroyed() const {return m_destroyed;}
void resized(const boo::SWindowRect& rect);
void resized(const boo::SWindowRect& root, const boo::SWindowRect& sub); void resized(const boo::SWindowRect& root, const boo::SWindowRect& sub);
void mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mods); void mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mods);
void mouseUp(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mods); void mouseUp(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mods);
@ -45,6 +47,7 @@ public:
void modKeyDown(boo::EModifierKey mod, bool isRepeat); void modKeyDown(boo::EModifierKey mod, bool isRepeat);
void modKeyUp(boo::EModifierKey mod); void modKeyUp(boo::EModifierKey mod);
void dispatchEvents() {m_events.dispatchEvents();}
void draw(boo::IGraphicsCommandQueue* gfxQ); void draw(boo::IGraphicsCommandQueue* gfxQ);
const boo::SWindowRect& rootRect() const {return m_rootRect;} const boo::SWindowRect& rootRect() const {return m_rootRect;}

View File

@ -218,10 +218,7 @@ static bool ReadDecompressed(Athena::io::FileReader& reader, atUint8* data, size
} }
inflateEnd(&z); inflateEnd(&z);
return adler32 == z.adler;
if (adler32 != z.adler)
return false;
return true;
} }
FontAtlas::FontAtlas(boo::IGraphicsDataFactory* gf, FT_Face face, uint32_t dpi, FontAtlas::FontAtlas(boo::IGraphicsDataFactory* gf, FT_Face face, uint32_t dpi,
@ -300,7 +297,7 @@ FontAtlas::FontAtlas(boo::IGraphicsDataFactory* gf, FT_Face face, uint32_t dpi,
else else
{ {
size_t count = TEXMAP_DIM * totalHeight; size_t count = TEXMAP_DIM * totalHeight;
texmap.reset(new RgbaPixel[TEXMAP_DIM * totalHeight]); texmap.reset(new RgbaPixel[count]);
bufSz = count * sizeof(RgbaPixel); bufSz = count * sizeof(RgbaPixel);
memset(texmap.get(), 0, bufSz); memset(texmap.get(), 0, bufSz);
} }
@ -375,7 +372,7 @@ FontAtlas::FontAtlas(boo::IGraphicsDataFactory* gf, FT_Face face, uint32_t dpi,
else else
{ {
size_t count = TEXMAP_DIM * totalHeight; size_t count = TEXMAP_DIM * totalHeight;
texmap.reset(new GreyPixel[TEXMAP_DIM * totalHeight]); texmap.reset(new GreyPixel[count]);
bufSz = count * sizeof(GreyPixel); bufSz = count * sizeof(GreyPixel);
memset(texmap.get(), 0, bufSz); memset(texmap.get(), 0, bufSz);
} }

View File

@ -5,19 +5,19 @@ namespace Specter
{ {
static LogVisor::LogModule Log("Specter::RootView"); static LogVisor::LogModule Log("Specter::RootView");
RootView::RootView(ViewResources& system, boo::IWindow* window) RootView::RootView(ViewResources& res, boo::IWindow* window)
: View(system, *this), m_window(window) : View(res, *this), m_window(window), m_events(*this)
{ {
window->setCallback(this); window->setCallback(&m_events);
boo::SWindowRect rect = window->getWindowFrame(); boo::SWindowRect rect = window->getWindowFrame();
m_renderTex = system.m_factory->newRenderTexture(rect.size[0], rect.size[1], 1); m_renderTex = res.m_factory->newRenderTexture(rect.size[0], rect.size[1], 1);
commitResources(system); commitResources(res);
m_splitView.reset(new SplitView(system, *this, SplitView::Axis::Horizontal)); m_splitView.reset(new SplitView(res, *this, SplitView::Axis::Horizontal));
MultiLineTextView* textView1 = new MultiLineTextView(system, *this, system.m_heading18); MultiLineTextView* textView1 = new MultiLineTextView(res, *this, res.m_heading18);
MultiLineTextView* textView2 = new MultiLineTextView(system, *this, system.m_heading18); MultiLineTextView* textView2 = new MultiLineTextView(res, *this, res.m_heading18);
m_splitView->setContentView(0, std::unique_ptr<MultiLineTextView>(textView1)); m_splitView->setContentView(0, std::unique_ptr<MultiLineTextView>(textView1));
m_splitView->setContentView(1, std::unique_ptr<MultiLineTextView>(textView2)); m_splitView->setContentView(1, std::unique_ptr<MultiLineTextView>(textView2));
resized(rect); resized(rect, rect);
textView1->typesetGlyphs("Hello, World!\n\n", Zeus::CColor::skWhite); textView1->typesetGlyphs("Hello, World!\n\n", Zeus::CColor::skWhite);
textView2->typesetGlyphs("こんにちは世界!\n\n", Zeus::CColor::skWhite); textView2->typesetGlyphs("こんにちは世界!\n\n", Zeus::CColor::skWhite);
Zeus::CColor transBlack(0.f, 0.f, 0.f, 0.5f); Zeus::CColor transBlack(0.f, 0.f, 0.f, 0.5f);
@ -31,18 +31,15 @@ void RootView::destroyed()
m_destroyed = true; m_destroyed = true;
} }
void RootView::resized(const boo::SWindowRect& rect)
{
resized(rect, rect);
}
void RootView::resized(const boo::SWindowRect& root, const boo::SWindowRect&) void RootView::resized(const boo::SWindowRect& root, const boo::SWindowRect&)
{ {
boo::SWindowRect old = m_rootRect;
m_rootRect = root; m_rootRect = root;
m_rootRect.location[0] = 0; m_rootRect.location[0] = 0;
m_rootRect.location[1] = 0; m_rootRect.location[1] = 0;
View::resized(m_rootRect, m_rootRect); View::resized(m_rootRect, m_rootRect);
m_splitView->resized(m_rootRect, m_rootRect); m_splitView->resized(m_rootRect, m_rootRect);
if (old != m_rootRect)
m_resizeRTDirty = true; m_resizeRTDirty = true;
} }

View File

@ -429,6 +429,8 @@ void TextView::think()
void TextView::draw(boo::IGraphicsCommandQueue* gfxQ) void TextView::draw(boo::IGraphicsCommandQueue* gfxQ)
{ {
View::draw(gfxQ); View::draw(gfxQ);
if (m_glyphs.size())
{
int pendingSlot = 1 << gfxQ->pendingDynamicSlot(); int pendingSlot = 1 << gfxQ->pendingDynamicSlot();
if ((m_validSlots & pendingSlot) == 0) if ((m_validSlots & pendingSlot) == 0)
{ {
@ -438,6 +440,7 @@ void TextView::draw(boo::IGraphicsCommandQueue* gfxQ)
gfxQ->setShaderDataBinding(m_shaderBinding); gfxQ->setShaderDataBinding(m_shaderBinding);
gfxQ->setDrawPrimitive(boo::Primitive::TriStrips); gfxQ->setDrawPrimitive(boo::Primitive::TriStrips);
gfxQ->drawInstances(0, 4, m_glyphs.size()); gfxQ->drawInstances(0, 4, m_glyphs.size());
}
} }

View File

@ -145,12 +145,12 @@ void View::System::init(boo::ID3DDataFactory* factory)
" return tex.Sample(samp, vtf.uv);\n" " return tex.Sample(samp, vtf.uv);\n"
"}\n"; "}\n";
boo::VertexElementDescriptor vdescs[] = boo::VertexElementDescriptor solidvdescs[] =
{ {
{nullptr, nullptr, boo::VertexSemantic::Position4}, {nullptr, nullptr, boo::VertexSemantic::Position4},
{nullptr, nullptr, boo::VertexSemantic::Color | boo::VertexSemantic::Instanced} {nullptr, nullptr, boo::VertexSemantic::Color | boo::VertexSemantic::Instanced}
}; };
m_solidVtxFmt = factory->newVertexFormat(2, vdescs); m_solidVtxFmt = factory->newVertexFormat(2, solidvdescs);
ComPtr<ID3DBlob> vertBlob; ComPtr<ID3DBlob> vertBlob;
ComPtr<ID3DBlob> fragBlob; ComPtr<ID3DBlob> fragBlob;
@ -159,17 +159,17 @@ void View::System::init(boo::ID3DDataFactory* factory)
boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha, boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha,
false, false, false); false, false, false);
boo::VertexElementDescriptor vdescs[] = boo::VertexElementDescriptor texvdescs[] =
{ {
{nullptr, nullptr, boo::VertexSemantic::Position4}, {nullptr, nullptr, boo::VertexSemantic::Position4},
{nullptr, nullptr, boo::VertexSemantic::UV4} {nullptr, nullptr, boo::VertexSemantic::UV4}
}; };
m_texVtxFmt = factory->newVertexFormat(2, vdescs); m_texVtxFmt = factory->newVertexFormat(2, texvdescs);
vertBlob.Reset(); vertBlob.Reset();
fragBlob.Reset(); fragBlob.Reset();
pipeBlob.Reset(); pipeBlob.Reset();
m_solidShader = factory->newShaderPipeline(TexVS, TexFS, vertBlob, fragBlob, pipeBlob, m_texVtxFmt, m_texShader = factory->newShaderPipeline(TexVS, TexFS, vertBlob, fragBlob, pipeBlob, m_texVtxFmt,
boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha, boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha,
false, false, false); false, false, false);
} }
@ -249,23 +249,23 @@ void View::System::init(boo::MetalDataFactory* factory)
" return tex.sample(samp, vtf.uv);\n" " return tex.sample(samp, vtf.uv);\n"
"}\n"; "}\n";
boo::VertexElementDescriptor vdescs[] = boo::VertexElementDescriptor solidvdescs[] =
{ {
{nullptr, nullptr, boo::VertexSemantic::Position4}, {nullptr, nullptr, boo::VertexSemantic::Position4},
{nullptr, nullptr, boo::VertexSemantic::Color | boo::VertexSemantic::Instanced} {nullptr, nullptr, boo::VertexSemantic::Color | boo::VertexSemantic::Instanced}
}; };
m_solidVtxFmt = factory->newVertexFormat(2, vdescs); m_solidVtxFmt = factory->newVertexFormat(2, solidvdescs);
m_solidShader = factory->newShaderPipeline(SolidVS, SolidFS, m_solidVtxFmt, 1, m_solidShader = factory->newShaderPipeline(SolidVS, SolidFS, m_solidVtxFmt, 1,
boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha, boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha,
false, false, false); false, false, false);
boo::VertexElementDescriptor vdescs[] = boo::VertexElementDescriptor texvdescs[] =
{ {
{nullptr, nullptr, boo::VertexSemantic::Position4}, {nullptr, nullptr, boo::VertexSemantic::Position4},
{nullptr, nullptr, boo::VertexSemantic::UV4} {nullptr, nullptr, boo::VertexSemantic::UV4}
}; };
m_texVtxFmt = factory->newVertexFormat(2, vdescs); m_texVtxFmt = factory->newVertexFormat(2, texvdescs);
m_texShader = factory->newShaderPipeline(TexVS, TexFS, m_texVtxFmt, 1, m_texShader = factory->newShaderPipeline(TexVS, TexFS, m_texVtxFmt, 1,
boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha, boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha,