diff --git a/data/resources-default/default.ui b/data/resources-default/default.ui
new file mode 100644
index 0000000000..50138f245a
--- /dev/null
+++ b/data/resources-default/default.ui
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/drape/batcher.cpp b/drape/batcher.cpp
index cbb7159a89..a6ea7d49b9 100644
--- a/drape/batcher.cpp
+++ b/drape/batcher.cpp
@@ -43,7 +43,7 @@ public:
uint16_t * GetIndexStorage(uint16_t size, uint16_t & startIndex)
{
startIndex = m_buffer->GetStartIndexValue();
- if (m_overlay.IsNull())
+ if (m_overlay.IsNull() || !m_overlay->RequiresIndexes())
{
m_indexStorage.resize(size);
return &m_indexStorage[0];
@@ -54,7 +54,7 @@ public:
void SubmitIndexes()
{
- if (m_overlay.IsNull())
+ if (m_overlay.IsNull() || !m_overlay->RequiresIndexes())
m_buffer->UploadIndexes(&m_indexStorage[0], m_indexStorage.size());
}
diff --git a/drape/drape.pro b/drape/drape.pro
index 3a629deadd..ccd0c63d4e 100644
--- a/drape/drape.pro
+++ b/drape/drape.pro
@@ -19,3 +19,4 @@ OTHER_FILES += \
shaders/line_fragment_shader.fsh \
shaders/text_fragment_shader.fsh \
shaders/text_vertex_shader.vsh \
+ shaders/compass_vertex_shader.vsh
diff --git a/drape/glsl_func.hpp b/drape/glsl_func.hpp
index 9e97fbb050..17e25d3859 100644
--- a/drape/glsl_func.hpp
+++ b/drape/glsl_func.hpp
@@ -17,6 +17,7 @@ using glm::distance;
using glm::translate;
using glm::rotate;
using glm::scale;
+using glm::transpose;
using glm::value_ptr;
diff --git a/drape/overlay_handle.cpp b/drape/overlay_handle.cpp
index 9aa17e16d0..679bdf894d 100644
--- a/drape/overlay_handle.cpp
+++ b/drape/overlay_handle.cpp
@@ -66,20 +66,16 @@ uint16_t * OverlayHandle::IndexStorage(uint16_t size)
return &m_indexes[0];
}
-size_t OverlayHandle::GetIndexCount() const
-{
- return m_indexes.size();
-}
-
void OverlayHandle::GetElementIndexes(RefPointer mutator) const
{
ASSERT_EQUAL(m_isVisible, true, ());
mutator->AppendIndexes(&m_indexes[0], m_indexes.size());
}
-void OverlayHandle::GetAttributeMutation(RefPointer mutator, const ScreenBase & screen) const
+void OverlayHandle::GetAttributeMutation(RefPointer mutator, ScreenBase const & screen) const
{
UNUSED_VALUE(mutator);
+ UNUSED_VALUE(screen);
}
bool OverlayHandle::HasDynamicAttributes() const
diff --git a/drape/overlay_handle.hpp b/drape/overlay_handle.hpp
index fbbd235db7..1cf6a78342 100644
--- a/drape/overlay_handle.hpp
+++ b/drape/overlay_handle.hpp
@@ -39,8 +39,8 @@ public:
bool IsIntersect(ScreenBase const & screen, OverlayHandle const & h) const;
+ virtual bool RequiresIndexes() const { return true; }
uint16_t * IndexStorage(uint16_t size);
- size_t GetIndexCount() const;
void GetElementIndexes(RefPointer mutator) const;
virtual void GetAttributeMutation(RefPointer mutator, ScreenBase const & screen) const;
diff --git a/drape/render_bucket.cpp b/drape/render_bucket.cpp
index 6242cdf2cb..964b51019a 100644
--- a/drape/render_bucket.cpp
+++ b/drape/render_bucket.cpp
@@ -27,6 +27,31 @@ RefPointer RenderBucket::GetBuffer()
return m_buffer.GetRefPointer();
}
+TransferPointer RenderBucket::MoveBuffer()
+{
+ return m_buffer.Move();
+}
+
+size_t RenderBucket::GetOverlayHandlesCount() const
+{
+ return m_overlay.size();
+}
+
+TransferPointer RenderBucket::PopOverlayHandle()
+{
+ ASSERT(!m_overlay.empty(), ());
+ size_t lastElement = m_overlay.size() - 1;
+ swap(m_overlay[0], m_overlay[lastElement]);
+ TransferPointer h = m_overlay[lastElement].Move();
+ m_overlay.resize(lastElement);
+ return h;
+}
+
+RefPointer RenderBucket::GetOverlayHandle(size_t index)
+{
+ return m_overlay[index].GetRefPointer();
+}
+
void RenderBucket::AddOverlayHandle(TransferPointer handle)
{
m_overlay.push_back(MasterPointer(handle));
@@ -47,6 +72,8 @@ void RenderBucket::CollectOverlayHandles(RefPointer tree)
void RenderBucket::Render(ScreenBase const & screen)
{
+ ASSERT(!m_buffer.IsNull(), ());
+
if (!m_overlay.empty())
{
// in simple case when overlay is symbol each element will be contains 6 indexes
diff --git a/drape/render_bucket.hpp b/drape/render_bucket.hpp
index d2948f1e9a..071a07943e 100644
--- a/drape/render_bucket.hpp
+++ b/drape/render_bucket.hpp
@@ -18,7 +18,11 @@ public:
~RenderBucket();
RefPointer GetBuffer();
+ TransferPointer MoveBuffer();
+ size_t GetOverlayHandlesCount() const;
+ TransferPointer PopOverlayHandle();
+ RefPointer GetOverlayHandle(size_t index);
void AddOverlayHandle(TransferPointer handle);
void Update(ScreenBase const & modelView);
diff --git a/drape/shaders/compass_vertex_shader.vsh b/drape/shaders/compass_vertex_shader.vsh
new file mode 100644
index 0000000000..a7d1525415
--- /dev/null
+++ b/drape/shaders/compass_vertex_shader.vsh
@@ -0,0 +1,13 @@
+attribute vec2 a_position;
+attribute vec2 a_colorTexCoords;
+
+uniform mat4 modelView;
+uniform mat4 projection;
+
+varying vec2 v_colorTexCoords;
+
+void main(void)
+{
+ gl_Position = vec4(a_position, 0, 1) * modelView * projection;
+ v_colorTexCoords = a_colorTexCoords;
+}
diff --git a/drape/shaders/shader_index.txt b/drape/shaders/shader_index.txt
index eece273841..d10a51cf2c 100644
--- a/drape/shaders/shader_index.txt
+++ b/drape/shaders/shader_index.txt
@@ -1,3 +1,4 @@
TEXTURING_PROGRAM texturing_vertex_shader.vsh texturing_fragment_shader.fsh
LINE_PROGRAM line_vertex_shader.vsh line_fragment_shader.fsh
TEXT_PROGRAM text_vertex_shader.vsh text_fragment_shader.fsh
+COMPASS_PROGRAM compass_vertex_shader.vsh texturing_fragment_shader.fsh
diff --git a/drape/vertex_array_buffer.cpp b/drape/vertex_array_buffer.cpp
index a3c8df22f3..663fff9093 100644
--- a/drape/vertex_array_buffer.cpp
+++ b/drape/vertex_array_buffer.cpp
@@ -185,7 +185,11 @@ void VertexArrayBuffer::UploadIndexes(uint16_t const * data, uint16_t count)
void VertexArrayBuffer::ApplyMutation(RefPointer indexMutator,
RefPointer attrMutator)
{
- m_indexBuffer->UpdateData(indexMutator->GetIndexes(), indexMutator->GetIndexCount());
+ if (!indexMutator.IsNull())
+ m_indexBuffer->UpdateData(indexMutator->GetIndexes(), indexMutator->GetIndexCount());
+
+ if (attrMutator.IsNull())
+ return;
typedef AttributeBufferMutator::TMutateData TMutateData;
typedef AttributeBufferMutator::TMutateNodes TMutateNodes;
diff --git a/drape_frontend/backend_renderer.cpp b/drape_frontend/backend_renderer.cpp
index 0720b1977b..d3b11514ae 100644
--- a/drape_frontend/backend_renderer.cpp
+++ b/drape_frontend/backend_renderer.cpp
@@ -26,9 +26,10 @@ BackendRenderer::BackendRenderer(dp::RefPointer commutator,
MapDataProvider const & model)
: m_model(model)
, m_engineContext(commutator)
+ , m_texturesManager(textureManager)
+ , m_guiCacher("default", df::VisualParams::Instance().GetVisualScale())
, m_commutator(commutator)
, m_contextFactory(oglcontextfactory)
- , m_texturesManager(textureManager)
{
m_commutator->RegisterThread(ThreadsCommutator::ResourceUploadThread, this);
m_batchersPool.Reset(new BatchersPool(ReadManager::ReadCount(), bind(&BackendRenderer::FlushGeometry, this, _1)));
@@ -57,6 +58,15 @@ void BackendRenderer::AcceptMessage(dp::RefPointer message)
m_readManager->UpdateCoverage(screen, tiles);
break;
}
+ case Message::Resize:
+ {
+ ResizeMessage * msg = df::CastMessage(message);
+ df::Viewport const & v = msg->GetViewport();
+ m_guiCacher.Resize(v.GetWidth(), v.GetHeight());
+ GuiLayerRecachedMessage * outputMsg = new GuiLayerRecachedMessage(m_guiCacher.Recache(m_texturesManager));
+ m_commutator->PostMessage(ThreadsCommutator::RenderThread, dp::MovePointer(outputMsg));
+ break;
+ }
case Message::InvalidateReadManagerRect:
{
InvalidateReadManagerRectMessage * msg = df::CastMessage(message);
diff --git a/drape_frontend/backend_renderer.hpp b/drape_frontend/backend_renderer.hpp
index 1678c3ec81..eb4ce96e01 100644
--- a/drape_frontend/backend_renderer.hpp
+++ b/drape_frontend/backend_renderer.hpp
@@ -5,6 +5,7 @@
#include "drape_frontend/viewport.hpp"
#include "drape_frontend/map_data_provider.hpp"
+#include "drape_gui/layer_render.hpp"
#include "drape/pointers.hpp"
#include "base/thread.hpp"
@@ -40,6 +41,8 @@ private:
EngineContext m_engineContext;
dp::MasterPointer m_batchersPool;
dp::MasterPointer m_readManager;
+ dp::RefPointer m_texturesManager;
+ gui::LayerCacher m_guiCacher;
/////////////////////////////////////////
// MessageAcceptor //
@@ -74,8 +77,6 @@ private:
threads::Thread m_selfThread;
dp::RefPointer m_commutator;
dp::RefPointer m_contextFactory;
-
- dp::RefPointer m_texturesManager;
};
} // namespace df
diff --git a/drape_frontend/frontend_renderer.cpp b/drape_frontend/frontend_renderer.cpp
index 7251d87e69..24ca739c03 100644
--- a/drape_frontend/frontend_renderer.cpp
+++ b/drape_frontend/frontend_renderer.cpp
@@ -152,6 +152,8 @@ void FrontendRenderer::AcceptMessage(dp::RefPointer message)
RefreshProjection();
RefreshModelView();
ResolveTileKeys();
+ m_commutator->PostMessage(ThreadsCommutator::ResourceUploadThread,
+ dp::MovePointer(new ResizeMessage(m_viewport)));
m_commutator->PostMessage(ThreadsCommutator::ResourceUploadThread,
dp::MovePointer(new UpdateReadManagerMessage(m_view, m_tiles)));
break;
@@ -207,6 +209,14 @@ void FrontendRenderer::AcceptMessage(dp::RefPointer message)
group->SetIsVisible(m->IsVisible());
break;
}
+ case Message::GuiLayerRecached:
+ {
+ GuiLayerRecachedMessage * msg = df::CastMessage(message);
+ m_guiRenderer.Destroy();
+ m_guiRenderer = msg->AcceptRenderer();
+ m_guiRenderer->Build(m_gpuProgramManager.GetRefPointer());
+ break;
+ }
default:
ASSERT(false, ());
}
@@ -290,6 +300,10 @@ void FrontendRenderer::RenderScene()
}
}
+ GLFunctions::glClearDepth();
+ if (!m_guiRenderer.IsNull())
+ m_guiRenderer->Render(m_gpuProgramManager.GetRefPointer(), m_view);
+
#ifdef DRAW_INFO
AfterDrawFrame();
#endif
diff --git a/drape_frontend/frontend_renderer.hpp b/drape_frontend/frontend_renderer.hpp
index 6c88a2a2bb..a3da83a055 100644
--- a/drape_frontend/frontend_renderer.hpp
+++ b/drape_frontend/frontend_renderer.hpp
@@ -14,13 +14,14 @@
#include "drape_frontend/backend_renderer.hpp"
#include "drape_frontend/render_group.hpp"
+#include "drape_gui/layer_render.hpp"
+
#include "drape/pointers.hpp"
#include "drape/glstate.hpp"
#include "drape/vertex_array_buffer.hpp"
#include "drape/gpu_program_manager.hpp"
#include "drape/oglcontextfactory.hpp"
#include "drape/overlay_tree.hpp"
-
#include "drape/uniform_values_storage.hpp"
#include "geometry/screenbase.hpp"
@@ -102,6 +103,7 @@ private:
private:
vector m_renderGroups;
vector m_userMarkRenderGroups;
+ dp::MasterPointer m_guiRenderer;
dp::UniformValuesStorage m_generalUniforms;
diff --git a/drape_frontend/message.hpp b/drape_frontend/message.hpp
index 13a8eb1d9e..d68709e005 100644
--- a/drape_frontend/message.hpp
+++ b/drape_frontend/message.hpp
@@ -22,7 +22,8 @@ public:
Resize,
ClearUserMarkLayer,
ChangeUserMarkLayerVisibility,
- UpdateUserMarkLayer
+ UpdateUserMarkLayer,
+ GuiLayerRecached
};
Message();
diff --git a/drape_frontend/message_subclasses.hpp b/drape_frontend/message_subclasses.hpp
index 15e58954b6..95cd8d1879 100644
--- a/drape_frontend/message_subclasses.hpp
+++ b/drape_frontend/message_subclasses.hpp
@@ -5,9 +5,12 @@
#include "drape_frontend/tile_key.hpp"
#include "drape_frontend/user_marks_provider.hpp"
+#include "drape_gui/layer_render.hpp"
+
#include "geometry/rect2d.hpp"
#include "geometry/screenbase.hpp"
+
#include "drape/glstate.hpp"
#include "drape/pointers.hpp"
#include "drape/render_bucket.hpp"
@@ -213,4 +216,22 @@ private:
#endif
};
+class GuiLayerRecachedMessage : public Message
+{
+public:
+ GuiLayerRecachedMessage(dp::TransferPointer renderer)
+ : m_renderer(move(renderer))
+ {
+ SetType(GuiLayerRecached);
+ }
+
+ dp::MasterPointer AcceptRenderer()
+ {
+ return dp::MasterPointer(m_renderer);
+ }
+
+private:
+ dp::TransferPointer m_renderer;
+};
+
} // namespace df
diff --git a/drape_gui/compass.cpp b/drape_gui/compass.cpp
new file mode 100644
index 0000000000..cd2f7afb9c
--- /dev/null
+++ b/drape_gui/compass.cpp
@@ -0,0 +1,118 @@
+#include "compass.hpp"
+
+#include "../drape/glsl_types.hpp"
+#include "../drape/glsl_func.hpp"
+#include "../drape/shader_def.hpp"
+
+#include "../drape/utils/vertex_decl.hpp"
+
+namespace gui
+{
+
+namespace
+{
+ struct CompassVertex
+ {
+ CompassVertex(glsl::vec2 const & position, glsl::vec2 const & texCoord)
+ : m_position(position)
+ , m_texCoord(texCoord) {}
+
+ glsl::vec2 m_position;
+ glsl::vec2 m_texCoord;
+ };
+
+ class CompassHandle : public Handle
+ {
+ public:
+ CompassHandle(glsl::vec2 const & pivot)
+ : Handle(FeatureID(), dp::Center, 0.0)
+ , m_pivot(pivot)
+ {
+ }
+
+ virtual void Update(ScreenBase const & screen) override
+ {
+ float angle = ang::AngleIn2PI(screen.GetAngle());
+ if (angle < my::DegToRad(5.0) || angle > my::DegToRad(355.0))
+ SetIsVisible(false);
+ else
+ {
+ SetIsVisible(true);
+ glsl::mat4 r = glsl::rotate(glsl::mat4(), angle, glsl::vec3(0.0, 0.0, 1.0));
+ glsl::mat4 m = glsl::translate(glsl::mat4(), glsl::vec3(m_pivot, 0.0));
+ m = glsl::transpose(m * r);
+ m_uniforms.SetMatrix4x4Value("modelView", glsl::value_ptr(m));
+ }
+ }
+
+ virtual bool RequiresIndexes() const override { return false; }
+
+ virtual m2::RectD GetPixelRect(ScreenBase const & screen) const override
+ {
+ return m2::RectD();
+ }
+
+ virtual void GetPixelShape(ScreenBase const & screen, Rects & rects) const override
+ {
+ UNUSED_VALUE(screen);
+ UNUSED_VALUE(rects);
+ }
+
+ private:
+ glsl::vec2 m_pivot;
+ };
+}
+
+void Compass::Draw(dp::RefPointer batcher, dp::RefPointer tex) const
+{
+ dp::TextureManager::SymbolRegion region;
+ tex->GetSymbolRegion("compass-image", region);
+ glsl::vec2 halfSize = glsl::ToVec2(m2::PointD(region.GetPixelSize()) * 0.5);
+ m2::RectF texRect = region.GetTexRect();
+
+ ASSERT_EQUAL(m_position.m_anchor, dp::Center, ());
+ CompassVertex vertexes[] =
+ {
+ CompassVertex(glsl::vec2(-halfSize.x, halfSize.y), glsl::ToVec2(texRect.LeftTop())),
+ CompassVertex(glsl::vec2(-halfSize.x, -halfSize.y), glsl::ToVec2(texRect.LeftBottom())),
+ CompassVertex(glsl::vec2(halfSize.x, halfSize.y), glsl::ToVec2(texRect.RightTop())),
+ CompassVertex(glsl::vec2(halfSize.x, -halfSize.y), glsl::ToVec2(texRect.RightBottom()))
+ };
+
+ dp::GLState state(gpu::COMPASS_PROGRAM, dp::GLState::UserMarkLayer);
+ state.SetBlending(dp::Blending(true));
+ state.SetColorTexture(region.GetTexture());
+
+ dp::AttributeProvider provider(1, 4);
+ dp::BindingInfo info(2);
+
+ dp::BindingDecl & posDecl = info.GetBindingDecl(0);
+ posDecl.m_attributeName = "a_position";
+ posDecl.m_componentCount = 2;
+ posDecl.m_componentType = gl_const::GLFloatType;
+ posDecl.m_offset = 0;
+ posDecl.m_stride = sizeof(CompassVertex);
+
+ dp::BindingDecl & texDecl = info.GetBindingDecl(1);
+ texDecl.m_attributeName = "a_colorTexCoords";
+ texDecl.m_componentCount = 2;
+ texDecl.m_componentType = gl_const::GLFloatType;
+ texDecl.m_offset = sizeof(glsl::vec2);
+ texDecl.m_stride = posDecl.m_stride;
+
+ provider.InitStream(0, info, dp::MakeStackRefPointer(&vertexes));
+ batcher->InsertTriangleStrip(state, dp::MakeStackRefPointer(&provider),
+ dp::MovePointer(new CompassHandle(glsl::ToVec2(m_position.m_pixelPivot))));
+}
+
+uint16_t Compass::GetVertexCount() const
+{
+ return 4;
+}
+
+uint16_t Compass::GetIndexCount() const
+{
+ return 6;
+}
+
+}
diff --git a/drape_gui/compass.hpp b/drape_gui/compass.hpp
new file mode 100644
index 0000000000..9e602495df
--- /dev/null
+++ b/drape_gui/compass.hpp
@@ -0,0 +1,16 @@
+#pragma once
+
+#include "shape.hpp"
+
+namespace gui
+{
+
+class Compass : public Shape
+{
+public:
+ virtual void Draw(dp::RefPointer batcher, dp::RefPointer tex) const;
+ virtual uint16_t GetVertexCount() const;
+ virtual uint16_t GetIndexCount() const;
+};
+
+}
diff --git a/drape_gui/drape_gui.pro b/drape_gui/drape_gui.pro
index be04255bf0..bc08aec758 100644
--- a/drape_gui/drape_gui.pro
+++ b/drape_gui/drape_gui.pro
@@ -6,8 +6,17 @@ DEPENDENCIES = drape base
ROOT_DIR = ..
include($$ROOT_DIR/common.pri)
+INCLUDEPATH *= $$ROOT_DIR/3party/expat/lib
+
HEADERS += \
skin.hpp \
+ compass.hpp \
+ shape.hpp \
+ layer_render.hpp
SOURCES += \
skin.cpp \
+ compass.cpp \
+ shape.cpp \
+ layer_render.cpp
+
diff --git a/drape_gui/layer_render.cpp b/drape_gui/layer_render.cpp
new file mode 100644
index 0000000000..72236e60a2
--- /dev/null
+++ b/drape_gui/layer_render.cpp
@@ -0,0 +1,84 @@
+#include "layer_render.hpp"
+#include "compass.hpp"
+
+#include "../drape/batcher.hpp"
+#include "../drape/render_bucket.hpp"
+
+#include "../base/stl_add.hpp"
+
+namespace gui
+{
+
+LayerCacher::LayerCacher(string const & deviceType, double vs)
+{
+ m_skin.reset(new Skin(ResolveGuiSkinFile(deviceType), vs));
+}
+
+void LayerCacher::Resize(int w, int h)
+{
+ m_skin->Resize(w, h);
+}
+
+dp::TransferPointer LayerCacher::Recache(dp::RefPointer textures)
+{
+ LayerRenderer * renderer = new LayerRenderer();
+
+ Compass compass;
+ compass.SetPosition(m_skin->ResolvePosition(Skin::ElementName::Compass));
+
+ auto flushFn = [&renderer, this](dp::GLState const & state, dp::TransferPointer bucket)
+ {
+ dp::MasterPointer b(bucket);
+ ASSERT(b->GetOverlayHandlesCount() == 1, ());
+ dp::TransferPointer buffer = b->MoveBuffer();
+ dp::TransferPointer transferH = b->PopOverlayHandle();
+ dp::MasterPointer handle(transferH);
+ b.Destroy();
+
+ static_cast(handle.GetRaw())->SetProjection(m_skin->GetWidth(), m_skin->GetHeight());
+
+ renderer->AddShapeRenderer(new ShapeRenderer(state, buffer, handle.Move()));
+ };
+
+ dp::Batcher batcher(compass.GetIndexCount(), compass.GetVertexCount());
+ batcher.StartSession(flushFn);
+ compass.Draw(dp::MakeStackRefPointer(&batcher), textures);
+ batcher.EndSession();
+
+ return dp::MovePointer(renderer);
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+
+LayerRenderer::~LayerRenderer()
+{
+ DestroyRenderers();
+}
+
+void LayerRenderer::Build(dp::RefPointer mng)
+{
+ for_each(m_renderers.begin(), m_renderers.end(), [mng](ShapeRenderer * r)
+ {
+ r->Build(mng);
+ });
+}
+
+void LayerRenderer::Render(dp::RefPointer mng, ScreenBase const & screen)
+{
+ for_each(m_renderers.begin(), m_renderers.end(), [&screen, mng](ShapeRenderer * r)
+ {
+ r->Render(screen, mng);
+ });
+}
+
+void LayerRenderer::DestroyRenderers()
+{
+ DeleteRange(m_renderers, DeleteFunctor());
+}
+
+void LayerRenderer::AddShapeRenderer(ShapeRenderer * shape)
+{
+ m_renderers.push_back(shape);
+}
+
+}
diff --git a/drape_gui/layer_render.hpp b/drape_gui/layer_render.hpp
new file mode 100644
index 0000000000..a498d7a605
--- /dev/null
+++ b/drape_gui/layer_render.hpp
@@ -0,0 +1,52 @@
+#pragma once
+
+#include "skin.hpp"
+#include "shape.hpp"
+
+#include "../geometry/screenbase.hpp"
+#include "../drape/texture_manager.hpp"
+#include "../drape/gpu_program_manager.hpp"
+
+#include "../std/unique_ptr.hpp"
+
+namespace gui
+{
+
+class LayerRenderer
+{
+public:
+ LayerRenderer() = default;
+ LayerRenderer(LayerRenderer && other) = delete;
+ LayerRenderer(LayerRenderer const & other) = delete;
+
+ LayerRenderer & operator=(LayerRenderer && other) = delete;
+ LayerRenderer & operator=(LayerRenderer const & other) = delete;
+
+ ~LayerRenderer();
+
+ void Build(dp::RefPointer mng);
+ void Render(dp::RefPointer mng, ScreenBase const & screen);
+
+private:
+ void DestroyRenderers();
+
+ friend class LayerCacher;
+ void AddShapeRenderer(ShapeRenderer * shape);
+
+private:
+ vector m_renderers;
+};
+
+class LayerCacher
+{
+public:
+ LayerCacher(string const & deviceType, double vs);
+
+ void Resize(int w, int h);
+ dp::TransferPointer Recache(dp::RefPointer textures);
+
+private:
+ unique_ptr m_skin;
+};
+
+}
diff --git a/drape_gui/shape.cpp b/drape_gui/shape.cpp
new file mode 100644
index 0000000000..95b39582ff
--- /dev/null
+++ b/drape_gui/shape.cpp
@@ -0,0 +1,63 @@
+#include "shape.hpp"
+
+#include "../drape/utils/projection.hpp"
+
+namespace gui
+{
+
+void Shape::SetPosition(gui::Position const & position)
+{
+ m_position = position;
+}
+
+ShapeRenderer::ShapeRenderer(dp::GLState const & state,
+ dp::TransferPointer buffer,
+ dp::TransferPointer implHandle)
+ : m_state(state)
+ , m_buffer(buffer)
+ , m_implHandle(implHandle)
+{
+}
+
+ShapeRenderer::~ShapeRenderer()
+{
+ m_implHandle.Destroy();
+ m_buffer.Destroy();
+}
+
+void ShapeRenderer::Build(dp::RefPointer mng)
+{
+ m_buffer->Build(mng->GetProgram(m_state.GetProgramIndex()));
+}
+
+void ShapeRenderer::Render(ScreenBase const & screen, dp::RefPointer mng)
+{
+ Handle * handle = static_cast(m_implHandle.GetRaw());
+ handle->Update(screen);
+ if (!(handle->IsVisible() && handle->IsValid()))
+ return;
+
+ dp::RefPointer prg = mng->GetProgram(m_state.GetProgramIndex());
+ prg->Bind();
+ dp::ApplyState(m_state, prg);
+ dp::ApplyUniforms(handle->GetUniforms(), prg);
+
+ if (handle->HasDynamicAttributes())
+ {
+ dp::AttributeBufferMutator mutator;
+ dp::RefPointer mutatorRef = dp::MakeStackRefPointer(&mutator);
+ handle->GetAttributeMutation(mutatorRef, screen);
+ m_buffer->ApplyMutation(dp::MakeStackRefPointer(nullptr), mutatorRef);
+ }
+
+ m_buffer->Render();
+}
+
+void Handle::SetProjection(int w, int h)
+{
+ array m;
+ dp::MakeProjection(m, 0.0f, w, h, 0.0f);
+ m_uniforms.SetMatrix4x4Value("projection", m.data());
+}
+
+}
diff --git a/drape_gui/shape.hpp b/drape_gui/shape.hpp
new file mode 100644
index 0000000000..6f04f75827
--- /dev/null
+++ b/drape_gui/shape.hpp
@@ -0,0 +1,57 @@
+#pragma once
+
+#include "skin.hpp"
+
+#include "../drape/glsl_types.hpp"
+#include "../drape/batcher.hpp"
+#include "../drape/texture_manager.hpp"
+#include "../drape/overlay_handle.hpp"
+#include "../drape/glstate.hpp"
+#include "../drape/vertex_array_buffer.hpp"
+#include "../drape/gpu_program_manager.hpp"
+
+namespace gui
+{
+
+class Shape
+{
+public:
+ virtual void Draw(dp::RefPointer batcher, dp::RefPointer 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:
+ Handle(FeatureID const & id, dp::Anchor anchor, double p) : dp::OverlayHandle(id, anchor, p) {}
+ dp::UniformValuesStorage const & GetUniforms() const { return m_uniforms; }
+
+ void SetProjection(int w, int h);
+
+protected:
+ dp::UniformValuesStorage m_uniforms;
+};
+
+class ShapeRenderer
+{
+public:
+ ShapeRenderer(dp::GLState const & state, dp::TransferPointer buffer,
+ dp::TransferPointer implHandle);
+ ~ShapeRenderer();
+
+ void Build(dp::RefPointer mng);
+ void Render(ScreenBase const & screen, dp::RefPointer mng);
+
+private:
+ dp::GLState m_state;
+ dp::MasterPointer m_buffer;
+ dp::MasterPointer m_implHandle;
+};
+
+}
diff --git a/drape_head/testing_engine.cpp b/drape_head/testing_engine.cpp
index 46032037dc..79991168e2 100644
--- a/drape_head/testing_engine.cpp
+++ b/drape_head/testing_engine.cpp
@@ -541,8 +541,9 @@ void TestingEngine::OnFlushData(dp::GLState const & state, dp::TransferPointer bucket(vao);
bucket->GetBuffer()->Build(m_programManager->GetProgram(state.GetProgramIndex()));
m_scene[state].push_back(bucket);
- bucket->ForEachOverlay([this](dp::OverlayHandle * handle)
+ for (size_t i = 0; i < bucket->GetOverlayHandlesCount(); ++i)
{
+ dp::RefPointer handle = bucket->GetOverlayHandle(i);
handle->Update(m_modelView);
if (handle->IsValid())
{
@@ -550,7 +551,7 @@ void TestingEngine::OnFlushData(dp::GLState const & state, dp::TransferPointerGetPixelShape(m_modelView, m_rects.back());
}
- });
+ };
}
void TestingEngine::ClearScene()
diff --git a/iphone/Maps/Maps.xcodeproj/project.pbxproj b/iphone/Maps/Maps.xcodeproj/project.pbxproj
index ce4f98d189..6bf74c77ac 100644
--- a/iphone/Maps/Maps.xcodeproj/project.pbxproj
+++ b/iphone/Maps/Maps.xcodeproj/project.pbxproj
@@ -605,6 +605,7 @@
9DF04B241B71010E00DACAF1 /* 02_droidsans-fallback.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 9DF04B231B71010E00DACAF1 /* 02_droidsans-fallback.ttf */; };
A32B6D4C1A14980500E54A65 /* iosOGLContext.mm in Sources */ = {isa = PBXBuildFile; fileRef = A32B6D491A14980500E54A65 /* iosOGLContext.mm */; };
A32B6D4D1A14980500E54A65 /* iosOGLContextFactory.mm in Sources */ = {isa = PBXBuildFile; fileRef = A32B6D4B1A14980500E54A65 /* iosOGLContextFactory.mm */; };
+ A3A65D511A9DD45B0057362E /* resources-default in Resources */ = {isa = PBXBuildFile; fileRef = A3A65D501A9DD45B0057362E /* resources-default */; };
A3CC2CD41A1C723900B832E1 /* LocationPredictor.mm in Sources */ = {isa = PBXBuildFile; fileRef = A3CC2CD21A1C723900B832E1 /* LocationPredictor.mm */; };
B00510FB1A11015900A61AA4 /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 972CDCC51887F1B7006641CA /* CFNetwork.framework */; };
B00511021A1101E000A61AA4 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 97C98655186C734000AF7E9E /* AVFoundation.framework */; };
@@ -1147,6 +1148,7 @@
A32B6D491A14980500E54A65 /* iosOGLContext.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = iosOGLContext.mm; path = Platform/opengl/iosOGLContext.mm; sourceTree = ""; };
A32B6D4A1A14980500E54A65 /* iosOGLContextFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = iosOGLContextFactory.h; path = Platform/opengl/iosOGLContextFactory.h; sourceTree = ""; };
A32B6D4B1A14980500E54A65 /* iosOGLContextFactory.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = iosOGLContextFactory.mm; path = Platform/opengl/iosOGLContextFactory.mm; sourceTree = ""; };
+ A3A65D501A9DD45B0057362E /* resources-default */ = {isa = PBXFileReference; lastKnownFileType = folder; path = "resources-default"; sourceTree = ""; };
A3CC2CD21A1C723900B832E1 /* LocationPredictor.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = LocationPredictor.mm; sourceTree = ""; };
A3CC2CD31A1C723900B832E1 /* LocationPredictor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LocationPredictor.h; sourceTree = ""; };
B00511031A1101F600A61AA4 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; };
@@ -2728,6 +2730,7 @@
978D4A30199A11E600D72CA7 /* faq.html */,
FAAEA7D0161BD26600CCD661 /* synonyms.txt */,
F7FDD822147F30CC005900FA /* drules_proto.bin */,
+ A3A65D501A9DD45B0057362E /* resources-default */,
97FC99D919C1A2CD00C1CF98 /* resources-mdpi */,
F607C1821C032A8800B53A87 /* resources-hdpi */,
97FC99DA19C1A2CD00C1CF98 /* resources-xhdpi */,
@@ -3041,6 +3044,7 @@
34CC4C0F1B82069C00E44C1F /* MWMSearchTabbedCollectionViewCell.xib in Resources */,
FA46DA2C12D4166E00968C36 /* countries.txt in Resources */,
4A23D15C1B8B4DD700D4EB6F /* resources-6plus_clear in Resources */,
+ A3A65D511A9DD45B0057362E /* resources-default in Resources */,
EE583CBB12F773F00042CBE3 /* unicode_blocks.txt in Resources */,
EEFE7C1412F8C9E1006AF8C3 /* fonts_blacklist.txt in Resources */,
4A23D15F1B8B4DD700D4EB6F /* resources-xxhdpi_clear in Resources */,
@@ -4725,6 +4729,7 @@
GCC_WARN_UNUSED_VARIABLE = YES;
HEADER_SEARCH_PATHS = (
../../3party/boost,
+ ../../3party/glm,
../../,
);
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
@@ -4743,6 +4748,7 @@
"-lmap",
"-lsearch",
"-ldrape_frontend",
+ "-ldrape_gui",
"-ldrape",
"-lstorage",
"-lrouting",
@@ -4844,6 +4850,7 @@
GCC_WARN_UNUSED_VARIABLE = YES;
HEADER_SEARCH_PATHS = (
../../3party/boost,
+ ../../3party/glm,
../../,
);
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
@@ -4863,6 +4870,7 @@
"-lmap",
"-lsearch",
"-ldrape_frontend",
+ "-ldrape_gui",
"-ldrape",
"-lstorage",
"-lrouting",
@@ -4967,6 +4975,7 @@
GCC_WARN_UNUSED_VARIABLE = YES;
HEADER_SEARCH_PATHS = (
../../3party/boost,
+ ../../3party/glm,
../../,
);
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
@@ -4985,6 +4994,7 @@
"-lmap",
"-lsearch",
"-ldrape_frontend",
+ "-ldrape_gui",
"-ldrape",
"-lstorage",
"-lrouting",
@@ -5090,6 +5100,7 @@
GCC_WARN_UNUSED_VARIABLE = YES;
HEADER_SEARCH_PATHS = (
../../3party/boost,
+ ../../3party/glm,
../../,
);
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
@@ -5108,6 +5119,7 @@
"-lmap",
"-lsearch",
"-ldrape_frontend",
+ "-ldrape_gui",
"-ldrape",
"-lstorage",
"-lrouting",
@@ -5211,6 +5223,7 @@
GCC_WARN_UNUSED_VARIABLE = YES;
HEADER_SEARCH_PATHS = (
../../3party/boost,
+ ../../3party/glm,
../../,
);
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
@@ -5230,6 +5243,7 @@
"-lmap",
"-lsearch",
"-ldrape_frontend",
+ "-ldrape_gui",
"-ldrape",
"-lstorage",
"-lrouting",
@@ -5332,6 +5346,7 @@
GCC_WARN_UNUSED_VARIABLE = YES;
HEADER_SEARCH_PATHS = (
../../3party/boost,
+ ../../3party/glm,
../../,
);
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
@@ -5350,6 +5365,7 @@
"-lmap",
"-lsearch",
"-ldrape_frontend",
+ "-ldrape_gui",
"-ldrape",
"-lstorage",
"-lrouting",
diff --git a/qt/qt.pro b/qt/qt.pro
index a5b2c810ae..842846fcc3 100644
--- a/qt/qt.pro
+++ b/qt/qt.pro
@@ -64,6 +64,8 @@ CLASSIFICATOR_RES.path = $$DATADIR
CLASSIFICATOR_RES.files = ../data/classificator.txt \
../data/types.txt \
../data/drules_proto.bin
+DEFAULT_SKIN_RES.path = $$RESDIR/resources-default
+DEFAULT_SKIN_RES.files = $$RESDIR/resources-default/default.ui
MDPI_SKIN_RES.path = $$DATADIR/resources-mdpi
MDPI_SKIN_RES.files = ../data/resources-mdpi/basic.skn ../data/resources-mdpi/symbols.png
XHDPI_SKIN_RES.path = $$DATADIR/resources-xhdpi
@@ -85,7 +87,7 @@ OTHER_RES.files += ../data/fonts_blacklist.txt \
MWM_RES.path = $$DATADIR
MWM_RES.files = ../data/World.mwm ../data/WorldCoasts.mwm
-ALL_RESOURCES = OTHER_RES CLASSIFICATOR_RES MDPI_SKIN_RES XHDPI_SKIN_RES FONT_RES MWM_RES
+ALL_RESOURCES = OTHER_RES CLASSIFICATOR_RES DEFAULT_SKIN_RES MDPI_SKIN_RES XHDPI_SKIN_RES FONT_RES MWM_RES
linux* {
INSTALLS += $$ALL_RESOURCES