SDL入门教程(五):3、对SDL_BlitSurface()的进一步讨论

作者:龙飞

3.1:矩形区域SDL_Rect。

typedef  struct {
  Sint16 x, y;
  Uint16 w, h;
} SDL_Rect;
        因为显示器通常是矩形的,所以,矩形是计算机图形学中最基本的操作区域单元。这个结构很简单,x和y是矩形的左上角坐标。x从左到右增加;y从上到下增加。左上角的坐标就是(0,0)——SDL中就是这样的。w是矩形的宽,h是矩形的高。

3.2:进一步了解SDL_BlitSurface()。
int  SDL_BlitSurface(SDL_Surface  * src, SDL_Rect  * srcrect, SDL_Surface  * dst, SDL_Rect  * dstrect);
        4个参数都是指针——2个SDL_Surface指针,2个SDL_Rect指针。src是源面,也就是被blit的面;dst是目的面,也就是源面被blit到的面。srcrect是源面上的一个矩形区域,实际上,正是这个矩形区域被blit,如果是空指针,则整个源面被blit;dstrect虽然是个矩形区域指针,但是实际上只用到了这个矩形左上角坐标的数据。所以,实际上,它是源面被blit到目的面上的坐标。如果是空指针,则被blit到目的面的左上角(0,0)。

3.3:为surface类增加新的方法。
class  DisplaySurface
{
public :
    
bool  blit( int  at_x,  int  at_y)  const ;
    
bool  blit( int  at_x,  int  at_y,  int  from_x,  int  from_y,  int  w,  int  h,  int  delta_x  =   2 int  delta_y  =   2 const ;
};
我们重载了blit()方法。
bool  DisplaySurface::blit( int  at_x,  int  at_y)  const
{
    SDL_Rect offset;
    offset.x 
=  at_x;
    offset.y 
=  at_y;

    
if  ( SDL_BlitSurface(pSurface,  0 , pScreen,  & offset)  <   0  )
        
return   false ;
    
else   return   true ;
}
这个方法,让整个源面被blit到目的面的(at_x,at_y)坐标上。
bool  DisplaySurface::blit( int  at_x,  int  at_y,
                          
int  from_x,  int  from_y,  int  w,  int  h,
                          
int  delta_x,  int  delta_y)  const
{
    SDL_Rect offset;
    offset.x 
=  at_x  -  delta_x;
    offset.y 
=  at_y  -  delta_y;

    SDL_Rect dest;
    dest.x 
=  from_x  -  delta_x;
    dest.y 
=  from_y  -  delta_y;
    dest.w 
=  w  +  delta_x * 2 ;
    dest.h 
=  h  +  delta_y * 2 ;

    
if  ( SDL_BlitSurface(pSurface,  & dest, pScreen,  & offset)  <   0  )
        
return   false ;
    
else   return   true ;
}
这个函数,把源面上,一个左上角坐标是(from_x,from_y),宽为w,高为h的矩形区域,blit到目的面的(at_x,at_y)坐标上。
要说明delta_x和delta_y的作用,我们先思考一个问题:动画效果是如何实现的。
我们假设有个作为背景的surface,名为back,我们要让一个名为front的surface在back上动起来。显然,至少有两种方法:
1) 把front blit到back上,把back blit到screen上,flit screen,显示出原来的图像;
    把back面“搽干净”;改变front的坐标,将改变坐标后的front blit到back上,把back blit到screen上,flit screen,显示出更新后的图像。
2) 把back blit到screen上,flit screen,首先显示出back图像;
    先把back面“搽干净”;把front blit到screen上(back是一直保持在screen上的,而front会被blit到back的上层),flit screen,显示出更新后的图像。
因为,第二种方法把所有的surface都直接往screen上blit,思路更为简单,所以,我们先讨论这种方法。
而对于“搽干净”这个概念,又有两种思路:
1) 全部back更新;
2) 更新back上“被弄脏”的部分。
实际上,当前的电脑速度对在平面上的blit速度问题已经不再是问题了。但是,在不久之前,程序员们还在为了计算机图形的实现速度而绞尽脑汁。blit一部分应该是比blit全部图像要快的。所以,这个重载的blit()方法多用于对于back的blit。delta_x和delta_y是为了保证blit的back部分,比front大那么一点点。不然的话——实际上大家可以把delta_x和delta_y设置为0看看是什么效果。  

你可能感兴趣的:(SDL入门教程(五):3、对SDL_BlitSurface()的进一步讨论)