2009年8月6日星期四

初步SDL - Simple DirectMedia Layer

使用SDL - Simple DirectMedia Layer
官方说:SDL是一个自由的跨平台的多媒体开发包
适用于游戏,演示,或其他等多媒体软件的开发
地址为http://www.libsdl.org/

参考文档
SDL Introduction
http://www.libsdl.org/intro.cn/toc.html
这是最简单精要的特性介绍,对SDL的认识和使用即可围绕此文档展开
另一份重要文档在SDK是可以找到,在目录docs下
内有#Guide和#Reference两部分
是分别说明了SDL的用法和所提供函数的具体描述
可供使用时参照此文档,也是对intro的补充
这里Doc Wiki
http://www.libsdl.org/cgi/docwiki.cgi
也提供了一些扩展库的用法,比如用于支持更过图像,媒体(视频,音频)格式或提供网络功能
需要添加对应SDK

SDL是LGPL协议,所以通常是按照动态链接的方式来使用。

开发环境
暂先省事,这次用Ubuntu804,C(GCC),geany来编写
安装包 libsdl1.2-dev
编译时添加-lSDL
c代码中添加#include
Win下估计类似

OK,要点就到此了
搜索时找到一下两个链接
http://www.cppblog.com/lf426/archive/2008/01/30/42161.aspx
http://www.cppblog.com/sandy/archive/2005/12/28/2219.html
是中文的,看着比较亲切,虽然内容初看可能会让人糊涂
先可作为对官方文档的补充,之后也能找到许多有用的东西。

恩,下面开始笔记体,不继续写介绍文了。上面已经提到可参照的文档,各自按需要看吧。
已经写的这么些是作为自己给自己的新手导读哦。说明,以下有代码复制于文档。
此外,SDK中也有提供若干示例。

PART.2
使用SDL
初始化
有参数为激活的部分

/* Initialize defaults, Video and Audio */
if((SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO)==-1)) {
printf("Could not initialize SDL: %s.\n", SDL_GetError());
exit(-1);
}

atexit(SDL_Quit);

视频

SDL_Surface *screen;

/* 省略初始化SDL部分的代码 */

/*
* 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"自动选择最接近的模式
绘制像素
使用文档所示的
getpixel()
putpixel()
直接操作缓冲区
加载显示BMP文件
涉及加载,设置透明,区域刷新
有例程 void ShowBMP(char *file, SDL_Surface *screen, int x, int y)
使用OpenGL
...
输入操作
等待事件SDL_WaitEvent()
事件轮询SDL_PollEvent()
键盘事件/鼠标,Joystick

while( SDL_PollEvent( &event ) ){
switch( event.type ){
/* Look for a keypress */
case SDL_KEYDOWN:
/* Check the SDLKey values and move change the coords */
switch( event.key.keysym.sym ){
case SDLK_LEFT:
/* .... */


{
SDL_Event event;

while ( SDL_PollEvent(&event) ) {
switch (event.type) {
case SDL_MOUSEMOTION:
printf("鼠标移动了%d,%d 到 (%d,%d)\n",
event.motion.xrel, event.motion.yrel,
event.motion.x, event.motion.y);
break;
case SDL_MOUSEBUTTONDOWN:
printf("鼠标 %d 点击在 (%d,%d)\n",
event.button.button, event.button.x, event.button.y);
break;
case SDL_QUIT:
exit(0);
}
}
}

事件轮询放在主循环内

/* Loop until an SDL_QUIT event is found */
while( !quit ){
while( SDL_PollEvent( &event ) ){
switch( event.type ){
case SDL_QUIT:
quit = 1;
break;
/* ... */

另一种处理事件的方式是使用检查事件的函数。
音频
打开音频设备
加载和回放声音
CDROM
定时器
取得当前时间(毫秒级)
SDL_GetTicks()
等待一段时间(毫秒级)
SDL_Delay()
其他
线程
字节序无关

下面贴一下code::block里的初始代码,在生成SDL项目时获得,是cpp的。

#ifdef __cplusplus
#include
#else
#include
#endif
#ifdef __APPLE__
#include
#else
#include
#endif

int main ( int argc, char** argv )
{
// initialize SDL video
if ( SDL_Init( SDL_INIT_VIDEO ) < 0 )
{
printf( "Unable to init SDL: %s\n", SDL_GetError() );
return 1;
}

// make sure SDL cleans up before exit
atexit(SDL_Quit);

// create a new window
SDL_Surface* screen = SDL_SetVideoMode(640, 480, 16,
SDL_HWSURFACE|SDL_DOUBLEBUF);
if ( !screen )
{
printf("Unable to set 640x480 video: %s\n", SDL_GetError());
return 1;
}

// load an image
SDL_Surface* bmp = SDL_LoadBMP("cb.bmp");
if (!bmp)
{
printf("Unable to load bitmap: %s\n", SDL_GetError());
return 1;
}

// centre the bitmap on screen
SDL_Rect dstrect;
dstrect.x = (screen->w - bmp->w) / 2;
dstrect.y = (screen->h - bmp->h) / 2;

// program main loop
bool done = false;
while (!done)
{
// message processing loop
SDL_Event event;
while (SDL_PollEvent(&event))
{
// check for messages
switch (event.type)
{
// exit if the window is closed
case SDL_QUIT:
done = true;
break;

// check for keypresses
case SDL_KEYDOWN:
{
// exit if ESCAPE is pressed
if (event.key.keysym.sym == SDLK_ESCAPE)
done = true;
break;
}
} // end switch
} // end of message processing

// DRAWING STARTS HERE

// clear screen
SDL_FillRect(screen, 0, SDL_MapRGB(screen->format, 0, 0, 0));

// draw bitmap
SDL_BlitSurface(bmp, 0, screen, &dstrect);

// DRAWING ENDS HERE

// finally, update the screen :)
SDL_Flip(screen);
} // end main loop

// free loaded bitmap
SDL_FreeSurface(bmp);

// all is well ;)
printf("Exited cleanly\n");
return 0;
}


其他库
SDL_image
SDL_mixer
SDL_net
SMPEG
ogg/vorbis libraries
JPEG library:
PNG library
Zlib
TIFF library
SDL_ttf
SDL_rtf

不过这点记录是按照SDL提供的功能来堆的,
如果是从使用的角度说,会有差异。这次本文暂且略过。
等有多使用了后再来贴体会了。觉得本次模糊感的文字有为成篇而赶紧堆之感啊,
不过也能算作是导读文吧。最好好事成要点的积累啊那种。
最近废话多了,有时记录好事随手些好。


http://www.qqread.com/vc/u302921200_7.html

补充:
在视频部分
显示sprite用Surface实现,显示时绘制到screen上,可以用SDL_SetColorKey()来设置透明色,或进行SDL_LoadBMP()载入图片,SDL_BlitSurface()块传递,SDL_UpdateRects()区域更新屏幕,SDL_DisplayFormat()。注意不同于直接大量绘制,这里在Blit时不能锁住surface。
以此实现怪兽的行动。可在事件轮询后用SDL_GetKeyState();获得方向键的状态并处理。
对整个屏幕更新,可用SDL_Flip(screen)或SDL_UpdateRect(screen, 0, 0, 0, 0)。
其中SDL_Surface *screen = SDL_SetVideoMode(...)为初始化所得。

没有评论: