到现在为止,已经写了好几个显示图片一类的程序 现在就来好好总结一下
首先我们在最开始 是在屏幕上显示一张图片
整个过程如下:
定义两个 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()函数是扩展库提供的 我这边就不多说了