上一次我们建立起了SDL环境,接下来,我们谈一谈什么是SDL?如何起动和退出SDL.
Simple DirectMedia Layer库,简称SDL,它是一个跨平台的多媒体库,以用于直接控制底层的多媒体硬件的接口。这些多媒体功能包括了视频、音频、键盘和鼠标(事件)、游戏摇杆等。当然,最为重要的是提供了2D图形帧缓冲(framebuffer)的接口,以及为OpenGL与各种操作系统之间提供了统一的标准接口以实现3D图形。也就是说我们通过这个图形库可以自己写游戏,播放电影、歌曲等等,哪些C语言基本库里无法完成的任务,我们可以通过SDL的库完成,只要按上一次的要求安装完了SDL,我们就可以自由的使用SDL完成自己想要完成的功能!
SDL是一个跨平台的库,它支持: Windows, Windows CE,Linux, BeOS, MacOS, Mac OS X, FreeBSD, NetBSD, OpenBSD, BSD/OS, Solaris, IRIX,QNX
SDL是用C语言开发的,但它对C++支持的更好!所以你在网上可以找到很多SDL源代码都是C++写的。除了这两种语言,SDL还支持:Java,C#, D,PHP,Eiffel, Erlang, Python,Euphoria, Ada, Go,Guile, Haskell, Lisp, Lua, ML, Objective C, Pascal, Perl, Pike, Pliant, Ruby, Smalltalk, and Tcl.几乎支持所有当下流行的语言!
为什么选择SDL做图形库而不是DirectX、OpenGl等著名的图形库呢?第一,SDl是免费的,它能够完成绝大多数哪些大的图形库的功能,但你可以随意使用不需要付费,而且它是跨平台的,可以在多种平台上使用。第二,SDL小巧精悍,接口简单,向用户隐蔽了复杂的操作,用户只需要懂一点C语言的基础知识就可以调用它完成很炫的功能。换句话说SDL使你的编程工作变得简单容易,而完成同样的功能DirectX代码量最少是SDL的5到6倍!那么你现在是不是觉得对于一个编程新手来说,SDL是最佳选择!
本系列教程是写给C编程的入门者或对C语言情有独钟者!所有代码均用C语言实现,用C语言也可以实现很酷的功能!
下面我们看一下如何调用SDL的库函数完成相应的功能,还以上次安装教程里的代码为例。
#include <stdio.h> #include <stdlib.h> #include <SDL\SDL.h> SDL_Surface *gpScreen; int main(int argc,char *argv[]) { if((SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO)==-1)) { exit(-1); } gpScreen = SDL_SetVideoMode(600,600, 0, SDL_HWSURFACE | SDL_HWPALETTE | SDL_DOUBLEBUF ); if( NULL == gpScreen ) { SDL_Quit(); return -1; } SDL_Delay(3000); SDL_FreeSurface(gpScreen);//退出程序前必须释放 SDL_Quit();//关闭SDL各个子系统 system("pause"); return 0; }
要使用SDL,必须先初始化SDL,函数int SDL_Init(Uint32 flags),参数flags是一个无符号整数,表示要初始化SDL哪些子系统。
名称 | 常量 | 值 | 说明 | 自动初始化 |
定时器 |
SDL_INIT_TIMER | 0x00000001 | 初始化时间子系统 | 否 |
音频 |
SDL_INIT_AUDIO | 0x00000010 | 初始化音频子系统 | 否 |
视频 |
SDL_INIT_VIDEO | 0x00000020 | 初始化视频子系统 | 否 |
CDROM |
SDL_INIT_CDROM | 0x00000100 | 初始化CDROM子系统 | 否 |
游戏杆 |
SDL_INIT_JOYSTICK | 0x00000200 | 初始化JOYSTICK子系统 | 否 |
错误捕获 |
SDL_INIT_NOPARACHUTE | 0x00100000 | 避免捕获致命错误 | 是 |
线程 |
SDL_INIT_EVENTTHREAD | 0x01000000 | 初始化线程子系统 | 是 |
全部子系统 |
SDL_INIT_EVERYTHING | 0x0000FFFF | 初始化上述所有子系统 | 否 |
SDL_Init()函数初始化成功返回0。如果初始化失败,函数返回值为-1。函数只接受各个子系统的常量作为参数。如果要初始化视频屏幕,传入常数SDL_INIT_VIDEO作为参数;初始化音频,传入常数SDL_INIT_AUDIO;如果同时初始化视频和音频,传入SDL_INIT_VIDEO|SDL_INIT_AUDIO。如果同时传入多个量要使用|将它们隔开:
1if ( SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0 )2{3 printf(“Unable to init SDL: %s\n”, SDL_GetError());4return1;5 }
初始化失败,要直接退出程序,不能使用SDL了,其中SDL_GetError函数是返回SDL的错误,其原型是:char *SDL_GetError
(void);其返回值是一个字符串。
初始化完成后,你就可以使用相应SDL子系统完成相应的任务了,当你完成所有工作需要退出程序时,必须关闭相应SDL子系统并做相关清理工作,完成这项工作可以调用void SDL_Quit
(void);函数完成关闭SDL。一般可以这样写:
....//初始化SDL SDL_InitSDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO);//添加自己的处理代码.....SDL_Quit();......
记住退出程序之前必须调用这个函数关闭SDL,如果你的代码里有多个地方写exit函数结束程序或return 0结束程序则必须在这些语句前调用SDL_Quit()函数。一般这种情况我们使用另外一个函数来关闭SDL:atexit(SDL_Quit); atexit(void (__cdecl *func )( void ))是C语言标准库里的函数,从函数名atexit可以看出这个函数是在结束程序的时候调用,所以我们可以调用这个函数来关闭SDL,atexit()函数的参数是一个函数的名字,意思是在程序结束前调用指定函数做一些善后处理工作。atexit()函数的作用是向系统注册传进来的函数,以便程序结束时调用该函数。这个函数可以在微软的MSDN中查到。
....//初始化SDL SDL_InitSDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO);atexit(SDL_Quit);
//添加自己的处理代码...........
这样写,无论你在哪里结束程序,系统都会执行SDL_Quit()函数关闭SDL。和初始化结束相关的函数还有:
函数名 | 功能 |
SDL_Init | 初始化SDL一个或多个子系统 |
SDL_InitSubSystem | 在调用SDL_Init初始化SDL后,你可以调用该函数初始化其他子系统,用法和SDL_Init相同,但必须在SDL_Init调用后调用 |
SDL_Quit | 关闭所有SDL子系统,清理SDL所占资源。 |
SDL_QuitSubSystem | 在初始化后如果你想关闭某个子系统而不想关闭所有SDL子系统则可以调用该函数。 |
SDL_WasInit | 检查指定子系统是否被初始化,返回值是该子系统的常量值(见表2.1) |
SDL_GetError | 返回最后一次SDL的错误,返回值是一个字符串。 |
本次讨论了SDL起动和结束需要注意的地方。大家应该掌握SDL初始化过程和退出SDL时应该怎样处理。
下一次我们将一起看一看SDL中用的最多的子系统视频子系统。