Drawing smooth lines with Cocos2dx

Because if we assign different colors for different vertices, OpenGL will provide color interpolation for our triangle:Color gradient interpolationAnd this also works for alpha channel value (opacity).

So with only that method we already can go pretty far.

We can eliminate the line’s feathers if we’ll draw triangles like these:Same color, different opacityBy varying the alpha value we can make gradients from full color to fully transparent at line’s edge.

By using only this method I’ve been able to achieve these results (screenshot from an Android app):Smooooth!This curve was drawn by setting up the coordinates and colors for every one triangle vertices.

This looks solid, but do I really need an engine, if I do triangle drawing all by myself?SegmentSo I continued my research about how cocos draw things and after some experiments, I’ve found the only one thing which cocos draw strangely smooth — segment:I highlight geometry for youAs you can see, it is drawn from 6 triangles and what allows its line edges to be so smooth is this line of the fragment shader:gl_FragColor = v_color*smoothstep(0.

0, 0.

1, 1.

0 – length(v_texcoord));when DrawNode sets the texture offsets at drawSegment.

Cardinal SplinesWe can reuse such a cool primitive inside cardinal splines:I’ve got the code from DrawNode::drawCardinalSpline, fix the bug at cardinal splines math, which is apparently been there since the beginning of DrawNode, and start drawing segments with segments, instead of some edgy poly primitives.

And that's what I’ve got:If you zoom up these images, you would see that at large widths we’ve got good results, but at thin lines, there are still some artifacts.

TesselationFor such cases I’ve implemented a simple tessellation algorithm:I’ve started with the line segment:and then adjust the line joints:I used 4 triangles for each line segment and set the border vertices opacity to zero.

Such a scheme doesn’t work well with wide lines — we need more triangle layers for this, but fortunately enough I only need this for thin lines:And by combining both approachesvoid AwesomeNode::drawACardinalSpline(PointArray *config, float tension, unsigned int segments,float w, const Color4F &color) { auto *vertices = calculateVertices(config, tension, segments); if (w < LINE_SIZE_THRESHOLD) { tessellation(vertices, segments, w, color); } else { for (int i = 2; i <= segments + 1; ++i) { drawSegment(vertices[i – 2], vertices[i – 1], w / 2, color); } } CC_SAFE_DELETE_ARRAY(vertices);}we’ll have the results you can see at the header of this post.

Final solutionThese experiments resulted in a library called AwesomeNode, which you can find here:intmainreturn00/AwesomeNodeExtended cocos2dx DrawNode with tessellation and AntiAliasing for smooth drawing.

????.- intmainreturn00/AwesomeNodegithub.

comYou just need to copy-paste AwesomeNode.

h and AwesomeNode.

cpp into your cocos2d-x based project and you’re all set for drawing extra-smooth lines!.(Don’t forget to add AwesomeNode.

cpp to LOCAL_SRC_FILES section at Android.

mk on Android).

If you have any questions I would love to answer it here, or you may open an issue or send PR to me at GitHub.

.. More details

Leave a Reply