[drape] bookmark creation animation

This commit is contained in:
ExMix 2015-06-09 12:38:51 +03:00 committed by r.kuznetsov
parent a8409a9df7
commit 92bd202123
14 changed files with 171 additions and 64 deletions

View file

@ -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 \

View file

@ -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 <>

View file

@ -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

View 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;
}

View file

@ -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();

View file

@ -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);

View file

@ -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)

View file

@ -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

View file

@ -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);
}

View file

@ -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

View file

@ -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)
{

View file

@ -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

View file

@ -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, ());

View file

@ -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;