最近偶的工作任务是写一个类似DDraw中Blt的函数..同时还要实现关键色,alpha透明,左右镜像,上下镜像,缩放..偶的程序写好了,功能正常,但速度暴慢..同时渲染100张图(278*142大小),且把上述特效都打开,只能达到10帧..偶的程序主要是逐点处理,下面是处理循环的代码片断,请高手指点一下,给点改进意见,怎么才能加快速度.for(UINT y=0; y<rect_src.ui32H; y++)
{
    //记录每行的开始位置
    addr_dst_t = addr_dst;
    addr_src_t = addr_src;    if(b_lrmirror)    //左右镜像
        addr_src += pixel_per_line<<1 ;    if(b_zoom)    //缩放,index_x是缩放处理每行的标志
        index_x = 0;    for(UINT x=0; x<rect_src.ui32W; x++)
    {
        if(b_colorkey)    //关键色
        {
            UCHAR    red,blue,green;
            src_data = *addr_src;
            r= (src_data>>11) & 31;
            g= (src_data>>5) & 63;
            b= src_data & 31;            if(    r>=red_l && r<=red_h 
                &&    b>=blue_l && b<=blue_h
                &&    g>=green_l && g<=green_h)
            {
                b_flip = true;
            }
            else
                b_flip = false;
            }
            if(b_alpha)    //alpha透明
            {
                src_data = *addr_src;
                dst_data=*addr_dst;
                if(!b_colorkey)
                {
                    r = (UCHAR)( (((src_data>>11) & 31)*alpha + ((dst_data>>11) & 31)*_alpha) >> 5 );
                    g = (UCHAR)( (((src_data>>5) & 63)*alpha + ((dst_data>>5) & 63)*_alpha) >> 5 );
                    b = (UCHAR)( ((src_data & 31)*alpha + (dst_data & 31)*_alpha) >> 5 );
                }
                else
                {
                    r = (UCHAR)((r*alpha + ((dst_data>>11) & 31)*_alpha)>>5);
                    g = (UCHAR)((g*alpha + ((dst_data>>5) & 63)*_alpha)>>5);
                    b = (UCHAR)((b*alpha + (dst_data & 31)*_alpha)>>5);
                }
            }            //写数据,步进指针            if(b_zoom)
            {
                while( index_x < x_rate )
                {
                    if(!b_flip)
                    {
                        if(b_alpha)
                            *addr_dst++ = _RGB16BIT565(r,g,b);
                        else
                            *addr_dst++ = *addr_src;
                    }
                    else
                        addr_dst++;
                    index_x += 1000;
                }
                index_x -= x_rate;    //x_rate,y_rate为缩放比例*1000(避免用浮点数)
            }
            else
            {
                if(b_flip)
                {
                    addr_dst++;
                }
                else
                {
                    if(b_alpha)
                        *addr_dst++ = _RGB16BIT565(r,g,b);
                    else
                        *addr_dst++ = *addr_src;
                }
                    
            }
            addr_src ++;    
            if(b_lrmirror)    //左右镜像时的校正
                addr_src -= 2;
                    
        }        //步进到下一行
        addr_dst = addr_dst_t + lpitch_dst;
        
        if(b_zoom)
        {
            index_y += 1000;
            while( index_y < y_rate )
            {
                memcpy(addr_dst, addr_dst-lpitch_dst,rect_dst.ui32W<<1);
                addr_dst = lpitch_dst + addr_dst;
                index_y += 1000;
            }
            index_y -= y_rate;
        }
        addr_src = addr_src_t + lpitch_src;
        
}在线等!!

解决方案 »

  1.   

    是需要优化第一种:算法优化,这个优化是必须的,算法好坏对于效率影响最大
      可以把循环当中if条件提取到for的外部去第二种:语言优化,它是算法之后的优化
      比如用汇编来实现另外,既然有ddraw为何不用它呢,那个可是硬件支持的直接访问显存的操作
    而你自己是不能直接访问显存的,效率自然就会低下
      

  2.   

    谢谢楼上各位朋友的解答.
    偶这段程序的目的是,如果显卡不支持alpha,就要用软件来模拟它.
    而要模拟alpha,我就必须逐点处理,所以要用一个双重循环.
    而且,在支持alpha的同时还要支持colorkey,缩放,镜像等,所以我的循环中有那么多的if..(if影响效率极低吧).更要命的是还要支持颜色转换(565->32,32->565),这个以后再说吧,先把前边的搞定.听说MMX能很大的提高效率,哪位达人会用MMX呢.偶的汇编学得不好,如果哪位能把colorkey及alpha处理那一段改写成MMX汇编,小弟不胜感激,再开帖送分,送完为止.
      

  3.   

    ddraw已经是普遍的支持了,不支持alpha的显卡现在还很多吗?关于if和for的优化的说明:
    for(N次)
      if (flag)
        A
      else 
        B
    显然if被判断了N次如果改成
    if (f)
       for () A;
    else
       for () B;
    显然if只被判断了一次而已,这样是可以提高效率的在双层循环内部的每个操作都被循环放大了很多次数,最主要优化的就是内层循环的东西VC里面提供的profiling功能是可以用来分析函数当中各个部分的执行效率的
      

  4.   

    非常感谢 happy__888的解答,但有这样一个问题:
    虽然你把if提出来了,但一个for变成了两个.我的循环中有N个if,我还要考虑它们的组合,如果全提出来,得写多少个for啊..
    我试过,即使在循环中写10 个if,好像影响也不及一个++运算大..可能是CPU能针对if做很大程度的优化吧
      

  5.   

    http://dev.gameres.com/Program/Visual/2D/IntelAlpha.htm
    有一篇文章:
      可能是最快的算法alpha blend汇编源代码,Intel官方提供 
     
      

  6.   

    多谢happy_888,这个汇编码不错,偶好好研究研究.看来没人来讨论了,结帖吧..