C++ 带深度优化的DrawScanline

C++ 带深度优化的DrawScanline,c++,c,performance,optimization,drawing,C++,C,Performance,Optimization,Drawing,我有一些绘制扫描线的程序 深度-它以x作为x起点,以xk作为x终点, y和zs为xs处的z深度,zk为zk处的z深度 (z值从xs线性变化为xk)浮动深度 ram中的缓冲器用于深度测试 给你 inline void drawScanlineWithDepth(int y, int xs, int xk, float zs, float zk, unsigned color) { if(y<0) return; //clip if(y

我有一些绘制扫描线的程序 深度-它以x作为x起点,以xk作为x终点, y和zs为xs处的z深度,zk为zk处的z深度 (z值从xs线性变化为xk)浮动深度 ram中的缓冲器用于深度测试

给你

    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;
 }

 }
inline void drawScanlineWithDepth(int y、int xs、int xk、float zs、float zk、unsigned color)
{
如果(y=客户_y)返回//
if(xs>xk)//交换以确保xs位于左侧,xk位于右侧
{
int temp=xs;xs=xk;xk=temp;
浮点tempp=zs;zs=zk;zk=tempp;
}
if(xs=CLIENT_X)返回;
float sub_zk=(xk-(客户_X-1))*float(zk zs)/float(xk xs);
zk-=sub_zk;
xk=客户_X-1;
}
int len=xk xs;
int yc=客户_Y-Y-1//反转y坐标,因为blitter会反转y坐标
int adr=yc*客户机X+xs;

对于优化来说,一个非常重要的事情是考虑最重要的工作量是什么?它是不是画了很多短的(ISH)跨度,还是它绘制的大多是很长的跨度?每种情况下优化的主要目标都是不同的。 此外,您使用的处理器也很重要;分支预测是否会遗漏(即,作为一个整体的分支)会降低您的速度

短跨度:

一点是,最好将一些测试(y剪裁等)移到这个函数之外,以确保它根本不会被那些y值调用

交换侧面也是一样;您也可以展开这些箱子

大跨度:


答案取决于您的编译器和CPU;使用一些多媒体扩展将是一个好主意。此外,您可以在for()中展开循环,在一次迭代中执行两个像素,以赢得一点(除非你能让你的编译器帮你做这件事;你看过汇编输出并调整了优化器设置吗?

它用于软件光栅化器,所以两种情况都会使用-一瞬间10万个短帧,然后当接近单个三角形时/s一整屏长三角形