Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Digital Differential Analyzer with Wu's Algorithm in OpenGL

I'm trying to make an algorithm which draws lines, using the DDA (Digital Differential Analyzer), that also use the Wu's algorithm as anti-aliasing.

The problem is that the output doesn't look quite good. In particular:

  • the color that i choose, it changes (i know why but i want to know if it has to be like this)
  • the color of the pixel more bright is to bright

How can i choose the color that i want for the line? Considering that it's affected by the algorithm ?

Here's the code:

void dda(int x0, int y0, int x1, int y1, int z, float red, float green, float blue) {
    float dy = y1-y0;
    float dx = x1-x0;
    float m = dy/dx;

    if (m<=1) {
        int x;
        float y;
        y = y0;
        for (x=x0; x<x1; x++) {
            pixel(x, round(y), z, frame, rfpart(red), rfpart(green), rfpart(blue));
            pixel(x, round(y)+1, z, frame, fpart(red), fpart(green), fpart(blue));
            y = y+m;
        }
    }
}

int round(float d) {
  return floor(d + 0.5);
}

float fpart(float x) {
    if (x < 0)
        return 1 - (x - floor(x));
    return x - floor(x);
}

float rfpart(float x) {
    return 1 - fpart(x);
}
like image 542
giogix Avatar asked Mar 12 '26 21:03

giogix


1 Answers

  1. your code works only for first octant

    so I hope you are testing only there

  2. you have forgot to mix the background color and line color

    so add transparency or read the background pixel directly and mix colors on your own. The a,a0 coefficients would be the alpha for transparency color mixing. In that case you should not change the r,g,b values but the alpha only instead. Also if you know the background color you could ignore the reading of pixels but the result will be of a bit while crossing something already rendered.

I change your code to be compatible with mine coding in C++:

void DDA_line_antialiasing(int x0,int y0,int x1,int y1,int col) // DDA antialiasing
    {
    int   x,y,dx,dy,kx,ky,f,df;
    DWORD a,a0;
    union
        {
        DWORD dd;
        BYTE db[4];
        } c,c0;
    dx=x1-x0; kx=0; if (dx>0) kx=+1; else if (dx<0) { kx=-1; dx=-dx; }
    dy=y1-y0; ky=0; if (dy>0) ky=+1; else if (dy<0) { ky=-1; dy=-dy; }
    if (dx+dy==0)
        {
        pnt(x0,y0,col);
        pnt(x1,y1,col);
        return;
        }
    if (dx>=dy)
     for (df=(dy<<8)/dx,x=x0,y=y0,f=0;;f+=df,x+=kx)
        {
        // fixed point y step
        if (f>=256) { f-=256; y+=ky; }
        // line color + background color mixing
        c.dd=col; c0.dd=pnt(x,y); a=256-f; a0=f;
        c.db[0]=DWORD(((DWORD(c.db[0])*a)+(DWORD(c0.db[0])*a0))>>8);
        c.db[1]=DWORD(((DWORD(c.db[1])*a)+(DWORD(c0.db[1])*a0))>>8);
        c.db[2]=DWORD(((DWORD(c.db[2])*a)+(DWORD(c0.db[2])*a0))>>8);
        pnt(x,y   ,c.dd);
        // line color + background color mixing
        c.dd=col; c0.dd=pnt(x,y+ky); a=f; a0=256-f;
        c.db[0]=DWORD(((DWORD(c.db[0])*a)+(DWORD(c0.db[0])*a0))>>8);
        c.db[1]=DWORD(((DWORD(c.db[1])*a)+(DWORD(c0.db[1])*a0))>>8);
        c.db[2]=DWORD(((DWORD(c.db[2])*a)+(DWORD(c0.db[2])*a0))>>8);
        pnt(x,y+ky,c.dd);
        if (x==x1) break;
        }
    else
     for (df=(dx<<8)/dy,x=x0,y=y0,f=0;;f+=df,y+=ky)
        {
        // fixed point x step
        if (f>=256) { f-=256; x+=kx; }
        // line color + background color mixing
        c.dd=col; c0.dd=pnt(x,y); a=256-f; a0=f;
        c.db[0]=DWORD(((DWORD(c.db[0])*a)+(DWORD(c0.db[0])*a0))>>8);
        c.db[1]=DWORD(((DWORD(c.db[1])*a)+(DWORD(c0.db[1])*a0))>>8);
        c.db[2]=DWORD(((DWORD(c.db[2])*a)+(DWORD(c0.db[2])*a0))>>8);
        pnt(x,y   ,c.dd);
        // line color + background color mixing
        c.dd=col; c0.dd=pnt(x+kx,y); a=f; a0=256-f;
        c.db[0]=DWORD(((DWORD(c.db[0])*a)+(DWORD(c0.db[0])*a0))>>8);
        c.db[1]=DWORD(((DWORD(c.db[1])*a)+(DWORD(c0.db[1])*a0))>>8);
        c.db[2]=DWORD(((DWORD(c.db[2])*a)+(DWORD(c0.db[2])*a0))>>8);
        pnt(x+kx,y,c.dd);
        if (y==y1) break;
        }
    }


changed to fixed point (8-bit fractional part) f,df
changed the round to floor (my pixels are already shifted by half)
added color mixing with background color
pnt(x,y,col); draws a pixel x,y with color col
col=pnt(x,y); reads the pixel from screen/image into col
col is 32 bit color (0x00RRGGBB) that union is there just for easy r,g,b access

example output

like image 193
Spektre Avatar answered Mar 14 '26 11:03

Spektre



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!