diff --git a/drape/shaders/line_vertex_shader.vsh b/drape/shaders/line_vertex_shader.vsh index 721a64b3d9..76fc6aeea5 100644 --- a/drape/shaders/line_vertex_shader.vsh +++ b/drape/shaders/line_vertex_shader.vsh @@ -3,7 +3,7 @@ attribute highp vec4 deltas; attribute highp vec4 width_type; attribute highp vec4 centres; attribute lowp vec4 colors; -attribute mediump vec4 index_opasity; +attribute mediump vec4 index_opacity; varying highp float v_dx; varying highp vec4 v_radius; @@ -45,6 +45,6 @@ void main(void) v_type = width_type.yz; v_colors = colors; - v_index = index_opasity.xy; - v_opacity = index_opasity.zw; + v_index = index_opacity.xy; + v_opacity = index_opacity.zw; } diff --git a/drape/stipple_pen_resource.cpp b/drape/stipple_pen_resource.cpp index c2e20b8edf..cad69f2446 100644 --- a/drape/stipple_pen_resource.cpp +++ b/drape/stipple_pen_resource.cpp @@ -96,10 +96,10 @@ void StipplePenHandle::Init(buffer_vector const & pattern) StipplePenRasterizator::StipplePenRasterizator(StipplePenKey const & key) : m_key(key) { - uint32_t fullPattern = accumulate(m_key.m_pattern.begin(), m_key.m_pattern.end(), 0); - ASSERT(fullPattern < MAX_STIPPLE_PEN_LENGTH, ()); - uint32_t count = floor(MAX_STIPPLE_PEN_LENGTH / fullPattern); - m_pixelLength = count * fullPattern; + m_patternLength = accumulate(m_key.m_pattern.begin(), m_key.m_pattern.end(), 0); + ASSERT(m_patternLength < MAX_STIPPLE_PEN_LENGTH, ()); + uint32_t count = floor(MAX_STIPPLE_PEN_LENGTH / m_patternLength); + m_pixelLength = count * m_patternLength; } uint32_t StipplePenRasterizator::GetSize() const @@ -107,6 +107,11 @@ uint32_t StipplePenRasterizator::GetSize() const return m_pixelLength; } +uint32_t StipplePenRasterizator::GetPatternSize() const +{ + return m_patternLength; +} + uint32_t StipplePenRasterizator::GetBufferSize() const { return m_pixelLength; @@ -146,7 +151,8 @@ StipplePenResourceInfo const * StipplePenIndex::MapResource(StipplePenKey const typedef pair TInsertionNode; MasterPointer info(new StipplePenResourceInfo(m_packer.MapTextureCoords(pixelRect), - resource.GetSize())); + resource.GetSize(), + resource.GetPatternSize())); TInsertionNode result = m_resourceMapping.insert(TResourceMapping::value_type(handle, info)); ASSERT(result.second, ()); return result.first->second.GetRaw(); diff --git a/drape/stipple_pen_resource.hpp b/drape/stipple_pen_resource.hpp index 2d0a5025a6..1814d1e479 100644 --- a/drape/stipple_pen_resource.hpp +++ b/drape/stipple_pen_resource.hpp @@ -43,10 +43,11 @@ private: class StipplePenRasterizator { public: - StipplePenRasterizator() : m_pixelLength(0) {} + StipplePenRasterizator() : m_pixelLength(0), m_patternLength(0) {} StipplePenRasterizator(StipplePenKey const & key); uint32_t GetSize() const; + uint32_t GetPatternSize() const; uint32_t GetBufferSize() const; void Rasterize(void * buffer); @@ -54,22 +55,26 @@ public: private: StipplePenKey m_key; uint32_t m_pixelLength; + uint32_t m_patternLength; }; class StipplePenResourceInfo : public Texture::ResourceInfo { public: - StipplePenResourceInfo(m2::RectF const & texRect, uint32_t pixelLength) + StipplePenResourceInfo(m2::RectF const & texRect, uint32_t pixelLength, uint32_t patternLength) : Texture::ResourceInfo(texRect) , m_pixelLength(pixelLength) + , m_patternLength(patternLength) { } virtual Texture::ResourceType GetType() const { return Texture::StipplePen; } uint32_t GetPixelLength() const { return m_pixelLength; } + uint32_t GetPatternLength() const { return m_patternLength; } private: uint32_t m_pixelLength; + uint32_t m_patternLength; }; class StipplePenPacker diff --git a/drape/texture_set_holder.cpp b/drape/texture_set_holder.cpp index 138d7a3fbc..4df896641d 100644 --- a/drape/texture_set_holder.cpp +++ b/drape/texture_set_holder.cpp @@ -83,4 +83,10 @@ uint32_t TextureSetHolder::StippleRegion::GetTemplateLength() const return static_cast(m_info)->GetPixelLength(); } +uint32_t TextureSetHolder::StippleRegion::GetPatternLength() const +{ + ASSERT(m_info->GetType() == Texture::StipplePen, ()); + return static_cast(m_info)->GetPatternLength(); +} + } // namespace dp diff --git a/drape/texture_set_holder.hpp b/drape/texture_set_holder.hpp index 4047358558..5d5b0b0510 100644 --- a/drape/texture_set_holder.hpp +++ b/drape/texture_set_holder.hpp @@ -68,6 +68,7 @@ public: StippleRegion() : BaseRegion() {} uint32_t GetTemplateLength() const; + uint32_t GetPatternLength() const; }; class ColorRegion : public BaseRegion diff --git a/drape_frontend/apply_feature_functors.cpp b/drape_frontend/apply_feature_functors.cpp index 121ac598c7..488f193b6f 100644 --- a/drape_frontend/apply_feature_functors.cpp +++ b/drape_frontend/apply_feature_functors.cpp @@ -43,9 +43,9 @@ void Extract(::LineDefProto const * lineRule, DashDotProto const & dd = lineRule->dashdot(); int const count = dd.dd_size(); - params.m_key.m_pattern.reserve(count); + params.m_pattern.reserve(count); for (int i = 0; i < count; ++i) - params.m_key.m_pattern.push_back(dd.dd(i) * scale); + params.m_pattern.push_back(dd.dd(i) * scale); } switch(lineRule->cap()) @@ -346,10 +346,7 @@ void ApplyLineFeature::ProcessRule(Stylist::rule_wrapper_t const & rule) LineViewParams params; Extract(pLineRule, params); params.m_depth = depth; - if (params.m_key.m_pattern.empty()) - m_context.InsertShape(m_tileKey, dp::MovePointer(new LineShape(m_spline->GetPath(), params))); - else - m_context.InsertShape(m_tileKey, dp::MovePointer(new LineShape(m_spline->GetPath(), params, m_currentScaleGtoP))); + m_context.InsertShape(m_tileKey, dp::MovePointer(new LineShape(m_spline->GetPath(), params, m_currentScaleGtoP))); } } } diff --git a/drape_frontend/line_shape.cpp b/drape_frontend/line_shape.cpp index 5dabd8a25f..d7ef8561c8 100644 --- a/drape_frontend/line_shape.cpp +++ b/drape_frontend/line_shape.cpp @@ -62,25 +62,6 @@ void Bisector(float R, PointF const & v1, PointF const & v2, PointF const & v3, rightBisector += v2; } -LineShape::LineShape(vector const & points, - LineViewParams const & params) - : m_params(params) - , m_points(params.m_cap == dp::ButtCap ? points.size() : points.size() + 2) - , m_scaleGtoP(1.0f) -{ - ASSERT_GREATER(points.size(), 1, ()); - - int const size = m_points.size(); - if (m_params.m_cap != dp::ButtCap) - { - m_points[0] = points[0] + (points[0] - points[1]).Normalize();; - m_points[size - 1] = points[size - 3] + (points[size - 3] - points[size - 4]).Normalize(); - memcpy(&m_points[1], &points[0], (size - 2) * sizeof(PointF)); - } - else - m_points = points; -} - LineShape::LineShape(vector const & points, LineViewParams const & params, float const scaleGtoP) : m_params(params) @@ -88,42 +69,81 @@ LineShape::LineShape(vector const & points, { ASSERT_GREATER(points.size(), 1, ()); - int const size = points.size(); - if (m_params.m_cap != dp::ButtCap) - m_points.push_back(points[0] + (points[0] - points[1]).Normalize()); + if (m_params.m_pattern.empty()) + { + int const size = params.m_cap == dp::ButtCap ? points.size() : points.size() + 2; + m_points.resize(size); + if (m_params.m_cap != dp::ButtCap) + { + m_points[0] = points[0] + (points[0] - points[1]).Normalize();; + m_points[size - 1] = points[size - 3] + (points[size - 3] - points[size - 4]).Normalize(); + memcpy(&m_points[1], &points[0], (size - 2) * sizeof(PointF)); + } + else + m_points = points; + } + else + m_points = points; +} - dp::StipplePenRasterizator resource(m_params.m_key); - uint32_t const patternLength = resource.GetSize(); - m_points.push_back(points[0]); +void LineShape::doPartition(uint32_t patternLength, uint32_t templateLength, vector & points) const +{ + int const size = m_points.size(); + if (m_params.m_cap != dp::ButtCap) + points.push_back(m_points[0] + (m_points[0] - m_points[1]).Normalize()); + + points.push_back(m_points[0]); for (int i = 1; i < size; ++i) { - PointF const pt = points[i] - points[i - 1]; + PointF const pt = m_points[i] - m_points[i - 1]; float const length = pt.Length() * m_scaleGtoP; - uint32_t const patternPart = std::accumulate(m_params.m_key.m_pattern.begin(), m_params.m_key.m_pattern.end(), 0); - if (length > patternLength - patternPart) + if (length > templateLength - patternLength) { - int const numParts = static_cast(ceilf(length / (patternLength - patternPart))); + int const numParts = static_cast(ceilf(length / (templateLength - patternLength))); PointF const addition = pt / (float)numParts; for (int j = 1; j < numParts; ++j) - m_points.push_back(m_points.back() + addition); + points.push_back(points.back() + addition); } - if (patternLength == patternPart && length > patternLength) + if (templateLength == patternLength && length > templateLength) { - int const numParts = static_cast(ceilf(length / patternLength)); + int const numParts = static_cast(ceilf(length / templateLength)); PointF const addition = pt / (float)numParts; for (int j = 1; j < numParts; ++j) - m_points.push_back(m_points.back() + addition); + points.push_back(points.back() + addition); } - m_points.push_back(points[i]); + points.push_back(m_points[i]); } if (m_params.m_cap != dp::ButtCap) - m_points.push_back(points[size - 1] + (points[size - 1] - points[size - 2]).Normalize()); + points.push_back(m_points[size - 1] + (m_points[size - 1] - m_points[size - 2]).Normalize()); } void LineShape::Draw(dp::RefPointer batcher, dp::RefPointer textures) const { - int size = m_points.size(); + float templateLength, patternLength; + int textureOpacitySet; + m2::RectF rectOpacity; + float texIndexPattern; + vector points; + if (!m_params.m_pattern.empty()) + { + dp::StipplePenKey key; + key.m_pattern = m_params.m_pattern; + dp::TextureSetHolder::StippleRegion region; + textures->GetStippleRegion(key, region); + patternLength = region.GetPatternLength(); + templateLength = region.GetTemplateLength(); + + rectOpacity = m2::RectF(region.GetTexRect()); + texIndexPattern = static_cast(region.GetTextureNode().m_textureOffset); + textureOpacitySet = region.GetTextureNode().m_textureSet; + + doPartition(patternLength, templateLength, points); + } + + vector const & activePoints = m_params.m_pattern.empty() ? m_points : points; + + int size = activePoints.size(); float const r = 1.0f; int const numVert = (size - 1) * 4; @@ -134,8 +154,8 @@ void LineShape::Draw(dp::RefPointer batcher, dp::RefPointer batcher, dp::RefPointer batcher, dp::RefPointerGetColorRegion(key, region); m2::RectF const & rect = region.GetTexRect(); - PointF const coordColor = (rect.RightTop() + rect.LeftBottom()) * 0.5f; + PointF const coordColor = rect.RightTop(); key.SetColor(dp::Color(127, 127, 127, 255).GetColorInInt()); textures->GetColorRegion(key, region); m2::RectF const & outlineRect = region.GetTexRect(); - PointF const coordOutline = (outlineRect.RightTop() + outlineRect.LeftBottom()) * 0.5f; + PointF const coordOutline = outlineRect.RightTop(); float const texIndexColor = static_cast(region.GetTextureNode().m_textureOffset); int textureSet = region.GetTextureNode().m_textureSet; - quad.v[0] = vec4(coordColor, coordOutline); - quad.v[1] = vec4(coordColor, coordOutline); - quad.v[2] = vec4(coordColor, coordOutline); - quad.v[3] = vec4(coordColor, coordOutline); - vector colors(numVert / 4, quad); + vec4 temp = vec4(coordColor, coordOutline); + vector colors(numVert / 4, Quad4(temp, temp, temp, temp)); - if (!m_params.m_key.m_pattern.empty()) + if (!m_params.m_pattern.empty()) { - dp::TextureSetHolder::StippleRegion region; - textures->GetStippleRegion(m_params.m_key, region); - - m2::RectF const & rect = region.GetTexRect(); - float const texIndexPattern = static_cast(region.GetTextureNode().m_textureOffset); - textureSet = region.GetTextureNode().m_textureSet; - - dp::StipplePenRasterizator resource(m_params.m_key); - float const patternLength = resource.GetSize() / (rect.maxX() - rect.minX()); - float const patternPart = std::accumulate(m_params.m_key.m_pattern.begin(), m_params.m_key.m_pattern.end(), 0) / patternLength; + textureSet = textureOpacitySet; + templateLength /= (rectOpacity.maxX() - rectOpacity.minX()); + patternLength /= templateLength; float const koef = halfWidth / m_scaleGtoP / 2.0f; float patternStart = 0.0f; for(int i = 1; i < size; ++i) { - PointF const dif = m_points[i] - m_points[i-1]; + PointF const dif = activePoints[i] - activePoints[i-1]; float dx1 = dxVals[(i-1) * 4].x * koef; float dx2 = dxVals[(i-1) * 4 + 1].x * koef; float dx3 = dxVals[(i-1) * 4 + 2].x * koef; float dx4 = dxVals[(i-1) * 4 + 3].x * koef; - float const length = dif.Length() * m_scaleGtoP / patternLength / (fabs(dx1) + fabs(dx3) + 1.0); + float const length = dif.Length() * m_scaleGtoP / templateLength / (fabs(dx1) + fabs(dx3) + 1.0); float const f1 = fabs(dx1) * length; float const length2 = (fabs(dx1) + 1.0) * length; @@ -269,24 +279,21 @@ void LineShape::Draw(dp::RefPointer batcher, dp::RefPointer= patternPart) - patternStart -= patternPart; + while (patternStart >= patternLength) + patternStart -= patternLength; index.push_back(quad); } } else { - quad.v[0] = vec4(texIndexColor, texIndexColor, coordColor); - quad.v[1] = vec4(texIndexColor, texIndexColor, coordColor); - quad.v[2] = vec4(texIndexColor, texIndexColor, coordColor); - quad.v[3] = vec4(texIndexColor, texIndexColor, coordColor); - index.resize(numVert / 4, quad); + temp = vec4(texIndexColor, texIndexColor, coordColor); + index.resize(numVert / 4, Quad4(temp, temp, temp, temp)); } dp::GLState state(gpu::SOLID_LINE_PROGRAM, dp::GLState::GeometryLayer); @@ -354,7 +361,7 @@ void LineShape::Draw(dp::RefPointer batcher, dp::RefPointer const & points, - LineViewParams const & params); LineShape(vector const & points, LineViewParams const & params, float const scaleGtoP); @@ -24,6 +22,9 @@ public: float GetWidth() const { return m_params.m_width; } dp::Color const & GetColor() const { return m_params.m_color; } +private: + void doPartition(uint32_t patternLength, uint32_t templateLength, vector & points) const; + private: LineViewParams m_params; vector m_points; diff --git a/drape_frontend/shape_view_params.hpp b/drape_frontend/shape_view_params.hpp index d176c1f699..f5855bd69e 100644 --- a/drape_frontend/shape_view_params.hpp +++ b/drape_frontend/shape_view_params.hpp @@ -45,7 +45,7 @@ struct LineViewParams : CommonViewParams float m_width; dp::LineCap m_cap; dp::LineJoin m_join; - dp::StipplePenKey m_key; + buffer_vector m_pattern; }; struct FontDecl diff --git a/drape_head/testing_engine.cpp b/drape_head/testing_engine.cpp index 0b5eb49baa..9382225eab 100644 --- a/drape_head/testing_engine.cpp +++ b/drape_head/testing_engine.cpp @@ -418,7 +418,7 @@ private: vector points; ParseGeometry(json_object_get(object, "geometry"), points); - return new LineShape(points, params); + return new LineShape(points, params, 1.0); } MapShape * CreateArea(json_t * object) @@ -646,7 +646,7 @@ void TestingEngine::DrawImpl() params7.m_width = 4; params7.m_join = dp::LineJoin::RoundJoin; params7.m_cap = dp::LineCap::ButtCap; - params7.m_key = key; + params7.m_pattern = key.m_pattern; vector points; points.push_back(m2::PointF(100.0f, 100.0f));