From 92bd2021230e4e4e815fd6df3020b3dc49b7637d Mon Sep 17 00:00:00 2001 From: ExMix Date: Tue, 9 Jun 2015 12:38:51 +0300 Subject: [PATCH] [drape] bookmark creation animation --- drape/drape.pro | 17 +++--- drape/glsl_types.hpp | 9 +++- drape/shaders/shader_index.txt | 1 + drape/shaders/user_mark.vsh | 19 +++++++ drape_frontend/frontend_renderer.cpp | 12 +---- drape_frontend/frontend_renderer.hpp | 2 +- drape_frontend/render_group.cpp | 75 ++++++++++++++++---------- drape_frontend/render_group.hpp | 22 +++++--- drape_frontend/user_mark_shapes.cpp | 59 +++++++++++++++++--- drape_frontend/user_marks_provider.hpp | 1 + map/bookmark.cpp | 10 ++++ map/bookmark.hpp | 2 + map/user_mark.cpp | 5 ++ map/user_mark.hpp | 1 + 14 files changed, 171 insertions(+), 64 deletions(-) create mode 100644 drape/shaders/user_mark.vsh diff --git a/drape/drape.pro b/drape/drape.pro index 0129e908c0..396cc46639 100644 --- a/drape/drape.pro +++ b/drape/drape.pro @@ -12,14 +12,15 @@ include($$DRAPE_DIR/drape_common.pri) SOURCES += glfunctions.cpp OTHER_FILES += \ - shaders/texturing_vertex_shader.vsh \ - shaders/texturing_fragment_shader.fsh \ - shaders/shader_index.txt \ - shaders/line_vertex_shader.vsh \ + shaders/compass_vertex_shader.vsh \ shaders/line_fragment_shader.fsh \ + shaders/line_vertex_shader.vsh \ + shaders/my_position_shader.vsh \ + shaders/position_accuracy_shader.vsh \ + shaders/ruler_vertex_shader.vsh \ + shaders/shader_index.txt \ shaders/text_fragment_shader.fsh \ shaders/text_vertex_shader.vsh \ - shaders/compass_vertex_shader.vsh \ - shaders/ruler_vertex_shader.vsh \ - shaders/position_accuracy_shader.vsh \ - shaders/my_position_shader.vsh + shaders/texturing_fragment_shader.fsh \ + shaders/texturing_vertex_shader.vsh \ + shaders/user_mark.vsh \ diff --git a/drape/glsl_types.hpp b/drape/glsl_types.hpp index 7ff0f0e405..48f3a27092 100644 --- a/drape/glsl_types.hpp +++ b/drape/glsl_types.hpp @@ -64,11 +64,16 @@ inline vec4 ToVec4(dp::Color const & color) double(color.GetAlfa()) / 255); } +template::value || is_floating_point::value>::type> +inline uint8_t GetArithmeticComponentCount() +{ + return 1; +} + template inline uint8_t GetComponentCount() { - ASSERT(false, ()); - return 0; + return GetArithmeticComponentCount(); } template <> diff --git a/drape/shaders/shader_index.txt b/drape/shaders/shader_index.txt index 09aef4d4e7..7adb7b7b14 100644 --- a/drape/shaders/shader_index.txt +++ b/drape/shaders/shader_index.txt @@ -6,3 +6,4 @@ RULER_PROGRAM ruler_vertex_shader.vsh texturing_fragment_shader.fsh ACCURACY_PROGRAM position_accuracy_shader.vsh texturing_fragment_shader.fsh MY_POSITION_PROGRAM my_position_shader.vsh texturing_fragment_shader.fsh BUTTON_PROGRAM button_vertex_shader.vsh button_fragment_shader.fsh +BOOKMARK_PROGRAM user_mark.vsh texturing_fragment_shader.fsh diff --git a/drape/shaders/user_mark.vsh b/drape/shaders/user_mark.vsh new file mode 100644 index 0000000000..1d9a77677e --- /dev/null +++ b/drape/shaders/user_mark.vsh @@ -0,0 +1,19 @@ +attribute vec3 a_position; +attribute vec2 a_normal; +attribute vec2 a_colorTexCoords; +attribute float a_animate; + +uniform mat4 modelView; +uniform mat4 projection; +uniform float u_interpolationT; + +varying vec2 v_colorTexCoords; + +void main(void) +{ + vec2 normal = a_normal; + if (a_animate > 0.0) + normal = u_interpolationT * normal; + gl_Position = (vec4(normal, 0, 0) + vec4(a_position, 1) * modelView) * projection; + v_colorTexCoords = a_colorTexCoords; +} diff --git a/drape_frontend/frontend_renderer.cpp b/drape_frontend/frontend_renderer.cpp index f515bfd966..a0c066af50 100755 --- a/drape_frontend/frontend_renderer.cpp +++ b/drape_frontend/frontend_renderer.cpp @@ -492,15 +492,7 @@ void FrontendRenderer::RenderScene(ScreenBase const & modelView) ASSERT(group.get() != nullptr, ()); group->UpdateAnimation(); if (m_userMarkVisibility.find(group->GetTileKey()) != m_userMarkVisibility.end()) - { - dp::GLState const & state = group->GetState(); - ref_ptr program = m_gpuProgramManager->GetProgram(state.GetProgramIndex()); - program->Bind(); - ApplyUniforms(m_generalUniforms, program); - ApplyUniforms(group->GetUniforms(), program); - ApplyState(state, program); - group->Render(modelView); - } + RenderSingleGroup(modelView, make_ref(group)); } GLFunctions::glClearDepth(); @@ -512,7 +504,7 @@ void FrontendRenderer::RenderScene(ScreenBase const & modelView) #endif } -void FrontendRenderer::RenderSingleGroup(ScreenBase const & modelView, ref_ptr group) +void FrontendRenderer::RenderSingleGroup(ScreenBase const & modelView, ref_ptr group) { group->UpdateAnimation(); dp::GLState const & state = group->GetState(); diff --git a/drape_frontend/frontend_renderer.hpp b/drape_frontend/frontend_renderer.hpp index 65b605cf39..9f2a98dd6c 100755 --- a/drape_frontend/frontend_renderer.hpp +++ b/drape_frontend/frontend_renderer.hpp @@ -127,7 +127,7 @@ protected: private: void OnResize(ScreenBase const & screen); void RenderScene(ScreenBase const & modelView); - void RenderSingleGroup(ScreenBase const & modelView, ref_ptr group); + void RenderSingleGroup(ScreenBase const & modelView, ref_ptr group); void RefreshProjection(); void RefreshModelView(ScreenBase const & screen); ScreenBase const & UpdateScene(bool & modelViewChanged); diff --git a/drape_frontend/render_group.cpp b/drape_frontend/render_group.cpp index 1573ee426a..d8d069a9b1 100755 --- a/drape_frontend/render_group.cpp +++ b/drape_frontend/render_group.cpp @@ -10,34 +10,7 @@ namespace df void BaseRenderGroup::UpdateAnimation() { - double opactity = 1.0; - if (m_disappearAnimation != nullptr) - opactity = m_disappearAnimation->GetOpacity(); - - m_uniforms.SetFloatValue("u_opacity", opactity); -} - -double BaseRenderGroup::GetOpacity() const -{ - if (m_disappearAnimation != nullptr) - return m_disappearAnimation->GetOpacity(); - - return 1.0; -} - -bool BaseRenderGroup::IsAnimating() const -{ - if (m_disappearAnimation == nullptr || m_disappearAnimation->IsFinished()) - return false; - - return true; -} - -void BaseRenderGroup::Disappear() -{ - m_disappearAnimation = make_unique(0.25 /* duration */, - 1.0 /* startOpacity */, - 0.0 /* endOpacity */); + m_uniforms.SetFloatValue("u_opacity", 1.0); } RenderGroup::RenderGroup(dp::GLState const & state, df::TileKey const & tileKey) @@ -84,6 +57,38 @@ bool RenderGroup::IsLess(RenderGroup const & other) const return m_state < other.m_state; } +void RenderGroup::UpdateAnimation() +{ + double opactity = 1.0; + if (m_disappearAnimation != nullptr) + opactity = m_disappearAnimation->GetOpacity(); + + m_uniforms.SetFloatValue("u_opacity", opactity); +} + +double RenderGroup::GetOpacity() const +{ + if (m_disappearAnimation != nullptr) + return m_disappearAnimation->GetOpacity(); + + return 1.0; +} + +bool RenderGroup::IsAnimating() const +{ + if (m_disappearAnimation == nullptr || m_disappearAnimation->IsFinished()) + return false; + + return true; +} + +void RenderGroup::Disappear() +{ + m_disappearAnimation = make_unique(0.25 /* duration */, + 1.0 /* startOpacity */, + 0.0 /* endOpacity */); +} + bool RenderGroupComparator::operator()(drape_ptr const & l, drape_ptr const & r) { dp::GLState const & lState = l->GetState(); @@ -122,13 +127,27 @@ UserMarkRenderGroup::UserMarkRenderGroup(dp::GLState const & state, drape_ptr && bucket) : TBase(state, tileKey) , m_renderBucket(move(bucket)) + , m_animation(new OpacityAnimation(0.25 /*duration*/, 0.0 /* minValue */, 1.0 /* maxValue*/)) { + m_mapping.AddRangePoint(0.6, 1.3); + m_mapping.AddRangePoint(0.85, 0.8); + m_mapping.AddRangePoint(1.0, 1.0); } UserMarkRenderGroup::~UserMarkRenderGroup() { } +void UserMarkRenderGroup::UpdateAnimation() +{ + BaseRenderGroup::UpdateAnimation(); + float t = 1.0; + if (m_animation) + t = m_animation->GetOpacity(); + + m_uniforms.SetFloatValue("u_interpolationT", m_mapping.GetValue(t)); +} + void UserMarkRenderGroup::Render(ScreenBase const & screen) { if (m_renderBucket != nullptr) diff --git a/drape_frontend/render_group.hpp b/drape_frontend/render_group.hpp index 810e75fdbe..87981509aa 100755 --- a/drape_frontend/render_group.hpp +++ b/drape_frontend/render_group.hpp @@ -1,6 +1,7 @@ #pragma once #include "drape_frontend/animation/opacity_animation.hpp" +#include "drape_frontend/animation/value_mapping.hpp" #include "drape_frontend/tile_utils.hpp" #include "drape/pointers.hpp" @@ -28,16 +29,12 @@ public: TileKey const & GetTileKey() const { return m_tileKey; } dp::UniformValuesStorage const & GetUniforms() const { return m_uniforms; } - double GetOpacity() const; - void UpdateAnimation(); - bool IsAnimating() const; - - void Disappear(); + virtual void UpdateAnimation(); + virtual void Render(ScreenBase const & /*screen*/) {} protected: dp::GLState m_state; dp::UniformValuesStorage m_uniforms; - unique_ptr m_disappearAnimation; private: TileKey m_tileKey; @@ -52,7 +49,7 @@ public: void Update(ScreenBase const & modelView); void CollectOverlay(ref_ptr tree); - void Render(ScreenBase const & screen); + void Render(ScreenBase const & screen) override; void PrepareForAdd(size_t countForAdd); void AddBucket(drape_ptr && bucket); @@ -63,8 +60,14 @@ public: bool IsLess(RenderGroup const & other) const; + void UpdateAnimation() override; + double GetOpacity() const; + bool IsAnimating() const; + void Disappear(); + private: vector > m_renderBuckets; + unique_ptr m_disappearAnimation; mutable bool m_pendingOnDelete; @@ -87,10 +90,13 @@ public: drape_ptr && bucket); ~UserMarkRenderGroup(); - void Render(ScreenBase const & screen); + void UpdateAnimation() override; + void Render(ScreenBase const & screen) override; private: drape_ptr m_renderBucket; + unique_ptr m_animation; + ValueMapping m_mapping; }; } // namespace df diff --git a/drape_frontend/user_mark_shapes.cpp b/drape_frontend/user_mark_shapes.cpp index 4d01aa6294..22ce3da0f1 100644 --- a/drape_frontend/user_mark_shapes.cpp +++ b/drape_frontend/user_mark_shapes.cpp @@ -73,6 +73,50 @@ void AlignVertical(float halfHeight, dp::Anchor anchor, AlignFormingNormals([&halfHeight]{ return glsl::vec2(0.0f, -halfHeight); }, anchor, dp::Top, dp::Bottom, up, down); } +template +uint8_t FillDecl(size_t index, string const & attrName, dp::BindingInfo & info, uint8_t offset) +{ + dp::BindingDecl & decl = info.GetBindingDecl(index); + decl.m_attributeName = attrName; + decl.m_componentCount = glsl::GetComponentCount(); + decl.m_componentType = gl_const::GLFloatType; + decl.m_offset = offset; + decl.m_stride = sizeof(TVertexType); + + return sizeof(TFieldType); +} + +struct UserPointVertex : gpu::BaseVertex +{ + UserPointVertex() = default; + UserPointVertex(TPosition const & pos, TNormal const & normal, TTexCoord const & texCoord, bool isAnim) + : m_position(pos) + , m_normal(normal) + , m_texCoord(texCoord) + , m_isAnim(isAnim ? 1.0 : -1.0) + { + } + + static dp::BindingInfo GetBinding() + { + dp::BindingInfo info(4); + uint8_t offset = 0; + offset += FillDecl(0, "a_position", info, offset); + offset += FillDecl(1, "a_normal", info, offset); + offset += FillDecl(2, "a_colorTexCoords", info, offset); + offset += FillDecl(3, "a_animate", info, offset); + + return info; + } + + TPosition m_position; + TNormal m_normal; + TTexCoord m_texCoord; + float m_isAnim; +}; + +using UPV = UserPointVertex; + void CacheUserPoints(UserMarksProvider const * provider, ref_ptr batcher, ref_ptr textures) @@ -83,7 +127,7 @@ void CacheUserPoints(UserMarksProvider const * provider, uint32_t vertexCount = dp::Batcher::VertexPerQuad * markCount; // 4 vertex per quad - buffer_vector buffer; + buffer_vector buffer; buffer.reserve(vertexCount); vector marks; @@ -105,22 +149,23 @@ void CacheUserPoints(UserMarksProvider const * provider, m2::PointF pxSize = region.GetPixelSize(); dp::Anchor anchor = pointMark->GetAnchor(); glsl::vec3 pos = glsl::vec3(glsl::ToVec2(pointMark->GetPivot()), pointMark->GetDepth() + 10 * (markCount - i)); + bool runAnim = pointMark->RunCreationAnim(); glsl::vec2 left, right, up, down; AlignHorizontal(pxSize.x * 0.5f, anchor, left, right); AlignVertical(pxSize.y * 0.5f, anchor, up, down); - buffer.push_back(gpu::SolidTexturingVertex(pos, left + down, glsl::ToVec2(texRect.LeftTop()))); - buffer.push_back(gpu::SolidTexturingVertex(pos, left + up, glsl::ToVec2(texRect.LeftBottom()))); - buffer.push_back(gpu::SolidTexturingVertex(pos, right + down, glsl::ToVec2(texRect.RightTop()))); - buffer.push_back(gpu::SolidTexturingVertex(pos, right + up, glsl::ToVec2(texRect.RightBottom()))); + buffer.emplace_back(pos, left + down, glsl::ToVec2(texRect.LeftTop()), runAnim); + buffer.emplace_back(pos, left + up, glsl::ToVec2(texRect.LeftBottom()), runAnim); + buffer.emplace_back(pos, right + down, glsl::ToVec2(texRect.RightTop()), runAnim); + buffer.emplace_back(pos, right + up, glsl::ToVec2(texRect.RightBottom()), runAnim); } - dp::GLState state(gpu::TEXTURING_PROGRAM, dp::GLState::UserMarkLayer); + dp::GLState state(gpu::BOOKMARK_PROGRAM, dp::GLState::UserMarkLayer); state.SetColorTexture(region.GetTexture()); dp::AttributeProvider attribProvider(1, buffer.size()); - attribProvider.InitStream(0, gpu::SolidTexturingVertex::GetBindingInfo(), make_ref(buffer.data())); + attribProvider.InitStream(0, UPV::GetBinding(), make_ref(buffer.data())); batcher->InsertListOfStrip(state, make_ref(&attribProvider), dp::Batcher::VertexPerQuad); } diff --git a/drape_frontend/user_marks_provider.hpp b/drape_frontend/user_marks_provider.hpp index 2ae2156ea1..39c2f033d1 100644 --- a/drape_frontend/user_marks_provider.hpp +++ b/drape_frontend/user_marks_provider.hpp @@ -19,6 +19,7 @@ public: virtual string GetSymbolName() const = 0; virtual dp::Anchor GetAnchor() const = 0; virtual float GetDepth() const = 0; + virtual bool RunCreationAnim() const = 0; }; class UserLineMark diff --git a/map/bookmark.cpp b/map/bookmark.cpp index 5c302c6942..eb181e5132 100644 --- a/map/bookmark.cpp +++ b/map/bookmark.cpp @@ -29,12 +29,14 @@ Bookmark::Bookmark(m2::PointD const & ptOrg, UserMarkContainer * container) : TBase(ptOrg, container) + , m_runCreationAnim(true) { } Bookmark::Bookmark(BookmarkData const & data, m2::PointD const & ptOrg, UserMarkContainer * container) : TBase(ptOrg, container) , m_data(data) + , m_runCreationAnim(true) { } @@ -75,6 +77,13 @@ void Bookmark::FillLogEvent(TEventContainer & details) const details.emplace("name", GetData().GetName()); } +bool Bookmark::RunCreationAnim() const +{ + bool result = m_runCreationAnim; + m_runCreationAnim = false; + return result; +} + string const & Bookmark::GetName() const { return m_data.GetName(); @@ -412,6 +421,7 @@ namespace { Bookmark * bm = static_cast(m_controller.CreateUserMark(m_org)); bm->SetData(BookmarkData(m_name, m_type, m_description, m_scale, m_timeStamp)); + bm->RunCreationAnim(); } else if (GEOMETRY_TYPE_LINE == m_geometryType) { diff --git a/map/bookmark.hpp b/map/bookmark.hpp index da5a4ec4e3..4081e6cddf 100644 --- a/map/bookmark.hpp +++ b/map/bookmark.hpp @@ -83,6 +83,7 @@ public: Type GetMarkType() const override; void FillLogEvent(TEventContainer & details) const override; + bool RunCreationAnim() const override; string const & GetName() const; void SetName(string const & name); @@ -110,6 +111,7 @@ public: private: BookmarkData m_data; + mutable bool m_runCreationAnim; }; class BookmarkCategory : public UserMarkContainer diff --git a/map/user_mark.cpp b/map/user_mark.cpp index cc2e69c60b..0060bcc18e 100644 --- a/map/user_mark.cpp +++ b/map/user_mark.cpp @@ -39,6 +39,11 @@ float UserMark::GetDepth() const return GetContainer()->GetPointDepth(); } +bool UserMark::RunCreationAnim() const +{ + return false; +} + UserMarkContainer const * UserMark::GetContainer() const { ASSERT(m_container != nullptr, ()); diff --git a/map/user_mark.hpp b/map/user_mark.hpp index e508b2cbfd..cd99e84dcc 100644 --- a/map/user_mark.hpp +++ b/map/user_mark.hpp @@ -41,6 +41,7 @@ public: m2::PointD const & GetPivot() const override; dp::Anchor GetAnchor() const override; float GetDepth() const override; + bool RunCreationAnim() const override; /////////////////////////////////////////////////////// UserMarkContainer const * GetContainer() const;