Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1640086
  • 博文数量: 311
  • 博客积分: 7778
  • 博客等级: 少将
  • 技术积分: 4186
  • 用 户 组: 普通用户
  • 注册时间: 2009-11-09 19:59
个人简介

蓝点工坊(http://www.bluedrum.cn) 创始人,App和嵌入式产品开发。同时也做相应培训和外包工作。 详细介绍 http://pan.baidu.com/s/1y2g88

文章存档

2012年(3)

2011年(115)

2010年(170)

2009年(23)

分类: C/C++

2010-03-15 22:57:12

 
Andrew Huang
 
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位的情况。这个后面会使用
 
像素处理

void DrawPixel(SDL_Surface *screen, Uint8 R, Uint8 G, Uint8 B)
{
    Uint32 color = SDL_MapRGB(screen->format, R, G, B);

    if ( SDL_MUSTLOCK(screen) ) {
        if ( SDL_LockSurface(screen) < 0 ) {
            return;
        }
    }
    switch (screen->format->BytesPerPixel) {
        case 1: { /* Assuming 8-bpp */
            Uint8 *bufp;

            bufp = (Uint8 *)screen->pixels + y*screen->pitch + x;
            *bufp = color;
        }
        break;

        case 2: { /* Probably 15-bpp or 16-bpp */
            Uint16 *bufp;

            bufp = (Uint16 *)screen->pixels + y*screen->pitch/2 + x;
            *bufp = color;
        }
        break;

        case 3: { /* Slow 24-bpp mode, usually not used */
            Uint8 *bufp;

            bufp = (Uint8 *)screen->pixels + y*screen->pitch + x;
            *(bufp+screen->format->Rshift/8) = R;
            *(bufp+screen->format->Gshift/8) = G;
            *(bufp+screen->format->Bshift/8) = B;
        }
        break;

        case 4: { /* Probably 32-bpp */
            Uint32 *bufp;

            bufp = (Uint32 *)screen->pixels + y*screen->pitch/4 + x;
            *bufp = color;
        }
        break;
    }
    if ( SDL_MUSTLOCK(screen) ) {
        SDL_UnlockSurface(screen);
    }
    SDL_UpdateRect(screen, x, y, 1, 1);
}


 
 
 
 
 

阅读(5107) | 评论(1) | 转发(0) |
0

上一篇:LCD模块 FPC接线

下一篇:SDL 编程基本知识

给主人留下些什么吧!~~

chinaunix网友2010-09-09 22:16:01

请问x、y值何来?