用Alpha测试实现透明位块传输

      透明位块传输是2D游戏图片处理中常用的技术,即俗称图片“去背”,可以通过在渲染时忽略纹理的一部分不进行渲染来实现,从而透过这个不渲染的部分可以看到背景图形,这在游戏开发中采用纹理贴图实现窗户、树、灌木丛等效果是很有用的。透明位块传输技术在DirectDraw中使用关键色很容易实现,在Direct3D中,可以在载入纹理时设置关键色,在贴图时使用Alpha测试使关键色在多边形渲染时是不被绘制出来的

      举例来说,假如有一棵树的纹理,树的周围被黑色所包围(如下图 1),就可以将黑色设置为关键色。这样,当渲染应用了该纹理的多边形时,Direct3D就不会绘制这些黑色像素,而只有树被渲染。

 用Alpha测试实现透明位块传输_第1张图片 

                    图 1

可以调用D3DX库函数D3DXCreateTextureFromFileEx实现指定关键色从位图文件加载纹理,该函数原型如下:

HRESULT D3DXCreateTextureFromFileEx(

__in LPDIRECT3DDEVICE9 pDevice,

__in LPCTSTR pSrcFile,

__in UINT Width,

__in UINT Height,

__in UINT MipLevels,

__in DWORD Usage,

__in D3DFORMAT Format, // 用于alpha测试时,格式必须带有alpha通道

__in D3DPOOL Pool,

__in DWORD Filter,

__in DWORD MipFilter,

__in D3DCOLOR ColorKey, // 即为需要指定的关键色

__inout D3DXIMAGE_INFO *pSrcInfo,

__out PALETTEENTRY *pPalette,

__out LPDIRECT3DTEXTURE9 *ppTexture );

 

    该函数的参数ColorKey即为需要指定的关键色。纹理文件中与ColorKey匹配的像素,在基于该纹理文件加载的纹理对象中,其对应的像素会被替换为透明的黑色(即其alpha部分为0);ColorKey设置为0则表示禁用ColorKey。若从位图文件中加载纹理,位图文件是不带alpha通道的,ColorKey就必须设置为最大,即0xFF;若从已经包含了alpha通道值的非位图文件(比如.tga文件)中加载纹理,就必须是ColorKey的alpha值同纹理文件中的alpha值匹配。

    举例来说,如果使用该函数从一个BMP文件(假设就是上图 1)中加载纹理,指定关键色为纹理文件的背景色(在图 1中即为黑色),ColorKey就应设置为D3DCOLOR_ARGB(255, 0, 0, 0)(因为BMP文件不带通道,所以ColorKey的alpha部分设置为255),这样就创建了一个背景为黑色的,背景像素alpha值为0(即完全透明)的纹理对象,它的RGBA颜色值为(0,0,0,0)。然后,在渲染时启用alpha测试,并使alpha测试仅对alpha值大于或等于某个值的像素颜色写入帧缓存。这样上图1的背景像素就会在alpha测试中被忽略掉,从而实现透明绘制。载入纹理的函数如下:

    D3DXCreateTextureFromFileEx(    pd3dDevice ,//LPDIRECT3DDEVICE9 pDevice
                                    "tree.bmp" ,//LPCTSTR pSrcFile
                                    D3DX_DEFAULT  ,D3DX_DEFAULT  ,//UINT Width,UINT Height
                                    0 , 0 , //UINT MipLevels,DWORD Usage
                                    D3DFMT_A8R8G8B8 , //D3DFORMAT Format
                                    D3DPOOL_MANAGED ,//D3DPOOL Pool
                                    D3DX_DEFAULT , //DWORD Filter
                                    D3DX_DEFAULT , //DWORD MipFilter
                                    D3DCOLOR_ARGB( 255 , 0 , 0 , 0 ) , // D3DCOLOR ColorKey
                                    NULL ,//D3DXIMAGE_INFO *pSrcInfo
                                    NULL ,//PALETTEENTRY *pPalette
                                    &m_pTexture );//LPDIRECT3DTEXTURE9 *ppTexture

      本质上,仍然是纹理对象的alpha值标示出了作为透明的像素,而不是关键色。在指定了关键色的纹理对象中,与关键色匹配的纹素(即纹理像素)其alpha值必须要设为0,而对于要绘制的纹素其alpha值必须设置为最大(即255);因为在Direct3D中启用alpha测试时,像素要么完全透明,要么完全不透明。

      虽然使用alpha混合也可以实现透明效果,但是,与alpha混合相比,alpha测试无需对颜色缓冲区进行读操作和颜色混合,因此在渲染速度上要优于alpha混合。

 

要在Direct3D程序中使用alpha测试,只需额外添加下面的三个步骤:

1. 启用alpha测试

d3d9Device->SetRenderState(D3DRS_ALPHATESTENABLE, true);

2. 设置alpha测试参考值,Alpha值小于0x1的像素不渲染

d3d9Device->SetRenderState(D3DRS_ALPHAREF, 0x1);

3. 设置alpha测试函数

d3d9Device->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL);

 

下面图示演示了使用alpha测试绘制图 1中的树的效果(若不使用alpha测试,则效果就是图 1所示):

用Alpha测试实现透明位块传输_第2张图片

注:客户区背景为白色。


你可能感兴趣的:(用Alpha测试实现透明位块传输)