Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorExMix <rahuba.youri@mapswithme.com>2015-01-13 15:23:46 +0300
committerAlex Zolotarev <alex@maps.me>2015-09-23 02:36:05 +0300
commitd81394156a9549338ae0f31fdd30d809156acfe9 (patch)
treeee203cb4833e5e35bb26851d99de80c69700078d
parent5f09ba278b9b860f44cf528f133d817dca234bdc (diff)
[drape] texture coord generation for stipple lines
-rw-r--r--drape_frontend/line_shape.cpp177
1 files 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<float>(m_region.GetMaskPixelLength());
+ m_patternLength = static_cast<float>(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<dp::Batcher> batcher, dp::RefPointer<dp::TextureManager> textures) const
{
+ typedef gpu::LineVertex LV;
buffer_vector<gpu::LineVertex, 128> geometry;
vector<m2::PointD> const & path = m_spline->GetPath();
@@ -37,19 +102,24 @@ void LineShape::Draw(dp::RefPointer<dp::Batcher> batcher, dp::RefPointer<dp::Tex
textures->GetColorRegion(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<dp::Batcher> batcher, dp::RefPointer<dp::Tex
glsl::vec2 leftSegment(SEGMENT, LEFT_WIDTH);
glsl::vec2 rightSegment(SEGMENT, RIGHT_WIDTH);
+ TexDescription texCoords[2];
+
if (generateCap)
{
glsl::vec2 startPoint = glsl::ToVec2(path[0]);
glsl::vec2 endPoint = glsl::ToVec2(path[1]);
glsl::vec2 tangent, leftNormal, rightNormal;
calcTangentAndNormals(startPoint, endPoint, tangent, leftNormal, rightNormal);
- tangent = -halfWidth * glsl::normalize(tangent);
+ tangent = -halfWidth * tangent;
glsl::vec3 pivot = glsl::vec3(startPoint, m_params.m_depth);
glsl::vec2 leftCap(capType, LEFT_WIDTH);
glsl::vec2 rightCap(capType, RIGHT_WIDTH);
- geometry.push_back(gpu::LineVertex(pivot, leftNormal + tangent, colorCoord, maskCoord, leftCap));
- geometry.push_back(gpu::LineVertex(pivot, rightNormal + tangent, colorCoord, maskCoord, rightCap));
- geometry.push_back(gpu::LineVertex(pivot, leftNormal, colorCoord, maskCoord, leftSegment));
- geometry.push_back(gpu::LineVertex(pivot, rightNormal, colorCoord, maskCoord, rightSegment));
+ texCoords[TEX_BEG_IDX].m_globalLength = 0.0;
+ texCoords[TEX_END_IDX].m_globalLength = glbHalfWidth;
+
+ VERIFY(texCoordGen.GetTexCoords(texCoords[TEX_BEG_IDX]), ());
+ VERIFY(texCoordGen.GetTexCoords(texCoords[TEX_END_IDX]), ());
+
+ geometry.push_back(LV(pivot, leftNormal + tangent, colorCoord, texCoords[TEX_BEG_IDX].m_texCoord, leftCap));
+ geometry.push_back(LV(pivot, rightNormal + tangent, colorCoord, texCoords[TEX_BEG_IDX].m_texCoord, rightCap));
+ geometry.push_back(LV(pivot, leftNormal, colorCoord, texCoords[TEX_END_IDX].m_texCoord, leftSegment));
+ geometry.push_back(LV(pivot, rightNormal, colorCoord, texCoords[TEX_END_IDX].m_texCoord, rightSegment));
}
glsl::vec2 prevPoint;
@@ -108,26 +186,39 @@ void LineShape::Draw(dp::RefPointer<dp::Batcher> batcher, dp::RefPointer<dp::Tex
if (m_params.m_join == dp::BevelJoin)
{
- geometry.push_back(gpu::LineVertex(startPivot, prevForming, colorCoord, maskCoord, leftSegment));
- geometry.push_back(gpu::LineVertex(startPivot, zeroNormal, colorCoord, maskCoord, leftSegment));
- geometry.push_back(gpu::LineVertex(startPivot, nextForming, colorCoord, maskCoord, leftSegment));
- geometry.push_back(gpu::LineVertex(startPivot, nextForming, colorCoord, maskCoord, leftSegment));
+ texCoords[TEX_BEG_IDX].m_globalLength = 0.0f;
+ texCoords[TEX_END_IDX].m_globalLength = glsl::length(nextForming - prevForming) / m_params.m_baseGtoPScale;
+ VERIFY(texCoordGen.GetTexCoords(texCoords[TEX_BEG_IDX]), ());
+ VERIFY(texCoordGen.GetTexCoords(texCoords[TEX_END_IDX]), ());
+
+ geometry.push_back(LV(startPivot, prevForming, colorCoord, texCoords[TEX_BEG_IDX].m_texCoord, leftSegment));
+ geometry.push_back(LV(startPivot, zeroNormal, colorCoord, texCoords[TEX_BEG_IDX].m_texCoord, leftSegment));
+ geometry.push_back(LV(startPivot, nextForming, colorCoord, texCoords[TEX_END_IDX].m_texCoord, leftSegment));
+ geometry.push_back(LV(startPivot, nextForming, colorCoord, texCoords[TEX_END_IDX].m_texCoord, leftSegment));
}
else
{
glsl::vec2 middleForming = glsl::normalize(prevForming + nextForming);
glsl::vec2 zeroDxDy(0.0, 0.0);
+ texCoords[TEX_BEG_IDX].m_globalLength = 0.0f;
+ texCoords[TEX_END_IDX].m_globalLength = glsl::length(nextForming - prevForming) / m_params.m_baseGtoPScale;
+ TexDescription middle;
+ middle.m_globalLength = texCoords[TEX_END_IDX].m_globalLength / 2.0f;
+ VERIFY(texCoordGen.GetTexCoords(texCoords[TEX_BEG_IDX]), ());
+ VERIFY(texCoordGen.GetTexCoords(middle), ());
+ VERIFY(texCoordGen.GetTexCoords(texCoords[TEX_END_IDX]), ());
+
if (m_params.m_join == dp::MiterJoin)
{
float const b = glsl::length(prevForming - nextForming) / 2.0;
float const a = glsl::length(prevForming);
middleForming *= static_cast<float>(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<dp::Batcher> batcher, dp::RefPointer<dp::Tex
glsl::vec2 dxdyLeft(0.0, -1.0);
glsl::vec2 dxdyRight(0.0, -1.0);
glsl::vec2 dxdyMiddle(1.0, 1.0);
- geometry.push_back(gpu::LineVertex(startPivot, zeroNormal, colorCoord, maskCoord, zeroDxDy));
- geometry.push_back(gpu::LineVertex(startPivot, prevForming, colorCoord, maskCoord, dxdyLeft));
- geometry.push_back(gpu::LineVertex(startPivot, nextForming, colorCoord, maskCoord, dxdyRight));
- geometry.push_back(gpu::LineVertex(startPivot, middleForming, colorCoord, maskCoord, dxdyMiddle));
+ geometry.push_back(LV(startPivot, zeroNormal, colorCoord, texCoords[TEX_BEG_IDX].m_texCoord, zeroDxDy));
+ geometry.push_back(LV(startPivot, prevForming, colorCoord, texCoords[TEX_BEG_IDX].m_texCoord, dxdyLeft));
+ geometry.push_back(LV(startPivot, nextForming, colorCoord, texCoords[TEX_END_IDX].m_texCoord, dxdyRight));
+ geometry.push_back(LV(startPivot, middleForming, colorCoord, middle.m_texCoord, dxdyMiddle));
}
}
}
- geometry.push_back(gpu::LineVertex(startPivot, leftNormal, colorCoord, maskCoord, leftSegment));
- geometry.push_back(gpu::LineVertex(startPivot, rightNormal, colorCoord, maskCoord, rightSegment));
- geometry.push_back(gpu::LineVertex(endPivot, leftNormal, colorCoord, maskCoord, leftSegment));
- geometry.push_back(gpu::LineVertex(endPivot, rightNormal, colorCoord, maskCoord, rightSegment));
+ texCoords[TEX_BEG_IDX].m_globalLength = 0.0;
+ texCoords[TEX_END_IDX].m_globalLength = glsl::length(endPoint - startPoint);
+ VERIFY(texCoordGen.GetTexCoords(texCoords[TEX_BEG_IDX]), ());
+ while (!texCoordGen.GetTexCoords(texCoords[TEX_END_IDX]))
+ {
+ glsl::vec2 newEndPoint = startPoint + tangent * texCoords[TEX_END_IDX].m_globalLength;
+ glsl::vec3 newEndPivot = glsl::vec3(newEndPoint, m_params.m_depth);
+
+ geometry.push_back(LV(startPivot, leftNormal, colorCoord, texCoords[TEX_BEG_IDX].m_texCoord, leftSegment));
+ geometry.push_back(LV(startPivot, rightNormal, colorCoord, texCoords[TEX_BEG_IDX].m_texCoord, rightSegment));
+ geometry.push_back(LV(newEndPivot, leftNormal, colorCoord, texCoords[TEX_END_IDX].m_texCoord, leftSegment));
+ geometry.push_back(LV(newEndPivot, rightNormal, colorCoord, texCoords[TEX_END_IDX].m_texCoord, rightSegment));
+
+ startPoint = newEndPoint;
+ startPivot = newEndPivot;
+
+ VERIFY(texCoordGen.GetTexCoords(texCoords[TEX_BEG_IDX]), ());
+ texCoords[TEX_END_IDX].m_globalLength = glsl::length(endPoint - startPoint);
+ }
+
+ geometry.push_back(LV(startPivot, leftNormal, colorCoord, texCoords[TEX_BEG_IDX].m_texCoord, leftSegment));
+ geometry.push_back(LV(startPivot, rightNormal, colorCoord, texCoords[TEX_BEG_IDX].m_texCoord, rightSegment));
+ geometry.push_back(LV(endPivot, leftNormal, colorCoord, texCoords[TEX_END_IDX].m_texCoord, leftSegment));
+ geometry.push_back(LV(endPivot, rightNormal, colorCoord, texCoords[TEX_END_IDX].m_texCoord, rightSegment));
prevPoint = startPoint;
prevLeftNormal = leftNormal;
@@ -161,16 +272,22 @@ void LineShape::Draw(dp::RefPointer<dp::Batcher> batcher, dp::RefPointer<dp::Tex
glsl::vec2 endPoint = glsl::ToVec2(path[lastPointIndex]);
glsl::vec2 tangent, leftNormal, rightNormal;
calcTangentAndNormals(startPoint, endPoint, tangent, leftNormal, rightNormal);
- tangent = halfWidth * glsl::normalize(tangent);
+ tangent = halfWidth * tangent;
glsl::vec3 pivot = glsl::vec3(endPoint, m_params.m_depth);
glsl::vec2 leftCap(capType, LEFT_WIDTH);
glsl::vec2 rightCap(capType, RIGHT_WIDTH);
- geometry.push_back(gpu::LineVertex(pivot, leftNormal, colorCoord, maskCoord, leftSegment));
- geometry.push_back(gpu::LineVertex(pivot, rightNormal, colorCoord, maskCoord, rightSegment));
- geometry.push_back(gpu::LineVertex(pivot, leftNormal + tangent, colorCoord, maskCoord, leftCap));
- geometry.push_back(gpu::LineVertex(pivot, rightNormal + tangent, colorCoord, maskCoord, rightCap));
+ texCoords[TEX_BEG_IDX].m_globalLength = 0.0;
+ texCoords[TEX_END_IDX].m_globalLength = glbHalfWidth;
+
+ VERIFY(texCoordGen.GetTexCoords(texCoords[TEX_BEG_IDX]), ());
+ VERIFY(texCoordGen.GetTexCoords(texCoords[TEX_END_IDX]), ());
+
+ geometry.push_back(LV(pivot, leftNormal, colorCoord, texCoords[TEX_BEG_IDX].m_texCoord, leftSegment));
+ geometry.push_back(LV(pivot, rightNormal, colorCoord, texCoords[TEX_BEG_IDX].m_texCoord, rightSegment));
+ geometry.push_back(LV(pivot, leftNormal + tangent, colorCoord, texCoords[TEX_END_IDX].m_texCoord, leftCap));
+ geometry.push_back(LV(pivot, rightNormal + tangent, colorCoord, texCoords[TEX_END_IDX].m_texCoord, rightCap));
}
dp::GLState state(gpu::LINE_PROGRAM, dp::GLState::GeometryLayer);