http://blog.sina.com.cn/ufownl[订阅]
字体大小: 正文
第二章 图像和视频(上)(2007-08-23 22:56:16)
 

第二章 图像和视频

SDL Vidow显示

初始化SDL Video显示

视频是最常用的部分,也是SDL最完整的子系统。下面的初始化过程是每个SDL程序都要做的,即使可能有些不同。

 

例2-1 初始化视频

    SDL_Surface *screen;

 

    /* Initialize the SDL library */

    if( SDL_Init(SDL_INIT_VIDEO) < 0 ) {

        fprintf(stderr,

                "Couldn't initialize SDL: %s\n", SDL_GetError());

        exit(1);

    }

 

    /* Clean up on exit */

    atexit(SDL_Quit);

   

    /*

     * Initialize the display in a 640x480 8-bit palettized mode,

     * requesting a software surface

     */

    screen = SDL_SetVideoMode(640, 480, 8, SDL_SWSURFACE);

    if ( screen == NULL ) {

        fprintf(stderr, "Couldn't set 640x480x8 video mode: %s\n",

                        SDL_GetError());

        exit(1);

    }

初始化最佳视频模式

如果你希望某种色深(颜色数)但如果用户的显示器不支持也可以接受其他色深,使用加SDL_ANYFORMAT参数的SDL_SetVideoMode。您还可以用SDL_VideoModeOK来找到与请求模式最接近的模式。

 

例2-2 初始化最佳视频模式

    /* Have a preference for 8-bit, but accept any depth */

    screen = SDL_SetVideoMode(640, 480, 8, SDL_SWSURFACE|SDL_ANYFORMAT);

    if ( screen == NULL ) {

        fprintf(stderr, "Couldn't set 640x480x8 video mode: %s\n",

                        SDL_GetError());

        exit(1);

    }

    printf("Set 640x480 at %d bits-per-pixel mode\n",

           screen->format->BitsPerPixel);

读取并显示BMP文件

当SDL已经初始化,视频模式已经选择,下面的函数将读取并显示指定的BMP文件。

 

例2-3 读取并显示BMP文件

void display_bmp(char *file_name)

{

    SDL_Surface *image;

 

    /* Load the BMP file into a surface */

    image = SDL_LoadBMP(file_name);

    if (image == NULL) {

        fprintf(stderr, "Couldn't load %s: %s\n", file_name, SDL_GetError());

        return;

    }

 

    /*

     * Palettized screen modes will have a default palette (a standard

     * 8*8*4 colour cube), but if the image is palettized as well we can

     * use that palette for a nicer colour matching

     */

    if (image->format->palette && screen->format->palette) {

    SDL_SetColors(screen, image->format->palette->colors, 0,

                  image->format->palette->ncolors);

    }

 

    /* Blit onto the screen surface */

    if(SDL_BlitSurface(image, NULL, screen, NULL) < 0)

        fprintf(stderr, "BlitSurface error: %s\n", SDL_GetError());

 

    SDL_UpdateRect(screen, 0, 0, image->w, image->h);

 

    /* Free the allocated BMP surface */

    SDL_FreeSurface(image);

}

直接在显示上绘图

下面两个函数实现在图像平面的像素读写。它们被细心设计成可以用于所有色深。记住在使用前要先锁定图像平面,之后要解锁。

 

在像素值和其红、绿、蓝值间转换,使用SDL_GetRGB()和SDL_MapRGB()。

 

例2-4 getpixel()

/*

 * Return the pixel value at (x, y)

 * NOTE: The surface must be locked before calling this!

 */

Uint32 getpixel(SDL_Surface *surface, int x, int y)

{

    int bpp = surface->format->BytesPerPixel;

    /* Here p is the address to the pixel we want to retrieve */

    Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;

 

    switch(bpp) {

    case 1:

        return *p;

 

    case 2:

        return *(Uint16 *)p;

 

    case 3:

        if(SDL_BYTEORDER == SDL_BIG_ENDIAN)

            return p[0] << 16 | p[1] << 8 | p[2];

        else

            return p[0] | p[1] << 8 | p[2] << 16;

 

    case 4:

        return *(Uint32 *)p;

 

    default:

        return 0;       /* shouldn't happen, but avoids warnings */

    }

}

例2-5 putpixel()

/*

 * Set the pixel at (x, y) to the given value

 * NOTE: The surface must be locked before calling this!

 */

void putpixel(SDL_Surface *surface, int x, int y, Uint32 pixel)

{

    int bpp = surface->format->BytesPerPixel;

    /* Here p is the address to the pixel we want to set */

    Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;

 

    switch(bpp) {

    case 1:

        *p = pixel;

        break;

 

    case 2:

        *(Uint16 *)p = pixel;

        break;

 

    case 3:

        if(SDL_BYTEORDER == SDL_BIG_ENDIAN) {

            p[0] = (pixel >> 16) & 0xff;

            p[1] = (pixel >> 8) & 0xff;

            p[2] = pixel & 0xff;

        } else {

            p[0] = pixel & 0xff;

            p[1] = (pixel >> 8) & 0xff;

            p[2] = (pixel >> 16) & 0xff;

        }

        break;

 

    case 4:

        *(Uint32 *)p = pixel;

        break;

    }

}

例2-6 使用上面的putpixel()在屏幕中心画一个黄点

    /* Code to set a yellow pixel at the center of the screen */

 

    int x, y;

    Uint32 yellow;

 

    /* Map the color yellow to this display (R=0xff, G=0xFF, B=0x00)

       Note:  If the display is palettized, you must set the palette first.

    */

    yellow = SDL_MapRGB(screen->format, 0xff, 0xff, 0x00);

 

    x = screen->w / 2;

    y = screen->h / 2;

 

    /* Lock the screen for direct access to the pixels */

    if ( SDL_MUSTLOCK(screen) ) {

        if ( SDL_LockSurface(screen) < 0 ) {

            fprintf(stderr, "Can't lock screen: %s\n", SDL_GetError());

            return;

        }

    }

 

    putpixel(screen, x, y, yellow);

 

    if ( SDL_MUSTLOCK(screen) ) {

        SDL_UnlockSurface(screen);

    }

    /* Update just the part of the display that we've changed */

    SDL_UpdateRect(screen, x, y, 1, 1);

 

    return;

加载中,请稍候...
  • 评论加载中,请稍候...

验证码:请点击后输入验证码  收听验证码

发评论

以上网友发言只代表其个人观点,不代表新浪网的观点或立场。

相关博文
读取中...
推荐博文
读取中...