[drape] line joins

join ready
This commit is contained in:
Dmitry Kunin 2014-02-05 18:18:09 +03:00 committed by Alex Zolotarev
parent a90539bb72
commit 2694651c86
6 changed files with 118 additions and 52 deletions

View file

@ -1,59 +1,48 @@
uniform lowp vec4 u_color;
uniform highp float u_width;
varying highp vec4 v_vertType;
varying highp vec4 v_distanceInfo;
highp float cap(lowp float type, highp float dx, highp float dy, highp float width)
highp float cap(lowp float type, highp float dx, highp float dy)
{
highp float hw = width/2.0;
if (type == 0.0)
{
highp float hw = u_width/2.0;
return -(dx*dx + dy*dy) + hw*hw;
}
else
return 1.0;
}
highp float join(lowp float type, highp float dx, highp float dy, highp float width)
highp float join(lowp float type, highp float dx, highp float dy)
{
return 1.0;
if (type > 0.0)
{
highp float hw = u_width/2.0;
return -(dx*dx + dy*dy) + hw*hw;
}
else
return 1.0;
}
void main(void)
{
lowp float vertType = v_vertType.x;
if (vertType == 0.0)
{
gl_FragColor = u_color;
return;
}
highp vec2 d = v_distanceInfo.zw - v_distanceInfo.xy;
highp float width = v_vertType.w;
if (vertType > 0.0)
{
lowp float joinType = v_vertType.z;
if ( join(joinType, d.x, d.y, width) > 0.0 )
{
gl_FragColor = vec4(0.0, 0.0, 1.0, 1.0);
return;
}
discard;
lowp float joinType = v_vertType.y;
if ( join(joinType, d.x, d.y) < 0.0 )
discard;
}
else if (vertType < 0.0)
{
lowp float capType = v_vertType.y;
if ( cap(capType, d.x, d.y, width) > 0.0 )
{
gl_FragColor = u_color;
return;
}
discard;
if ( cap(capType, d.x, d.y) < 0.0 )
discard;
}
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
gl_FragColor = u_color;
}

View file

