随笔 - 96  文章 - 255  trackbacks - 0
<2008年2月>
272829303112
3456789
10111213141516
17181920212223
2425262728291
2345678

E-mail:zbln426@163.com QQ:85132383 长期寻找对战略游戏感兴趣的合作伙伴。

常用链接

留言簿(21)

随笔分类

随笔档案

SDL相关网站

我的个人网页

我的小游戏

资源下载

搜索

  •  

积分与排名

  • 积分 - 484975
  • 排名 - 37

最新评论

阅读排行榜

评论排行榜

作者:龙飞

1:什么是抠色(Color Keying)

        我们总是blit矩形区域的图片,但是很显然,几乎没有一个游戏的角色图片是矩形的。美工把图片画到一个矩形范围内,如果设定了特定的背景颜色,我们就可以把矩形图片上的角色“抠”下来,相对于背景来说,我们就是把不属于角色的背景颜色扣掉,故称抠色。
        我们看看SDL抠色函数的原形:
int SDL_SetColorKey(SDL_Surface *surface, Uint32 flag, Uint32 key);
        这里有个参数是Uint32 key,这就是我们要抠掉的颜色。要明白SDL如何描述颜色的,我们先看看另外一个函数。

2:RGB映射
Uint32 SDL_MapRGB(SDL_PixelFormat *fmt, Uint8 r, Uint8 g, Uint8 b);
        显然,参数r, g, b代表了红,绿和蓝。而fmt则是代表了这些颜色的格式。我们一般会选择使用作为被抠色的矩形图片的颜色格式。这样的图片是一个SDL_Surface结构。
typedef struct SDL_Surface {
  Uint32 flags;                           
/* Read-only */
  SDL_PixelFormat 
*format;                /* Read-only */
  
int w, h;                               /* Read-only */
  Uint16 pitch;                           
/* Read-only */
  
void *pixels;                           /* Read-write */
  SDL_Rect clip_rect;                     
/* Read-only */
  
int refcount;                           /* Read-mostly */

  
/* This structure also contains private fields not shown here */

} SDL_Surface;
        也就是成员数据format,所以,我们很自然的可以把RGB映射看成是SDL Surface的一个方法。同样,因为抠色行为也绑定在相应的Surface上,所以我们可以想到把这两个函数合起来,作为我们所构建的SDL Surface的一个类方法。
        请注意成员数据w和h,在之前的程序中,我们直接定义了frontImage的大小为常量。我们可以把程序修改得更加健壮一些——让程序自动反馈frontImage的大小。
    //moving image's size.
    const int IMG_WIDTH = frontImage.point()->w;
    
const int IMG_HEIGHT = frontImage.point()->h;

3:添加Surface的类方法,抠色
class DisplaySurface
{
private:
    
//
public:
    
//
        void colorKey(Uint8 r, Uint8 g, Uint8 b, Uint32 flag = SDL_SRCCOLORKEY);
};
        其它的成员数据和成员函数不需要做任何的改变。我们只需要增加一个新的类方法colorKey()。
        需要说明的是flag位标,它有三种模式:
SDL_SRCCOLORKEY 表示正常抠色;
0 表示清除扣色效果;
SDL_SRCCOLORKEY|SDL_RLEACCEL 表示将扣色后的图片重新编码(通常意味着重复使用时会快些)。
    作为背景的颜色,一般选择“无红满绿满蓝”(r=0,g=0xFF,b=0xFF)或者“满红无绿满蓝”(r=0xFF,g=0,b=oxFF)。要直观的了解这两种颜色,最好的方法是直接打开画图程序,用调色版将这两种颜色配出来。(我们这里的例子中使用了“无红满绿满蓝”的背景。)类方法的实现如下:
void DisplaySurface::colorKey(Uint8 r, Uint8 g, Uint8 b, Uint32 flag)
{
    Uint32 colorkey 
= SDL_MapRGB(pSurface->format, r, g, b);
    
if ( SDL_SetColorKey(pSurface, flag, colorkey ) < 0 )
        
throw ErrorInfo(SDL_GetError());
}
        SDL的风格,如果SDL_SetColorkey()成功则返回0,否则返回-1。

4:在主程序中使用新的类方法,抠色

        因为是类方法,所以使用起来就很直观了。我们在创建需要抠色的DisplaySurface对象之后,直接使用类方法就可以了。比如一个使用“无红满绿满蓝”背景的需要抠色的图片colorkey.bmp,我们使用如下语句就可以轻松实现抠色了。
    DisplaySurface frontImage("colorkey.bmp", screen);
    frontImage.colorKey(
00xFF0xFF);
posted on 2008-03-19 20:33 lf426 阅读(4532) 评论(2)  编辑 收藏 引用 所属分类: SDL入门教程

FeedBack:
# re: SDL入门教程(七):SDL抠色(Color Keying) 2011-08-08 13:56 waynewonk
没变化哎  回复  更多评论
  
# re: SDL入门教程(七):SDL抠色(Color Keying) 2013-04-08 18:08 ylguo
key设置的不对@waynewonk
  回复  更多评论
  

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理