游戏开发论坛

 找回密码
 立即注册
搜索
查看: 9152|回复: 13

同时使用ColorKey以及顶点Alpha效果

[复制链接]

362

主题

3023

帖子

3553

积分

论坛元老

Rank: 8Rank: 8

积分
3553
发表于 2008-1-13 05:03:00 | 显示全部楼层 |阅读模式
(1)如何使用ColorKey?

可以使用一张带Alpha通道的纹理,以及AlphaBlend来实现。
也可以使用AlphaTest(先略过不表)。

具体做法:
在InitDeviceObjects()中加入:
D3DXCreateTextureFromFileEx(m_pd3dDevice,"a.bmp",D3DX_DEFAULT,D3DX_DEFAULT,1,0,
D3DFMT_A8R8G8B8,D3DPOOL_DEFAULT,D3DX_FILTER_POINT,D3DX_FILTER_POINT,
0xff000000,NULL,NULL,&m_pTexture);
其中,你需要使用带alpha通道的格式比如A8R8G8B8,
色彩键(透明色)我设为了0xff000000纯黑色。

这里做一个详细说明:
本质上,d3d里没有色彩键。所谓的色彩键,是通过将alpha通道设为0x00来实现的。
D3DXCreateTextureFromFileEx函数里,如果你制定了色彩键(比如0xff000000),
那么,函数会把纹理中所有的0xff000000的象素的alpha通道设置为0x00。

有一些朋友抱怨说:“在这个函数里使用了色彩键,但是没有效果”。
其实这个函数只是设置了alpha通道。你需要使用alpha相关的绘图函数,效果才会出来。

现在,我们的纹理,含有了alpha值(或者说相当于色彩键)。
那么,我们就需要利用纹理中含有的alpha值,来进行alpha混合。
这样,就可以实现色彩键的效果。

在Render()函数里加入:
//设置alpha混合
m_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE,TRUE);
m_pd3dDevice->SetRenderState(D3DRS_SRCBLEND,D3DBLEND_SRCALPHA);
m_pd3dDevice->SetRenderState(D3DRS_DESTBLEND,D3DBLEND_INVSRCALPHA);
//把alpha参数设为纹理的alpha值(下面2行其实也可以去掉,因为默认就是这样的)
m_pd3dDevice->SetTextureStageState(0,D3DTSS_ALPHAARG1,D3DTA_TEXTURE);
m_pd3dDevice->SetTextureStageState(0,D3DTSS_ALPHAOP,D3DTOP_SELECTARG1);
//渲染图元
m_pd3dDevice->SetFVF(FVF);
m_pd3dDevice->SetStreamSource(0,m_pVB,0,sizeof(VERTEX));
m_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLEFAN,0,2);
//还原渲染状态
m_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE,FALSE);         
m_pd3dDevice->SetRenderState(D3DRS_SRCBLEND,D3DBLEND_ONE);   
m_pd3dDevice->SetRenderState(D3DRS_DESTBLEND,D3DBLEND_ZERO);

运行程序,发现,的确实现了ColoyKey效果!

*****************************************************************

(2)如何使用顶点alpha?

顶点alpha应用很多,有一个例子是,在用户界面中,利用顶点alpha,可以
像QQ那样随意切换透明度。(只需要设置一下矩形的4个顶点的alpha值即可)

方法是:为顶点的diffuse(色彩)设置alpha值,
然后,使用顶点的diffuse里的alpha通道,来进行alpha混合即可。

具体做法:

由于同样是alpha混合操作,所以与上面的(1)非常类似。
因此你可以Ctrl+C、Ctrl+V。

首先需要更改顶点定义。加上color值。或者叫做diffuse。
struct COLORVERTEX
{
    FLOAT x, y, z, rhw; // The transformed position for the vertex
    DWORD color;
    FLOAT tu, tv;
};
const DWORD FVF = (D3DFVF_XYZRHW | D3DFVF_TEX1 | D3DFVF_DIFFUSE);

在InitDeviceObjects()函数里,加载纹理,和(1)一样,去复制粘贴吧^_^

在RestoreDeviceObjects()函数里,设置各各顶点。以及顶点的alpha值:
我觉的这段代码我可以不用写了。
比如,我把color的最高位,也就是alpha通道设为0x88。(50%透明)
(根据需要,你可能需要实时地改变顶点的alpha值,这个你自己来写)

现在,我们的顶点,含有了alpha值0x88。(50%透明)
那么,我们就需要利用顶点中含有的alpha值,来进行alpha混合。
这样,就可以实现顶点alpha的半透明效果。

修改(1)中的Render()函数,修改1行就可以:
把这一行:
m_pd3dDevice->SetTextureStageState(0,D3DTSS_ALPHAARG1,D3DTA_TEXTURE);
修改为:
m_pd3dDevice->SetTextureStageState(0,D3DTSS_ALPHAARG1,D3DTA_DIFFUSE);
这样就可以了。也就是更改了一个参数而已。

运行程序,发现,的确实现了半透明效果。


