SDL显示图片总结

到现在为止,已经写了好几个显示图片一类的程序  现在就来好好总结一下

首先我们在最开始   是在屏幕上显示一张图片
整个过程如下:
定义两个 SDL_Surface 指针变量   分别是表示窗口和图像  
之后就调用 SDL_Init()进行初始化SDL的子系统
SDL_SetVideoMode()函数是用来设置窗口的
之后就是加载图像(现期的sdl只能加载bmp位图  其他格式需要调用扩展库)调用 SDL_LoadBMP()
在窗口和图像都赋值以后就调用 SDL_BlitSurface(图像 , NULL, 窗口, NULL )将图像映射到窗口
当然现在还不会显示  调用 SDL_Flip(窗口)就可以显示了
SDL_Delay()的作用就是为了延迟显示时间 能够让你看到
完事以后记得 SDL_FreeSurface()释放资源
最后  SDL_Quit()退出就好了

上面的过程其实已经基本上差不多了
第二个程序其实是第一个的优化版本,因为有时候加载的图片与显示的位数不同,所以在现实的时候存在一个隐式的格式转换。比较浪费时间,所以在加载的时候  我们可以读取的时候就把他转一下  就不用在显示的时候转换
主要就是在调用 SDL_LoadBMP() 以后  再调用 SDL_DisplayFormat()

第三个则是引进了扩展库  用来识别更多格式的图片
只是将 SDL_LoadBMP() 改成了 IMG_Load()

——————————————————————————————————————————————
下面就来细化一下上面说的一些函数:
SDL_Surface类型     我们可以在SDL_video.h里面找到它的定义
/** This structure should be treated as read-only, except for 'pixels',
*  which, if not NULL, contains the raw pixel data for the surface.
*这个结构应该被视为只读结构,除了‘像素’,如果不是NULL,它包含表面的原始像素数据。
*/
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 */
    int offset;                /**< Private */
    /** Hardware-specific surface info */
    struct private_hwdata *hwdata;
    /** clipping information */
    SDL_Rect clip_rect;            /**< Read-only */
    Uint32 unused1;                /**< for binary compatibility */
    /** Allow recursive locks */
    Uint32 locked;                /**< Private */
    /** info for fast blit mapping to other surfaces */
    struct SDL_BlitMap *map;        /**< Private */
    /** format version, bumped at every change to invalidate blit maps */
    unsigned int format_version;        /**< Private */
    /** Reference count -- used when freeing surface */
    int refcount;                /**< Read-mostly */
} SDL_Surface;
——————————————————————————————————————————————
SDL_Init()函数是用来初始化子系统的   定义在SDL.c文件里面
下面是初始化的子系统
/** @name SDL_INIT Flags
*  These are the flags which may be passed to SDL_Init() -- you should
*  specify the subsystems which you will be using in your application.
*/
/*@{*/
#define    SDL_INIT_TIMER        0x00000001
#define SDL_INIT_AUDIO        0x00000010
#define SDL_INIT_VIDEO        0x00000020
#define SDL_INIT_CDROM        0x00000100
#define SDL_INIT_JOYSTICK    0x00000200
#define SDL_INIT_NOPARACHUTE    0x00100000    /**< Don't catch fatal signals */
#define SDL_INIT_EVENTTHREAD    0x01000000    /**< Not supported on all OS's */
#define SDL_INIT_EVERYTHING    0x0000FFFF
——————————————————————————————————————————————
SDL_SetVideoMode()函数  是用来设置窗口的   定义在SDL_video.c文件中
Set the requested video mode, allocating a shadow buffer if necessary.
设置请求的视频模式,必要时分配阴影缓冲区。

SDL_Surface * SDL_SetVideoMode (int width, int height, int bpp, Uint32 flags)


——————————————————————————————————————————————

SDL_LoadBMP(file)其实调用的 SDL_LoadBMP_RW()
我们可以在SDL_video.h看到
#define SDL_LoadBMP(file)    SDL_LoadBMP_RW(SDL_RWFromFile(file, "rb"), 1)
SDL_LoadBMP_RW()函数的定义在SDL_bmp.c中

——————————————————————————————————————————————

SDL_BlitSurface()函数  感觉是比较重要的一个函数

