![]() |
|
首页 │ Apache │ Linux│ Java│ MySQL│ 注册│帮助 | |||
[B]1、SDL是什么?[/B][/COLOR]
SDL是一个自由的跨平台的多媒体开发包
- http://www.devolution.com/~slouken/SDL/
适用于 游戏、游戏SDK、演示软件、模拟器、 MPEG播放器和其他应用软件。
[B]2、SDL有哪些功能?[/B][/COLOR]
[B]视频[/B]
设置8bpp或更高的任意色彩深度的视频模式。如果某个模式硬件不支持,可以选择转化为另一模式。直接写入线性的图像帧缓冲(framebuffer)。用颜色键值(colorkey)或者alpha混合属性创建surface。Surface的blit能自动的转化为目标格式。blit是优化过的,并能使用硬件加速。x86平台上有针对MMX优化过的blit。硬件加速的blit和fill(填充)操作,如果硬件支持的话。你可以分别用SDL_WM_SetCaption()和 SDL_WM_SetIcon() 设置程序的标题栏和图标(如果有的话) 。
[B]事件[/B]
提供以下事件:
应用程序的visibility发生改变
键盘输入
鼠标输入
用户要求的退出
每种事件都能通过SDL_EventState()关闭或者打开。事件经由用户指定的过滤函数再被加入到内部的事件队列。
线程安全的事件队列。调用SDL_PeepEvents() 在事件队列中搜索特定类型的事件。
[B]音频[/B]
设置8位和16位的音频,单声道或者立体声,如果格式硬件不支持,可以选择转换。由独立的线程执行音频部分,并提供用户回调(callback)机制。设计上考虑到了客户定制的软混音器,但实际上在例程中就包含了一个完整的音频/音乐输出库。用 SDL_LockAudio() 和 SDL_UnlockAudio()对音频回调函数和程序其他部分都要访问到的数据进行同步。
[B]CD音频[/B]
完整的CD音频控制API
如果向CD-ROM API传递一个NULL CD-ROM句柄,结果将是最后被打开的CD-ROM执行相应的动作。
[B]线程[/B]
简单的线程创建API
用于同步的简单的二进制信号量(semaphores)在线程中不要使用I/O和内存管理这样的C函数库,除非你能采取必要的措施—— 因为这些函数会把其他线程使用的资源锁定。
[B]定时器[/B]
读取已流逝的毫秒数。
等待指定的毫秒数。
设置一个10毫秒精度的周期性定时器。Win32上的GetTickCount() 可以很方便的用 SDL_GetTicks()替代。
[B]字节序无关[/B]
侦测当前系统的字节序
快速转换数据的函数
读写指定字节序的数据
[B]3、SDL支持哪些系统平台?[/B][/COLOR]
[B]Linux[/B]
视频显示使用X11,利用XFree86 DGA扩展的优势,全屏显示使用新的w MTRR加速。声音使用OSS API。使用clone()系统调用和SysV IPC,或者glibc-2.1的pthreads实现线程。你可以通过SDL_GetWMInfo()取得SDL驱动接口的隐藏部分,从而可以实现诸如去除窗口要素和图标化窗口等效果。
[B]Win32[/B]
有两个版本,一个是适合所有基于Win32的系统的安全版本,另一个是基于DirectX的高性能版本。安全版本的视频显示采用GDI。高性能版本采用DirectDraw,并支持硬件加速。安全版本的音频回放采用waveOut API。高性能版本采用DirectSound。你必须在主线程中定期的读取Windows消息队列,以保持程序能够作出响应。
[B]BeOS[/B]
视频显示采用BWindow。音频回放采用BSoundPlayer API。Linux和BeOS支持 SDL_INIT_EVENTTHREAD,调用SDL_Init()时使用该标记将使得事件循环在另一个线程中异步运行。这样即使程序忙,色彩光标也能响应。
[B]非正式的移植版本,进展中[/B]
Solaris, IRIX, FreeBSD
MacOS
[B]4、使用SDL[/B][/COLOR]
[B]初始化SDL库[/B]
调用SDL_Init()动态的加载和初始化SDL库。 该函数带有一组标记来表示哪部分需要激活:
SDL_INIT_AUDIO
SDL_INIT_VIDEO
SDL_INIT_CDROM
SDL_INIT_TIMER
使用完毕最后调用SDL_Quit()。SDL动态的从系统的标准库路径加载SDL。如果你的软件发布包里带有SDL动态库,你可以调用SDL_SetLibraryPath()指定另一个路径。
#include
#include "SDL.h"
main(int argc, char *argv[])
{
if ( SDL_Init(SDL_INIT_AUDIO|SDL_INIT_VIDEO) < 0 ) {
fprintf(stderr, "无法初始化SDL: %s\n", SDL_GetError());
exit(1);
}
atexit(SDL_Quit);
...
}
不要紧张,其实PHP-SDL就是在C的扩展,自己的经验,把SDL函数前面加上一个PHP,就差不多是PHP-SDL了,所以这里贴SDL的教程,一样适用于PHP-SDL。[/COLOR]
例如,PHP-SDL中音频初始化就是phpSDL_Init(SDL_INIT_AUDIO )
另外注意,程序的开始需要设置运行时间先set_time_limit(0)
[B]视频[/B]
简便的选择和设置视频模式
只需选取中意的色彩深度和分辨率,然后设置即可!
SDL_GetVideoInfo()可以获得硬件所支持的最快的色彩深度。
SDL_ListModes()可以获得某个色彩深度下所有支持的分辨率。
例程::
{ SDL_Surface *screen;
screen = SDL_SetVideoMode(640, 480, 16, SDL_SWSURFACE);
if ( screen == NULL ) {
fprintf(stderr, "无法设置640x480的视频模式:%s\n", SDL_GetError());
exit(1);
}
}
[B]在屏幕上绘制像素 [/B]
通过直接写入图形帧缓冲(framebuffer)和调用屏幕更新函数来绘制屏幕。
如果你需要进行大量绘制,最好在绘制前锁住屏幕(如果有必要),绘制时保持一个需要更新的区域列表,并且在更新显示前对屏幕解锁。
例程:
在任意格式的屏幕上绘制像素
void DrawPixel(SDL_Surface *screen, Uint8 R, Uint8 G, Uint8 B)
{
Uint32 color = SDL_MapRGB(screen->format, R, G, B);
if ( SDL_MUSTLOCK(screen) ) {
if ( SDL_LockSurface(screen) < 0 ) {
return;
}
}
switch (screen->format->BytesPerPixel) {
case 1: { /* 假定是8-bpp */
Uint8 *bufp;
bufp = (Uint8 *)screen->pixels + y*screen->pitch + x;
*bufp = color;
}
break;
case 2: { /* 可能是15-bpp 或者 16-bpp */
Uint16 *bufp;
bufp = (Uint16 *)screen->pixels + y*screen->pitch/2 + x;
*bufp = color;
}
break;
case 3: { /* 慢速的24-bpp模式,通常不用 */
Uint8 *bufp;
bufp = (Uint8 *)screen->pixels + y*screen->pitch + x;
*(bufp+screen->format->Rshift/8) = R;
*(bufp+screen->format->Gshift/8) = G;
*(bufp+screen->format->Bshift/8) = B;
}
break;
case 4: { /* 可能是32-bpp */
Uint32 *bufp;
bufp = (Uint32 *)screen->pixels + y*screen->pitch/4 + x;
*bufp = color;
}
break;
}
if ( SDL_MUSTLOCK(screen) ) {
SDL_UnlockSurface(screen);
}
SDL_UpdateRect(screen, x, y, 1, 1);
}
[B]加载和显示图片[/B]
SDL只提供了SDL_LoadBMP(),但在SDL的示例文档中有一个用于加载图片的函数库。
SDL_BlitSurface()将图片blit进图形帧缓冲,从而显示图片。SDL_BlitSurface()自动对blit矩形进行裁边,blit矩形在调用SDL_UpdateRects()时被用作更新屏幕变化了的部分。
如果你需要多次显示某个图片,你可以调用 SDL_DisplayFormat()将图片转换成屏幕的格式,从而提高blit的速度。
许多sprite的图片要求透明背景,你可以用SDL_SetColorKey()来设置透明色,从而实现透明效果的blit(也就是带colorkey的blit)。
例程:
void ShowBMP(char *file, SDL_Surface *screen, int x, int y)
{
SDL_Surface *image;
SDL_Rect dest;
/* 将BMP文件加载到一个surface*/
image = SDL_LoadBMP(file);
if ( image == NULL ) {
fprintf(stderr, "无法加载 %s: %s\n", file, SDL_GetError());
return;
}
/* Blit到屏幕surface。onto the screen surface.
这时不能锁住surface。
*/
dest.x = x;
dest.y = y;
dest.w = image->w;
dest.h = image->h;
SDL_BlitSurface(image, NULL, screen, &dest);
/* 刷新屏幕的变化部分 */
SDL_UpdateRects(screen, 1, &dest);
}