但是,这个顶点alpha效果中,没有色彩键,这就很讨厌,那么怎么实现呢?

*****************************************************************

(3)怎样同时使用ColorKey以及顶点Alpha效果?

开门见山,先说怎么实现:

修改(2)中的Render()函数中的几行代码,
为了怕你弄错了,我浪费大量篇幅把修改后的Render()代码全部写出来:

//设置alpha混合
m_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE,TRUE);
m_pd3dDevice->SetRenderState(D3DRS_SRCBLEND,D3DBLEND_SRCALPHA);
m_pd3dDevice->SetRenderState(D3DRS_DESTBLEND,D3DBLEND_INVSRCALPHA);
//设置alpha值(把纹理alpha和顶点alpha进行乘法运算)
m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );
m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE );
//渲染图元
m_pd3dDevice->SetFVF(FVF);
m_pd3dDevice->SetStreamSource(0,m_pVB,0,sizeof(VERTEX));
m_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLEFAN,0,2);
//还原渲染状态
m_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE,FALSE);         
m_pd3dDevice->SetRenderState(D3DRS_SRCBLEND,D3DBLEND_ONE);   
m_pd3dDevice->SetRenderState(D3DRS_DESTBLEND,D3DBLEND_ZERO);

运行程序,成功地实现了漂亮的ColorKey加顶点Alpha效果。


说明:

原理是什么呢?
在一个纹理阶段中,d3d可以对2个参数进行某种运算,获得一个alpha的输出(op)值。

我们的目的是,
纹理alpha为0x00 --   0%(色彩键)的时候,alpha的op为零,即完全透明。
纹理alpha为0xFF -- 100%(非色彩键)的时候,alpha的op为顶点的alpha。

那么,很容易想到,使用乘法运算。
看看头文件,D3DTOP_MODULATE 做的就是乘法运算。然后,试验通过。

因为,
   0% * 顶点alpha值 == 0 (完全透明)
100% * 顶点alpha值 == 顶点alpha值
(运算的时候,换算为百分比,即0xff的alpha值换算为1.0 == 100%)

362

主题

3023

帖子

3553

积分

论坛元老

Rank: 8Rank: 8

积分
3553
 楼主| 发表于 2008-1-13 06:24:00 | 显示全部楼层

Re: 同时使用ColorKey以及顶点Alpha效果

传个截图看看^ ^

看看Fps!这样做使用了3d硬件加速,所以很快。

如果你使用lock,然后自己写alpha混合,色彩键算法的话,会很慢的.
sf_20081136241.jpg

52

主题

155

帖子

160

积分

注册会员

Rank: 2

积分
160
发表于 2008-1-13 09:25:00 | 显示全部楼层

Re:同时使用ColorKey以及顶点Alpha效果

谢谢分享

14

主题

345

帖子

376

积分

中级会员

Rank: 3Rank: 3

积分
376
QQ
发表于 2008-5-18 12:44:00 | 显示全部楼层

Re:同时使用ColorKey以及顶点Alpha效果

用shader更方便

86

主题

2251

帖子

2384

积分

金牌会员

Rank: 6Rank: 6

积分
2384
QQ
发表于 2008-5-18 13:09:00 | 显示全部楼层

Re:同时使用ColorKey以及顶点Alpha效果

直接用美术工具把该透的地方alpha降成0x00得了。

362

主题

3023

帖子

3553

积分

论坛元老

Rank: 8Rank: 8

积分
3553
 楼主| 发表于 2008-5-18 17:36:00 | 显示全部楼层

Re: Re:同时使用ColorKey以及顶点Alpha效果

funcman: Re:同时使用ColorKey以及顶点Alpha效果

直接用美术工具把该透的地方alpha降成0x00得了。


...那MS是本文之外的话题,本文主要讲如何绘制

362

主题

3023

帖子

3553

积分

论坛元老

Rank: 8Rank: 8

积分
3553
 楼主| 发表于 2008-5-18 17:36:00 | 显示全部楼层

Re: Re:同时使用ColorKey以及顶点Alpha效果

xoyojank: Re:同时使用ColorKey以及顶点Alpha效果

用shader更方便


4个顶点没必要Shader,还有不能运行的机器。

121

主题

2029

帖子

2034

积分

金牌会员

Rank: 6Rank: 6

积分
2034
QQ
发表于 2008-5-18 20:46:00 | 显示全部楼层

Re:同时使用ColorKey以及顶点Alpha效果

用VS可以用REF的,速度也贼快。

362

主题

3023

帖子

3553

积分

论坛元老

Rank: 8Rank: 8

积分
3553
 楼主| 发表于 2008-5-19 04:34:00 | 显示全部楼层

Re:同时使用ColorKey以及顶点Alpha效果

俺的?C器?行不起来VS

22

主题

63

帖子

63

积分

注册会员

Rank: 2

积分
63
发表于 2008-5-19 11:00:00 | 显示全部楼层

Re:同时使用ColorKey以及顶点Alpha效果

楼主是个好人。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-6-8 06:05

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表