forked from organicmaps/organicmaps
[drape] bookmark creation animation
This commit is contained in:
parent
a8409a9df7
commit
92bd202123
14 changed files with 171 additions and 64 deletions
|
@ -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 \
|
||||
|
|
|
@ -64,11 +64,16 @@ inline vec4 ToVec4(dp::Color const & color)
|
|||
double(color.GetAlfa()) / 255);
|
||||
}
|
||||
|
||||
template<typename T, class = typename enable_if<is_integral<T>::value || is_floating_point<T>::value>::type>
|
||||
inline uint8_t GetArithmeticComponentCount()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline uint8_t GetComponentCount()
|
||||
{
|
||||
ASSERT(false, ());
|
||||
return 0;
|
||||
return GetArithmeticComponentCount<T>();
|
||||
}
|
||||
|
||||
template <>
|
||||
|
|
|
@ -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
|
||||
|
|
19
drape/shaders/user_mark.vsh
Normal file
19
drape/shaders/user_mark.vsh
Normal file
|
@ -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;
|
||||
}
|
|
@ -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<dp::GpuProgram> 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<RenderGroup> group)
|
||||
void FrontendRenderer::RenderSingleGroup(ScreenBase const & modelView, ref_ptr<BaseRenderGroup> group)
|
||||
{
|
||||
group->UpdateAnimation();
|
||||
dp::GLState const & state = group->GetState();
|
||||
|
|
|
@ -127,7 +127,7 @@ protected:
|
|||
private:
|
||||
void OnResize(ScreenBase const & screen);
|
||||
void RenderScene(ScreenBase const & modelView);
|
||||
void RenderSingleGroup(ScreenBase const & modelView, ref_ptr<RenderGroup> group);
|
||||
void RenderSingleGroup(ScreenBase const & modelView, ref_ptr<BaseRenderGroup> group);
|
||||
void RefreshProjection();
|
||||
void RefreshModelView(ScreenBase const & screen);
|
||||
ScreenBase const & UpdateScene(bool & modelViewChanged);
|
||||
|
|
|
@ -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<OpacityAnimation>(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<OpacityAnimation>(0.25 /* duration */,
|
||||
1.0 /* startOpacity */,
|
||||
0.0 /* endOpacity */);
|
||||
}
|
||||
|
||||
bool RenderGroupComparator::operator()(drape_ptr<RenderGroup> const & l, drape_ptr<RenderGroup> const & r)
|
||||
{
|
||||
dp::GLState const & lState = l->GetState();
|
||||
|
@ -122,13 +127,27 @@ UserMarkRenderGroup::UserMarkRenderGroup(dp::GLState const & state,
|
|||
drape_ptr<dp::RenderBucket> && 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)
|
||||
|
|
|
@ -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<OpacityAnimation> m_disappearAnimation;
|
||||
|
||||
private:
|
||||
TileKey m_tileKey;
|
||||
|
@ -52,7 +49,7 @@ public:
|
|||
|
||||
void Update(ScreenBase const & modelView);
|
||||
void CollectOverlay(ref_ptr<dp::OverlayTree> tree);
|
||||
void Render(ScreenBase const & screen);
|
||||
void Render(ScreenBase const & screen) override;
|
||||
|
||||
void PrepareForAdd(size_t countForAdd);
|
||||
void AddBucket(drape_ptr<dp::RenderBucket> && 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<drape_ptr<dp::RenderBucket> > m_renderBuckets;
|
||||
unique_ptr<OpacityAnimation> m_disappearAnimation;
|
||||
|
||||
mutable bool m_pendingOnDelete;
|
||||
|
||||
|
@ -87,10 +90,13 @@ public:
|
|||
drape_ptr<dp::RenderBucket> && bucket);
|
||||
~UserMarkRenderGroup();
|
||||
|
||||
void Render(ScreenBase const & screen);
|
||||
void UpdateAnimation() override;
|
||||
void Render(ScreenBase const & screen) override;
|
||||
|
||||
private:
|
||||
drape_ptr<dp::RenderBucket> m_renderBucket;
|
||||
unique_ptr<OpacityAnimation> m_animation;
|
||||
ValueMapping<float> m_mapping;
|
||||
};
|
||||
|
||||
} // namespace df
|
||||
|
|
|
@ -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 <typename TFieldType, typename TVertexType>
|
||||
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<TFieldType>();
|
||||
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<TPosition, UserPointVertex>(0, "a_position", info, offset);
|
||||
offset += FillDecl<TNormal, UserPointVertex>(1, "a_normal", info, offset);
|
||||
offset += FillDecl<TTexCoord, UserPointVertex>(2, "a_colorTexCoords", info, offset);
|
||||
offset += FillDecl<bool, UserPointVertex>(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<dp::Batcher> batcher,
|
||||
ref_ptr<dp::TextureManager> textures)
|
||||
|
@ -83,7 +127,7 @@ void CacheUserPoints(UserMarksProvider const * provider,
|
|||
|
||||
uint32_t vertexCount = dp::Batcher::VertexPerQuad * markCount; // 4 vertex per quad
|
||||
|
||||
buffer_vector<gpu::SolidTexturingVertex, 1024> buffer;
|
||||
buffer_vector<UPV, 1024> buffer;
|
||||
buffer.reserve(vertexCount);
|
||||
|
||||
vector<UserPointMark const *> 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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<Bookmark *>(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)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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, ());
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue