[drape] gui rendering refactoring. Complex shapes can incapsulate rendering of their parts into single ShapeRenderer

This commit is contained in:
ExMix 2015-03-18 00:30:09 +03:00 committed by r.kuznetsov
parent 6d7013a831
commit 1fa8c1e98c
11 changed files with 230 additions and 271 deletions

View file

@ -46,7 +46,7 @@ namespace
};
}
void Compass::Draw(dp::RefPointer<dp::Batcher> batcher, dp::RefPointer<dp::TextureManager> tex) const
dp::TransferPointer<ShapeRenderer> Compass::Draw(dp::RefPointer<dp::TextureManager> tex) const
{
dp::TextureManager::SymbolRegion region;
tex->GetSymbolRegion("compass-image", region);
@ -83,18 +83,15 @@ void Compass::Draw(dp::RefPointer<dp::Batcher> batcher, dp::RefPointer<dp::Textu
texDecl.m_stride = posDecl.m_stride;
provider.InitStream(0, info, dp::MakeStackRefPointer<void>(&vertexes));
batcher->InsertTriangleStrip(state, dp::MakeStackRefPointer(&provider),
dp::MovePointer<dp::OverlayHandle>(new CompassHandle(m_position.m_pixelPivot)));
}
uint16_t Compass::GetVertexCount() const
{
return 4;
}
ShapeRenderer * renderer = new ShapeRenderer();
dp::Batcher batcher(6, 4);
batcher.StartSession(renderer->GetFlushRoutine());
batcher.InsertTriangleStrip(state, dp::MakeStackRefPointer(&provider),
dp::MovePointer<dp::OverlayHandle>(new CompassHandle(m_position.m_pixelPivot)));
batcher.EndSession();
uint16_t Compass::GetIndexCount() const
{
return 6;
return dp::MovePointer(renderer);
}
}

View file

@ -8,9 +8,7 @@ namespace gui
class Compass : public Shape
{
public:
virtual void Draw(dp::RefPointer<dp::Batcher> batcher, dp::RefPointer<dp::TextureManager> tex) const;
virtual uint16_t GetVertexCount() const;
virtual uint16_t GetIndexCount() const;
virtual dp::TransferPointer<ShapeRenderer> Draw(dp::RefPointer<dp::TextureManager> tex) const override;
};
}

View file

@ -9,24 +9,22 @@ include($$ROOT_DIR/common.pri)
INCLUDEPATH *= $$ROOT_DIR/3party/expat/lib
HEADERS += \
skin.hpp \
compass.hpp \
shape.hpp \
drape_gui.hpp \
gui_text.hpp \
layer_render.hpp \
ruler.hpp \
ruler_helper.hpp \
drape_gui.hpp \
gui_text.hpp \
ruler_text.hpp \
shape.hpp \
skin.hpp \
SOURCES += \
skin.cpp \
compass.cpp \
shape.cpp \
drape_gui.cpp \
gui_text.cpp \
layer_render.cpp \
ruler.cpp \
ruler_helper.cpp \
drape_gui.cpp \
gui_text.cpp \
ruler_text.cpp \
shape.cpp \
skin.cpp \

View file

