Improving Cocos2D Line Drawing: Part 1
*Warning* This post is a little more technical, and features implementation details
One of the exciting features of Cocos2D was the CCRibbon class. This class claimed to easily draw and animate lines stroked with any custom texture. This was to be huge for Bulge since it has large irregularly shaped locations that will need to be selected and outlined. It would also be useful for drawing the glowing front line. This is not the case, while it created a textured line, the textures were distorted and broken. Lines seem to fold in on themselves. Even increasing the number of sample points did not improve the output. Like Admiral Ozzel, CCRibbon has failed me for the last time.
CCRibbon works in many basic cases, and with the CCMotionStreak class to provide some animation to the lines created. Most users won’t even notice some of errors if they use a solid color as a texture, maybe the occasional line that appears a bit “pinched”. It’s once the texture stroking the line becomes more complex its weakness is exposed: it cannot cleanly draw lines with points too close together, or that would make lines with moderate changes to angle.
No big deal, when in doubt just go to OpenGL right? Sadly GL_Line has its own limitations. GL Lines are only anti-aliased SOMETIMES, and only guaranteed to be smooth when their width is set to 1. Lastly, when setting the width of a GL_Line, it will always be drawn that width, even if the layer calling the openGL drawing gets scaled. It looks bad, real bad.
Test Case Time!
If you’ve seen the Kickstarter Info you’ll notice this is how the fronts get drawn. This is the toughest case to deal with: Custom Texture, Transparency, frequent irregular angles. The arrows in the image below show where line endpoints are placed. Starting at the top left, a nice clean line. This is expected behavior. Next point is directly below and it seems like it is arcing to the next point. Not terrible, could make sense, the subsequent points, are get worse and worse. This isn’t error carrying forward, but entirely expected behavior when dealing with textured triangles. (See right image)
CCRibbon creates two triangles to create a rectangle. Blue lines are the given width of the CCRibbon, Red Lines show the polygons created with the endpoints of the Blue lines. It’s no wonder the texture is getting skewed with such irregularly shaped polygons as a base. Texture Location is only specified at endpoints of the triangle, so the texture scaling goes wrong along the shared edge of the triangles.
So taking a look at what CCRibbon does, and what can be done, we need a line that:
- Is drawn with an arbitrary amount of points
- Can make any angle cleanly
- Can be textured with any custom texture
- Is antialiased
- Works at every zoom level
More details next time!
2 Responses to “Improving Cocos2D Line Drawing: Part 1”
Leave a Reply
Did you solve this?
I’m testing this function -
needs to be migrated to cocos2d.
(taken from https://github.com/hiepnd/cocos2d-ext)
- (void) drawLineFrom:(CGPoint) from
to:(CGPoint) to
texture:(CCTexture2D *) texture
baseLength:(float) base
stretch:(BOOL) stretch{
float length = stretch ? base : ccpDistance(from, to);
float pwide = texture.pixelsWide;
float phigh = texture.pixelsHigh/2;
if (stretch) {
length = ((int) length/pwide) * pwide;
}
float vertices[] = {0,phigh,
length, phigh,
0,-phigh,
length, -phigh
};
float textCoors[] = {0.,1.,
length/pwide,
1.,0.,0.,
length/pwide,0.};
… { Full code Edited by Admin }



Did you solve this?
I’m testing this function -
needs to be migrated to cocos2d.
(taken from https://github.com/hiepnd/cocos2d-ext)
- (void) drawLineFrom:(CGPoint) from
to:(CGPoint) to
texture:(CCTexture2D *) texture
baseLength:(float) base
stretch:(BOOL) stretch{
float length = stretch ? base : ccpDistance(from, to);
float pwide = texture.pixelsWide;
float phigh = texture.pixelsHigh/2;
if (stretch) {
length = ((int) length/pwide) * pwide;
}
float vertices[] = {0,phigh,
length, phigh,
0,-phigh,
length, -phigh
};
float textCoors[] = {0.,1.,
length/pwide,
1.,0.,0.,
length/pwide,0.};
… { Full code Edited by Admin }
Hi John, yes check out my next post ( http://www.shenandoah-studio.com/improving-cocos2d-line-drawing-part-2/ ) for the solution. There is a 3rd part with optimizations too.
Long story short, the code you posted will still create the problems seen above. The solution is to use 4 Triangles instead of 2.