GBA探索日记(三)(Color Special Effects)
我们知道在游戏中做Alpha混合和Fade-in/Fade-out等颜色特效是十分消耗CPU的.对于GBA这样的16.78MHz的CPU就更显得费劲.不过还好,GBA提供了硬件上对这两种颜色特效(Color Special Effects)的支持.所以你就不用担心这些问题了.
1.Alpha混合
首先你应该知道什么是Alpha混合.其实就是透明处理.
其处理的算法就是
R=R1*alpha+R2*(1-alpha);
G=G1*alpha+G2*(1-alpha);
B=B1*alpha+B2*(1-alpha);
其中alpha是个小于等于1的小数.而R,G,B是混合后的点的RGB值,R1,G1,B1和R2,G2,B2分别是两个要混合的点的RGB值.
由于一张图片有好几千到好几百万个点,而每个点又包含三个浮点运算,所以这中Alpha混合的计算量是很巨大的,计算速度就是个很严重的问题.
GBA中有对Alpha混合的硬件支持,你只需对相关的寄存器设置好参数,然后它就会自己来帮你计算,由于是硬件上的计算,所以速度问题就解决了.
下面我们就直接看看如何设置Alpha混合的寄存器.
在AgbLib中定义了下面两个寄存器
#define REG_BLDCNT (REG_BASE + 0x50) //
Blend Mode Control
#define REG_BLDALPHA (REG_BASE + 0x52) // Semi-transparent
Parameter
其中涉及到REG_BASE,它是寄存的开始地址,你可以看看它的总线地址
#define REG_BASE
0x04000000 // Registers
REG_BLDCNT是设置颜色特效(Color Special
Effects)参数的寄存器.它不仅控制Alpha混合,还控制后面讲的Fade-in/Fade-out的设置.
在AgbLib中的官方文档中是这么说的这个寄存器的
The types of
color special effects and the target pixels, are determined by the BLDMOD
register.
可以看出,REG_BLDCNT的0-5位是设置第一个混合目标(1st Target Pixel)的范围,可以是BG0-BG3,OBJ,BD中的一个或多个.
9-13位是设置第二个混合目标(2nd Targer Pixel)的范围,同样的是BG0-BG3,OBJ,BD中的一个或多个.
而中间的06-07是设置颜色特效的种类.
下面我们再来看另一个控制Alpha混合的寄存器REG_BLDALPHA的设置
这个寄存器简单地说就是设置Alpha值的寄存器.我们还是看看官方文档中怎么讲解它的
其中EVB,EVA就是Alpha值.只能是0-16
它们在寄存器中设置的值和参与计算的值对应如下:
其中讲到EVY,它是关于Fade-in/Fade-out的,现在可以不管它.
实际GBA硬件内部进行Alpha混合的计算的方式是这样的.
Alpha Blending (16 levels of semi-transparency) Operations
Display
color (R) = 1st pixel color (R) ×EVA + 2nd pixel color (R)×EVB
Display
color (G) = 1st pixel color (G) ×EVA + 2nd pixel color (G) ×EVB
Display
color (B) = 1st pixel color (B) ×EVA + 2nd pixel color (B) ×EVB
好,说了这么多,让我们来看一个例子.
先看看这张经过Alpha混合的图片
其中地面是放在BG0,海洋是放在BG1,白云是放在BG2,中间白色的球是放在OBJ中的.
其中Alpha混合的目的是要让地面,海洋,百球都和白云混合.
它的寄存器是这样设置的.
// Semi-transparent setting for cloud
*(vu16 *)REG_BLDCNT = 0x3b44; // 11101101000100
*(vu16 *)REG_BLDALPHA = 0x080c; //
10000000001100
然后你就自己对照着前面的图表去看吧.
2 Fade-in/Fade-out
Fade-in/Fade-out就是淡入淡出效果.GBA同样提供了硬件支持.而且它的设置跟上面讲的Alpha混合几乎是完全一样的.
设置它的同样是两个寄存器.
#define REG_BLDCNT (REG_BASE + 0x50) //
Blend Mode Control
#define REG_BLDY (REG_BASE +
0x54) // Brightness Change Parameter
关于REG_BLDCNT,前面讲的Alpha混合中已经消息讲解过了.
下面我们就直接看看REG_BLDY这个寄存器
似乎有点浪费,这个16位的寄存器只有前5位有用.
这5位就是表示明暗侄EVY.
同样请看看前面关于EVA,EVB,EVY的图表.它记录了EVY对应的实际计算值.
然后看看GBA硬件是怎么样计算Fade-in/Fade-out效果的.
Brightness
Increase Operations
Display
color (R) = 1st pixel (R) + (31 - 1st pixel (R) ) ×EVY
Display
color (G) = 1st pixel (G) + (63 - 1st pixel (G) ) ×EVY
Display
color (B) = 1st pixel (B) + (31 - 1st pixel (B) ) ×EVY
Brightness
Decrease Operations
Display
color (R) = 1st pixel (R) - 1st pixel (R) ×EVY
Display
color (G) = 1st pixel (G) - 1st pixel (G) ×EVY
Display
color (B) = 1st pixel (B) - 1st pixel (B) ×EVY
讲到这里基本就结束了吧.这里也不用再举例子了,Fade-in/Fade-out的处理和前面的Alpha混合几乎是一样的.所以这里就没有这个必要了.不过要说明的是Brightness Increase Operations是逐渐变白,Brightness
Decrease Operations是逐渐变黑