From a79643d279e58944ab7386f4d670ca193a2a30b7 Mon Sep 17 00:00:00 2001 From: "r.kuznetsov" Date: Tue, 2 Jun 2015 10:57:22 +0300 Subject: [PATCH] Fixed UV generation for line shapes --- drape/shaders/line_fragment_shader.fsh | 8 +- drape/shaders/line_vertex_shader.vsh | 3 - drape/utils/vertex_decl.cpp | 17 +- drape/utils/vertex_decl.hpp | 4 +- drape_frontend/line_shape.cpp | 359 +++++++------------------ 5 files changed, 98 insertions(+), 293 deletions(-) diff --git a/drape/shaders/line_fragment_shader.fsh b/drape/shaders/line_fragment_shader.fsh index faa7afa94d..785d84ee00 100644 --- a/drape/shaders/line_fragment_shader.fsh +++ b/drape/shaders/line_fragment_shader.fsh @@ -1,6 +1,5 @@ varying vec2 v_colorTexCoord; varying vec2 v_maskTexCoord; -varying vec2 v_dxdy; uniform sampler2D u_colorTex; uniform sampler2D u_maskTex; @@ -9,13 +8,10 @@ uniform float u_opacity; void main(void) { float mask = texture2D(u_maskTex, v_maskTexCoord).a; - vec4 color = texture2D(u_colorTex, v_colorTexCoord); - - float domen = v_dxdy.x * v_dxdy.x + v_dxdy.y * v_dxdy.y; - - if (mask < 0.1 || domen > 1.0) + if (mask < 0.1) discard; + vec4 color = texture2D(u_colorTex, v_colorTexCoord); color.a *= u_opacity; gl_FragColor = color; } diff --git a/drape/shaders/line_vertex_shader.vsh b/drape/shaders/line_vertex_shader.vsh index 61f84a671f..841b05c998 100644 --- a/drape/shaders/line_vertex_shader.vsh +++ b/drape/shaders/line_vertex_shader.vsh @@ -2,14 +2,12 @@ attribute vec3 a_position; attribute vec2 a_normal; attribute vec2 a_colorTexCoord; attribute vec2 a_maskTexCoord; -attribute vec2 a_dxdy; uniform mat4 modelView; uniform mat4 projection; varying vec2 v_colorTexCoord; varying vec2 v_maskTexCoord; -varying vec2 v_dxdy; void main(void) { @@ -24,6 +22,5 @@ void main(void) v_colorTexCoord = a_colorTexCoord; v_maskTexCoord = a_maskTexCoord; - v_dxdy = a_dxdy; gl_Position = vec4(transformedAxisPos, a_position.z, 1.0) * projection; } diff --git a/drape/utils/vertex_decl.cpp b/drape/utils/vertex_decl.cpp index 5e3dd04891..99e29ac77a 100644 --- a/drape/utils/vertex_decl.cpp +++ b/drape/utils/vertex_decl.cpp @@ -110,9 +110,10 @@ dp::BindingInfo TextDynamicBindingInit() dp::BindingInfo LineBindingInit() { static_assert(sizeof(LineVertex) == sizeof(LineVertex::TPosition) + - 2 * sizeof(LineVertex::TNormal) + + sizeof(LineVertex::TNormal) + 2 * sizeof(LineVertex::TTexCoord), ""); - dp::BindingInfo info(5); + dp::BindingInfo info(4); +> dp::BindingDecl & posDecl = info.GetBindingDecl(0); posDecl.m_attributeName = "a_position"; @@ -142,13 +143,6 @@ dp::BindingInfo LineBindingInit() maskDecl.m_offset = colorDecl.m_offset + sizeof(LineVertex::TTexCoord); maskDecl.m_stride = posDecl.m_stride; - dp::BindingDecl & dxdyDecl = info.GetBindingDecl(4); - dxdyDecl.m_attributeName = "a_dxdy"; - dxdyDecl.m_componentCount = glsl::GetComponentCount(); - dxdyDecl.m_componentType = gl_const::GLFloatType; - dxdyDecl.m_offset = maskDecl.m_offset + sizeof(LineVertex::TNormal); - dxdyDecl.m_stride = posDecl.m_stride; - return info; } @@ -242,18 +236,15 @@ LineVertex::LineVertex() , m_normal(0.0, 0.0) , m_colorTexCoord(0.0, 0.0) , m_maskTexCoord(0.0, 0.0) - , m_dxdy(0.0, 0.0) { } LineVertex::LineVertex(TPosition const & position, TNormal const & normal, - TTexCoord const & color, TTexCoord const & mask, - TNormal const & dxdy) + TTexCoord const & color, TTexCoord const & mask) : m_position(position) , m_normal(normal) , m_colorTexCoord(color) , m_maskTexCoord(mask) - , m_dxdy(dxdy) { } diff --git a/drape/utils/vertex_decl.hpp b/drape/utils/vertex_decl.hpp index 9a9c888f42..046476c548 100644 --- a/drape/utils/vertex_decl.hpp +++ b/drape/utils/vertex_decl.hpp @@ -63,14 +63,12 @@ struct LineVertex : BaseVertex { LineVertex(); LineVertex(TPosition const & position, TNormal const & normal, - TTexCoord const & color, TTexCoord const & mask, - TNormal const & dxdy); + TTexCoord const & color, TTexCoord const & mask); TPosition m_position; TNormal m_normal; TTexCoord m_colorTexCoord; TTexCoord m_maskTexCoord; - TNormal m_dxdy; static dp::BindingInfo const & GetBindingInfo(); }; diff --git a/drape_frontend/line_shape.cpp b/drape_frontend/line_shape.cpp index e02ae5b8c2..be09d642e4 100644 --- a/drape_frontend/line_shape.cpp +++ b/drape_frontend/line_shape.cpp @@ -16,10 +16,8 @@ namespace df namespace { - float const SEGMENT = 0.0f; - float const CAP = 1.0f; - float const LEFT_WIDTH = 1.0f; - float const RIGHT_WIDTH = -1.0f; + using LV = gpu::LineVertex; + using TGeometryBuffer = buffer_vector; class TextureCoordGenerator { @@ -89,14 +87,14 @@ namespace glsl::vec2 m_leftNormals[PointsCount]; glsl::vec2 m_rightBaseNormal; glsl::vec2 m_rightNormals[PointsCount]; - float m_leftWidthScalar[PointsCount]; - float m_rightWidthScalar[PointsCount]; + glsl::vec2 m_leftWidthScalar[PointsCount]; + glsl::vec2 m_rightWidthScalar[PointsCount]; bool m_hasLeftJoin[PointsCount]; LineSegment() { - m_leftWidthScalar[StartPoint] = m_leftWidthScalar[EndPoint] = 1.0f; - m_rightWidthScalar[StartPoint] = m_rightWidthScalar[EndPoint] = 1.0f; + m_leftWidthScalar[StartPoint] = m_leftWidthScalar[EndPoint] = glsl::vec2(1.0f, 0.0f); + m_rightWidthScalar[StartPoint] = m_rightWidthScalar[EndPoint] = glsl::vec2(1.0f, 0.0f); m_hasLeftJoin[StartPoint] = m_hasLeftJoin[EndPoint] = true; } }; @@ -130,7 +128,8 @@ namespace segment2->m_rightNormals[StartPoint] = averageNormal; float const cosAngle = glsl::dot(segment1->m_tangent, averageNormal); - segment1->m_rightWidthScalar[EndPoint] = 1.0f / sqrt(1.0f - cosAngle * cosAngle); + segment1->m_rightWidthScalar[EndPoint].x = 1.0f / sqrt(1.0f - cosAngle * cosAngle); + segment1->m_rightWidthScalar[EndPoint].y = segment1->m_rightWidthScalar[EndPoint].x * cosAngle; segment2->m_rightWidthScalar[StartPoint] = segment1->m_rightWidthScalar[EndPoint]; } else @@ -145,7 +144,8 @@ namespace segment2->m_leftNormals[StartPoint] = averageNormal; float const cosAngle = glsl::dot(segment1->m_tangent, averageNormal); - segment1->m_leftWidthScalar[EndPoint] = 1.0f / sqrt(1.0f - cosAngle * cosAngle); + segment1->m_leftWidthScalar[EndPoint].x = 1.0f / sqrt(1.0f - cosAngle * cosAngle); + segment1->m_leftWidthScalar[EndPoint].y = segment1->m_leftWidthScalar[EndPoint].x * cosAngle; segment2->m_leftWidthScalar[StartPoint] = segment1->m_leftWidthScalar[EndPoint]; } } @@ -161,24 +161,6 @@ namespace UpdateNormalBetweenSegments(segment, nextSegment); } - /*uint32_t BuildRect(vector & vertices, - glsl::vec2 const & v1, glsl::vec2 const & v2, - glsl::vec2 const & v3, glsl::vec2 const & v4) - - { - glsl::vec3 const position(0.0f, 0.0f, 0.0f); - - vertices.push_back(Button::ButtonVertex(position, v1)); - vertices.push_back(Button::ButtonVertex(position, v2)); - vertices.push_back(Button::ButtonVertex(position, v3)); - - vertices.push_back(Button::ButtonVertex(position, v3)); - vertices.push_back(Button::ButtonVertex(position, v2)); - vertices.push_back(Button::ButtonVertex(position, v4)); - - return dp::Batcher::IndexPerQuad; - }*/ - void GenerateJoinNormals(dp::LineJoin joinType, glsl::vec2 const & normal1, glsl::vec2 const & normal2, float halfWidth, bool isLeft, float widthScalar, vector & normals) { @@ -269,6 +251,35 @@ namespace } } } + + float GetProjectionLength(glsl::vec2 const & newPoint, glsl::vec2 const & startPoint, + glsl::vec2 const & endPoint) + { + glsl::vec2 const v1 = endPoint - startPoint; + glsl::vec2 const v2 = newPoint - startPoint; + float const squareLen = glsl::dot(v1, v1); + float const proj = glsl::dot(v1, v2) / squareLen; + return sqrt(squareLen) * max(min(proj, 1.0f), 0.0f); + } + + void CalculateTangentAndNormals(glsl::vec2 const & pt0, glsl::vec2 const & pt1, + glsl::vec2 & tangent, glsl::vec2 & leftNormal, + glsl::vec2 & rightNormal) + { + tangent = glsl::normalize(pt1 - pt0); + leftNormal = glsl::vec2(-tangent.y, tangent.x); + rightNormal = -leftNormal; + } + + glsl::vec2 GetNormal(LineSegment const & segment, bool isLeft, ENormalType normalType) + { + if (normalType == BaseNormal) + return isLeft ? segment.m_leftBaseNormal : segment.m_rightBaseNormal; + + int const index = (normalType == StartNormal) ? StartPoint : EndPoint; + return isLeft ? segment.m_leftWidthScalar[index].x * segment.m_leftNormals[index]: + segment.m_rightWidthScalar[index].x * segment.m_rightNormals[index]; + } } LineShape::LineShape(m2::SharedSpline const & spline, @@ -281,12 +292,12 @@ LineShape::LineShape(m2::SharedSpline const & spline, void LineShape::Draw(ref_ptr batcher, ref_ptr textures) const { - typedef gpu::LineVertex LV; - buffer_vector geometry; - buffer_vector joinsGeometry; + TGeometryBuffer geometry; + TGeometryBuffer joinsGeometry; vector const & path = m_spline->GetPath(); ASSERT(path.size() > 1, ()); + // set up uv-generator dp::TextureManager::ColorRegion colorRegion; textures->GetColorRegion(m_params.m_color, colorRegion); glsl::vec2 colorCoord(glsl::ToVec2(colorRegion.GetTexRect().Center())); @@ -299,54 +310,32 @@ void LineShape::Draw(ref_ptr batcher, ref_ptr t 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 = [](glsl::vec2 const & pt0, glsl::vec2 const & pt1, - glsl::vec2 & tangent, glsl::vec2 & leftNormal, - glsl::vec2 & rightNormal) + auto const getLineVertex = [&](LineSegment const & segment, glsl::vec3 const & pivot, + glsl::vec2 const & normal, float offsetFromStart) { - tangent = glsl::normalize(pt1 - pt0); - leftNormal = glsl::vec2(-tangent.y, tangent.x); - rightNormal = -leftNormal; + float distance = GetProjectionLength(pivot.xy() + glbHalfWidth * normal, + segment.m_points[StartPoint], + segment.m_points[EndPoint]) - offsetFromStart; + + return LV(pivot, halfWidth * normal, colorCoord, texCoordGen.GetTexCoordsByDistance(distance)); }; - auto const getNormal = [&halfWidth](LineSegment const & segment, bool isLeft, ENormalType normalType) + auto const generateTriangles = [&](glsl::vec3 const & pivot, vector const & normals) { - if (normalType == BaseNormal) - return halfWidth * (isLeft ? segment.m_leftBaseNormal : segment.m_rightBaseNormal); - - int const index = (normalType == StartNormal) ? StartPoint : EndPoint; - return halfWidth * (isLeft ? segment.m_leftWidthScalar[index] * segment.m_leftNormals[index] : - segment.m_rightWidthScalar[index] * segment.m_rightNormals[index]); + size_t const trianglesCount = normals.size() / 3; + for (int j = 0; j < trianglesCount; j++) + { + glsl::vec2 const uv = texCoordGen.GetTexCoords(0.0f); + joinsGeometry.push_back(LV(pivot, normals[3 * j], colorCoord, uv)); + joinsGeometry.push_back(LV(pivot, normals[3 * j + 1], colorCoord, uv)); + joinsGeometry.push_back(LV(pivot, normals[3 * j + 2], colorCoord, uv)); + } }; - float capType = m_params.m_cap == dp::RoundCap ? CAP : SEGMENT; - - glsl::vec2 leftSegment(SEGMENT, LEFT_WIDTH); - glsl::vec2 rightSegment(SEGMENT, RIGHT_WIDTH); - - /*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 * tangent; - - glsl::vec3 pivot = glsl::vec3(startPoint, m_params.m_depth); - glsl::vec2 leftCap(capType, LEFT_WIDTH); - glsl::vec2 rightCap(capType, RIGHT_WIDTH); - glsl::vec2 const uvStart = texCoordGen.GetTexCoordsByDistance(0.0); - glsl::vec2 const uvEnd = texCoordGen.GetTexCoordsByDistance(glbHalfWidth); - - geometry.push_back(LV(pivot, leftNormal + tangent, colorCoord, uvStart, leftCap)); - geometry.push_back(LV(pivot, rightNormal + tangent, colorCoord, uvStart, rightCap)); - geometry.push_back(LV(pivot, leftNormal, colorCoord, uvEnd, leftSegment)); - geometry.push_back(LV(pivot, rightNormal, colorCoord, uvEnd, rightSegment)); - }*/ - // constuct segments vector segments; segments.reserve(path.size() - 1); @@ -355,8 +344,8 @@ void LineShape::Draw(ref_ptr batcher, ref_ptr t LineSegment segment; segment.m_points[StartPoint] = glsl::ToVec2(path[i - 1]); segment.m_points[EndPoint] = glsl::ToVec2(path[i]); - calcTangentAndNormals(segment.m_points[StartPoint], segment.m_points[EndPoint], segment.m_tangent, - segment.m_leftBaseNormal, segment.m_rightBaseNormal); + CalculateTangentAndNormals(segment.m_points[StartPoint], segment.m_points[EndPoint], segment.m_tangent, + segment.m_leftBaseNormal, segment.m_rightBaseNormal); segment.m_leftNormals[StartPoint] = segment.m_leftNormals[EndPoint] = segment.m_leftBaseNormal; segment.m_rightNormals[StartPoint] = segment.m_rightNormals[EndPoint] = segment.m_rightBaseNormal; @@ -370,14 +359,23 @@ void LineShape::Draw(ref_ptr batcher, ref_ptr t UpdateNormals(&segments[i], (i > 0) ? &segments[i - 1] : nullptr, (i < segments.size() - 1) ? &segments[i + 1] : nullptr); + // calculate number of steps to cover line segment float const initialGlobalLength = glsl::length(segments[i].m_points[EndPoint] - segments[i].m_points[StartPoint]); - float const pixelLen = initialGlobalLength * m_params.m_baseGtoPScale; int steps = 1; float maskSize = initialGlobalLength; if (!texCoordGen.IsSolid()) { - maskSize = texCoordGen.GetMaskLength() / m_params.m_baseGtoPScale; - steps = static_cast((pixelLen + texCoordGen.GetMaskLength() - 1) / texCoordGen.GetMaskLength()); + float const leftWidth = glbHalfWidth * max(segments[i].m_leftWidthScalar[StartPoint].y, + segments[i].m_rightWidthScalar[StartPoint].y); + float const rightWidth = glbHalfWidth * max(segments[i].m_leftWidthScalar[EndPoint].y, + segments[i].m_rightWidthScalar[EndPoint].y); + float const effectiveLength = initialGlobalLength - leftWidth - rightWidth; + if (effectiveLength > 0) + { + float const pixelLen = effectiveLength * m_params.m_baseGtoPScale; + steps = static_cast((pixelLen + texCoordGen.GetMaskLength() - 1) / texCoordGen.GetMaskLength()); + maskSize = effectiveLength / steps; + } } // generate main geometry @@ -385,37 +383,29 @@ void LineShape::Draw(ref_ptr batcher, ref_ptr t glsl::vec3 currentStartPivot = glsl::vec3(segments[i].m_points[StartPoint], m_params.m_depth); for (int step = 0; step < steps; step++) { + float const offsetFromStart = currentSize; currentSize += maskSize; - float endOffset = 1.0f; - if (currentSize >= initialGlobalLength) - { - endOffset = (initialGlobalLength - currentSize + maskSize) / maskSize; - currentSize = initialGlobalLength; - } - glsl::vec2 const newPoint = segments[i].m_points[StartPoint] + segments[i].m_tangent * currentSize; glsl::vec3 const newPivot = glsl::vec3(newPoint, m_params.m_depth); - glsl::vec2 const uvStart = texCoordGen.GetTexCoords(0.0f); - glsl::vec2 const uvEnd = texCoordGen.GetTexCoords(endOffset); ENormalType normalType1 = (step == 0) ? StartNormal : BaseNormal; ENormalType normalType2 = (step == steps - 1) ? EndNormal : BaseNormal; - glsl::vec2 const leftNormal1 = getNormal(segments[i], true /* isLeft */, normalType1); - glsl::vec2 const rightNormal1 = getNormal(segments[i], false /* isLeft */, normalType1); - glsl::vec2 const leftNormal2 = getNormal(segments[i], true /* isLeft */, normalType2); - glsl::vec2 const rightNormal2 = getNormal(segments[i], false /* isLeft */, normalType2); + glsl::vec2 const leftNormal1 = GetNormal(segments[i], true /* isLeft */, normalType1); + glsl::vec2 const rightNormal1 = GetNormal(segments[i], false /* isLeft */, normalType1); + glsl::vec2 const leftNormal2 = GetNormal(segments[i], true /* isLeft */, normalType2); + glsl::vec2 const rightNormal2 = GetNormal(segments[i], false /* isLeft */, normalType2); - geometry.push_back(LV(currentStartPivot, glsl::vec2(0, 0), colorCoord, uvStart, rightSegment)); - geometry.push_back(LV(currentStartPivot, leftNormal1, colorCoord, uvStart, leftSegment)); - geometry.push_back(LV(newPivot, glsl::vec2(0, 0), colorCoord, uvEnd, rightSegment)); - geometry.push_back(LV(newPivot, leftNormal2, colorCoord, uvEnd, leftSegment)); + geometry.push_back(getLineVertex(segments[i], currentStartPivot, glsl::vec2(0, 0), offsetFromStart)); + geometry.push_back(getLineVertex(segments[i], currentStartPivot, leftNormal1, offsetFromStart)); + geometry.push_back(getLineVertex(segments[i], newPivot, glsl::vec2(0, 0), offsetFromStart)); + geometry.push_back(getLineVertex(segments[i], newPivot, leftNormal2, offsetFromStart)); - geometry.push_back(LV(currentStartPivot, rightNormal1, colorCoord, uvStart, rightSegment)); - geometry.push_back(LV(currentStartPivot, glsl::vec2(0, 0), colorCoord, uvStart, leftSegment)); - geometry.push_back(LV(newPivot, rightNormal2, colorCoord, uvEnd, rightSegment)); - geometry.push_back(LV(newPivot, glsl::vec2(0, 0), colorCoord, uvEnd, leftSegment)); + geometry.push_back(getLineVertex(segments[i], currentStartPivot, rightNormal1, offsetFromStart)); + geometry.push_back(getLineVertex(segments[i], currentStartPivot, glsl::vec2(0, 0), offsetFromStart)); + geometry.push_back(getLineVertex(segments[i], newPivot, rightNormal2, offsetFromStart)); + geometry.push_back(getLineVertex(segments[i], newPivot, glsl::vec2(0, 0), offsetFromStart)); currentStartPivot = newPivot; } @@ -428,25 +418,15 @@ void LineShape::Draw(ref_ptr batcher, ref_ptr t glsl::vec2 n2 = segments[i + 1].m_hasLeftJoin[StartPoint] ? segments[i + 1].m_leftNormals[StartPoint] : segments[i + 1].m_rightNormals[StartPoint]; - float widthScalar = segments[i].m_hasLeftJoin[EndPoint] ? segments[i].m_rightWidthScalar[EndPoint] : - segments[i].m_leftWidthScalar[EndPoint]; + float widthScalar = segments[i].m_hasLeftJoin[EndPoint] ? segments[i].m_rightWidthScalar[EndPoint].x : + segments[i].m_leftWidthScalar[EndPoint].x; vector normals; normals.reserve(24); GenerateJoinNormals(m_params.m_join, n1, n2, halfWidth, segments[i].m_hasLeftJoin[EndPoint], widthScalar, normals); - glsl::vec3 const joinPivot = glsl::vec3(segments[i].m_points[EndPoint], m_params.m_depth); - - size_t const trianglesCount = normals.size() / 3; - for (int j = 0; j < trianglesCount; j++) - { - glsl::vec2 const uv = texCoordGen.GetTexCoords(0.0f); //TODO - - joinsGeometry.push_back(LV(joinPivot, normals[3 * j], colorCoord, uv, leftSegment)); - joinsGeometry.push_back(LV(joinPivot, normals[3 * j + 1], colorCoord, uv, rightSegment)); - joinsGeometry.push_back(LV(joinPivot, normals[3 * j + 2], colorCoord, uv, leftSegment)); - } + generateTriangles(glsl::vec3(segments[i].m_points[EndPoint], m_params.m_depth), normals); } // generate caps @@ -458,17 +438,7 @@ void LineShape::Draw(ref_ptr batcher, ref_ptr t segments[i].m_rightNormals[StartPoint], -segments[i].m_tangent, halfWidth, true /* isStart */, normals); - glsl::vec3 const joinPivot = glsl::vec3(segments[i].m_points[StartPoint], m_params.m_depth); - - size_t const trianglesCount = normals.size() / 3; - for (int j = 0; j < trianglesCount; j++) - { - glsl::vec2 const uv = texCoordGen.GetTexCoords(0.0f); //TODO - - joinsGeometry.push_back(LV(joinPivot, normals[3 * j], colorCoord, uv, leftSegment)); - joinsGeometry.push_back(LV(joinPivot, normals[3 * j + 1], colorCoord, uv, rightSegment)); - joinsGeometry.push_back(LV(joinPivot, normals[3 * j + 2], colorCoord, uv, leftSegment)); - } + generateTriangles(glsl::vec3(segments[i].m_points[StartPoint], m_params.m_depth), normals); } if (i == segments.size() - 1) @@ -479,157 +449,10 @@ void LineShape::Draw(ref_ptr batcher, ref_ptr t segments[i].m_rightNormals[EndPoint], segments[i].m_tangent, halfWidth, false /* isStart */, normals); - glsl::vec3 const joinPivot = glsl::vec3(segments[i].m_points[EndPoint], m_params.m_depth); - - size_t const trianglesCount = normals.size() / 3; - for (int j = 0; j < trianglesCount; j++) - { - glsl::vec2 const uv = texCoordGen.GetTexCoords(0.0f); //TODO - - joinsGeometry.push_back(LV(joinPivot, normals[3 * j], colorCoord, uv, leftSegment)); - joinsGeometry.push_back(LV(joinPivot, normals[3 * j + 1], colorCoord, uv, rightSegment)); - joinsGeometry.push_back(LV(joinPivot, normals[3 * j + 2], colorCoord, uv, leftSegment)); - } + generateTriangles(glsl::vec3(segments[i].m_points[EndPoint], m_params.m_depth), normals); } } - //glsl::vec2 prevPoint; - //glsl::vec2 prevLeftNormal; - //glsl::vec2 prevRightNormal; - - /*for (size_t i = 1; i < path.size(); ++i) - { - glsl::vec2 startPoint = glsl::ToVec2(path[i - 1]); - glsl::vec2 endPoint = glsl::ToVec2(path[i]); - glsl::vec2 tangent, leftNormal, rightNormal; - calcTangentAndNormals(startPoint, endPoint, tangent, leftNormal, rightNormal); - - glsl::vec3 startPivot = glsl::vec3(startPoint, m_params.m_depth); - - // Create join beetween current segment and previous - if (i > 1) - { - glsl::vec2 zeroNormal(0.0, 0.0); - glsl::vec2 prevForming, nextForming; - if (glsl::dot(prevLeftNormal, tangent) < 0) - { - prevForming = prevLeftNormal; - nextForming = leftNormal; - } - else - { - prevForming = prevRightNormal; - nextForming = rightNormal; - } - - float const distance = glsl::length(nextForming - prevForming) / m_params.m_baseGtoPScale; - float const endUv = min(1.0f, texCoordGen.GetUvOffsetByDistance(distance)); - glsl::vec2 const uvStart = texCoordGen.GetTexCoords(0.0f); - glsl::vec2 const uvEnd = texCoordGen.GetTexCoords(endUv); - - if (m_params.m_join == dp::BevelJoin) - { - geometry.push_back(LV(startPivot, prevForming, colorCoord, uvStart, leftSegment)); - geometry.push_back(LV(startPivot, zeroNormal, colorCoord, uvStart, leftSegment)); - geometry.push_back(LV(startPivot, nextForming, colorCoord, uvEnd, leftSegment)); - geometry.push_back(LV(startPivot, nextForming, colorCoord, uvEnd, leftSegment)); - } - else - { - glsl::vec2 middleForming = glsl::normalize(prevForming + nextForming); - glsl::vec2 zeroDxDy(0.0, 0.0); - - float const middleUv = 0.5f * endUv; - glsl::vec2 const uvMiddle = texCoordGen.GetTexCoords(middleUv); - - if (m_params.m_join == dp::MiterJoin) - { - float const b = 0.5f * glsl::length(prevForming - nextForming); - float const a = glsl::length(prevForming); - middleForming *= static_cast(sqrt(a * a + b * b)); - - geometry.push_back(LV(startPivot, prevForming, colorCoord, uvStart, zeroDxDy)); - geometry.push_back(LV(startPivot, zeroNormal, colorCoord, uvStart, zeroDxDy)); - geometry.push_back(LV(startPivot, middleForming, colorCoord, uvMiddle, zeroDxDy)); - geometry.push_back(LV(startPivot, nextForming, colorCoord, uvEnd, zeroDxDy)); - } - else - { - middleForming *= glsl::length(prevForming); - - glsl::vec2 dxdyLeft(0.0, -1.0); - glsl::vec2 dxdyRight(0.0, -1.0); - glsl::vec2 dxdyMiddle(1.0, 1.0); - geometry.push_back(LV(startPivot, zeroNormal, colorCoord, uvStart, zeroDxDy)); - geometry.push_back(LV(startPivot, prevForming, colorCoord, uvStart, dxdyLeft)); - geometry.push_back(LV(startPivot, nextForming, colorCoord, uvEnd, dxdyRight)); - geometry.push_back(LV(startPivot, middleForming, colorCoord, uvMiddle, dxdyMiddle)); - } - } - } - - float initialGlobalLength = glsl::length(endPoint - startPoint); - float pixelLen = initialGlobalLength * m_params.m_baseGtoPScale; - int steps = 1; - float maskSize = initialGlobalLength; - if (!texCoordGen.IsSolid()) - { - maskSize = texCoordGen.GetMaskLength() / m_params.m_baseGtoPScale; - steps = static_cast((pixelLen + texCoordGen.GetMaskLength() - 1) / texCoordGen.GetMaskLength()); - } - - float currentSize = 0; - glsl::vec3 currentStartPivot = startPivot; - for (int i = 0; i < steps; i++) - { - currentSize += maskSize; - - float endOffset = 1.0f; - if (currentSize >= initialGlobalLength) - { - endOffset = (initialGlobalLength - currentSize + maskSize) / maskSize; - currentSize = initialGlobalLength; - } - - glsl::vec2 const newPoint = startPoint + tangent * currentSize; - glsl::vec3 const newPivot = glsl::vec3(newPoint, m_params.m_depth); - glsl::vec2 const uvStart = texCoordGen.GetTexCoords(0.0f); - glsl::vec2 const uvEnd = texCoordGen.GetTexCoords(endOffset); - - geometry.push_back(LV(currentStartPivot, leftNormal, colorCoord, uvStart, leftSegment)); - geometry.push_back(LV(currentStartPivot, rightNormal, colorCoord, uvStart, rightSegment)); - geometry.push_back(LV(newPivot, leftNormal, colorCoord, uvEnd, leftSegment)); - geometry.push_back(LV(newPivot, rightNormal, colorCoord, uvEnd, rightSegment)); - - currentStartPivot = newPivot; - } - - prevPoint = currentStartPivot.xy(); - prevLeftNormal = leftNormal; - prevRightNormal = rightNormal; - }*/ - - /*if (generateCap) - { - size_t lastPointIndex = path.size() - 1; - glsl::vec2 startPoint = glsl::ToVec2(path[lastPointIndex - 1]); - glsl::vec2 endPoint = glsl::ToVec2(path[lastPointIndex]); - glsl::vec2 tangent, leftNormal, rightNormal; - calcTangentAndNormals(startPoint, endPoint, tangent, leftNormal, rightNormal); - 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); - glsl::vec2 const uvStart = texCoordGen.GetTexCoordsByDistance(0.0); - glsl::vec2 const uvEnd = texCoordGen.GetTexCoordsByDistance(glbHalfWidth); - - geometry.push_back(LV(pivot, leftNormal, colorCoord, uvStart, leftSegment)); - geometry.push_back(LV(pivot, rightNormal, colorCoord, uvStart, rightSegment)); - geometry.push_back(LV(pivot, leftNormal + tangent, colorCoord, uvEnd, leftCap)); - geometry.push_back(LV(pivot, rightNormal + tangent, colorCoord, uvEnd, rightCap)); - }*/ - dp::GLState state(gpu::LINE_PROGRAM, dp::GLState::GeometryLayer); state.SetColorTexture(colorRegion.GetTexture()); state.SetMaskTexture(maskRegion.GetTexture());