mirror of https://github.com/AxioDL/metaforce.git
Uniform and Vertex buffer pool refactor
This commit is contained in:
parent
474ef07953
commit
a9322292f5
|
@ -60,7 +60,9 @@ list(APPEND SPECTER_HEADERS
|
|||
include/specter/FileBrowser.hpp
|
||||
include/specter/Icon.hpp
|
||||
include/specter/FontCache.hpp
|
||||
include/specter/Translator.hpp)
|
||||
include/specter/Translator.hpp
|
||||
include/specter/UniformBufferPool.hpp
|
||||
include/specter/VertexBufferPool.hpp)
|
||||
|
||||
atdna(atdna_FontCache.cpp include/specter/FontCache.hpp)
|
||||
|
||||
|
|
|
@ -27,7 +27,12 @@ private:
|
|||
std::unique_ptr<IconView> m_icon;
|
||||
|
||||
SolidShaderVert m_verts[40];
|
||||
VertexBufferBinding m_vertsBinding;
|
||||
VertexBufferBindingSolid m_vertsBinding;
|
||||
|
||||
void _loadVerts()
|
||||
{
|
||||
m_vertsBinding.load<decltype(m_verts)>(m_verts);
|
||||
}
|
||||
|
||||
RectangleConstraint m_constraint;
|
||||
int m_nomWidth, m_nomHeight;
|
||||
|
@ -117,7 +122,7 @@ public:
|
|||
View::setMultiplyColor(color);
|
||||
m_viewVertBlock.m_color = color;
|
||||
if (m_viewVertBlockBuf)
|
||||
m_viewVertBlockBuf->load(&m_viewVertBlock, sizeof(ViewBlock));
|
||||
m_viewVertBlockBuf->access() = m_viewVertBlock;
|
||||
m_text->setMultiplyColor(color);
|
||||
if (m_icon)
|
||||
m_icon->setMultiplyColor(color);
|
||||
|
|
|
@ -55,7 +55,7 @@ public:
|
|||
|
||||
class IconView : public View
|
||||
{
|
||||
VertexBufferBinding m_vertexBinding;
|
||||
VertexBufferBindingTex m_vertexBinding;
|
||||
public:
|
||||
IconView(ViewResources& res, View& parentView, Icon& icon);
|
||||
void resized(const boo::SWindowRect& root, const boo::SWindowRect& sub);
|
||||
|
|
|
@ -19,7 +19,7 @@ class Menu : public View
|
|||
int m_cWidth, m_cHeight, m_cTop;
|
||||
|
||||
SolidShaderVert m_verts[8];
|
||||
VertexBufferBinding m_vertsBinding;
|
||||
VertexBufferBindingSolid m_vertsBinding;
|
||||
void setVerts(int width, int height, float pf);
|
||||
|
||||
struct ContentView : View
|
||||
|
@ -29,7 +29,7 @@ class Menu : public View
|
|||
|
||||
boo::SWindowRect m_scissorRect;
|
||||
SolidShaderVert m_hlVerts[4];
|
||||
VertexBufferBinding m_hlVertsBinding;
|
||||
VertexBufferBindingSolid m_hlVertsBinding;
|
||||
|
||||
size_t m_highlightedItem = -1;
|
||||
void setHighlightedItem(size_t idx);
|
||||
|
|
|
@ -36,12 +36,16 @@ private:
|
|||
zeus::CColor m_line2Clear;
|
||||
|
||||
ViewBlock m_viewBlock;
|
||||
boo::IGraphicsBufferD* m_viewBlockBuf;
|
||||
struct
|
||||
std::experimental::optional<UniformBufferPool<ViewBlock>::Token> m_viewBlockBuf;
|
||||
union
|
||||
{
|
||||
SolidShaderVert lineVerts[22];
|
||||
SolidShaderVert fillVerts[16];
|
||||
} m_verts;
|
||||
struct
|
||||
{
|
||||
SolidShaderVert lineVerts[22];
|
||||
SolidShaderVert fillVerts[16];
|
||||
} m_verts;
|
||||
SolidShaderVert _m_verts[38];
|
||||
};
|
||||
|
||||
void setLineVerts(int width, int height, float pf, float t);
|
||||
void setLineVertsOut(int width, int height, float pf, float t);
|
||||
|
@ -50,7 +54,11 @@ private:
|
|||
void setFillVerts(int width, int height, float pf);
|
||||
void setFillColors(float t);
|
||||
|
||||
VertexBufferBinding m_vertsBinding;
|
||||
VertexBufferBindingSolid m_vertsBinding;
|
||||
void _loadVerts()
|
||||
{
|
||||
m_vertsBinding.load<decltype(_m_verts)>(_m_verts);
|
||||
}
|
||||
|
||||
boo::GraphicsDataToken m_windowGfxData;
|
||||
|
||||
|
|
|
@ -54,9 +54,9 @@ class RootView : public View
|
|||
float m_interactiveSplit = 0.5;
|
||||
bool m_interactiveDown = false;
|
||||
|
||||
VertexBufferBinding m_vertsBinding;
|
||||
VertexBufferBindingSolid m_vertsBinding;
|
||||
ViewBlock m_viewBlock;
|
||||
boo::IGraphicsBufferD* m_viewVertBlockBuf;
|
||||
std::experimental::optional<UniformBufferPool<ViewBlock>::Token> m_viewVertBlockBuf;
|
||||
SolidShaderVert m_verts[32];
|
||||
void setArrowVerts(const boo::SWindowRect& rect, SplitView::ArrowDir dir);
|
||||
void setLineVerts(const boo::SWindowRect& rect, float split, SplitView::Axis axis);
|
||||
|
|
|
@ -32,7 +32,7 @@ private:
|
|||
bool m_drawSideButtons = false;
|
||||
|
||||
SolidShaderVert m_verts[4];
|
||||
VertexBufferBinding m_vertsBinding;
|
||||
VertexBufferBindingSolid m_vertsBinding;
|
||||
|
||||
enum class SideButtonState
|
||||
{
|
||||
|
|
|
@ -37,7 +37,7 @@ class Space : public View
|
|||
struct CornerView : View
|
||||
{
|
||||
Space& m_space;
|
||||
VertexBufferBinding m_vertexBinding;
|
||||
VertexBufferBindingSolid m_vertexBinding;
|
||||
bool m_flip;
|
||||
CornerView(ViewResources& res, Space& space, const zeus::CColor& triColor);
|
||||
void mouseEnter(const boo::SWindowCoord&);
|
||||
|
|
|
@ -43,7 +43,7 @@ private:
|
|||
|
||||
ViewChild<View*> m_views[2];
|
||||
ViewBlock m_splitBlock;
|
||||
boo::IGraphicsBufferD* m_splitBlockBuf;
|
||||
std::experimental::optional<UniformBufferPool<ViewBlock>::Token> m_splitBlockBuf;
|
||||
TexShaderVert m_splitVerts[4];
|
||||
|
||||
int m_clearanceA, m_clearanceB;
|
||||
|
@ -72,7 +72,7 @@ private:
|
|||
m_splitVerts[3].m_uv.assign(1, 0);
|
||||
}
|
||||
|
||||
VertexBufferBinding m_splitVertsBinding;
|
||||
VertexBufferBindingTex m_splitVertsBinding;
|
||||
|
||||
public:
|
||||
SplitView(ViewResources& res, View& parentView, ISplitSpaceController* controller,
|
||||
|
@ -104,7 +104,7 @@ public:
|
|||
{
|
||||
View::setMultiplyColor(color);
|
||||
m_splitBlock.m_color = color;
|
||||
m_splitBlockBuf->load(&m_splitBlock, sizeof(m_splitBlock));
|
||||
m_splitBlockBuf->access() = m_splitBlock;
|
||||
|
||||
if (m_views[0].m_view)
|
||||
m_views[0].m_view->setMultiplyColor(color);
|
||||
|
|
|
@ -84,7 +84,7 @@ class Table : public View
|
|||
size_t m_hDraggingIdx = 0;
|
||||
|
||||
std::unique_ptr<SolidShaderVert[]> m_hVerts;
|
||||
VertexBufferBinding m_vertsBinding;
|
||||
VertexBufferBindingSolid m_vertsBinding;
|
||||
void _setHeaderVerts(const boo::SWindowRect& rect);
|
||||
|
||||
std::vector<boo::SWindowRect> getCellRects(const boo::SWindowRect& tableRect) const;
|
||||
|
@ -96,7 +96,7 @@ class Table : public View
|
|||
Table& m_t;
|
||||
|
||||
std::unique_ptr<SolidShaderVert[]> m_verts;
|
||||
VertexBufferBinding m_vertsBinding;
|
||||
VertexBufferBindingSolid m_vertsBinding;
|
||||
size_t m_visibleStart = 0;
|
||||
size_t m_visibleRows = 0;
|
||||
boo::SWindowRect m_scissorRect;
|
||||
|
|
|
@ -19,7 +19,7 @@ class TextField : public ITextInputView
|
|||
std::unique_ptr<TextView> m_errText;
|
||||
|
||||
SolidShaderVert m_verts[41];
|
||||
VertexBufferBinding m_vertsBinding;
|
||||
VertexBufferBindingSolid m_vertsBinding;
|
||||
|
||||
int m_nomWidth = 0;
|
||||
int m_nomHeight = 0;
|
||||
|
@ -118,7 +118,7 @@ public:
|
|||
View::setMultiplyColor(color);
|
||||
m_viewVertBlock.m_color = color;
|
||||
if (m_viewVertBlockBuf)
|
||||
m_viewVertBlockBuf->load(&m_viewVertBlock, sizeof(ViewBlock));
|
||||
m_viewVertBlockBuf->access() = m_viewVertBlock;
|
||||
m_text->setMultiplyColor(color);
|
||||
if (m_errText)
|
||||
m_errText->setMultiplyColor(color);
|
||||
|
|
|
@ -22,15 +22,33 @@ public:
|
|||
Center,
|
||||
Right
|
||||
};
|
||||
struct RenderGlyph
|
||||
{
|
||||
zeus::CVector3f m_pos[4];
|
||||
zeus::CMatrix4f m_mv;
|
||||
zeus::CVector3f m_uv[4];
|
||||
zeus::CColor m_color;
|
||||
|
||||
RenderGlyph(int& adv, const FontAtlas::Glyph& glyph, const zeus::CColor& defaultColor);
|
||||
};
|
||||
struct RenderGlyphInfo
|
||||
{
|
||||
uint32_t m_char;
|
||||
std::pair<int,int> m_dims;
|
||||
int m_adv;
|
||||
bool m_space = false;
|
||||
|
||||
RenderGlyphInfo(uint32_t ch, int width, int height, int adv)
|
||||
: m_char(ch), m_dims(width, height), m_adv(adv), m_space(iswspace(ch) != 0) {}
|
||||
};
|
||||
|
||||
private:
|
||||
size_t m_capacity;
|
||||
boo::IGraphicsBufferD* m_glyphBuf;
|
||||
std::experimental::optional<VertexBufferPool<RenderGlyph>::Token> m_glyphBuf;
|
||||
boo::IVertexFormat* m_vtxFmt = nullptr; /* OpenGL only */
|
||||
boo::IShaderDataBinding* m_shaderBinding;
|
||||
const FontAtlas& m_fontAtlas;
|
||||
Alignment m_align;
|
||||
bool m_valid = false;
|
||||
int m_width = 0;
|
||||
|
||||
friend class MultiLineTextView;
|
||||
|
@ -42,6 +60,14 @@ public:
|
|||
friend class ViewResources;
|
||||
friend class TextView;
|
||||
friend class MultiLineTextView;
|
||||
|
||||
VertexBufferPool<RenderGlyph> m_glyphPool;
|
||||
|
||||
void updateBuffers()
|
||||
{
|
||||
m_glyphPool.updateBuffers();
|
||||
}
|
||||
|
||||
FontCache* m_fcache = nullptr;
|
||||
boo::IShaderPipeline* m_regular = nullptr;
|
||||
boo::IShaderPipeline* m_subpixel = nullptr;
|
||||
|
@ -62,33 +88,14 @@ public:
|
|||
TextView(ViewResources& res, View& parentView, const FontAtlas& font, Alignment align=Alignment::Left, size_t capacity=256);
|
||||
TextView(ViewResources& res, View& parentView, FontTag font, Alignment align=Alignment::Left, size_t capacity=256);
|
||||
|
||||
struct RenderGlyph
|
||||
{
|
||||
zeus::CVector3f m_pos[4];
|
||||
zeus::CMatrix4f m_mv;
|
||||
zeus::CVector3f m_uv[4];
|
||||
zeus::CColor m_color;
|
||||
|
||||
RenderGlyph(int& adv, const FontAtlas::Glyph& glyph, const zeus::CColor& defaultColor);
|
||||
};
|
||||
struct RenderGlyphInfo
|
||||
{
|
||||
uint32_t m_char;
|
||||
std::pair<int,int> m_dims;
|
||||
int m_adv;
|
||||
bool m_space = false;
|
||||
|
||||
RenderGlyphInfo(uint32_t ch, int width, int height, int adv)
|
||||
: m_char(ch), m_dims(width, height), m_adv(adv), m_space(iswspace(ch) != 0) {}
|
||||
};
|
||||
std::vector<RenderGlyph>& accessGlyphs() {return m_glyphs;}
|
||||
const std::vector<RenderGlyph>& accessGlyphs() const {return m_glyphs;}
|
||||
void updateGlyphs() {m_valid = false;}
|
||||
|
||||
void typesetGlyphs(const std::string& str,
|
||||
const zeus::CColor& defaultColor=zeus::CColor::skWhite);
|
||||
void typesetGlyphs(const std::wstring& str,
|
||||
const zeus::CColor& defaultColor=zeus::CColor::skWhite);
|
||||
void invalidateGlyphs();
|
||||
|
||||
void colorGlyphs(const zeus::CColor& newColor);
|
||||
void colorGlyphsTypeOn(const zeus::CColor& newColor, float startInterval=0.2, float fadeTime=0.5);
|
||||
|
|
|
@ -31,7 +31,7 @@ private:
|
|||
std::vector<std::vector<ViewChild<View*>>> m_children;
|
||||
|
||||
ViewBlock m_tbBlock;
|
||||
boo::IGraphicsBufferD* m_tbBlockBuf;
|
||||
std::experimental::optional<UniformBufferPool<ViewBlock>::Token> m_tbBlockBuf;
|
||||
TexShaderVert m_tbVerts[10];
|
||||
int m_nomGauge = 25;
|
||||
int m_padding = 10;
|
||||
|
@ -39,7 +39,7 @@ private:
|
|||
void setHorizontalVerts(int width);
|
||||
void setVerticalVerts(int height);
|
||||
|
||||
VertexBufferBinding m_vertsBinding;
|
||||
VertexBufferBindingTex m_vertsBinding;
|
||||
|
||||
public:
|
||||
Toolbar(ViewResources& res, View& parentView, Position toolbarPos, unsigned units);
|
||||
|
|
|
@ -10,14 +10,14 @@ namespace specter
|
|||
class Tooltip : public View
|
||||
{
|
||||
ViewBlock m_ttBlock;
|
||||
boo::IGraphicsBufferD* m_ttBlockBuf;
|
||||
std::experimental::optional<UniformBufferPool<ViewBlock>::Token> m_ttBlockBuf;
|
||||
SolidShaderVert m_ttVerts[16];
|
||||
int m_nomWidth = 25;
|
||||
int m_nomHeight = 25;
|
||||
|
||||
void setVerts(int width, int height, float pf);
|
||||
|
||||
VertexBufferBinding m_vertsBinding;
|
||||
VertexBufferBindingSolid m_vertsBinding;
|
||||
|
||||
std::string m_titleStr;
|
||||
std::unique_ptr<TextView> m_title;
|
||||
|
|
|
@ -0,0 +1,155 @@
|
|||
#ifndef SPECTER_UNIFORMBUFFERPOOL_HPP
|
||||
#define SPECTER_UNIFORMBUFFERPOOL_HPP
|
||||
|
||||
#include <boo/boo.hpp>
|
||||
#include <hecl/BitVector.hpp>
|
||||
#include <vector>
|
||||
#include <cstdlib>
|
||||
|
||||
namespace specter
|
||||
{
|
||||
|
||||
#define SPECTER_UBUFPOOL_ALLOCATION_BLOCK 262144
|
||||
|
||||
/** This class provides a uniform structure for packing instanced uniform-buffer
|
||||
* data with consistent stride into a vector of 64K 'Buckets'.
|
||||
*
|
||||
* This results in a space-efficient way of managing GPU data of things like UI
|
||||
* widgets. These can potentially have numerous binding instances, so this avoids
|
||||
* allocating a full GPU buffer object for each. */
|
||||
template <typename UniformStruct>
|
||||
class UniformBufferPool
|
||||
{
|
||||
/* Resolve div_t type using ssize_t as basis */
|
||||
using IndexTp = ssize_t;
|
||||
struct InvalidTp {};
|
||||
using DivTp = std::conditional_t<std::is_same<IndexTp, long long>::value, std::lldiv_t,
|
||||
std::conditional_t<std::is_same<IndexTp, long>::value, std::ldiv_t,
|
||||
std::conditional_t<std::is_same<IndexTp, int>::value, std::div_t, InvalidTp>>>;
|
||||
static_assert(!std::is_same<DivTp, InvalidTp>::value, "unsupported IndexTp for DivTp resolution");
|
||||
|
||||
/** Size of single element, rounded up to 256-multiple */
|
||||
static constexpr IndexTp m_stride = ROUND_UP_256(sizeof(UniformStruct));
|
||||
static_assert(m_stride <= SPECTER_UBUFPOOL_ALLOCATION_BLOCK, "Stride too large for uniform pool");
|
||||
|
||||
/** Number of rounded elements per 64K bucket */
|
||||
static constexpr IndexTp m_countPerBucket = SPECTER_UBUFPOOL_ALLOCATION_BLOCK / m_stride;
|
||||
|
||||
/** Buffer size per bucket (ideally 64K) */
|
||||
static constexpr IndexTp m_sizePerBucket = m_stride * m_countPerBucket;
|
||||
|
||||
/** BitVector indicating free allocation blocks */
|
||||
hecl::llvm::BitVector m_freeBlocks;
|
||||
|
||||
/** Efficient way to get bucket and block simultaneously */
|
||||
DivTp getBucketDiv(IndexTp idx) const { return std::div(idx, m_countPerBucket); }
|
||||
|
||||
/** Buffer pool token */
|
||||
boo::GraphicsBufferPoolToken m_token;
|
||||
|
||||
/** Private bucket info */
|
||||
struct Bucket
|
||||
{
|
||||
boo::IGraphicsBufferD* buffer;
|
||||
std::unique_ptr<uint8_t[]> cpuBuffer;
|
||||
bool dirty = false;
|
||||
Bucket(const Bucket& other) = delete;
|
||||
Bucket& operator=(const Bucket& other) = delete;
|
||||
Bucket(Bucket&& other) = default;
|
||||
Bucket& operator=(Bucket&& other) = default;
|
||||
Bucket(UniformBufferPool& pool)
|
||||
: cpuBuffer(new uint8_t[pool.m_sizePerBucket])
|
||||
{
|
||||
buffer = pool.m_token.newPoolBuffer(boo::BufferUse::Uniform, pool.m_stride, pool.m_countPerBucket);
|
||||
}
|
||||
void updateBuffer(UniformBufferPool& pool)
|
||||
{
|
||||
buffer->load(cpuBuffer.get(), pool.m_sizePerBucket);
|
||||
dirty = false;
|
||||
}
|
||||
};
|
||||
std::vector<Bucket> m_buckets;
|
||||
|
||||
public:
|
||||
/** User block-owning token */
|
||||
class Token
|
||||
{
|
||||
friend class UniformBufferPool;
|
||||
UniformBufferPool& m_pool;
|
||||
IndexTp m_index;
|
||||
DivTp m_div;
|
||||
Token(UniformBufferPool& pool)
|
||||
: m_pool(pool)
|
||||
{
|
||||
auto& freeSpaces = pool.m_freeBlocks;
|
||||
auto& buckets = pool.m_buckets;
|
||||
int idx = freeSpaces.find_first();
|
||||
if (idx == -1)
|
||||
{
|
||||
buckets.emplace_back(pool);
|
||||
m_index = freeSpaces.size();
|
||||
freeSpaces.resize(freeSpaces.size() + pool.m_countPerBucket, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_index = idx;
|
||||
}
|
||||
freeSpaces.reset(m_index);
|
||||
m_div = pool.getBucketDiv(m_index);
|
||||
}
|
||||
|
||||
public:
|
||||
Token(const Token& other) = delete;
|
||||
Token& operator=(const Token& other) = delete;
|
||||
Token& operator=(Token&& other) = delete;
|
||||
Token(Token&& other)
|
||||
: m_pool(other.m_pool), m_index(other.m_index),
|
||||
m_div(other.m_div)
|
||||
{
|
||||
other.m_index = -1;
|
||||
}
|
||||
|
||||
~Token()
|
||||
{
|
||||
if (m_index != -1)
|
||||
m_pool.m_freeBlocks.set(m_index);
|
||||
}
|
||||
|
||||
UniformStruct& access()
|
||||
{
|
||||
Bucket& bucket = m_pool.m_buckets[m_div.quot];
|
||||
bucket.dirty = true;
|
||||
return reinterpret_cast<UniformStruct&>(bucket.cpuBuffer[m_div.rem * m_pool.m_stride]);
|
||||
}
|
||||
|
||||
std::pair<boo::IGraphicsBufferD*, IndexTp> getBufferInfo() const
|
||||
{
|
||||
Bucket& bucket = m_pool.m_buckets[m_div.quot];
|
||||
return {bucket.buffer, m_div.rem * m_pool.m_stride};
|
||||
}
|
||||
};
|
||||
|
||||
UniformBufferPool() = default;
|
||||
UniformBufferPool(const UniformBufferPool& other) = delete;
|
||||
UniformBufferPool& operator=(const UniformBufferPool& other) = delete;
|
||||
|
||||
/** Load dirty buffer data into GPU */
|
||||
void updateBuffers()
|
||||
{
|
||||
for (Bucket& bucket : m_buckets)
|
||||
if (bucket.dirty)
|
||||
bucket.updateBuffer(*this);
|
||||
}
|
||||
|
||||
/** Allocate free block into client-owned Token */
|
||||
Token allocateBlock(boo::IGraphicsDataFactory* factory)
|
||||
{
|
||||
if (!m_token)
|
||||
m_token = factory->newBufferPool();
|
||||
return Token(*this);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // SPECTER_UNIFORMBUFFERPOOL_HPP
|
|
@ -0,0 +1,158 @@
|
|||
#ifndef SPECTER_VERTEXBUFFERPOOL_HPP
|
||||
#define SPECTER_VERTEXBUFFERPOOL_HPP
|
||||
|
||||
#include <boo/boo.hpp>
|
||||
#include <hecl/BitVector.hpp>
|
||||
#include <vector>
|
||||
#include <cstdlib>
|
||||
|
||||
namespace specter
|
||||
{
|
||||
|
||||
#define SPECTER_VBUFPOOL_ALLOCATION_BLOCK 262144
|
||||
|
||||
/** This class provides a uniform structure for packing instanced vertex-buffer
|
||||
* data with consistent stride into a vector of 64K 'Buckets'.
|
||||
*
|
||||
* This results in a space-efficient way of managing GPU data of things like UI
|
||||
* widgets. These can potentially have numerous binding instances, so this avoids
|
||||
* allocating a full GPU buffer object for each. */
|
||||
template <typename VertStruct>
|
||||
class VertexBufferPool
|
||||
{
|
||||
/* Resolve div_t type using ssize_t as basis */
|
||||
using IndexTp = ssize_t;
|
||||
struct InvalidTp {};
|
||||
using DivTp = std::conditional_t<std::is_same<IndexTp, long long>::value, std::lldiv_t,
|
||||
std::conditional_t<std::is_same<IndexTp, long>::value, std::ldiv_t,
|
||||
std::conditional_t<std::is_same<IndexTp, int>::value, std::div_t, InvalidTp>>>;
|
||||
static_assert(!std::is_same<DivTp, InvalidTp>::value, "unsupported IndexTp for DivTp resolution");
|
||||
|
||||
/** Size of single element */
|
||||
static constexpr IndexTp m_stride = sizeof(VertStruct);
|
||||
static_assert(m_stride <= SPECTER_VBUFPOOL_ALLOCATION_BLOCK, "Stride too large for vertex pool");
|
||||
|
||||
/** Number of elements per 64K bucket */
|
||||
static constexpr IndexTp m_countPerBucket = SPECTER_VBUFPOOL_ALLOCATION_BLOCK / m_stride;
|
||||
|
||||
/** Buffer size per bucket (ideally 64K) */
|
||||
static constexpr IndexTp m_sizePerBucket = m_stride * m_countPerBucket;
|
||||
|
||||
/** BitVector indicating free allocation elements */
|
||||
hecl::llvm::BitVector m_freeElements;
|
||||
|
||||
/** Efficient way to get bucket and element simultaneously */
|
||||
DivTp getBucketDiv(IndexTp idx) const { return std::div(idx, m_countPerBucket); }
|
||||
|
||||
/** Buffer pool token */
|
||||
boo::GraphicsBufferPoolToken m_token;
|
||||
|
||||
/** Private bucket info */
|
||||
struct Bucket
|
||||
{
|
||||
boo::IGraphicsBufferD* buffer;
|
||||
std::unique_ptr<uint8_t[]> cpuBuffer;
|
||||
bool dirty = false;
|
||||
Bucket(const Bucket& other) = delete;
|
||||
Bucket& operator=(const Bucket& other) = delete;
|
||||
Bucket(Bucket&& other) = default;
|
||||
Bucket& operator=(Bucket&& other) = default;
|
||||
Bucket(VertexBufferPool& pool)
|
||||
: cpuBuffer(new uint8_t[pool.m_sizePerBucket])
|
||||
{
|
||||
buffer = pool.m_token.newPoolBuffer(boo::BufferUse::Vertex, pool.m_stride, pool.m_countPerBucket);
|
||||
}
|
||||
void updateBuffer(VertexBufferPool& pool)
|
||||
{
|
||||
buffer->load(cpuBuffer.get(), pool.m_sizePerBucket);
|
||||
dirty = false;
|
||||
}
|
||||
};
|
||||
std::vector<Bucket> m_buckets;
|
||||
|
||||
public:
|
||||
/** User element-owning token */
|
||||
class Token
|
||||
{
|
||||
friend class VertexBufferPool;
|
||||
VertexBufferPool& m_pool;
|
||||
IndexTp m_index;
|
||||
IndexTp m_count;
|
||||
DivTp m_div;
|
||||
Token(VertexBufferPool& pool, IndexTp count)
|
||||
: m_pool(pool), m_count(count)
|
||||
{
|
||||
assert(count <= pool.m_countPerBucket && "unable to fit in bucket");
|
||||
auto& freeSpaces = pool.m_freeElements;
|
||||
auto& buckets = pool.m_buckets;
|
||||
int idx = freeSpaces.find_first_contiguous(count);
|
||||
if (idx == -1)
|
||||
{
|
||||
buckets.emplace_back(pool);
|
||||
m_index = freeSpaces.size();
|
||||
freeSpaces.resize(freeSpaces.size() + pool.m_countPerBucket, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_index = idx;
|
||||
}
|
||||
freeSpaces.reset(m_index, m_index + count);
|
||||
m_div = pool.getBucketDiv(m_index);
|
||||
}
|
||||
public:
|
||||
Token(const Token& other) = delete;
|
||||
Token& operator=(const Token& other) = delete;
|
||||
Token& operator=(Token&& other) = delete;
|
||||
Token(Token&& other)
|
||||
: m_pool(other.m_pool), m_index(other.m_index),
|
||||
m_count(other.m_count), m_div(other.m_div)
|
||||
{
|
||||
other.m_index = -1;
|
||||
}
|
||||
|
||||
~Token()
|
||||
{
|
||||
if (m_index != -1)
|
||||
m_pool.m_freeElements.set(m_index, m_index + m_count);
|
||||
}
|
||||
|
||||
VertStruct* access()
|
||||
{
|
||||
Bucket& bucket = m_pool.m_buckets[m_div.quot];
|
||||
bucket.dirty = true;
|
||||
return reinterpret_cast<VertStruct*>(&bucket.cpuBuffer[m_div.rem * m_pool.m_stride]);
|
||||
}
|
||||
|
||||
std::pair<boo::IGraphicsBufferD*, IndexTp> getBufferInfo() const
|
||||
{
|
||||
Bucket& bucket = m_pool.m_buckets[m_div.quot];
|
||||
return {bucket.buffer, m_div.rem};
|
||||
}
|
||||
};
|
||||
|
||||
VertexBufferPool() = default;
|
||||
VertexBufferPool(const VertexBufferPool& other) = delete;
|
||||
VertexBufferPool& operator=(const VertexBufferPool& other) = delete;
|
||||
|
||||
/** Load dirty buffer data into GPU */
|
||||
void updateBuffers()
|
||||
{
|
||||
for (Bucket& bucket : m_buckets)
|
||||
if (bucket.dirty)
|
||||
bucket.updateBuffer(*this);
|
||||
}
|
||||
|
||||
/** Allocate free block into client-owned Token */
|
||||
Token allocateBlock(boo::IGraphicsDataFactory* factory, IndexTp count)
|
||||
{
|
||||
if (!m_token)
|
||||
m_token = factory->newBufferPool();
|
||||
return Token(*this, count);
|
||||
}
|
||||
|
||||
static constexpr IndexTp bucketCapacity() { return m_countPerBucket; }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // SPECTER_VERTEXBUFFERPOOL_HPP
|
|
@ -2,11 +2,14 @@
|
|||
#define SPECTER_VIEW_HPP
|
||||
|
||||
#include <boo/boo.hpp>
|
||||
#include "optional.hpp"
|
||||
#include "zeus/CVector3f.hpp"
|
||||
#include "zeus/CMatrix4f.hpp"
|
||||
#include "zeus/CTransform.hpp"
|
||||
#include "zeus/CColor.hpp"
|
||||
#include "hecl/CVar.hpp"
|
||||
#include "UniformBufferPool.hpp"
|
||||
#include "VertexBufferPool.hpp"
|
||||
|
||||
#include <boo/graphicsdev/GL.hpp>
|
||||
#include <boo/graphicsdev/D3D.hpp>
|
||||
|
@ -104,28 +107,57 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
template <typename VertStruct>
|
||||
struct VertexBufferBinding
|
||||
{
|
||||
boo::IGraphicsBufferD* m_vertsBuf = nullptr;
|
||||
std::experimental::optional<typename VertexBufferPool<VertStruct>::Token> m_vertsBuf;
|
||||
boo::IVertexFormat* m_vtxFmt = nullptr; /* OpenGL only */
|
||||
boo::IShaderDataBinding* m_shaderBinding = nullptr;
|
||||
|
||||
void initSolid(boo::IGraphicsDataFactory::Context& ctx,
|
||||
ViewResources& res, size_t count,
|
||||
boo::IGraphicsBuffer* viewBlockBuf);
|
||||
void initTex(boo::IGraphicsDataFactory::Context& ctx,
|
||||
ViewResources& res, size_t count,
|
||||
boo::IGraphicsBuffer* viewBlockBuf,
|
||||
boo::ITexture* texture);
|
||||
void load(const VertStruct* data, size_t count)
|
||||
{
|
||||
if (m_vertsBuf)
|
||||
{
|
||||
VertStruct* out = m_vertsBuf->access();
|
||||
for (size_t i=0; i<count; ++i)
|
||||
out[i] = data[i];
|
||||
}
|
||||
}
|
||||
template <typename VertArray>
|
||||
void load(const VertArray data)
|
||||
{
|
||||
static_assert(std::is_same<std::remove_all_extents_t<VertArray>,
|
||||
VertStruct>::value, "mismatched type");
|
||||
if (m_vertsBuf)
|
||||
{
|
||||
constexpr size_t count = sizeof(VertArray) / sizeof(VertStruct);
|
||||
VertStruct* out = m_vertsBuf->access();
|
||||
for (size_t i=0; i<count; ++i)
|
||||
out[i] = data[i];
|
||||
}
|
||||
}
|
||||
|
||||
void load(const void* data, size_t sz) {if (m_vertsBuf) m_vertsBuf->load(data, sz);}
|
||||
operator boo::IShaderDataBinding*() {return m_shaderBinding;}
|
||||
operator boo::IShaderDataBinding*() { return m_shaderBinding; }
|
||||
};
|
||||
struct VertexBufferBindingSolid : VertexBufferBinding<SolidShaderVert>
|
||||
{
|
||||
void init(boo::IGraphicsDataFactory::Context& ctx,
|
||||
ViewResources& res, size_t count,
|
||||
const UniformBufferPool<ViewBlock>::Token& viewBlockBuf);
|
||||
};
|
||||
struct VertexBufferBindingTex : VertexBufferBinding<TexShaderVert>
|
||||
{
|
||||
void init(boo::IGraphicsDataFactory::Context& ctx,
|
||||
ViewResources& res, size_t count,
|
||||
const UniformBufferPool<ViewBlock>::Token& viewBlockBuf,
|
||||
boo::ITexture* texture);
|
||||
};
|
||||
|
||||
private:
|
||||
RootView& m_rootView;
|
||||
View& m_parentView;
|
||||
boo::SWindowRect m_subRect;
|
||||
VertexBufferBinding m_bgVertsBinding;
|
||||
VertexBufferBindingSolid m_bgVertsBinding;
|
||||
SolidShaderVert m_bgRect[4];
|
||||
boo::GraphicsDataToken m_gfxData;
|
||||
|
||||
|
@ -152,11 +184,22 @@ protected:
|
|||
" float4x4 mv;\n"\
|
||||
" float4 mulColor;\n"\
|
||||
"};\n"
|
||||
boo::IGraphicsBufferD* m_viewVertBlockBuf = nullptr;
|
||||
std::experimental::optional<UniformBufferPool<ViewBlock>::Token> m_viewVertBlockBuf;
|
||||
|
||||
public:
|
||||
struct Resources
|
||||
{
|
||||
UniformBufferPool<ViewBlock> m_bufPool;
|
||||
VertexBufferPool<SolidShaderVert> m_solidPool;
|
||||
VertexBufferPool<TexShaderVert> m_texPool;
|
||||
|
||||
void updateBuffers()
|
||||
{
|
||||
m_bufPool.updateBuffers();
|
||||
m_solidPool.updateBuffers();
|
||||
m_texPool.updateBuffers();
|
||||
}
|
||||
|
||||
boo::IShaderPipeline* m_solidShader = nullptr;
|
||||
boo::IVertexFormat* m_solidVtxFmt = nullptr; /* Not OpenGL */
|
||||
|
||||
|
@ -198,14 +241,14 @@ public:
|
|||
{
|
||||
for (int i=0 ; i<4 ; ++i)
|
||||
m_bgRect[i].m_color = color;
|
||||
m_bgVertsBinding.load(m_bgRect, sizeof(m_bgRect));
|
||||
m_bgVertsBinding.load<decltype(m_bgRect)>(m_bgRect);
|
||||
}
|
||||
|
||||
virtual void setMultiplyColor(const zeus::CColor& color)
|
||||
{
|
||||
m_viewVertBlock.m_color = color;
|
||||
if (m_viewVertBlockBuf)
|
||||
m_viewVertBlockBuf->load(&m_viewVertBlock, sizeof(ViewBlock));
|
||||
m_viewVertBlockBuf->access() = m_viewVertBlock;
|
||||
}
|
||||
|
||||
virtual int nominalWidth() const {return 0;}
|
||||
|
|
|
@ -193,6 +193,12 @@ public:
|
|||
m_resData.doDestroy();
|
||||
}
|
||||
|
||||
void updateBuffers()
|
||||
{
|
||||
m_viewRes.updateBuffers();
|
||||
m_textRes.updateBuffers();
|
||||
}
|
||||
|
||||
~ViewResources()
|
||||
{
|
||||
if (m_fcacheThread.joinable())
|
||||
|
|
|
@ -25,7 +25,7 @@ Button::Button(ViewResources& res, View& parentView,
|
|||
commitResources(res, [&](boo::IGraphicsDataFactory::Context& ctx) -> bool
|
||||
{
|
||||
buildResources(ctx, res);
|
||||
m_vertsBinding.initSolid(ctx, res, 40, m_viewVertBlockBuf);
|
||||
m_vertsBinding.init(ctx, res, 40, *m_viewVertBlockBuf);
|
||||
return true;
|
||||
});
|
||||
|
||||
|
@ -59,7 +59,7 @@ Button::Button(ViewResources& res, View& parentView,
|
|||
}
|
||||
for (int i=28 ; i<31 ; ++i)
|
||||
m_verts[i].m_color = m_textColor;
|
||||
m_vertsBinding.load(m_verts, sizeof(m_verts));
|
||||
_loadVerts();
|
||||
|
||||
if (controlBinding)
|
||||
m_menuStyle = controlBinding->menuStyle(this);
|
||||
|
@ -156,7 +156,7 @@ void Button::setText(const std::string& text, const zeus::CColor& textColor)
|
|||
m_verts[37].m_pos.assign(m_textIconWidth+1, height+1, 0);
|
||||
m_verts[38].m_pos.assign(m_textIconWidth+1, 1, 0);
|
||||
|
||||
m_vertsBinding.load(m_verts, sizeof(m_verts));
|
||||
_loadVerts();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -191,7 +191,7 @@ void Button::setText(const std::string& text, const zeus::CColor& textColor)
|
|||
m_verts[33].m_pos.assign(arrowX + arrowLineWidth, -1*pf, 0);
|
||||
m_verts[34].m_pos.assign(arrowX + arrowLineWidth, -2*pf, 0);
|
||||
|
||||
m_vertsBinding.load(m_verts, sizeof(m_verts));
|
||||
_loadVerts();
|
||||
}
|
||||
|
||||
m_nomWidth = width;
|
||||
|
@ -214,7 +214,7 @@ void Button::colorGlyphs(const zeus::CColor& newColor)
|
|||
m_text->colorGlyphs(newColor);
|
||||
for (int i=28 ; i<31 ; ++i)
|
||||
m_verts[i].m_color = newColor;
|
||||
m_vertsBinding.load(m_verts, sizeof(m_verts));
|
||||
_loadVerts();
|
||||
}
|
||||
|
||||
void Button::ButtonTarget::setInactive()
|
||||
|
@ -228,13 +228,13 @@ void Button::ButtonTarget::setInactive()
|
|||
m_button.m_verts[2].m_color = c1;
|
||||
m_button.m_verts[3].m_color = c2;
|
||||
m_button.m_verts[4].m_color = c2;
|
||||
m_button.m_vertsBinding.load(m_button.m_verts, sizeof(m_button.m_verts));
|
||||
m_button._loadVerts();
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i=0 ; i<4 ; ++i)
|
||||
m_button.m_verts[i].m_color = zeus::CColor::skClear;
|
||||
m_button.m_vertsBinding.load(m_button.m_verts, sizeof(m_button.m_verts));
|
||||
m_button._loadVerts();
|
||||
m_button.m_text->colorGlyphs(m_button.m_textColor);
|
||||
}
|
||||
}
|
||||
|
@ -249,7 +249,7 @@ void Button::MenuTarget::setInactive()
|
|||
m_button.m_verts[32].m_color = c2;
|
||||
m_button.m_verts[33].m_color = c1;
|
||||
m_button.m_verts[34].m_color = c2;
|
||||
m_button.m_vertsBinding.load(m_button.m_verts, sizeof(m_button.m_verts));
|
||||
m_button._loadVerts();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -257,7 +257,7 @@ void Button::MenuTarget::setInactive()
|
|||
m_button.m_verts[i].m_color = m_button.m_textColor;
|
||||
for (int i=31 ; i<35 ; ++i)
|
||||
m_button.m_verts[i].m_color = zeus::CColor::skClear;
|
||||
m_button.m_vertsBinding.load(m_button.m_verts, sizeof(m_button.m_verts));
|
||||
m_button._loadVerts();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -272,13 +272,13 @@ void Button::ButtonTarget::setHover()
|
|||
m_button.m_verts[2].m_color = c1;
|
||||
m_button.m_verts[3].m_color = c2;
|
||||
m_button.m_verts[4].m_color = c2;
|
||||
m_button.m_vertsBinding.load(m_button.m_verts, sizeof(m_button.m_verts));
|
||||
m_button._loadVerts();
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i=0 ; i<4 ; ++i)
|
||||
m_button.m_verts[i].m_color = m_button.m_textColor;
|
||||
m_button.m_vertsBinding.load(m_button.m_verts, sizeof(m_button.m_verts));
|
||||
m_button._loadVerts();
|
||||
m_button.m_text->colorGlyphs(m_button.m_textColor);
|
||||
}
|
||||
}
|
||||
|
@ -293,7 +293,7 @@ void Button::MenuTarget::setHover()
|
|||
m_button.m_verts[32].m_color = c2;
|
||||
m_button.m_verts[33].m_color = c1;
|
||||
m_button.m_verts[34].m_color = c2;
|
||||
m_button.m_vertsBinding.load(m_button.m_verts, sizeof(m_button.m_verts));
|
||||
m_button._loadVerts();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -301,7 +301,7 @@ void Button::MenuTarget::setHover()
|
|||
m_button.m_verts[i].m_color = m_button.m_textColor;
|
||||
for (int i=31 ; i<35 ; ++i)
|
||||
m_button.m_verts[i].m_color = m_button.m_textColor;
|
||||
m_button.m_vertsBinding.load(m_button.m_verts, sizeof(m_button.m_verts));
|
||||
m_button._loadVerts();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -316,13 +316,13 @@ void Button::ButtonTarget::setPressed()
|
|||
m_button.m_verts[2].m_color = c1;
|
||||
m_button.m_verts[3].m_color = c2;
|
||||
m_button.m_verts[4].m_color = c2;
|
||||
m_button.m_vertsBinding.load(m_button.m_verts, sizeof(m_button.m_verts));
|
||||
m_button._loadVerts();
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i=0 ; i<4 ; ++i)
|
||||
m_button.m_verts[i].m_color = m_button.m_textColor;
|
||||
m_button.m_vertsBinding.load(m_button.m_verts, sizeof(m_button.m_verts));
|
||||
m_button._loadVerts();
|
||||
m_button.m_text->colorGlyphs(m_button.m_textColor);
|
||||
}
|
||||
}
|
||||
|
@ -337,7 +337,7 @@ void Button::MenuTarget::setPressed()
|
|||
m_button.m_verts[32].m_color = c2;
|
||||
m_button.m_verts[33].m_color = c1;
|
||||
m_button.m_verts[34].m_color = c2;
|
||||
m_button.m_vertsBinding.load(m_button.m_verts, sizeof(m_button.m_verts));
|
||||
m_button._loadVerts();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -345,7 +345,7 @@ void Button::MenuTarget::setPressed()
|
|||
m_button.m_verts[i].m_color = m_button.m_textColor;
|
||||
for (int i=31 ; i<35 ; ++i)
|
||||
m_button.m_verts[i].m_color = m_button.m_textColor;
|
||||
m_button.m_vertsBinding.load(m_button.m_verts, sizeof(m_button.m_verts));
|
||||
m_button._loadVerts();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -360,13 +360,13 @@ void Button::ButtonTarget::setDisabled()
|
|||
m_button.m_verts[2].m_color = c1;
|
||||
m_button.m_verts[3].m_color = c2;
|
||||
m_button.m_verts[4].m_color = c2;
|
||||
m_button.m_vertsBinding.load(m_button.m_verts, sizeof(m_button.m_verts));
|
||||
m_button._loadVerts();
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i=0 ; i<4 ; ++i)
|
||||
m_button.m_verts[i].m_color = zeus::CColor::skClear;
|
||||
m_button.m_vertsBinding.load(m_button.m_verts, sizeof(m_button.m_verts));
|
||||
m_button._loadVerts();
|
||||
zeus::CColor dimText = m_button.m_textColor;
|
||||
dimText[3] *= 0.5;
|
||||
m_button.m_text->colorGlyphs(dimText);
|
||||
|
@ -383,7 +383,7 @@ void Button::MenuTarget::setDisabled()
|
|||
m_button.m_verts[32].m_color = c2;
|
||||
m_button.m_verts[33].m_color = c1;
|
||||
m_button.m_verts[34].m_color = c2;
|
||||
m_button.m_vertsBinding.load(m_button.m_verts, sizeof(m_button.m_verts));
|
||||
m_button._loadVerts();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -393,7 +393,7 @@ void Button::MenuTarget::setDisabled()
|
|||
m_button.m_verts[i].m_color = dimText;
|
||||
for (int i=31 ; i<35 ; ++i)
|
||||
m_button.m_verts[i].m_color = zeus::CColor::skClear;
|
||||
m_button.m_vertsBinding.load(m_button.m_verts, sizeof(m_button.m_verts));
|
||||
m_button._loadVerts();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ IconView::IconView(ViewResources& res, View& parentView, Icon& icon)
|
|||
commitResources(res, [&](boo::IGraphicsDataFactory::Context& ctx) -> bool
|
||||
{
|
||||
buildResources(ctx, res);
|
||||
m_vertexBinding.initTex(ctx, res, 4, m_viewVertBlockBuf, icon.m_tex);
|
||||
m_vertexBinding.init(ctx, res, 4, *m_viewVertBlockBuf, icon.m_tex);
|
||||
return true;
|
||||
});
|
||||
TexShaderVert verts[] =
|
||||
|
@ -20,7 +20,7 @@ IconView::IconView(ViewResources& res, View& parentView, Icon& icon)
|
|||
{{1, 1, 0}, icon.m_uvCoords[2]},
|
||||
{{1, 0, 0}, icon.m_uvCoords[3]},
|
||||
};
|
||||
m_vertexBinding.load(verts, sizeof(verts));
|
||||
m_vertexBinding.load<decltype(verts)>(verts);
|
||||
setBackground(zeus::CColor::skBlue);
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ Menu::Menu(ViewResources& res, View& parentView, IMenuNode* rootNode)
|
|||
commitResources(res, [&](boo::IGraphicsDataFactory::Context& ctx) -> bool
|
||||
{
|
||||
buildResources(ctx, res);
|
||||
m_vertsBinding.initSolid(ctx, res, 8, m_viewVertBlockBuf);
|
||||
m_vertsBinding.init(ctx, res, 8, *m_viewVertBlockBuf);
|
||||
return true;
|
||||
});
|
||||
m_headText.reset(new TextView(res, *this, res.m_mainFont));
|
||||
|
@ -32,7 +32,7 @@ void Menu::reset(IMenuNode* rootNode)
|
|||
|
||||
for (int i=0 ; i<8 ; ++i)
|
||||
m_verts[i].m_color = res.themeData().tooltipBackground();
|
||||
m_vertsBinding.load(m_verts, sizeof(m_verts));
|
||||
m_vertsBinding.load<decltype(m_verts)>(m_verts);
|
||||
|
||||
m_subMenu.reset();
|
||||
|
||||
|
@ -75,7 +75,7 @@ Menu::Menu(ViewResources& res, View& parentView, IMenuNode* rootNode, IMenuNode*
|
|||
commitResources(res, [&](boo::IGraphicsDataFactory::Context& ctx) -> bool
|
||||
{
|
||||
buildResources(ctx, res);
|
||||
m_vertsBinding.initSolid(ctx, res, 8, m_viewVertBlockBuf);
|
||||
m_vertsBinding.init(ctx, res, 8, *m_viewVertBlockBuf);
|
||||
return true;
|
||||
});
|
||||
m_headText.reset(new TextView(res, *this, res.m_mainFont));
|
||||
|
@ -90,7 +90,7 @@ Menu::ContentView::ContentView(ViewResources& res, Menu& menu)
|
|||
commitResources(res, [&](boo::IGraphicsDataFactory::Context& ctx) -> bool
|
||||
{
|
||||
buildResources(ctx, res);
|
||||
m_hlVertsBinding.initSolid(ctx, res, 4, m_viewVertBlockBuf);
|
||||
m_hlVertsBinding.init(ctx, res, 4, *m_viewVertBlockBuf);
|
||||
return true;
|
||||
});
|
||||
|
||||
|
@ -124,7 +124,7 @@ void Menu::setVerts(int width, int height, float pf)
|
|||
m_verts[6].m_pos.assign(width, height, 0);
|
||||
m_verts[7].m_pos.assign(width, height-m_cTop+pf, 0);
|
||||
|
||||
m_vertsBinding.load(m_verts, sizeof(m_verts));
|
||||
m_vertsBinding.load<decltype(m_verts)>(m_verts);
|
||||
}
|
||||
|
||||
void Menu::ContentView::setHighlightedItem(size_t idx)
|
||||
|
@ -152,7 +152,7 @@ void Menu::ContentView::setHighlightedItem(size_t idx)
|
|||
m_hlVerts[2].m_pos.assign(itemRect.size[0], y+itemRect.size[1], 0);
|
||||
m_hlVerts[3].m_pos.assign(itemRect.size[0], y, 0);
|
||||
|
||||
m_hlVertsBinding.load(m_hlVerts, sizeof(m_hlVerts));
|
||||
m_hlVertsBinding.load<decltype(m_hlVerts)>(m_hlVerts);
|
||||
}
|
||||
|
||||
void Menu::mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod)
|
||||
|
|
|
@ -295,8 +295,8 @@ ModalWindow::ModalWindow(ViewResources& res, View& parentView,
|
|||
m_windowGfxData = res.m_factory->commitTransaction([&](boo::IGraphicsDataFactory::Context& ctx) -> bool
|
||||
{
|
||||
buildResources(ctx, res);
|
||||
m_viewBlockBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(ViewBlock), 1);
|
||||
m_vertsBinding.initSolid(ctx, res, 38, m_viewBlockBuf);
|
||||
m_viewBlockBuf.emplace(res.m_viewRes.m_bufPool.allocateBlock(res.m_factory));
|
||||
m_vertsBinding.init(ctx, res, 38, *m_viewBlockBuf);
|
||||
return true;
|
||||
});
|
||||
|
||||
|
@ -317,7 +317,7 @@ ModalWindow::ModalWindow(ViewResources& res, View& parentView,
|
|||
setLineColors(0.0);
|
||||
setFillColors(0.0);
|
||||
|
||||
m_vertsBinding.load(&m_verts, sizeof(m_verts));
|
||||
_loadVerts();
|
||||
}
|
||||
|
||||
static float CubicEase(float t)
|
||||
|
@ -372,7 +372,7 @@ void ModalWindow::think()
|
|||
if (doneCount == 3)
|
||||
m_phase = Phase::Showing;
|
||||
if (loadVerts)
|
||||
m_vertsBinding.load(&m_verts, sizeof(m_verts));
|
||||
_loadVerts();
|
||||
++m_frame;
|
||||
break;
|
||||
}
|
||||
|
@ -407,7 +407,7 @@ void ModalWindow::think()
|
|||
tt = zeus::clamp(0.f, tt, 1.f);
|
||||
updateContentOpacity(tt);
|
||||
}
|
||||
m_vertsBinding.load(&m_verts, sizeof(m_verts));
|
||||
_loadVerts();
|
||||
++m_frame;
|
||||
break;
|
||||
}
|
||||
|
@ -427,7 +427,7 @@ bool ModalWindow::skipBuildInAnimation()
|
|||
setLineVerts(m_width, m_height, pf, 1.0);
|
||||
setLineColors(2.0);
|
||||
setFillColors(2.0);
|
||||
m_vertsBinding.load(&m_verts, sizeof(m_verts));
|
||||
_loadVerts();
|
||||
m_phase = Phase::ResWait;
|
||||
return true;
|
||||
}
|
||||
|
@ -453,11 +453,11 @@ void ModalWindow::resized(const boo::SWindowRect& root, const boo::SWindowRect&
|
|||
centerRect.location[1] = root.size[1] / 2 - m_height / 2.0;
|
||||
View::resized(root, centerRect);
|
||||
m_viewBlock.setViewRect(root, centerRect);
|
||||
m_viewBlockBuf->load(&m_viewBlock, sizeof(m_viewBlock));
|
||||
m_viewBlockBuf->access() = m_viewBlock;
|
||||
|
||||
setLineVerts(m_width, m_height, pf, m_lineTime);
|
||||
setFillVerts(m_width, m_height, pf);
|
||||
m_vertsBinding.load(&m_verts, sizeof(m_verts));
|
||||
_loadVerts();
|
||||
|
||||
boo::SWindowRect cornerRect = centerRect;
|
||||
cornerRect.size[0] = cornerRect.size[1] = 8 * pf;
|
||||
|
|
|
@ -26,8 +26,9 @@ RootView::SplitMenuSystem::SplitMenuSystem(RootView& rv, boo::IGraphicsDataFacto
|
|||
: m_rv(rv), m_text(rv.m_viewMan.translateOr("boundary_action", "Boundary Action")),
|
||||
m_splitActionNode(*this), m_joinActionNode(*this)
|
||||
{
|
||||
m_viewVertBlockBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(View::ViewBlock), 1);
|
||||
m_vertsBinding.initSolid(ctx, *rv.m_viewRes, 32, m_viewVertBlockBuf);
|
||||
ViewResources& res = *rv.m_viewRes;
|
||||
m_viewVertBlockBuf.emplace(res.m_viewRes.m_bufPool.allocateBlock(res.m_factory));
|
||||
m_vertsBinding.init(ctx, res, 32, *m_viewVertBlockBuf);
|
||||
|
||||
zeus::CColor col = {0.0,0.0,0.0,0.5};
|
||||
for (int i=0 ; i<32 ; ++i)
|
||||
|
@ -71,7 +72,7 @@ RootView::SplitMenuSystem::SplitMenuSystem(RootView& rv, boo::IGraphicsDataFacto
|
|||
m_verts[30].m_pos.assign(1.0, 1.0, 0);
|
||||
m_verts[31].m_pos.assign(1.0, -1.0, 0);
|
||||
|
||||
m_vertsBinding.load(m_verts, sizeof(m_verts));
|
||||
m_vertsBinding.load<decltype(m_verts)>(m_verts);
|
||||
}
|
||||
|
||||
RootView::SplitMenuSystem::SplitActionNode::SplitActionNode(SplitMenuSystem& smn)
|
||||
|
@ -105,7 +106,7 @@ void RootView::SplitMenuSystem::setArrowVerts(const boo::SWindowRect& rect, Spli
|
|||
m_viewBlock.m_mv[3][1] = 2.0f * (rect.location[1] + (dir == SplitView::ArrowDir::Down ? rect.size[1] : 0)) /
|
||||
float(root.size[1]) - 1.0f;
|
||||
}
|
||||
m_viewVertBlockBuf->load(&m_viewBlock, sizeof(m_viewBlock));
|
||||
m_viewVertBlockBuf->access() = m_viewBlock;
|
||||
}
|
||||
|
||||
void RootView::SplitMenuSystem::setLineVerts(const boo::SWindowRect& rect, float split, SplitView::Axis axis)
|
||||
|
@ -129,7 +130,7 @@ void RootView::SplitMenuSystem::setLineVerts(const boo::SWindowRect& rect, float
|
|||
m_viewBlock.m_mv[3][0] = (rect.location[0] + split * rect.size[0]) * m_viewBlock.m_mv[0][0] - 1.0f;
|
||||
m_viewBlock.m_mv[3][1] = 2.0f * (rect.location[1] + rect.size[1] / 2.0f) / float(root.size[1]) - 1.0f;
|
||||
}
|
||||
m_viewVertBlockBuf->load(&m_viewBlock, sizeof(m_viewBlock));
|
||||
m_viewVertBlockBuf->access() = m_viewBlock;
|
||||
}
|
||||
|
||||
void RootView::destroyed()
|
||||
|
@ -621,6 +622,7 @@ void RootView::draw(boo::IGraphicsCommandQueue* gfxQ)
|
|||
m_resizeRTDirty = false;
|
||||
gfxQ->schedulePostFrameHandler([&](){m_events.m_resizeCv.notify_one();});
|
||||
}
|
||||
m_viewRes->updateBuffers();
|
||||
gfxQ->setRenderTarget(m_renderTex);
|
||||
gfxQ->setViewport(m_rootRect);
|
||||
gfxQ->setScissor(m_rootRect);
|
||||
|
|
|
@ -13,7 +13,7 @@ ScrollView::ScrollView(ViewResources& res, View& parentView, Style style)
|
|||
commitResources(res, [&](boo::IGraphicsDataFactory::Context& ctx) -> bool
|
||||
{
|
||||
buildResources(ctx, res);
|
||||
m_vertsBinding.initSolid(ctx, res, 4, m_viewVertBlockBuf);
|
||||
m_vertsBinding.init(ctx, res, 4, *m_viewVertBlockBuf);
|
||||
return true;
|
||||
});
|
||||
|
||||
|
@ -277,7 +277,7 @@ void ScrollView::resized(const boo::SWindowRect& root, const boo::SWindowRect& s
|
|||
const zeus::CColor& color = rootView().themeData().scrollIndicator();
|
||||
for (int i=0 ; i<4 ; ++i)
|
||||
m_verts[i].m_color = color;
|
||||
m_vertsBinding.load(m_verts, sizeof(m_verts));
|
||||
m_vertsBinding.load<decltype(m_verts)>(m_verts);
|
||||
}
|
||||
}
|
||||
else if (m_style == Style::SideButtons && m_drawSideButtons)
|
||||
|
|
|
@ -40,7 +40,7 @@ Space::CornerView::CornerView(ViewResources& res, Space& space, const zeus::CCol
|
|||
commitResources(res, [&](boo::IGraphicsDataFactory::Context& ctx) -> bool
|
||||
{
|
||||
buildResources(ctx, res);
|
||||
m_vertexBinding.initSolid(ctx, res, 34, m_viewVertBlockBuf);
|
||||
m_vertexBinding.init(ctx, res, 34, *m_viewVertBlockBuf);
|
||||
return true;
|
||||
});
|
||||
float pf = res.pixelFactor();
|
||||
|
@ -113,7 +113,7 @@ Space::CornerView::CornerView(ViewResources& res, Space& space, const zeus::CCol
|
|||
verts[33].m_pos.assign((TRIANGLE_DIM5 + 1) * pf, 0, 0);
|
||||
verts[33].m_color = edgeColor2;
|
||||
|
||||
m_vertexBinding.load(verts, sizeof(verts));
|
||||
m_vertexBinding.load<decltype(verts)>(verts);
|
||||
}
|
||||
|
||||
View* Space::setContentView(View* view)
|
||||
|
|
|
@ -28,8 +28,8 @@ SplitView::SplitView(ViewResources& res, View& parentView, ISplitSpaceController
|
|||
commitResources(res, [&](boo::IGraphicsDataFactory::Context& ctx) -> bool
|
||||
{
|
||||
buildResources(ctx, res);
|
||||
m_splitBlockBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(ViewBlock), 1);
|
||||
m_splitVertsBinding.initTex(ctx, res, 4, m_splitBlockBuf, res.m_splitRes.m_shadingTex);
|
||||
m_splitBlockBuf.emplace(res.m_viewRes.m_bufPool.allocateBlock(res.m_factory));
|
||||
m_splitVertsBinding.init(ctx, res, 4, *m_splitBlockBuf, res.m_splitRes.m_shadingTex);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
@ -476,8 +476,8 @@ void SplitView::resized(const boo::SWindowRect& root, const boo::SWindowRect& su
|
|||
m_splitBlock.setViewRect(root, ssub);
|
||||
setVerticalVerts(ssub.size[1]);
|
||||
}
|
||||
m_splitBlockBuf->load(&m_splitBlock, sizeof(ViewBlock));
|
||||
m_splitVertsBinding.load(m_splitVerts, sizeof(m_splitVerts));
|
||||
m_splitBlockBuf->access() = m_splitBlock;
|
||||
m_splitVertsBinding.load<decltype(m_splitVerts)>(m_splitVerts);
|
||||
}
|
||||
|
||||
void SplitView::draw(boo::IGraphicsCommandQueue* gfxQ)
|
||||
|
@ -489,7 +489,6 @@ void SplitView::draw(boo::IGraphicsCommandQueue* gfxQ)
|
|||
m_views[1].m_view->draw(gfxQ);
|
||||
gfxQ->setShaderDataBinding(m_splitVertsBinding);
|
||||
gfxQ->draw(0, 4);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ Table::Table(ViewResources& res, View& parentView, ITableDataBinding* data,
|
|||
commitResources(res, [&](boo::IGraphicsDataFactory::Context& ctx) -> bool
|
||||
{
|
||||
buildResources(ctx, res);
|
||||
m_vertsBinding.initSolid(ctx, res, maxColumns * 6, m_viewVertBlockBuf);
|
||||
m_vertsBinding.init(ctx, res, maxColumns * 6, *m_viewVertBlockBuf);
|
||||
return true;
|
||||
});
|
||||
m_scroll.m_view->setContentView(&m_rowsView);
|
||||
|
@ -36,7 +36,7 @@ Table::RowsView::RowsView(Table& t, ViewResources& res)
|
|||
commitResources(res, [&](boo::IGraphicsDataFactory::Context& ctx) -> bool
|
||||
{
|
||||
buildResources(ctx, res);
|
||||
m_vertsBinding.initSolid(ctx, res, SPECTER_TABLE_MAX_ROWS * t.m_maxColumns * 6, m_viewVertBlockBuf);
|
||||
m_vertsBinding.init(ctx, res, SPECTER_TABLE_MAX_ROWS * t.m_maxColumns * 6, *m_viewVertBlockBuf);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
@ -120,7 +120,7 @@ void Table::_setHeaderVerts(const boo::SWindowRect& sub)
|
|||
}
|
||||
|
||||
if (c)
|
||||
m_vertsBinding.load(m_hVerts.get(), sizeof(SolidShaderVert) * 6 * c);
|
||||
m_vertsBinding.load(m_hVerts.get(), 6 * c);
|
||||
|
||||
m_headerNeedsUpdate = false;
|
||||
}
|
||||
|
@ -178,7 +178,7 @@ void Table::RowsView::_setRowVerts(const boo::SWindowRect& sub, const boo::SWind
|
|||
m_visibleStart = std::max(0, startIdx);
|
||||
m_visibleRows = r;
|
||||
if (r * c)
|
||||
m_vertsBinding.load(m_verts.get(), sizeof(SolidShaderVert) * 6 * r * c);
|
||||
m_vertsBinding.load(m_verts.get(), 6 * r * c);
|
||||
}
|
||||
|
||||
void Table::cycleSortColumn(size_t c)
|
||||
|
|
|
@ -11,14 +11,14 @@ TextField::TextField(ViewResources& res, View& parentView, IStringBinding* strBi
|
|||
commitResources(res, [&](boo::IGraphicsDataFactory::Context& ctx) -> bool
|
||||
{
|
||||
buildResources(ctx, res);
|
||||
m_vertsBinding.initSolid(ctx, res, 41, m_viewVertBlockBuf);
|
||||
m_vertsBinding.init(ctx, res, 41, *m_viewVertBlockBuf);
|
||||
return true;
|
||||
});
|
||||
|
||||
for (int i=28 ; i<32 ; ++i)
|
||||
m_verts[i].m_color = res.themeData().textfieldSelection();
|
||||
setInactive();
|
||||
m_vertsBinding.load(m_verts, sizeof(m_verts));
|
||||
m_vertsBinding.load<decltype(m_verts)>(m_verts);
|
||||
|
||||
m_text.reset(new TextView(res, *this, res.m_mainFont, TextView::Alignment::Left, 1024));
|
||||
if (strBind)
|
||||
|
@ -90,7 +90,7 @@ void TextField::_setMarkedText()
|
|||
size_t defLen = UTF8Iterator(m_deferredMarkStr.cbegin()).countTo(m_deferredMarkStr.cend());
|
||||
for (auto it=glyphs.begin()+repPoint ; it<glyphs.begin()+repPoint+defLen ; ++it)
|
||||
it->m_color = rootView().themeData().fieldMarkedText();
|
||||
m_text->updateGlyphs();
|
||||
m_text->invalidateGlyphs();
|
||||
|
||||
m_hasMarkSet = false;
|
||||
|
||||
|
@ -131,7 +131,7 @@ void TextField::setInactive()
|
|||
for (int i=5 ; i<28 ; ++i)
|
||||
m_verts[i].m_color = theme.textfield2Inactive();
|
||||
}
|
||||
m_vertsBinding.load(m_verts, sizeof(m_verts));
|
||||
m_vertsBinding.load<decltype(m_verts)>(m_verts);
|
||||
m_bgState = BGState::Inactive;
|
||||
}
|
||||
|
||||
|
@ -158,7 +158,7 @@ void TextField::setHover()
|
|||
for (int i=5 ; i<28 ; ++i)
|
||||
m_verts[i].m_color = theme.textfield2Inactive();
|
||||
}
|
||||
m_vertsBinding.load(m_verts, sizeof(m_verts));
|
||||
m_vertsBinding.load<decltype(m_verts)>(m_verts);
|
||||
m_bgState = BGState::Hover;
|
||||
}
|
||||
|
||||
|
@ -185,7 +185,7 @@ void TextField::setDisabled()
|
|||
for (int i=5 ; i<28 ; ++i)
|
||||
m_verts[i].m_color = theme.textfield2Disabled();
|
||||
}
|
||||
m_vertsBinding.load(m_verts, sizeof(m_verts));
|
||||
m_vertsBinding.load<decltype(m_verts)>(m_verts);
|
||||
m_bgState = BGState::Disabled;
|
||||
}
|
||||
|
||||
|
@ -605,7 +605,7 @@ void TextField::think()
|
|||
}
|
||||
for (size_t i=32 ; i<41 ; ++i)
|
||||
m_verts[i].m_color = errBg;
|
||||
m_vertsBinding.load(m_verts, sizeof(m_verts));
|
||||
m_vertsBinding.load<decltype(m_verts)>(m_verts);
|
||||
|
||||
m_errText->setMultiplyColor(errMult);
|
||||
}
|
||||
|
@ -648,7 +648,7 @@ void TextField::_reallySetCursorPos(size_t pos)
|
|||
m_verts[30].m_color = selColor;
|
||||
m_verts[31].m_pos.assign(offset2, 4 * pf, 0);
|
||||
m_verts[31].m_color = selColor;
|
||||
m_vertsBinding.load(m_verts, sizeof(m_verts));
|
||||
m_vertsBinding.load<decltype(m_verts)>(m_verts);
|
||||
|
||||
int focusRect[2] = {subRect().location[0] + offset1, subRect().location[1]};
|
||||
rootView().window()->claimKeyboardFocus(focusRect);
|
||||
|
@ -723,13 +723,13 @@ void TextField::_reallySetSelectionRange(size_t start, size_t len)
|
|||
else
|
||||
glyphs[i].m_color = deselColor;
|
||||
}
|
||||
m_text->updateGlyphs();
|
||||
m_text->invalidateGlyphs();
|
||||
|
||||
m_verts[28].m_pos.assign(offset1, 18 * pf, 0);
|
||||
m_verts[29].m_pos.assign(offset1, 4 * pf, 0);
|
||||
m_verts[30].m_pos.assign(offset2, 18 * pf, 0);
|
||||
m_verts[31].m_pos.assign(offset2, 4 * pf, 0);
|
||||
m_vertsBinding.load(m_verts, sizeof(m_verts));
|
||||
m_vertsBinding.load<decltype(m_verts)>(m_verts);
|
||||
|
||||
int focusRect[2] = {subRect().location[0] + offset1, subRect().location[1]};
|
||||
rootView().window()->claimKeyboardFocus(focusRect);
|
||||
|
@ -754,7 +754,7 @@ void TextField::_reallySetMarkRange(size_t start, size_t len)
|
|||
m_verts[30].m_color = selColor;
|
||||
m_verts[31].m_pos.assign(offset2, 4 * pf, 0);
|
||||
m_verts[31].m_color = selColor;
|
||||
m_vertsBinding.load(m_verts, sizeof(m_verts));
|
||||
m_vertsBinding.load<decltype(m_verts)>(m_verts);
|
||||
|
||||
int focusRect[2] = {subRect().location[0] + offset1, subRect().location[1]};
|
||||
rootView().window()->claimKeyboardFocus(focusRect);
|
||||
|
@ -803,7 +803,7 @@ void TextField::_clearSelectionRange()
|
|||
std::vector<TextView::RenderGlyph>& glyphs = m_text->accessGlyphs();
|
||||
for (size_t i=0 ; i<glyphs.size() ; ++i)
|
||||
glyphs[i].m_color = deselColor;
|
||||
m_text->updateGlyphs();
|
||||
m_text->invalidateGlyphs();
|
||||
|
||||
m_hasSelectionClear = false;
|
||||
}
|
||||
|
@ -884,7 +884,7 @@ void TextField::resized(const boo::SWindowRect& root, const boo::SWindowRect& su
|
|||
m_verts[i].m_color = zeus::CColor::skClear;
|
||||
}
|
||||
|
||||
m_vertsBinding.load(m_verts, sizeof(m_verts));
|
||||
m_vertsBinding.load<decltype(m_verts)>(m_verts);
|
||||
|
||||
m_nomWidth = width;
|
||||
m_nomHeight = height;
|
||||
|
|
|
@ -304,13 +304,16 @@ TextView::TextView(ViewResources& res,
|
|||
m_fontAtlas(font),
|
||||
m_align(align)
|
||||
{
|
||||
if (VertexBufferPool<RenderGlyph>::bucketCapacity() < capacity)
|
||||
Log.report(logvisor::Fatal, "bucket overflow [%" PRISize "/%" PRISize "]",
|
||||
capacity, VertexBufferPool<RenderGlyph>::bucketCapacity());
|
||||
|
||||
m_glyphs.reserve(capacity);
|
||||
commitResources(res, [&](boo::IGraphicsDataFactory::Context& ctx) -> bool
|
||||
{
|
||||
buildResources(ctx, res);
|
||||
|
||||
m_glyphBuf =
|
||||
ctx.newDynamicBuffer(boo::BufferUse::Vertex, sizeof(RenderGlyph), capacity);
|
||||
m_glyphBuf.emplace(res.m_textRes.m_glyphPool.allocateBlock(res.m_factory, capacity));
|
||||
|
||||
boo::IShaderPipeline* shader;
|
||||
if (font.subpixel())
|
||||
|
@ -318,38 +321,43 @@ TextView::TextView(ViewResources& res,
|
|||
else
|
||||
shader = res.m_textRes.m_regular;
|
||||
|
||||
auto vBufInfo = m_glyphBuf->getBufferInfo();
|
||||
auto uBufInfo = m_viewVertBlockBuf->getBufferInfo();
|
||||
boo::IGraphicsBuffer* uBufs[] = {uBufInfo.first};
|
||||
size_t uBufOffs[] = {uBufInfo.second};
|
||||
size_t uBufSizes[] = {sizeof(ViewBlock)};
|
||||
boo::ITexture* texs[] = {m_fontAtlas.texture()};
|
||||
|
||||
if (!res.m_textRes.m_vtxFmt)
|
||||
{
|
||||
boo::VertexElementDescriptor vdescs[] =
|
||||
{
|
||||
{m_glyphBuf, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 0},
|
||||
{m_glyphBuf, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 1},
|
||||
{m_glyphBuf, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 2},
|
||||
{m_glyphBuf, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 3},
|
||||
{m_glyphBuf, nullptr, boo::VertexSemantic::ModelView | boo::VertexSemantic::Instanced, 0},
|
||||
{m_glyphBuf, nullptr, boo::VertexSemantic::ModelView | boo::VertexSemantic::Instanced, 1},
|
||||
{m_glyphBuf, nullptr, boo::VertexSemantic::ModelView | boo::VertexSemantic::Instanced, 2},
|
||||
{m_glyphBuf, nullptr, boo::VertexSemantic::ModelView | boo::VertexSemantic::Instanced, 3},
|
||||
{m_glyphBuf, nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 0},
|
||||
{m_glyphBuf, nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 1},
|
||||
{m_glyphBuf, nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 2},
|
||||
{m_glyphBuf, nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 3},
|
||||
{m_glyphBuf, nullptr, boo::VertexSemantic::Color | boo::VertexSemantic::Instanced}
|
||||
{vBufInfo.first, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 0},
|
||||
{vBufInfo.first, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 1},
|
||||
{vBufInfo.first, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 2},
|
||||
{vBufInfo.first, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 3},
|
||||
{vBufInfo.first, nullptr, boo::VertexSemantic::ModelView | boo::VertexSemantic::Instanced, 0},
|
||||
{vBufInfo.first, nullptr, boo::VertexSemantic::ModelView | boo::VertexSemantic::Instanced, 1},
|
||||
{vBufInfo.first, nullptr, boo::VertexSemantic::ModelView | boo::VertexSemantic::Instanced, 2},
|
||||
{vBufInfo.first, nullptr, boo::VertexSemantic::ModelView | boo::VertexSemantic::Instanced, 3},
|
||||
{vBufInfo.first, nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 0},
|
||||
{vBufInfo.first, nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 1},
|
||||
{vBufInfo.first, nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 2},
|
||||
{vBufInfo.first, nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 3},
|
||||
{vBufInfo.first, nullptr, boo::VertexSemantic::Color | boo::VertexSemantic::Instanced}
|
||||
};
|
||||
m_vtxFmt = ctx.newVertexFormat(13, vdescs);
|
||||
boo::ITexture* texs[] = {m_fontAtlas.texture()};
|
||||
m_vtxFmt = ctx.newVertexFormat(13, vdescs, 0, vBufInfo.second);
|
||||
m_shaderBinding = ctx.newShaderDataBinding(shader, m_vtxFmt,
|
||||
nullptr, m_glyphBuf, nullptr, 1,
|
||||
(boo::IGraphicsBuffer**)&m_viewVertBlockBuf,
|
||||
nullptr, 1, texs);
|
||||
nullptr, vBufInfo.first, nullptr, 1,
|
||||
uBufs, nullptr, uBufOffs, uBufSizes,
|
||||
1, texs, 0, vBufInfo.second);
|
||||
}
|
||||
else
|
||||
{
|
||||
boo::ITexture* texs[] = {m_fontAtlas.texture()};
|
||||
m_shaderBinding = ctx.newShaderDataBinding(shader, res.m_textRes.m_vtxFmt,
|
||||
nullptr, m_glyphBuf, nullptr, 1,
|
||||
(boo::IGraphicsBuffer**)&m_viewVertBlockBuf,
|
||||
nullptr, 1, texs);
|
||||
nullptr, vBufInfo.first, nullptr, 1,
|
||||
uBufs, nullptr, uBufOffs, uBufSizes,
|
||||
1, texs, 0, vBufInfo.second);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
@ -453,7 +461,7 @@ void TextView::typesetGlyphs(const std::string& str, const zeus::CColor& default
|
|||
}
|
||||
|
||||
m_width = adv;
|
||||
m_valid = false;
|
||||
invalidateGlyphs();
|
||||
updateSize();
|
||||
}
|
||||
|
||||
|
@ -510,7 +518,7 @@ void TextView::typesetGlyphs(const std::wstring& str, const zeus::CColor& defaul
|
|||
}
|
||||
|
||||
m_width = adv;
|
||||
m_valid = false;
|
||||
invalidateGlyphs();
|
||||
updateSize();
|
||||
}
|
||||
|
||||
|
@ -518,11 +526,21 @@ void TextView::colorGlyphs(const zeus::CColor& newColor)
|
|||
{
|
||||
for (RenderGlyph& glyph : m_glyphs)
|
||||
glyph.m_color = newColor;
|
||||
m_valid = false;
|
||||
invalidateGlyphs();
|
||||
}
|
||||
|
||||
void TextView::colorGlyphsTypeOn(const zeus::CColor& newColor, float startInterval, float fadeTime)
|
||||
{
|
||||
}
|
||||
|
||||
void TextView::invalidateGlyphs()
|
||||
{
|
||||
RenderGlyph* out = m_glyphBuf->access();
|
||||
size_t i = 0;
|
||||
for (RenderGlyph& glyph : m_glyphs)
|
||||
out[i++] = glyph;
|
||||
}
|
||||
|
||||
void TextView::think()
|
||||
{
|
||||
}
|
||||
|
@ -537,11 +555,6 @@ void TextView::draw(boo::IGraphicsCommandQueue* gfxQ)
|
|||
View::draw(gfxQ);
|
||||
if (m_glyphs.size())
|
||||
{
|
||||
if (!m_valid)
|
||||
{
|
||||
m_glyphBuf->load(m_glyphs.data(), m_glyphs.size() * sizeof(RenderGlyph));
|
||||
m_valid = true;
|
||||
}
|
||||
gfxQ->setShaderDataBinding(m_shaderBinding);
|
||||
gfxQ->drawInstances(0, 4, m_glyphs.size());
|
||||
}
|
||||
|
|
|
@ -33,8 +33,8 @@ Toolbar::Toolbar(ViewResources& res, View& parentView, Position tbPos, unsigned
|
|||
commitResources(res, [&](boo::IGraphicsDataFactory::Context& ctx) -> bool
|
||||
{
|
||||
buildResources(ctx, res);
|
||||
m_tbBlockBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(ViewBlock), 1);
|
||||
m_vertsBinding.initTex(ctx, res, 10, m_tbBlockBuf, res.m_toolbarRes.m_shadingTex);
|
||||
m_tbBlockBuf.emplace(res.m_viewRes.m_bufPool.allocateBlock(res.m_factory));
|
||||
m_vertsBinding.init(ctx, res, 10, *m_tbBlockBuf, res.m_toolbarRes.m_shadingTex);
|
||||
return true;
|
||||
});
|
||||
setBackground(res.themeData().toolbarBackground());
|
||||
|
@ -138,9 +138,9 @@ void Toolbar::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub)
|
|||
{
|
||||
View::resized(root, sub);
|
||||
setHorizontalVerts(sub.size[0]);
|
||||
m_vertsBinding.load(m_tbVerts, sizeof(m_tbVerts));
|
||||
m_vertsBinding.load<decltype(m_tbVerts)>(m_tbVerts);
|
||||
m_tbBlock.setViewRect(root, sub);
|
||||
m_tbBlockBuf->load(&m_tbBlock, sizeof(ViewBlock));
|
||||
m_tbBlockBuf->access() = m_tbBlock;
|
||||
|
||||
float gaugeUnit = rootView().viewRes().pixelFactor() * SPECTER_TOOLBAR_GAUGE;
|
||||
float yOff = 0.0;
|
||||
|
|
|
@ -18,8 +18,8 @@ Tooltip::Tooltip(ViewResources& res, View& parentView, const std::string& title,
|
|||
commitResources(res, [&](boo::IGraphicsDataFactory::Context& ctx) -> bool
|
||||
{
|
||||
buildResources(ctx, res);
|
||||
m_ttBlockBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(ViewBlock), 1);
|
||||
m_vertsBinding.initSolid(ctx, res, 16, m_ttBlockBuf);
|
||||
m_ttBlockBuf.emplace(res.m_viewRes.m_bufPool.allocateBlock(res.m_factory));
|
||||
m_vertsBinding.init(ctx, res, 16, *m_ttBlockBuf);
|
||||
return true;
|
||||
});
|
||||
|
||||
|
@ -75,7 +75,7 @@ void Tooltip::setVerts(int width, int height, float pf)
|
|||
m_ttVerts[14].m_pos.assign(width-margin.first, margin.second, 0);
|
||||
m_ttVerts[15].m_pos.assign(width-margin.first, 0, 0);
|
||||
|
||||
m_vertsBinding.load(m_ttVerts, sizeof(m_ttVerts));
|
||||
m_vertsBinding.load<decltype(m_ttVerts)>(m_ttVerts);
|
||||
}
|
||||
|
||||
void Tooltip::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub)
|
||||
|
@ -84,7 +84,7 @@ void Tooltip::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub)
|
|||
float pf = rootView().viewRes().pixelFactor();
|
||||
setVerts(m_nomWidth, m_nomHeight, pf);
|
||||
m_ttBlock.setViewRect(root, sub);
|
||||
m_ttBlockBuf->load(&m_ttBlock, sizeof(ViewBlock));
|
||||
m_ttBlockBuf->access() = m_ttBlock;
|
||||
|
||||
std::pair<int,int> margin = m_cornersFilled[0]->queryGlyphDimensions(0);
|
||||
|
||||
|
|
|
@ -322,9 +322,8 @@ void View::Resources::init(boo::VulkanDataFactory::Context& ctx, const IThemeDat
|
|||
|
||||
void View::buildResources(boo::IGraphicsDataFactory::Context& ctx, ViewResources& res)
|
||||
{
|
||||
m_viewVertBlockBuf =
|
||||
ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(ViewBlock), 1);
|
||||
m_bgVertsBinding.initSolid(ctx, res, 4, m_viewVertBlockBuf);
|
||||
m_viewVertBlockBuf.emplace(res.m_viewRes.m_bufPool.allocateBlock(res.m_factory));
|
||||
m_bgVertsBinding.init(ctx, res, 4, *m_viewVertBlockBuf);
|
||||
}
|
||||
|
||||
View::View(ViewResources& res)
|
||||
|
@ -349,8 +348,8 @@ void View::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub)
|
|||
m_bgRect[2].m_pos.assign(sub.size[0], sub.size[1], 0.f);
|
||||
m_bgRect[3].m_pos.assign(sub.size[0], 0.f, 0.f);
|
||||
if (m_viewVertBlockBuf)
|
||||
m_viewVertBlockBuf->load(&m_viewVertBlock, sizeof(ViewBlock));
|
||||
m_bgVertsBinding.load(m_bgRect, sizeof(m_bgRect));
|
||||
m_viewVertBlockBuf->access() = m_viewVertBlock;
|
||||
m_bgVertsBinding.load<decltype(m_bgRect)>(m_bgRect);
|
||||
}
|
||||
|
||||
void View::resized(const ViewBlock& vb, const boo::SWindowRect& sub)
|
||||
|
@ -361,8 +360,8 @@ void View::resized(const ViewBlock& vb, const boo::SWindowRect& sub)
|
|||
m_bgRect[2].m_pos.assign(sub.size[0], sub.size[1], 0.f);
|
||||
m_bgRect[3].m_pos.assign(sub.size[0], 0.f, 0.f);
|
||||
if (m_viewVertBlockBuf)
|
||||
m_viewVertBlockBuf->load(&vb, sizeof(ViewBlock));
|
||||
m_bgVertsBinding.load(m_bgRect, sizeof(m_bgRect));
|
||||
m_viewVertBlockBuf->access() = vb;
|
||||
m_bgVertsBinding.load<decltype(m_bgRect)>(m_bgRect);
|
||||
}
|
||||
|
||||
void View::draw(boo::IGraphicsCommandQueue* gfxQ)
|
||||
|
@ -381,64 +380,76 @@ void View::commitResources(ViewResources& res, const boo::FactoryCommitFunc& com
|
|||
m_gfxData = res.m_factory->commitTransaction(commitFunc);
|
||||
}
|
||||
|
||||
void View::VertexBufferBinding::initSolid(boo::IGraphicsDataFactory::Context& ctx,
|
||||
|
||||
void View::VertexBufferBindingSolid::init(boo::IGraphicsDataFactory::Context& ctx,
|
||||
ViewResources& res, size_t count,
|
||||
boo::IGraphicsBuffer* viewBlockBuf)
|
||||
const UniformBufferPool<ViewBlock>::Token& viewBlockBuf)
|
||||
{
|
||||
m_vertsBuf = ctx.newDynamicBuffer(boo::BufferUse::Vertex, sizeof(SolidShaderVert), count);
|
||||
m_vertsBuf.emplace(res.m_viewRes.m_solidPool.allocateBlock(res.m_factory, count));
|
||||
auto vBufInfo = m_vertsBuf->getBufferInfo();
|
||||
auto uBufInfo = viewBlockBuf.getBufferInfo();
|
||||
|
||||
boo::IGraphicsBuffer* bufs[] = {uBufInfo.first};
|
||||
size_t bufOffs[] = {uBufInfo.second};
|
||||
size_t bufSizes[] = {sizeof(ViewBlock)};
|
||||
|
||||
if (!res.m_viewRes.m_solidVtxFmt)
|
||||
{
|
||||
boo::VertexElementDescriptor vdescs[] =
|
||||
{
|
||||
{m_vertsBuf, nullptr, boo::VertexSemantic::Position4},
|
||||
{m_vertsBuf, nullptr, boo::VertexSemantic::Color}
|
||||
{vBufInfo.first, nullptr, boo::VertexSemantic::Position4},
|
||||
{vBufInfo.first, nullptr, boo::VertexSemantic::Color}
|
||||
};
|
||||
m_vtxFmt = ctx.newVertexFormat(2, vdescs);
|
||||
boo::IGraphicsBuffer* bufs[] = {viewBlockBuf};
|
||||
m_vtxFmt = ctx.newVertexFormat(2, vdescs, vBufInfo.second);
|
||||
m_shaderBinding = ctx.newShaderDataBinding(res.m_viewRes.m_solidShader,
|
||||
m_vtxFmt, m_vertsBuf, nullptr,
|
||||
nullptr, 1, bufs, nullptr, 0, nullptr);
|
||||
m_vtxFmt, vBufInfo.first, nullptr,
|
||||
nullptr, 1, bufs, nullptr, bufOffs,
|
||||
bufSizes, 0, nullptr, vBufInfo.second);
|
||||
}
|
||||
else
|
||||
{
|
||||
boo::IGraphicsBuffer* bufs[] = {viewBlockBuf};
|
||||
m_shaderBinding = ctx.newShaderDataBinding(res.m_viewRes.m_solidShader,
|
||||
res.m_viewRes.m_solidVtxFmt,
|
||||
m_vertsBuf, nullptr,
|
||||
nullptr, 1, bufs, nullptr, 0, nullptr);
|
||||
vBufInfo.first, nullptr,
|
||||
nullptr, 1, bufs, nullptr, bufOffs,
|
||||
bufSizes, 0, nullptr, vBufInfo.second);
|
||||
}
|
||||
}
|
||||
|
||||
void View::VertexBufferBinding::initTex(boo::IGraphicsDataFactory::Context& ctx,
|
||||
void View::VertexBufferBindingTex::init(boo::IGraphicsDataFactory::Context& ctx,
|
||||
ViewResources& res, size_t count,
|
||||
boo::IGraphicsBuffer* viewBlockBuf,
|
||||
const UniformBufferPool<ViewBlock>::Token& viewBlockBuf,
|
||||
boo::ITexture* texture)
|
||||
{
|
||||
m_vertsBuf = ctx.newDynamicBuffer(boo::BufferUse::Vertex, sizeof(TexShaderVert), count);
|
||||
m_vertsBuf.emplace(res.m_viewRes.m_texPool.allocateBlock(res.m_factory, count));
|
||||
auto vBufInfo = m_vertsBuf->getBufferInfo();
|
||||
auto uBufInfo = viewBlockBuf.getBufferInfo();
|
||||
|
||||
boo::IGraphicsBuffer* bufs[] = {uBufInfo.first};
|
||||
size_t bufOffs[] = {uBufInfo.second};
|
||||
size_t bufSizes[] = {sizeof(ViewBlock)};
|
||||
boo::ITexture* tex[] = {texture};
|
||||
|
||||
if (!res.m_viewRes.m_texVtxFmt)
|
||||
{
|
||||
boo::VertexElementDescriptor vdescs[] =
|
||||
{
|
||||
{m_vertsBuf, nullptr, boo::VertexSemantic::Position4},
|
||||
{m_vertsBuf, nullptr, boo::VertexSemantic::UV4}
|
||||
{vBufInfo.first, nullptr, boo::VertexSemantic::Position4},
|
||||
{vBufInfo.first, nullptr, boo::VertexSemantic::UV4}
|
||||
};
|
||||
m_vtxFmt = ctx.newVertexFormat(2, vdescs);
|
||||
boo::IGraphicsBuffer* bufs[] = {viewBlockBuf};
|
||||
boo::ITexture* tex[] = {texture};
|
||||
m_vtxFmt = ctx.newVertexFormat(2, vdescs, vBufInfo.second);
|
||||
m_shaderBinding = ctx.newShaderDataBinding(res.m_viewRes.m_texShader,
|
||||
m_vtxFmt, m_vertsBuf, nullptr,
|
||||
nullptr, 1, bufs, nullptr, 1, tex);
|
||||
m_vtxFmt, vBufInfo.first, nullptr,
|
||||
nullptr, 1, bufs, nullptr, bufOffs,
|
||||
bufSizes, 1, tex, vBufInfo.second);
|
||||
}
|
||||
else
|
||||
{
|
||||
boo::IGraphicsBuffer* bufs[] = {viewBlockBuf};
|
||||
boo::ITexture* tex[] = {texture};
|
||||
m_shaderBinding = ctx.newShaderDataBinding(res.m_viewRes.m_texShader,
|
||||
res.m_viewRes.m_texVtxFmt,
|
||||
m_vertsBuf, nullptr,
|
||||
nullptr, 1, bufs, nullptr, 1, tex);
|
||||
vBufInfo.first, nullptr,
|
||||
nullptr, 1, bufs, nullptr, bufOffs,
|
||||
bufSizes, 1, tex, vBufInfo.second);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 7185e13abe85233086a94258d60d89666f7d3e4d
|
||||
Subproject commit a136d77458514201b8593824dca33289b0c9b69e
|
Loading…
Reference in New Issue