From d81394156a9549338ae0f31fdd30d809156acfe9 Mon Sep 17 00:00:00 2001 From: ExMix Date: Tue, 13 Jan 2015 15:23:46 +0300 Subject: [PATCH] [drape] texture coord generation for stipple lines --- drape_frontend/line_shape.cpp | 177 ++++++++++++++++++++++++++++------ 1 file changed, 147 insertions(+), 30 deletions(-) diff --git a/drape_frontend/line_shape.cpp b/drape_frontend/line_shape.cpp index 0b6c8f7868..eb434dcffe 100644 --- a/drape_frontend/line_shape.cpp +++ b/drape_frontend/line_shape.cpp @@ -18,6 +18,70 @@ namespace float const CAP = 1.0f; float const LEFT_WIDTH = 1.0f; float const RIGHT_WIDTH = -1.0f; + size_t const TEX_BEG_IDX = 0; + size_t const TEX_END_IDX = 1; + + struct TexDescription + { + float m_globalLength; + glsl::vec2 m_texCoord; + }; + + class TextureCoordGenerator + { + public: + TextureCoordGenerator(float const baseGtoPScale) + : m_baseGtoPScale(baseGtoPScale) + , m_basePtoGScale(1.0f / baseGtoPScale) + { + } + + void SetRegion(dp::TextureManager::StippleRegion const & region, bool isSolid) + { + m_isSolid = isSolid; + m_region = region; + if (!m_isSolid) + { + m_maskLength = static_cast(m_region.GetMaskPixelLength()); + m_patternLength = static_cast(m_region.GetPatternPixelLength()); + } + } + + bool GetTexCoords(TexDescription & desc) + { + if (m_isSolid) + { + desc.m_texCoord = glsl::ToVec2(m_region.GetTexRect().Center()); + return true; + } + + float const pxLength = desc.m_globalLength * m_baseGtoPScale; + float const maskRest = m_maskLength - m_pxCursor; + + m2::RectF const & texRect = m_region.GetTexRect(); + if (maskRest < pxLength) + { + desc.m_globalLength = maskRest * m_basePtoGScale; + desc.m_texCoord = glsl::vec2(texRect.maxX(), texRect.Center().y); + return false; + } + + float texX = texRect.minX() + ((m_pxCursor + pxLength) / m_maskLength) * texRect.SizeX(); + m_pxCursor = fmodf(m_pxCursor + pxLength, m_patternLength); + + desc.m_texCoord = glsl::vec2(texX, texRect.Center().y); + return true; + } + + private: + float const m_baseGtoPScale; + float const m_basePtoGScale; + dp::TextureManager::StippleRegion m_region; + float m_maskLength = 0.0f; + float m_patternLength = 0.0f; + bool m_isSolid = true; + float m_pxCursor = 0.0f; + }; } LineShape::LineShape(m2::SharedSpline const & spline, @@ -30,6 +94,7 @@ LineShape::LineShape(m2::SharedSpline const & spline, void LineShape::Draw(dp::RefPointer batcher, dp::RefPointer textures) const { + typedef gpu::LineVertex LV; buffer_vector geometry; vector const & path = m_spline->GetPath(); @@ -37,19 +102,24 @@ void LineShape::Draw(dp::RefPointer batcher, dp::RefPointerGetColorRegion(m_params.m_color, colorRegion); glsl::vec2 colorCoord(glsl::ToVec2(colorRegion.GetTexRect().Center())); + TextureCoordGenerator texCoordGen(m_params.m_baseGtoPScale); dp::TextureManager::StippleRegion maskRegion; - textures->GetStippleRegion(dp::TextureManager::TStipplePattern{1}, maskRegion); - glsl::vec2 maskCoord(glsl::ToVec2(maskRegion.GetTexRect().Center())); + if (m_params.m_pattern.empty()) + textures->GetStippleRegion(dp::TextureManager::TStipplePattern{1}, maskRegion); + else + textures->GetStippleRegion(m_params.m_pattern, maskRegion); + texCoordGen.SetRegion(maskRegion, m_params.m_pattern.empty()); float const halfWidth = m_params.m_width / 2.0f; + float const glbHalfWidth = halfWidth / m_params.m_baseGtoPScale; bool generateCap = m_params.m_cap != dp::ButtCap; auto const calcTangentAndNormals = [&halfWidth](glsl::vec2 const & pt0, glsl::vec2 const & pt1, glsl::vec2 & tangent, glsl::vec2 & leftNormal, glsl::vec2 & rightNormal) { - tangent = pt1 - pt0; - leftNormal = halfWidth * glsl::normalize(glsl::vec2(tangent.y, -tangent.x)); + tangent = glsl::normalize(pt1 - pt0); + leftNormal = halfWidth * glsl::vec2(tangent.y, -tangent.x); rightNormal = -leftNormal; }; @@ -58,22 +128,30 @@ void LineShape::Draw(dp::RefPointer batcher, dp::RefPointer batcher, dp::RefPointer(sqrt(a * a + b * b)); - geometry.push_back(gpu::LineVertex(startPivot, prevForming, colorCoord, maskCoord, zeroDxDy)); - geometry.push_back(gpu::LineVertex(startPivot, zeroNormal, colorCoord, maskCoord, zeroDxDy)); - geometry.push_back(gpu::LineVertex(startPivot, middleForming, colorCoord, maskCoord, zeroDxDy)); - geometry.push_back(gpu::LineVertex(startPivot, nextForming, colorCoord, maskCoord, zeroDxDy)); + geometry.push_back(LV(startPivot, prevForming, colorCoord, texCoords[TEX_BEG_IDX].m_texCoord, zeroDxDy)); + geometry.push_back(LV(startPivot, zeroNormal, colorCoord, texCoords[TEX_BEG_IDX].m_texCoord, zeroDxDy)); + geometry.push_back(LV(startPivot, middleForming, colorCoord, middle.m_texCoord, zeroDxDy)); + geometry.push_back(LV(startPivot, nextForming, colorCoord, texCoords[TEX_END_IDX].m_texCoord, zeroDxDy)); } else { @@ -136,18 +227,38 @@ void LineShape::Draw(dp::RefPointer batcher, dp::RefPointer batcher, dp::RefPointer