SDL 显示核心 SDL_Surface 操作

Surface是平面的含意,在SDL中,所有绘制在视频输出都是通过SDL_Sur对face对象来输出。一个图像,一段文字,一个视频都需要转换成 SDL_Surface对象来操作,它们可以平铺,堆叠。他们所有数据最终要在一个叠加在表示screen 的SDL_Surface的对象中输出显示。
TAG: SDL  

Andrew Huang bluedrum@163.com

Pixel 概念。

数字屏幕是一个二维可显示的像素空间,即一个一个点形成的。如果是黑白色,只需要0,1即可表示。但如果这个点有表达多种颜色。
 
SDL_Surface 概念
 
Surface是平面的含意,在SDL中,所有绘制在视频输出都是通过SDL_Sur对face对象来输出。一个图像,一段文字,一个视频都需要转换成SDL_Surface对象来操作,它们可以平铺,堆叠。他们所有数据最终要在一个叠加在表示screen 的SDL_Surface的对象中输出显示。

因此SDL_Surface本质是一个矩形的像素内存,它需要通过专门的绘点函数来输出到不同设备上。
其中SDL_Surface 的坐标系是左上角是原点,向下向左递增.

SDL_Surface的高,宽值保存在结构的w,h成员。(SDL_Surface.w,SDL_Surface.h);
 
一.屏幕Surface的操作
------------------------------------------------------------------------
一个带图形显示的的SDL程序(基本上所有都带),首先要初始化一个屏幕Surface.其余所有输出到屏幕的Surface数据都要填充到屏幕Surface上。
 
1.1 初始化屏幕
     采用 SDL_SetVideoMode()来初始化屏幕。这个屏幕是特指SDL绘制的窗口,并不是指整个屏幕。
 
    SDL_Surface* SDL_SetVideoMode(int width, int height, int bitsperpixel, Uint32 flags);

  width,height是输出高和宽,bitsperpixel 就是指bpp.即每点像素数,取值 8,16,32,值越大,说明屏幕表现力越丰富。它取决于显示器或LCD的硬件性能。一般桌面显示器是32.嵌入式设备的bpp可以用fbset 命令来查看。
 
flags 常见取值有如下(可以取多个值)
SDL_SWSURFACE :数据区建立在系统内存之上
SDL_HWSURFACE:数据区建立在显存之上
SDL_FULLSCREEN:全屏模式
SDL_NOFRAME:取消边框和标题栏
SDL_DOUBLEBUF:硬件双缓冲,必须与SDL_HWSURFACE同时使用。


例: screen = SDL_SetVideoMode( 640,320,32, SDL_SWSURFACE );

1.2 设置窗口标题
void SDL_WM_SetCaption(const char *title, const char *icon);
 
title 是窗口标题名字,如果是中文,必须是UTF-8编码。
icon 是窗口最小化采用显示文字。也采用UTF-8编码
 
1.3 把一个Surface数据拷入屏幕
    int SDL_BlitSurface(SDL_Surface *src, SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect);

   这里dst是输出surface(不一定是屏幕Surface,也可以另外一个Surface).
  dstrect是src在dst中相应的位置.
 
1.4 刷新屏幕
   int SDL_Flip(SDL_Surface* screen);
   把更新后的Surface数据显示在屏幕上,SDL_BlitSurface数据加入屏幕后,不执行这一句,将不会更新到屏幕上显示。
 
1.5 部分更新屏幕
   如果每次都更新整个屏幕,效率这样很低,可以用SDL_UpdateRect更新部分区域
   void SDL_UpdateRect(SDL_Surface* screen, Sint32 x, Sint32 y, Sint32 w, Sint32 h);

1.6 设置窗口图标
       void SDL_WM_SetIcon(SDL_Surface *icon, Uint8 *mask);  

二.SDL_Surface 基本操作
---------------------------------------------------------------------------
 
  SDL库内置对BMP的处理,因此我们用最常见的就是位图操作来演示Surface操作.
 
2.1 装入位图
 
我们采用如下方式生成一个位图Surface.
 
SDL_Surface *SDL_LoadBMP(const char *file);
注意SDL库不支持其它格式图片处理,如有这个需求,需要用SDL_image来扩展
 
其中SDL_Surface的宽度,高度就是位图的高,宽
 
将位图显示在屏幕上,采用SDL_BlitSurface来加入屏幕上。它将原始尺寸显示在屏幕上。如果位图从起点开始显示,宽度和高度超过屏幕。图像会被截掉。
 
2.2 缩放显示Surface
大部分的应用是需要把Surface 完整缩放显示在整个屏幕之上。SDL有一个未公开的函数SDL_Stretch:
extern DECLSPEC int SDLCALL SDL_SoftStretch(SDL_Surface *src, SDL_Rect *srcrect,SDL_Surface *dst, SDL_Rect *dstrect);
这个拉伸可能会极大影响图片效果,而且在文档中也明确声明可能不会用。但是实测是可以达到拉伸的效果。
 
2.3 释放Surface.
   一个Surface不使用必须使用SDL_FreeSurface来释放。

3.SDL_Surface 的底层输出
--------------------------------------
 在桌面平台一般无需处理原始像素输出。在嵌入式平台,如果分辩率不同,要做一些特殊处理。以下就一段通用代码。分别处理 像素数为8,16,32位的情况。这个后面会使用
 
像素处理

   
   
  1. void DrawPixel(SDL_Surface *screen, Uint8 R, Uint8 G, Uint8 B) 
  2.     Uint32 color = SDL_MapRGB(screen->format, R, G, B); 
  3.  
  4.     if ( SDL_MUSTLOCK(screen) ) { 
  5.         if ( SDL_LockSurface(screen) < 0 ) { 
  6.             return
  7.         } 
  8.     } 
  9.     switch (screen->format->BytesPerPixel) { 
  10.         case 1: { /* Assuming 8-bpp */ 
  11.             Uint8 *bufp; 
  12.  
  13.             bufp = (Uint8 *)screen->pixels + y*screen->pitch + x; 
  14.             *bufp = color; 
  15.         } 
  16.         break
  17.  
  18.         case 2: { /* Probably 15-bpp or 16-bpp */ 
  19.             Uint16 *bufp; 
  20.  
  21.             bufp = (Uint16 *)screen->pixels + y*screen->pitch/2 + x; 
  22.             *bufp = color; 
  23.         } 
  24.         break
  25.  
  26.         case 3: { /* Slow 24-bpp mode, usually not used */ 
  27.             Uint8 *bufp; 
  28.  
  29.             bufp = (Uint8 *)screen->pixels + y*screen->pitch + x; 
  30.             *(bufp+screen->format->Rshift/8) = R; 
  31.             *(bufp+screen->format->Gshift/8) = G; 
  32.             *(bufp+screen->format->Bshift/8) = B; 
  33.         } 
  34.         break
  35.  
  36.         case 4: { /* Probably 32-bpp */ 
  37.             Uint32 *bufp; 
  38.  
  39.             bufp = (Uint32 *)screen->pixels + y*screen->pitch/4 + x; 
  40.             *bufp = color; 
  41.         } 
  42.         break
  43.     } 
  44.     if ( SDL_MUSTLOCK(screen) ) { 
  45.         SDL_UnlockSurface(screen); 
  46.     } 
  47.     SDL_UpdateRect(screen, x, y, 1, 1); 
  48. }

 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值