@ -1,7 +1,6 @@
#include "layer_render.hpp"
#include "compass.hpp"
#include "ruler.hpp"
#include "ruler_text.hpp"
#include "ruler_helper.hpp"
#include "../drape/batcher.hpp"
@ -25,40 +24,17 @@ void LayerCacher::Resize(int w, int h)
dp::TransferPointer<LayerRenderer> LayerCacher::Recache(dp::RefPointer<dp::TextureManager> textures)
{
LayerRenderer * renderer = new LayerRenderer();
dp::Batcher::TFlushFn flushFn = [&renderer, this](dp::GLState const & state, dp::TransferPointer<dp::RenderBucket> bucket)
{
dp::MasterPointer<dp::RenderBucket> b(bucket);
ASSERT(b->GetOverlayHandlesCount() == 1, ());
dp::TransferPointer<dp::VertexArrayBuffer> buffer = b->MoveBuffer();
dp::TransferPointer<dp::OverlayHandle> transferH = b->PopOverlayHandle();
dp::MasterPointer<dp::OverlayHandle> handle(transferH);
b.Destroy();
static_cast<Handle *>(handle.GetRaw())->SetProjection(m_skin->GetWidth(), m_skin->GetHeight());
renderer->AddShapeRenderer(new ShapeRenderer(state, buffer, handle.Move()));
};
dp::Batcher batcher;
dp::RefPointer<dp::Batcher> pBatcher = dp::MakeStackRefPointer(&batcher);
CacheShape(flushFn, pBatcher, textures, Compass(), Skin::ElementName::Compass);
CacheShape(flushFn, pBatcher, textures, Ruler(), Skin::ElementName::Ruler);
CacheShape(flushFn, pBatcher, textures, RulerText(), Skin::ElementName::Ruler);
renderer->AddShapeRenderer(CacheShape(textures, Compass(), Skin::ElementName::Compass));
renderer->AddShapeRenderer(CacheShape(textures, Ruler(), Skin::ElementName::Ruler));
return dp::MovePointer(renderer);
}
void LayerCacher::CacheShape(dp::Batcher::TFlushFn const & flushFn, dp::RefPointer<dp::Batcher> batcher,
dp::RefPointer<dp::TextureManager> mng, Shape && shape, Skin::ElementName element)
dp::TransferPointer<ShapeRenderer> LayerCacher::CacheShape(dp::RefPointer<dp::TextureManager> mng, Shape && shape, Skin::ElementName element)
{
shape.SetPosition(m_skin->ResolvePosition(element));
batcher->SetVertexBufferSize(shape.GetVertexCount());
batcher->SetIndexBufferSize(shape.GetIndexCount());
batcher->StartSession(flushFn);
shape.Draw(batcher, mng);
batcher->EndSession();
return shape.Draw(mng);
}
//////////////////////////////////////////////////////////////////////////////////////////
@ -70,7 +46,7 @@ LayerRenderer::~LayerRenderer()
void LayerRenderer::Build(dp::RefPointer<dp::GpuProgramManager> mng)
{
for_each(m_renderers.begin(), m_renderers.end(), [mng](ShapeRenderer * r)
for_each(m_renderers.begin(), m_renderers.end(), [mng](dp::MasterPointer<ShapeRenderer> r)
{
r->Build(mng);
});
@ -79,7 +55,7 @@ void LayerRenderer::Build(dp::RefPointer<dp::GpuProgramManager> mng)
void LayerRenderer::Render(dp::RefPointer<dp::GpuProgramManager> mng, ScreenBase const & screen)
{
RulerHelper::Instance().Update(screen);
for_each(m_renderers.begin(), m_renderers.end(), [&screen, mng](ShapeRenderer * r)
for_each(m_renderers.begin(), m_renderers.end(), [&screen, mng](dp::MasterPointer<ShapeRenderer> r)
{
r->Render(screen, mng);
});
@ -87,12 +63,12 @@ void LayerRenderer::Render(dp::RefPointer<dp::GpuProgramManager> mng, ScreenBase
void LayerRenderer::DestroyRenderers()
{
DeleteRange(m_renderers, DeleteFunctor());
DeleteRange(m_renderers, dp::MasterPointerDeleter());
}
void LayerRenderer::AddShapeRenderer(ShapeRenderer * shape)
void LayerRenderer::AddShapeRenderer(dp::TransferPointer<ShapeRenderer> shape)
{
m_renderers.push_back(shape);
m_renderers.emplace_back(shape);
}
}

View file

@ -32,10 +32,10 @@ private:
void DestroyRenderers();
friend class LayerCacher;
void AddShapeRenderer(ShapeRenderer * shape);
void AddShapeRenderer(dp::TransferPointer<ShapeRenderer> shape);
private:
vector<ShapeRenderer *> m_renderers;
vector<dp::MasterPointer<ShapeRenderer> > m_renderers;
};
class LayerCacher
@ -47,8 +47,7 @@ public:
dp::TransferPointer<LayerRenderer> Recache(dp::RefPointer<dp::TextureManager> textures);
private:
void CacheShape(dp::Batcher::TFlushFn const & flushFn, dp::RefPointer<dp::Batcher> batcher,
dp::RefPointer<dp::TextureManager> mng, Shape && shape, Skin::ElementName element);
dp::TransferPointer<ShapeRenderer> CacheShape(dp::RefPointer<dp::TextureManager> mng, Shape && shape, Skin::ElementName element);
private:
unique_ptr<Skin> m_skin;

View file

@ -1,6 +1,10 @@
#include "ruler.hpp"
#include "ruler_helper.hpp"
#include "gui_text.hpp"
#include "drape_gui.hpp"
#include "../drape/glsl_func.hpp"
#include "../drape/glsl_types.hpp"
#include "../drape/shader_def.hpp"
namespace gui
@ -9,6 +13,9 @@ namespace gui
namespace
{
static size_t const FontSize = 7;
static dp::Color const FontColor = dp::Color(0x4D, 0x4D, 0x4D, 0xCC);
struct RulerVertex
{
RulerVertex() = default;
@ -82,9 +89,78 @@ public:
}
};
class RulerTextHandle : public Handle
{
public:
RulerTextHandle(dp::Anchor anchor, m2::PointF const & pivot)
: Handle(anchor, pivot)
{
SetIsVisible(true);
m_textView.Reset(new MutableLabel(anchor));
}
~RulerTextHandle()
{
m_textView.Destroy();
}
virtual void Update(ScreenBase const & screen) override
{
UNUSED_VALUE(screen);
SetIsVisible(RulerHelper::Instance().IsVisible(screen));
if (!IsVisible())
return;
glsl::mat4 m = glsl::transpose(glsl::translate(glsl::mat4(), glsl::vec3(m_pivot, 0.0)));
m_uniforms.SetMatrix4x4Value("modelView", glsl::value_ptr(m));
}
virtual void GetAttributeMutation(dp::RefPointer<dp::AttributeBufferMutator> mutator, ScreenBase const & screen) const override
{
UNUSED_VALUE(screen);
RulerHelper const & helper = RulerHelper::Instance();
if (!helper.IsTextDirty())
return;
buffer_vector<MutableLabel::DynamicVertex, 128> buffer;
m_textView->SetText(buffer, helper.GetRulerText());
size_t byteCount = buffer.size() * sizeof(MutableLabel::DynamicVertex);
void * dataPointer = mutator->AllocateMutationBuffer(byteCount);
memcpy(dataPointer, buffer.data(), byteCount);
dp::OverlayHandle::TOffsetNode offsetNode = GetOffsetNode(MutableLabel::DynamicVertex::GetBindingInfo().GetID());
dp::MutateNode mutateNode;
mutateNode.m_data = dp::MakeStackRefPointer(dataPointer);
mutateNode.m_region = offsetNode.second;
mutator->AddMutation(offsetNode.first, mutateNode);
}
dp::RefPointer<MutableLabel> GetTextView()
{
return m_textView.GetRefPointer();
}
private:
dp::MasterPointer<MutableLabel> m_textView;
};
}
void Ruler::Draw(dp::RefPointer<dp::Batcher> batcher, dp::RefPointer<dp::TextureManager> tex) const
dp::TransferPointer<ShapeRenderer> Ruler::Draw(dp::RefPointer<dp::TextureManager> tex) const
{
ShapeRenderer * renderer = new ShapeRenderer;
DrawRuler(renderer, tex);
DrawText(renderer, tex);
return dp::MovePointer(renderer);
}
void Ruler::DrawRuler(ShapeRenderer * renderer, dp::RefPointer<dp::TextureManager> tex) const
{
buffer_vector<RulerVertex, 4> data;
@ -117,18 +193,49 @@ void Ruler::Draw(dp::RefPointer<dp::Batcher> batcher, dp::RefPointer<dp::Texture
dp::AttributeProvider provider(1, 4);
provider.InitStream(0, GetBindingInfo(), dp::MakeStackRefPointer<void>(data.data()));
batcher->InsertTriangleStrip(state, dp::MakeStackRefPointer(&provider),
dp::MovePointer<dp::OverlayHandle>(new RulerHandle(m_position.m_anchor)));
dp::Batcher batcher(6, 4);
batcher.StartSession(renderer->GetFlushRoutine());
batcher.InsertTriangleStrip(state, dp::MakeStackRefPointer(&provider),
dp::MovePointer<dp::OverlayHandle>(new RulerHandle(m_position.m_anchor)));
batcher.EndSession();
}
uint16_t Ruler::GetVertexCount() const
void Ruler::DrawText(ShapeRenderer * renderer, dp::RefPointer<dp::TextureManager> tex) const
{
return 4;
}
string alphabet;
size_t maxTextLength;
RulerHelper::Instance().GetTextInitInfo(alphabet, maxTextLength);
uint16_t Ruler::GetIndexCount() const
{
return 6;
uint32_t vertexCount = 4 * maxTextLength;
uint32_t indexCount = 6 * maxTextLength;
m2::PointF rulerTextPivot = m_position.m_pixelPivot + m2::PointF(0.0, RulerHelper::Instance().GetVerticalTextOffset());
dp::Anchor anchor = static_cast<dp::Anchor>((m_position.m_anchor & (dp::Right | dp::Left)) | dp::Bottom);
RulerTextHandle * handle = new RulerTextHandle(anchor, rulerTextPivot);
dp::RefPointer<MutableLabel> textView = handle->GetTextView();
dp::RefPointer<dp::Texture> maskTexture = textView->SetAlphabet(alphabet, tex);
textView->SetMaxLength(maxTextLength);
buffer_vector<MutableLabel::StaticVertex, 128> statData;
buffer_vector<MutableLabel::DynamicVertex, 128> dynData;
dp::RefPointer<dp::Texture> colorTexture = textView->Precache(statData, dp::FontDecl(FontColor, FontSize * DrapeGui::Instance().GetScaleFactor()), tex);
ASSERT_EQUAL(vertexCount, statData.size(), ());
dynData.resize(statData.size());
dp::AttributeProvider provider(2, statData.size());
provider.InitStream(0, MutableLabel::StaticVertex::GetBindingInfo(), dp::MakeStackRefPointer<void>(statData.data()));
provider.InitStream(1, MutableLabel::DynamicVertex::GetBindingInfo(), dp::MakeStackRefPointer<void>(dynData.data()));
dp::GLState state(gpu::TEXT_PROGRAM, dp::GLState::UserMarkLayer);
state.SetColorTexture(colorTexture);
state.SetMaskTexture(maskTexture);
dp::Batcher batcher(indexCount, vertexCount);
batcher.StartSession(renderer->GetFlushRoutine());
batcher.InsertListOfStrip(state, dp::MakeStackRefPointer(&provider), dp::MovePointer<dp::OverlayHandle>(handle), 4);
batcher.EndSession();
}
}

View file

@ -8,9 +8,11 @@ namespace gui
class Ruler : public Shape
{
public:
virtual void Draw(dp::RefPointer<dp::Batcher> batcher, dp::RefPointer<dp::TextureManager> tex) const;
virtual uint16_t GetVertexCount() const;
virtual uint16_t GetIndexCount() const;
virtual dp::TransferPointer<ShapeRenderer> Draw(dp::RefPointer<dp::TextureManager> tex) const override;
private:
void DrawRuler(ShapeRenderer * renderer, dp::RefPointer<dp::TextureManager> tex) const;
void DrawText(ShapeRenderer * renderer, dp::RefPointer<dp::TextureManager> tex) const;
};
}

View file

@ -1,120 +0,0 @@
#include "ruler_text.hpp"
#include "ruler_helper.hpp"
#include "drape_gui.hpp"
#include "../drape/glsl_func.hpp"
#include "../drape/attribute_provider.hpp"
#include "../drape/shader_def.hpp"
namespace gui
{
static size_t const FontSize = 7;
static dp::Color const FontColor = dp::Color(0x4D, 0x4D, 0x4D, 0xCC);
namespace
{
class RulerTextHandle : public Handle
{
public:
RulerTextHandle(dp::Anchor anchor, m2::PointF const & pivot)
: Handle(anchor, pivot)
{
SetIsVisible(true);
m_textView.Reset(new MutableLabel(anchor));
}
~RulerTextHandle()
{
m_textView.Destroy();
}
virtual void Update(ScreenBase const & screen) override
{
UNUSED_VALUE(screen);
SetIsVisible(RulerHelper::Instance().IsVisible(screen));
if (!IsVisible())
return;
glsl::mat4 m = glsl::transpose(glsl::translate(glsl::mat4(), glsl::vec3(m_pivot, 0.0)));
m_uniforms.SetMatrix4x4Value("modelView", glsl::value_ptr(m));
}
virtual void GetAttributeMutation(dp::RefPointer<dp::AttributeBufferMutator> mutator, ScreenBase const & screen) const override
{
UNUSED_VALUE(screen);
RulerHelper const & helper = RulerHelper::Instance();
if (!helper.IsTextDirty())
return;
buffer_vector<MutableLabel::DynamicVertex, 128> buffer;
m_textView->SetText(buffer, helper.GetRulerText());
size_t byteCount = buffer.size() * sizeof(MutableLabel::DynamicVertex);
void * dataPointer = mutator->AllocateMutationBuffer(byteCount);
memcpy(dataPointer, buffer.data(), byteCount);
dp::OverlayHandle::TOffsetNode offsetNode = GetOffsetNode(MutableLabel::DynamicVertex::GetBindingInfo().GetID());
dp::MutateNode mutateNode;
mutateNode.m_data = dp::MakeStackRefPointer(dataPointer);
mutateNode.m_region = offsetNode.second;
mutator->AddMutation(offsetNode.first, mutateNode);
}
dp::RefPointer<MutableLabel> GetTextView()
{
return m_textView.GetRefPointer();
}
private:
dp::MasterPointer<MutableLabel> m_textView;
};
}
RulerText::RulerText()
{
RulerHelper::Instance().GetTextInitInfo(m_alphabet, m_maxLength);
}
void RulerText::Draw(dp::RefPointer<dp::Batcher> batcher, dp::RefPointer<dp::TextureManager> tex) const
{
m2::PointF rulerTextPivot = m_position.m_pixelPivot + m2::PointF(0.0, RulerHelper::Instance().GetVerticalTextOffset());
dp::Anchor anchor = static_cast<dp::Anchor>((m_position.m_anchor & (dp::Right | dp::Left)) | dp::Bottom);
RulerTextHandle * handle = new RulerTextHandle(anchor, rulerTextPivot);
dp::RefPointer<MutableLabel> textView = handle->GetTextView();
dp::RefPointer<dp::Texture> maskTexture = textView->SetAlphabet(m_alphabet, tex);
textView->SetMaxLength(m_maxLength);
buffer_vector<MutableLabel::StaticVertex, 128> statData;
buffer_vector<MutableLabel::DynamicVertex, 128> dynData;
dp::RefPointer<dp::Texture> colorTexture = textView->Precache(statData, dp::FontDecl(FontColor, FontSize * DrapeGui::Instance().GetScaleFactor()), tex);
ASSERT_EQUAL(GetVertexCount(), statData.size(), ());
dynData.resize(statData.size());
dp::AttributeProvider provider(2, statData.size());
provider.InitStream(0, MutableLabel::StaticVertex::GetBindingInfo(), dp::MakeStackRefPointer<void>(statData.data()));
provider.InitStream(1, MutableLabel::DynamicVertex::GetBindingInfo(), dp::MakeStackRefPointer<void>(dynData.data()));
dp::GLState state(gpu::TEXT_PROGRAM, dp::GLState::UserMarkLayer);
state.SetColorTexture(colorTexture);
state.SetMaskTexture(maskTexture);
batcher->InsertListOfStrip(state, dp::MakeStackRefPointer(&provider), dp::MovePointer<dp::OverlayHandle>(handle), 4);
}
uint16_t RulerText::GetVertexCount() const
{
return 4 * m_maxLength;
}
uint16_t RulerText::GetIndexCount() const
{
return 6 * m_maxLength;
}
}

View file

@ -1,23 +0,0 @@
#pragma once
#include "shape.hpp"
#include "gui_text.hpp"
namespace gui
{
class RulerText : public Shape
{
public:
RulerText();
virtual void Draw(dp::RefPointer<dp::Batcher> batcher, dp::RefPointer<dp::TextureManager> tex) const;
virtual uint16_t GetVertexCount() const;
virtual uint16_t GetIndexCount() const;
private:
string m_alphabet;
size_t m_maxLength;
};
}

View file

@ -10,13 +10,6 @@ void Shape::SetPosition(gui::Position const & position)
m_position = position;
}
void Handle::SetProjection(int w, int h)
{
array<float, 16> m;
dp::MakeProjection(m, 0.0f, w, h, 0.0f);
m_uniforms.SetMatrix4x4Value("projection", m.data());
}
bool Handle::IndexesRequired() const
{
return false;
@ -33,47 +26,69 @@ void Handle::GetPixelShape(const ScreenBase & screen, dp::OverlayHandle::Rects &
UNUSED_VALUE(rects);
}
ShapeRenderer::ShapeRenderer(dp::GLState const & state,
dp::TransferPointer<dp::VertexArrayBuffer> buffer,
dp::TransferPointer<dp::OverlayHandle> implHandle)
: m_state(state)
, m_buffer(buffer)
, m_implHandle(implHandle)
{
}
ShapeRenderer::~ShapeRenderer()
{
m_implHandle.Destroy();
m_buffer.Destroy();
for (ShapeInfo & shape : m_shapes)
{
shape.m_handle.Destroy();
shape.m_buffer.Destroy();
}
}
dp::Batcher::TFlushFn ShapeRenderer::GetFlushRoutine()
{
dp::Batcher::TFlushFn flushFn = [this](dp::GLState const & state, dp::TransferPointer<dp::RenderBucket> bucket)
{
dp::MasterPointer<dp::RenderBucket> b(bucket);
ASSERT(b->GetOverlayHandlesCount() == 1, ());
dp::TransferPointer<dp::VertexArrayBuffer> buffer = b->MoveBuffer();
dp::TransferPointer<dp::OverlayHandle> transferH = b->PopOverlayHandle();
b.Destroy();
m_shapes.emplace_back(state, buffer, transferH);
};
return flushFn;
}
void ShapeRenderer::Build(dp::RefPointer<dp::GpuProgramManager> mng)
{
m_buffer->Build(mng->GetProgram(m_state.GetProgramIndex()));
for (ShapeInfo & shape : m_shapes)
shape.m_buffer->Build(mng->GetProgram(shape.m_state.GetProgramIndex()));
}
void ShapeRenderer::Render(ScreenBase const & screen, dp::RefPointer<dp::GpuProgramManager> mng)
{
Handle * handle = static_cast<Handle *>(m_implHandle.GetRaw());
handle->Update(screen);
if (!(handle->IsValid() && handle->IsVisible()))
return;
array<float, 16> m;
m2::RectD const & pxRect = screen.PixelRect();
dp::MakeProjection(m, 0.0f, pxRect.SizeX(), pxRect.SizeY(), 0.0f);
dp::RefPointer<dp::GpuProgram> prg = mng->GetProgram(m_state.GetProgramIndex());
prg->Bind();
dp::ApplyState(m_state, prg);
dp::ApplyUniforms(handle->GetUniforms(), prg);
dp::UniformValuesStorage uniformStorage;
uniformStorage.SetMatrix4x4Value("projection", m.data());
if (handle->HasDynamicAttributes())
for (ShapeInfo & shape : m_shapes)
{
dp::AttributeBufferMutator mutator;
dp::RefPointer<dp::AttributeBufferMutator> mutatorRef = dp::MakeStackRefPointer(&mutator);
handle->GetAttributeMutation(mutatorRef, screen);
m_buffer->ApplyMutation(dp::MakeStackRefPointer<dp::IndexBufferMutator>(nullptr), mutatorRef);
Handle * handle = static_cast<Handle *>(shape.m_handle.GetRaw());
handle->Update(screen);
if (!(handle->IsValid() && handle->IsVisible()))
return;
dp::RefPointer<dp::GpuProgram> prg = mng->GetProgram(shape.m_state.GetProgramIndex());
prg->Bind();
dp::ApplyState(shape.m_state, prg);
dp::ApplyUniforms(handle->GetUniforms(), prg);
dp::ApplyUniforms(uniformStorage, prg);
if (handle->HasDynamicAttributes())
{
dp::AttributeBufferMutator mutator;
dp::RefPointer<dp::AttributeBufferMutator> mutatorRef = dp::MakeStackRefPointer(&mutator);
handle->GetAttributeMutation(mutatorRef, screen);
shape.m_buffer->ApplyMutation(dp::MakeStackRefPointer<dp::IndexBufferMutator>(nullptr), mutatorRef);
}
shape.m_buffer->Render();
}
m_buffer->Render();
}
}

