DirectDraw中alpha混合的简单实现

 


最近自己在写游戏,需要用到半透明的效果,于是研究了一下关于alpha混合的知识。
现在许多游戏为了达到光影或图象的透明效果都会采用AlphaBlend 技术。所谓AlphaBlend技术,其实就是按照"Alpha"混合向量的值来混合源像素和目标像素,一般用来处理半透明效果。在计算机中的图象可以用R(红色),G(绿色),B(蓝色)三原色来表示。假设一幅图象是A,另一幅透明的图象是B,那么透过B去看A,看上去的图象C就是B和A的混合图象,设B图象的透明度为alpha(取值为0-1,0为完全透明,1为完全不透明),Alpha混合公式如下:

  R(C)=alpha*R(B)+(1-alpha)*R(A)

  G(C)=alpha*G(B)+(1-alpha)*G(A)

  B(C)=alpha*B(B)+(1-alpha)*B(A)

  R(x)、G(x)、B(x)分别指颜色x的RGB分量原色值。从上面的公式可以知道,Alpha其实是一个决定混合透明度的数值。应用Alpha混合技术,可以实现游戏中的许多特效,比如火光、烟雾、阴影、动态光源等半透明效果。


根据这个思想我们可以写出以下算法:

注:lpdds1和lpdds2是两个经过再次封装的表面对象


void myAlphaBlend(CXDDR &lpdds1, CXDDR &lpdds2,float AlphaValue)
    
{


    HDC hdc1,hdc2;

    LPDIRECTDRAWSURFACE7 lps1
=lpdds1.Get_lpDDS();//获得离屏表面
    LPDIRECTDRAWSURFACE7 lps2=lpdds2.Get_lpDDS();

    BYTE R1,G1,B1;
    BYTE R2,G2,B2;
    BYTE R,G,B;    
    COLORREF rgb1,rgb2;
    
    
if (lps1->GetDC(&hdc1) == DD_OK && lps2->GetDC(&hdc2)==DD_OK)//获得设备句柄
        {
        
        
for(int t=0;t<=lpdds1.Get_lpDDS_W();++t)
            
for(int j=0;j<=lpdds1.Get_lpDDS_H();++j)
                
{
        
                rgb1 
= GetPixel(hdc1, t, j);
                rgb2 
= GetPixel(hdc2, t+50, j+50);
                
//if(rgb1==RGB(255,255,255))continue;
                
                R1
=GetRValue(rgb1);
                G1
=GetGValue(rgb1);
                B1
=GetBValue(rgb1);

                R2
=GetRValue(rgb2);
                G2
=GetGValue(rgb2);
                B2
=GetBValue(rgb2);
                
                R
=AlphaValue * ( R2 - R1 ) + R1;
                G
=AlphaValue * ( G2 - G1 ) + G1;
                B
=AlphaValue * ( B2 - B1 ) + B1;
                
                SetPixel(hdc1, t, j,RGB(R,G,B));
                }

        lps1
->ReleaseDC(hdc1);//释放句柄
        lps2->ReleaseDC(hdc2);
        }


        
        
    }




运行效果:



若对颜色键进行处理则可去掉上面卡通图案的白色背景,这里没有去掉是为了能看得更清楚。

posted on 2005-04-19 13:08  张瓅  阅读(3446)  评论(6编辑  收藏  举报

导航