From 9576341b7e6253ca75f8cb6885b7aacb0e9ce71f Mon Sep 17 00:00:00 2001 From: Mikko Mononen Date: Sun, 16 Feb 2014 18:41:56 +0200 Subject: [PATCH] Reversed path winding to make it actually ccw --- src/nanovg.c | 88 ++++++++++++++++++++++----------------------- src/nanovg_gl3buf.h | 11 +----- 2 files changed, 45 insertions(+), 54 deletions(-) diff --git a/src/nanovg.c b/src/nanovg.c index a2e43c4..fc40beb 100644 --- a/src/nanovg.c +++ b/src/nanovg.c @@ -1027,9 +1027,9 @@ static void nvg__flattenPaths(struct NVGcontext* ctx, float m) // Enforce winding. if (path->count > 2) { area = nvg__polyArea(pts, path->count); - if (path->winding == NVG_CCW && area > 0.0f) + if (path->winding == NVG_CCW && area < 0.0f) nvg__polyReverse(pts, path->count); - if (path->winding == NVG_CW && area < 0.0f) + if (path->winding == NVG_CW && area > 0.0f) nvg__polyReverse(pts, path->count); } @@ -1077,7 +1077,7 @@ static void nvg__flattenPaths(struct NVGcontext* ctx, float m) if ((dmr2 * m*m) < 1.0f) { cross = p1->dx * p0->dy - p0->dx * p1->dy; p1->flags |= NVG_BEVEL; - if (cross < 0) { + if (cross > 0.0f) { p1->flags |= NVG_LEFT; nleft++; } @@ -1149,19 +1149,19 @@ static int nvg__expandStrokeAndFill(struct NVGcontext* ctx, int feats, float w) float dlx1 = p1->dy; float dly1 = -p1->dx; if (p1->flags & NVG_LEFT) { - float lx = p1->x - p1->dmx * wo; - float ly = p1->y - p1->dmy * wo; + float lx = p1->x + p1->dmx * wo; + float ly = p1->y + p1->dmy * wo; nvg__vset(dst, lx, ly, 0.5f,1); dst++; } else { - float lx0 = p1->x - dlx0 * wo; - float ly0 = p1->y - dly0 * wo; - float lx1 = p1->x - dlx1 * wo; - float ly1 = p1->y - dly1 * wo; + float lx0 = p1->x + dlx0 * wo; + float ly0 = p1->y + dly0 * wo; + float lx1 = p1->x + dlx1 * wo; + float ly1 = p1->y + dly1 * wo; nvg__vset(dst, lx0, ly0, 0.5f,1); dst++; nvg__vset(dst, lx1, ly1, 0.5f,1); dst++; } } else { - nvg__vset(dst, p1->x - (p1->dmx * wo), p1->y - (p1->dmy * wo), 0.5f,1); dst++; + nvg__vset(dst, p1->x + (p1->dmx * wo), p1->y + (p1->dmy * wo), 0.5f,1); dst++; } p0 = p1++; } @@ -1181,7 +1181,7 @@ static int nvg__expandStrokeAndFill(struct NVGcontext* ctx, int feats, float w) // Calculate fringe if (feats & NVG_STROKE) { float lw = w + wo, rw = w - wo; - float u0 = 0, u1 = 1; + float ru = 1, lu = 0; int loop = ((feats & NVG_CAPS) && path->closed == 0) ? 0 : 1; dst = verts; path->stroke = dst; @@ -1190,7 +1190,7 @@ static int nvg__expandStrokeAndFill(struct NVGcontext* ctx, int feats, float w) // the shape can be rendered without stenciling. if (convex) { lw = wo; // This should generate the same vertex as fill inset above. - u1 = 0.5f; // Set outline fade at middle. + lu = 0.5f; // Set outline fade at middle. } if (loop) { @@ -1215,10 +1215,10 @@ static int nvg__expandStrokeAndFill(struct NVGcontext* ctx, int feats, float w) nvg__normalize(&dx, &dy); dlx = dy; dly = -dx; - nvg__vset(dst, p0->x + dlx*rw - dx*aa, p0->y + dly*rw - dy*aa, u0,0); dst++; - nvg__vset(dst, p0->x - dlx*lw - dx*aa, p0->y - dly*lw - dy*aa, u1,0); dst++; - nvg__vset(dst, p0->x + dlx*rw, p0->y + dly * rw, u0,1); dst++; - nvg__vset(dst, p0->x - dlx*lw, p0->y - dly * lw, u1,1); dst++; + nvg__vset(dst, p0->x + dlx*lw - dx*aa, p0->y + dly*lw - dy*aa, lu,0); dst++; + nvg__vset(dst, p0->x - dlx*rw - dx*aa, p0->y - dly*rw - dy*aa, ru,0); dst++; + nvg__vset(dst, p0->x + dlx*lw, p0->y + dly * lw, lu,1); dst++; + nvg__vset(dst, p0->x - dlx*rw, p0->y - dly * rw, ru,1); dst++; } for (j = s; j < e; ++j) { @@ -1228,39 +1228,39 @@ static int nvg__expandStrokeAndFill(struct NVGcontext* ctx, int feats, float w) float dlx1 = p1->dy; float dly1 = -p1->dx; if (p1->flags & NVG_LEFT) { - float rx0 = p1->x + dlx0 * rw; - float ry0 = p1->y + dly0 * rw; - float rx1 = p1->x + dlx1 * rw; - float ry1 = p1->y + dly1 * rw; - float lx = p1->x - p1->dmx * lw; - float ly = p1->y - p1->dmy * lw; - nvg__vset(dst, rx0, ry0, u0,1); dst++; - nvg__vset(dst, lx, ly, u1,1); dst++; - nvg__vset(dst, rx1, ry1, u0,1); dst++; - nvg__vset(dst, lx, ly, u1,1); dst++; + float rx0 = p1->x - dlx0 * rw; + float ry0 = p1->y - dly0 * rw; + float rx1 = p1->x - dlx1 * rw; + float ry1 = p1->y - dly1 * rw; + float lx = p1->x + p1->dmx * lw; + float ly = p1->y + p1->dmy * lw; + nvg__vset(dst, lx, ly, lu,1); dst++; + nvg__vset(dst, rx0, ry0, ru,1); dst++; + nvg__vset(dst, lx, ly, lu,1); dst++; + nvg__vset(dst, rx1, ry1, ru,1); dst++; } else { - float rx = p1->x + p1->dmx * rw; - float ry = p1->y + p1->dmy * rw; - float lx0 = p1->x - dlx0 * lw; - float ly0 = p1->y - dly0 * lw; - float lx1 = p1->x - dlx1 * lw; - float ly1 = p1->y - dly1 * lw; - nvg__vset(dst, rx, ry, u0,1); dst++; - nvg__vset(dst, lx0, ly0, u1,1); dst++; - nvg__vset(dst, rx, ry, u0,1); dst++; - nvg__vset(dst, lx1, ly1, u1,1); dst++; + float rx = p1->x - p1->dmx * rw; + float ry = p1->y - p1->dmy * rw; + float lx0 = p1->x + dlx0 * lw; + float ly0 = p1->y + dly0 * lw; + float lx1 = p1->x + dlx1 * lw; + float ly1 = p1->y + dly1 * lw; + nvg__vset(dst, lx0, ly0, lu,1); dst++; + nvg__vset(dst, rx, ry, ru,1); dst++; + nvg__vset(dst, lx1, ly1, lu,1); dst++; + nvg__vset(dst, rx, ry, ru,1); dst++; } } else { - nvg__vset(dst, p1->x + (p1->dmx * rw), p1->y + (p1->dmy * rw), u0,1); dst++; - nvg__vset(dst, p1->x - (p1->dmx * lw), p1->y - (p1->dmy * lw), u1,1); dst++; + nvg__vset(dst, p1->x + (p1->dmx * lw), p1->y + (p1->dmy * lw), lu,1); dst++; + nvg__vset(dst, p1->x - (p1->dmx * rw), p1->y - (p1->dmy * rw), ru,1); dst++; } p0 = p1++; } if (loop) { // Loop it - nvg__vset(dst, verts[0].x, verts[0].y, u0,1); dst++; - nvg__vset(dst, verts[1].x, verts[1].y, u1,1); dst++; + nvg__vset(dst, verts[0].x, verts[0].y, lu,1); dst++; + nvg__vset(dst, verts[1].x, verts[1].y, ru,1); dst++; } else { // Add cap float dx, dy, dlx, dly; @@ -1269,10 +1269,10 @@ static int nvg__expandStrokeAndFill(struct NVGcontext* ctx, int feats, float w) nvg__normalize(&dx, &dy); dlx = dy; dly = -dx; - nvg__vset(dst, p1->x + dlx*rw, p1->y + dly * rw, u0,1); dst++; - nvg__vset(dst, p1->x - dlx*lw, p1->y - dly * lw, u1,1); dst++; - nvg__vset(dst, p1->x + dlx*rw + dx*aa, p1->y + dly*rw + dy*aa, u0,0); dst++; - nvg__vset(dst, p1->x - dlx*lw + dx*aa, p1->y - dly*lw + dy*aa, u1,0); dst++; + nvg__vset(dst, p1->x + dlx*lw, p1->y + dly * lw, lu,1); dst++; + nvg__vset(dst, p1->x - dlx*rw, p1->y - dly * rw, ru,1); dst++; + nvg__vset(dst, p1->x + dlx*lw + dx*aa, p1->y + dly*lw + dy*aa, lu,0); dst++; + nvg__vset(dst, p1->x - dlx*rw + dx*aa, p1->y - dly*rw + dy*aa, ru,0); dst++; } path->nstroke = (int)(dst - verts); diff --git a/src/nanovg_gl3buf.h b/src/nanovg_gl3buf.h index 7562196..922dfc9 100644 --- a/src/nanovg_gl3buf.h +++ b/src/nanovg_gl3buf.h @@ -672,17 +672,12 @@ static void glnvg__fill(struct GLNVGcontext* gl, struct GLNVGcall* call) if (npaths == 1 && paths[0].convex) { - glEnable(GL_CULL_FACE); - glnvg__setupPaint(gl, &call->paint, &call->scissor, 1.0001f); - glDisable(GL_CULL_FACE); for (i = 0; i < npaths; i++) { glDrawArrays(GL_TRIANGLE_FAN, paths[i].fillOffset, paths[i].fillCount); } - glEnable(GL_CULL_FACE); - if (gl->edgeAntiAlias) { // Draw fringes for (i = 0; i < npaths; i++) { @@ -692,8 +687,6 @@ static void glnvg__fill(struct GLNVGcontext* gl, struct GLNVGcall* call) } else { - glEnable(GL_CULL_FACE); - // Draw shapes glDisable(GL_BLEND); glEnable(GL_STENCIL_TEST); @@ -711,7 +704,6 @@ static void glnvg__fill(struct GLNVGcontext* gl, struct GLNVGcall* call) for (i = 0; i < npaths; i++) { glDrawArrays(GL_TRIANGLE_FAN, paths[i].fillOffset, paths[i].fillCount); } - glEnable(GL_CULL_FACE); // Draw aliased off-pixels @@ -746,8 +738,6 @@ static void glnvg__stroke(struct GLNVGcontext* gl, struct GLNVGcall* call) glnvg__setupPaint(gl, &call->paint, &call->scissor, call->strokeWidth); - glEnable(GL_CULL_FACE); - // Draw Strokes for (i = 0; i < npaths; i++) { glDrawArrays(GL_TRIANGLE_STRIP, paths[i].strokeOffset, paths[i].strokeCount); @@ -784,6 +774,7 @@ static void glnvg__renderFlush(void* uptr) if (gl->ncalls > 0) { glUseProgram(gl->shader.prog); + glEnable(GL_CULL_FACE); // Upload vertex data glBindVertexArray(gl->vertArr);