Wednesday, October 24, 2012

Drawing smooth lines in Cocos2d 2.x

So when I originally coded Tracer I used cocos2d 1.0 which used openGL 1.1 and there was this great method I found online which you can find here on the cocos2d forms http://www.cocos2d-iphone.org/forum/topic/21368 However when I upgraded to cocos2d 2.0 I could no longer use this because cocos2d 2.x uses OpenGL2.0. I couldn't find a solution for drawing smooth lines online that was exactly what I needed so I just looked at the cocos2d source code and modified the original method to make it work. Hopefully this will save you some time if you need the same.
-(void) drawSmoothLine: (CGPoint) pos1: (CGPoint) pos2: (ccColor4F) someColor
{
    [shaderProgram_ use];
    [shaderProgram_ setUniformsForBuiltins];
 [shaderProgram_ setUniformLocation:-1 with4fv:(GLfloat*) &someColor.r count:1];
    
    ccGLEnableVertexAttribs(kCCVertexAttribFlag_Position | kCCVertexAttribFlag_Color );
    GLfloat lineVertices[12];
    CGPoint dir, tan;
    
    float width = 1.2f;
    dir.x = pos2.x - pos1.x;
    dir.y = pos2.y - pos1.y;
    float len = sqrtf(dir.x*dir.x+dir.y*dir.y);
    if(len<0.00001)
        return;
    dir.x = dir.x/len;
    dir.y = dir.y/len;
    tan.x = -width*dir.y;
    tan.y = width*dir.x;
    
    lineVertices[0] = pos1.x + tan.x;
    lineVertices[1] = pos1.y + tan.y;
    lineVertices[2] = pos2.x + tan.x;
    lineVertices[3] = pos2.y + tan.y;
    lineVertices[4] = pos1.x;
    lineVertices[5] = pos1.y;
    lineVertices[6] = pos2.x;
    lineVertices[7] = pos2.y;
    lineVertices[8] = pos1.x - tan.x;
    lineVertices[9] = pos1.y - tan.y;
    lineVertices[10] = pos2.x - tan.x;
    lineVertices[11] = pos2.y - tan.y;
    
    ccColor4F vertices[6];
    ccColor4F color1 = {rCol, gCol, bCol, 0};
    ccColor4F color2 = {rCol, gCol, bCol, opacity};
    vertices[0] = color1;
    vertices[1] = color1;
    vertices[2] = color2;
    vertices[3] = color2;
    vertices[4] = color1;
    vertices[5] = color1;
    
 glVertexAttribPointer(kCCVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, 0, lineVertices);
    glVertexAttribPointer(kCCVertexAttrib_Color, 4, GL_FLOAT, GL_FALSE, 0, vertices);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 glDrawArrays(GL_TRIANGLE_STRIP, 0, 6);
    
}
Now you may notice that when you draw lines there are tiny dots that appear in the line, well that's because of the way the triangles are drawn and I'll get into that in the next post and how to get rid of it! Also, if you use the above, make sure to go into ccConfig.h and enable CC_ENABLE_GL_STATE_CACHE, I got a huge performance improvement from that. In the above method, the values rCol, gCol and bCol are just the current rgb values which you can manually modify or get from the passed in ccColor4f value.

Pavan
Dutch Cheese Games