View file

@ -13,19 +13,6 @@
namespace gui
{
class Shape
{
public:
virtual void Draw(dp::RefPointer<dp::Batcher> batcher, dp::RefPointer<dp::TextureManager> tex) const = 0;
virtual uint16_t GetVertexCount() const = 0;
virtual uint16_t GetIndexCount() const = 0;
void SetPosition(gui::Position const & position);
protected:
gui::Position m_position;
};
class Handle : public dp::OverlayHandle
{
public:
@ -37,8 +24,6 @@ public:
dp::UniformValuesStorage const & GetUniforms() const { return m_uniforms; }
void SetProjection(int w, int h);
virtual bool IndexesRequired() const override;
virtual m2::RectD GetPixelRect(ScreenBase const & screen) const override;
virtual void GetPixelShape(ScreenBase const & screen, Rects & rects) const override;
@ -48,20 +33,45 @@ protected:
glsl::vec2 const m_pivot;
};
class ShapeRenderer
class ShapeRenderer final
{
public:
ShapeRenderer(dp::GLState const & state, dp::TransferPointer<dp::VertexArrayBuffer> buffer,
dp::TransferPointer<dp::OverlayHandle> implHandle);
~ShapeRenderer();
dp::Batcher::TFlushFn GetFlushRoutine();
void Build(dp::RefPointer<dp::GpuProgramManager> mng);
void Render(ScreenBase const & screen, dp::RefPointer<dp::GpuProgramManager> mng);
private:
dp::GLState m_state;
dp::MasterPointer<dp::VertexArrayBuffer> m_buffer;
dp::MasterPointer<dp::OverlayHandle> m_implHandle;
struct ShapeInfo
{
ShapeInfo(dp::GLState const & state, dp::TransferPointer<dp::VertexArrayBuffer> buffer,
dp::TransferPointer<dp::OverlayHandle> handle)
: m_state(state)
, m_buffer(buffer)
, m_handle(handle)
{
}
dp::GLState m_state;
dp::MasterPointer<dp::VertexArrayBuffer> m_buffer;
dp::MasterPointer<dp::OverlayHandle> m_handle;
};
vector<ShapeInfo> m_shapes;
};
class Shape
{
public:
virtual ~Shape() {}
virtual dp::TransferPointer<ShapeRenderer> Draw(dp::RefPointer<dp::TextureManager> tex) const = 0;
void SetPosition(gui::Position const & position);
protected:
gui::Position m_position;
};
}