它的定义在SDL_video.h文件中
/**
* This performs a fast blit from the source surface to the destination
* surface.  It assumes that the source and destination rectangles are
* the same size.  If either 'srcrect' or 'dstrect' are NULL, the entire
* surface (src or dst) is copied.  The final blit rectangles are saved
* in 'srcrect' and 'dstrect' after all clipping is performed.
* If the blit is successful, it returns 0, otherwise it returns -1.
*
* The blit function should not be called on a locked surface.
*
* The blit semantics for surfaces with and without alpha and colorkey
* are defined as follows:
*
* RGBA->RGB:
*     SDL_SRCALPHA set:
*     alpha-blend (using alpha-channel).
*     SDL_SRCCOLORKEY ignored.
*     SDL_SRCALPHA not set:
*     copy RGB.
*     if SDL_SRCCOLORKEY set, only copy the pixels matching the
*     RGB values of the source colour key, ignoring alpha in the
*     comparison.
*
* RGB->RGBA:
*     SDL_SRCALPHA set:
*     alpha-blend (using the source per-surface alpha value);
*     set destination alpha to opaque.
*     SDL_SRCALPHA not set:
*     copy RGB, set destination alpha to source per-surface alpha value.
*     both:
*     if SDL_SRCCOLORKEY set, only copy the pixels matching the
*     source colour key.
*
* RGBA->RGBA:
*     SDL_SRCALPHA set:
*     alpha-blend (using the source alpha channel) the RGB values;
*     leave destination alpha untouched. [Note: is this correct?]
*     SDL_SRCCOLORKEY ignored.
*     SDL_SRCALPHA not set:
*     copy all of RGBA to the destination.
*     if SDL_SRCCOLORKEY set, only copy the pixels matching the
*     RGB values of the source colour key, ignoring alpha in the
*     comparison.
*
* RGB->RGB:
*     SDL_SRCALPHA set:
*     alpha-blend (using the source per-surface alpha value).
*     SDL_SRCALPHA not set:
*     copy RGB.
*     both:
*     if SDL_SRCCOLORKEY set, only copy the pixels matching the
*     source colour key.
*
* If either of the surfaces were in video memory, and the blit returns -2,
* the video memory was lost, so it should be reloaded with artwork and
* re-blitted:
* @code
*    while ( SDL_BlitSurface(image, imgrect, screen, dstrect) == -2 ) {
*        while ( SDL_LockSurface(image) < 0 )
*            Sleep(10);
*        -- Write image pixels to image->pixels --
*        SDL_UnlockSurface(image);
*    }
* @endcode
*
* This happens under DirectX 5.0 when the system switches away from your
* fullscreen application.  The lock will also fail until you have access
* to the video memory again.
*
* You should call SDL_BlitSurface() unless you know exactly how SDL
* blitting works internally and how to use the other blit functions.
*/
#define SDL_BlitSurface SDL_UpperBlit
可以看出   调用 SDL_BlitSurface()
其实就是在调用 SDL_UpperBlit()我们可以看下这个函数 
他定义在SDL_surface.c中

——————————————————————————————————————————————
SDL_Flip()函数  函数的声明可以看SDL_video.h  定义的话  就在 SDL_video.c
/**
* On hardware that supports double-buffering, this function sets up a flip
* and returns.  The hardware will wait for vertical retrace, and then swap
* video buffers before the next video surface blit or lock will return.
* On hardware that doesn not support double-buffering, this is equivalent
* to calling SDL_UpdateRect(screen, 0, 0, 0, 0);
* The SDL_DOUBLEBUF flag must have been passed to SDL_SetVideoMode() when
* setting the video mode for this function to perform hardware flipping.
* This function returns 0 if successful, or -1 if there was an error.
*/
extern DECLSPEC int SDLCALL SDL_Flip(SDL_Surface *screen);

——————————————————————————————————————————————
SDL_Delay()这个函数  只是看起来简单  但是由于SDL的跨平台性  这个函数的定义就有点复杂了
函数声明在SDL_timer.h
/** Wait a specified number of milliseconds before returning */
extern DECLSPEC void SDLCALL SDL_Delay(Uint32 ms);
定义在SDL_systimer.c
——————————————————————————————————————————————
SDL_FreeSurface()函数
函数定义在SDL_surface.c文件中
——————————————————————————————————————————————
SDL_Quit()函数  与SDL_Init定义在同一个文件(SDL.c)

——————————————————————————————————————————————

SDL_DisplayFormat()函数声明在SDL_video.h中
/**
* This function takes a surface and copies it to a new surface of the
* pixel format and colors of the video framebuffer, suitable for fast
* blitting onto the display surface.  It calls SDL_ConvertSurface()
*
* If you want to take advantage of hardware colorkey or alpha blit
* acceleration, you should set the colorkey and alpha value before
* calling this function.
*
* If the conversion fails or runs out of memory, it returns NULL
*/
extern DECLSPEC SDL_Surface * SDLCALL SDL_DisplayFormat(SDL_Surface *surface);
函数的声明在SDL_video.c
——————————————————————————————————————————————
IMG_Load()函数是扩展库提供的   我这边就不多说了

猜你喜欢

转载自blog.csdn.net/cyq129445/article/details/80606193
SDL