我正在尝试使用 DDA(数字微分分析仪)制作一种绘制线条的算法,该算法还使用 Wu 的算法作为抗锯齿。
问题是输出看起来不太好。 特别是:
- 我选择的颜色,它会改变(我知道为什么,但我想知道是否必须这样)
- 颜色越亮的像素越亮
如何选择我想要的线条颜色?考虑到它受算法的影响?
代码如下:
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);
}
最佳答案
您的代码仅适用于第一个八分圆
所以我希望你只在那里测试
你忘了混合背景颜色和线条颜色
因此添加透明度或直接读取背景像素并自行混合颜色。
a,a0
系数将是透明度颜色混合的 alpha。在这种情况下,您不应更改r,g,b
值,而应仅更改 alpha。此外,如果您知道背景颜色,则可以忽略像素的读取,但在穿过已渲染的内容时结果会有点差。
我将您的代码更改为与我的 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;
}
}
改为定点(8位小数部分)f,df
将 round
更改为 floor
(我的像素已经移动了一半)
添加了与背景色的混色
pnt(x,y,col);
绘制一个像素x,y
,颜色为col
col=pnt(x,y);
从屏幕/图像中读取像素到 col
col
是 32 位颜色 (0x00RRGGBB),union 的存在只是为了方便 r,g,b
访问
关于c++ - 在 OpenGL 中使用 Wu 算法的数字微分分析仪,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30006412/