深度でスキャンラインを描画する手順があります-xsをax start xkとしてax end、yとzsをxsのz-depth、zkをzkのz-depthとして取ります(z値はxsからxkへの線形形式のz値の変更)フロートRAM の deptht バッファは、深度テストに使用されます
ここにあります
inline void drawScanlineWithDepth(int y, int xs, int xk, float zs, float zk, unsigned color)
{
if(y<0) return; //clip
if(y>=CLIENT_Y) return; //
if(xs>xk) // swap to assure xs is on left xk at right
{
int temp = xs; xs=xk; xk=temp;
float tempp = zs; zs=zk; zk=tempp;
}
if(xs<0) //cut left end to 0
{
if(xk<0) return;
float dod_zs = (-xs)*float(zk-zs)/float(xk-xs);
zs += dod_zs;
xs=0;
}
if(xk>=CLIENT_X) //cut right end to CLIENT_X-1
{
if(xs>=CLIENT_X) return;
float sub_zk = (xk-(CLIENT_X-1))*float(zk-zs)/float(xk-xs);
zk -= sub_zk;
xk = CLIENT_X-1;
}
int len = xk-xs;
int yc = CLIENT_Y-y-1; //reverse y coordinate becouse blitter reverses it
int adr_ = yc*CLIENT_X + xs;
int adr_depth = ( yc<<12 ) + xs; // depth[] is a static table with 4096 width
float* db = ((float*) depth) + adr_depth;
unsigned* adr = ((unsigned*)pBits) + adr_;
if(len<=3) //unwind short scanlines
{
if(len==0)
{
if(zs< *db) *db = zs, *adr = color;
return;
}
else if(len==1)
{
if(zs< *db) *db = zs, *adr = color; db++; adr++;
if(zk< *db) *db = zk, *adr = color;
return;
}
else if(len==2)
{
float zs_1 = zs + len*0.5;
if(zs <*db) *db = zs, *adr = color; db++; adr++;
if(zs_1<*db) *db = zs_1, *adr = color; db++; adr++;
if(zk <*db) *db = zk, *adr = color;
return;
}
else if(len==3)
{
float zs_1 = zs + (len)*(1./3.);
float zs_2 = zs + (len)*(2./3.);
if(zs < *db) *db = zs , *adr = color; db++; adr++;
if(zs_1< *db) *db = zs_1 , *adr = color; db++; adr++;
if(zs_2< *db) *db = zs_2 , *adr = color; db++; adr++;
if(zk < *db) *db = zk , *adr = color;
return;
}
}
if(len==0) ERROR_("len == 0");
if(len<0) ERROR_("len < 0");
float dz = float(zk-zs)/float(len);
float z = zs;
for(int i=0; i<=len; i++)
{
if(z < *db) //depthtest
{
*db = z; //set pixel
*adr = color;
}
adr++;
db++;
z+=dz;
}
}
上記の 1,2,3,4 の長さの短いスキャンラインのループを「ほどく」と高速になりますが、より多くのほどけるとあまり改善が見られません。さらに最適化できますか?
長さ