Ok, I think I've solved it.

What we want to do is compute coverate and turn it into alpha. Well, let's think about this for a moment. Any pixel that aligns exactly with the center of the line should have alpha of 1.0. Any pixel completely off the line should have alpha of 0, and any pixel which lies on the edge of the line should have alpha of 0.5. Why not draw a polygon which varies alpha from 1.0 at the center to 0.0 at the line width away from the center?




Here's the code:
(Note that this does NOT work right for width>1.0, which I will provide for you next.)




float sqrtf(float);


void antialiased_line() { WorldVertex A, B, C; float X1, Y1, X2, Y2, dx, dy, width, length;

    InitializeRenderer();
    memset(BlendState.pBuffer, 0, 256*256*4);
    BlendState.enable_read = 1;
    BlendState.LogicROP = 0xc;
    BlendState.EquationAlphaMode = FUNC_ADD;
    BlendState.EquationColorMode = FUNC_ADD;
    BlendState.SourceAlphaFunc = 4;  /* factor = 1.0 */
    BlendState.SourceColorFunc = 3;  /* factor = source alpha */
    BlendState.DestAlphaFunc = 4;    /* factor = 1.0 */
    BlendState.DestColorFunc = 8;    /* factor = 1.0 */


X1 = 100; Y1 = 100; X2 = 50; Y2 = -100; width = 1;


dx = X2-X1; dy = Y2-Y1; length = sqrtf(dx*dx + dy*dy);

    dx *= width/length;
    dy *= width/length;

    A.X = X1;
    A.Y = Y1;
    A.Z = 0;
    A.Ap = 1.0;
    A.Rp = A.Gp = A.Bp = 1.0;

    B.X = X1 - dx + dy;
    B.Y = Y1 - dy - dx;
    B.Z = 0;
    B.Ap = 0;
    B.Rp = B.Gp = B.Bp = 1.0;

    C.X = X1 - dx - dy;
    C.Y = Y1 - dy + dx;
    C.Z = 0;
    C.Ap = 0;
    C.Rp = C.Gp = C.Bp = 1.0;

    ComputeTriangle(A, B, C, 128, 128);

    C.X = X2;
    C.Y = Y2;
    C.Z = 0;
    C.Ap = 1.0;
    C.Rp = C.Gp = C.Bp = 1.0;

    ComputeTriangle(A, B, C, 128, 128);

    A.X = X2 + dx + dy ;
    A.Y = Y2 + dy - dx;
    A.Z = 0;
    A.Ap = 0;
    A.Rp = A.Gp = A.Bp = 1.0;

    ComputeTriangle(A, B, C, 128, 128);

    B.X = X2 + dx - dy;
    B.Y = Y2 + dy + dx;
    B.Z = 0;
    B.Ap = 0;
    B.Rp = B.Gp = B.Bp = 1.0;

    ComputeTriangle(A, B, C, 128, 128);

    A.X = X1;
    A.Y = Y1;
    A.Z = 0;
    A.Ap = 1.0;
    A.Rp = A.Gp = A.Bp = 1.0;

    ComputeTriangle(A, B, C, 128, 128);

    C.X = X1 - dx - dy;
    C.Y = Y1 - dy + dx;
    C.Z = 0;
    C.Ap = 0;
    C.Rp = C.Gp = C.Bp = 1.0;

    ComputeTriangle(A, B, C, 128, 128);

    write_ppm("antialiased_line.ppm", 256, 256, BlendState.pBuffer);
}


_______________________________________________ Open-graphics mailing list [email protected] http://lists.duskglow.com/mailman/listinfo/open-graphics List service provided by Duskglow Consulting, LLC (www.duskglow.com)

Reply via email to