@ -10,22 +10,30 @@ uniform highp mat4 projection;
void main(void)
{
highp float half_w = a_direction.z;
highp float shift_mult = a_direction.z;
highp float vertexType = a_vertType.x;
highp vec4 pos;
highp vec4 pivot = a_position * modelView;
highp vec4 n = vec4(-a_direction.y, a_direction.x, 0, 0);
highp vec4 pn = normalize(n * modelView) * half_w;
highp vec4 n = vec4(-a_direction.y, a_direction.x, 0, 0);
highp vec4 pn = normalize(n * modelView) * shift_mult;
highp vec4 d = vec4(a_direction.x, a_direction.y, 0, 0);
if (vertexType < 0.0)
{
highp vec4 d = vec4(a_direction.x, a_direction.y, 0, 0);
highp float quadWidth = a_vertType.y <= 0.0 ? 2.0 * abs(half_w) : abs(half_w);
highp float quadWidth = a_vertType.y <= 0.0 ? 2.0 * abs(shift_mult) : abs(shift_mult);
highp vec4 pd = normalize(d * modelView) * quadWidth;
pos = (pn - pd + pivot);
}
else if (vertexType > 0.0)
{
if (shift_mult != 0.0)
pos = pivot + normalize(d * modelView) * shift_mult;
else
pos = pivot;
}
else
{
pos = (pn + pivot);
@ -33,7 +41,6 @@ void main(void)
v_distanceInfo = vec4(pivot.x, pivot.y, pos.x, pos.y);
v_vertType = a_vertType;
v_vertType.w = 2.0 * abs(half_w);
gl_Position = pos * projection;
}

View file

@ -42,7 +42,7 @@ namespace df
switch (lineRule->join())
{
case ::NOJOIN : params.m_join = df::NonJoin;
case ::NOJOIN : params.m_join = df::MiterJoin;
break;
case ::ROUNDJOIN : params.m_join = df::RoundJoin;
break;

View file

@ -34,6 +34,7 @@ namespace df
const float T_CAP = -1.f;
const float T_SEGMENT = 0.f;
const float T_JOIN = +1.f;
const float MIN_JOIN_ANGLE = 15*math::pi/180;
typedef m2::PointF vec2;
@ -109,6 +110,65 @@ namespace df
renderDirections.push_back(directionNeg);
renderVertexTypes.push_back(vec2(T_SEGMENT, 0));
// This is a join!
const bool needJoinSegments = (end != m_points[count - 1]);
if (needJoinSegments && (m_params.m_join != BevelJoin))
{
vec2 vIn = m_points[i] - m_points[i-1];
vec2 vOut = m_points[i+1] - m_points[i];
const float cross = vIn.x*vOut.y - vIn.y*vOut.x;
const float dot = vIn.x*vOut.x + vIn.y*vOut.y;
const float joinAngle = atan2f(cross, dot);
const bool clockWise = cross < 0;
const float directionFix = ( clockWise ? +1 : -1 );
if (fabsf(joinAngle) > MIN_JOIN_ANGLE)
{
const float joinHeight = (m_params.m_join == MiterJoin)
? fabsf(hw / cosf(joinAngle/2))
: 2*hw; // ensure we have enough space for sector
// Add join triangles
Point3D pivot = Point3D::From2D(m_points[i], m_depth);
// T123
vec2 nIn(-vIn.y, vIn.x);
vec2 nInFixed = nIn.Normalize() * directionFix;
renderPoints.push_back(pivot);//1
renderDirections.push_back(Point3D::From2D(nInFixed, hw));
renderVertexTypes.push_back(vec2(T_JOIN, m_params.m_join));
renderPoints.push_back(pivot);//2
renderDirections.push_back(Point3D(0,0,0)); // zero-shift point
renderVertexTypes.push_back(vec2(T_JOIN, m_params.m_join));
// T234
vec2 nOut(-vOut.y, vOut.x);
vec2 nOutFixed = nOut.Normalize() * directionFix;
vec2 joinBackBisec = (nInFixed + nOutFixed).Normalize();
renderPoints.push_back(pivot); //3
renderDirections.push_back(Point3D::From2D(joinBackBisec, joinHeight));
renderVertexTypes.push_back(vec2(T_JOIN, m_params.m_join));
renderPoints.push_back(pivot); //4
renderDirections.push_back(Point3D::From2D(nOutFixed, hw));
renderVertexTypes.push_back(vec2(T_JOIN, m_params.m_join));
if (!clockWise)
{
// We use triangle strip, so we need to create zero-sqare triangle
// for correct rasterization.
renderPoints.push_back(pivot); //4 second time
renderDirections.push_back(Point3D::From2D(nOutFixed, hw));
renderVertexTypes.push_back(vec2(T_JOIN, m_params.m_join));
}
}
}
//
start = end;
}
@ -130,6 +190,7 @@ namespace df
float r, g, b, a;
::Convert(GetColor(), r, g, b, a);
state.GetUniformValues().SetFloatValue("u_color", r, g, b, a);
state.GetUniformValues().SetFloatValue("u_width", GetWidth());
AttributeProvider provider(3, renderPoints.size());

View file

@ -13,9 +13,9 @@ namespace df
enum LineJoin
{
NonJoin = 0,
MiterJoin = -1,
BevelJoin = 0,
RoundJoin = 1,
BevelJoin = 2
};
struct LineViewParams

View file

@ -98,38 +98,45 @@ namespace df
// ... ...
// [0,0] ... [0,31]
//1
vector<m2::PointF> linePoints1;
linePoints1.push_back(grid[1][1]);
linePoints1.push_back(grid[4][2]);
linePoints1.push_back(grid[4][6]);
linePoints1.push_back(grid[8][1]);
linePoints1.push_back(grid[16][4]);
linePoints1.push_back(grid[16][10]);
linePoints1.push_back(grid[24][1]);
linePoints1.push_back(grid[29][4]);
LineViewParams params1;
params1.m_cap = RoundCap;
params1.m_cap = RoundCap;
params1.m_join = RoundJoin;
params1.m_color = Color(255, 255, 50, 255);
params1.m_width = 50.f;
params1.m_width = 80.f;
df::LineShape * line1 = new df::LineShape(linePoints1, 0.0f, params1);
line1->Draw(m_batcher.GetRefPointer());
//
//2
vector<m2::PointF> linePoints2;
linePoints2.push_back(grid[1][5]);
linePoints2.push_back(grid[4][6]);
linePoints2.push_back(grid[8][5]);
linePoints2.push_back(grid[16][8]);
linePoints2.push_back(grid[24][5]);
linePoints2.push_back(grid[29][8]);
linePoints2.push_back(grid[2][28]);
linePoints2.push_back(grid[6][28]);
linePoints2.push_back(grid[6][22]);
linePoints2.push_back(grid[2][22]);
linePoints2.push_back(grid[2][16]);
linePoints2.push_back(grid[6][16]);
LineViewParams params2;
params2.m_cap = SquareCap;
params2.m_cap = SquareCap;
params2.m_join = RoundJoin;
params2.m_color = Color(0, 255, 255, 255);
params2.m_width = 50.f;
df::LineShape * line2 = new df::LineShape(linePoints2, 0.0f, params2);
line2->Draw(m_batcher.GetRefPointer());
//
//3
vector<m2::PointF> linePoints3;
linePoints3.push_back(grid[1][9]);
@ -140,11 +147,13 @@ namespace df
linePoints3.push_back(grid[29][12]);
LineViewParams params3;
params3.m_cap = ButtCap;
params3.m_cap = ButtCap;
params3.m_join = MiterJoin;
params3.m_color = Color(255, 0, 255, 255);
params3.m_width = 50.f;
params3.m_width = 60.f;
df::LineShape * line3 = new df::LineShape(linePoints3, 0.0f, params3);
line3->Draw(m_batcher.GetRefPointer());
//
}
void TestingEngine::ModelViewInit()