SDL学习

http://wenku.baidu.com/view/c953c0878762caaedd33d4d8.html

一、安装:

sudo apt-get install libsdl1.2-dev libsdl-image1.2-dev libsdl-ttf2.0-dev libsdl-mixer1.2-dev libsdl-net1.2-dev libsdl-sound1.2-dev

二、编译测试用例:

sdl: 添加`sdl-config --cflags --libs` // 或-lSDL

opengl : -lGL -LGLU

三、函数详解:

1.初始化,反初始化

SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER)            //

SDL_INIT_EVERYTHING

初始化音视频以及timer库

SDL_Quit();

结束

2.初始化display

SDL_Surface* screen = NULL;

//Initialize the display in a 640x480 8-bit palettized mode,requesting a software surface

screen = SDL_SetVideoMode(640, 480, 8, SDL_SWSURFACE);

3.timer&callback

SDL_TimerID SDL_AddTimer(Uint32 interval, SDL_NewTimerCallback callback, void* param);

typedef Uint32 (*SDL_NewTimerCallback)(Uint32 interval, void* param);

SDL_WaitEvent(&event);

SDL_PollEvent()

例子:

 1 {
 2 ...
 3
 4     delay = 10;
 5     my_timer_id = SDL_AddTimer(delay, my_callbackfunc, my_callback_param);
 6
 7 ...
 8 }
 9
10 Uint32 my_callbackfunc(Uint32 interval, void *param)
11 {
12     SDL_Event event;
13     SDL_UserEvent userevent;
14
15     userevent.type = SDL_USEREVENT;
16     userevent.code = 0;
17     userevent.data1 = &my_func;
18     userevent.data2 = NULL;
19
20     event.type = SDL_USEREVENT;
21     event.user = userevent;
22
23     SDL_PushEvent(&event);
24     return(interval);
25 }
26
27
28 {
29 ...
30     SDL_Event event;
31     while (SDL_PollEvent (&event)) {
32         switch(event.type) {
33             case SDL_USEREVENT: {
34                 void (*p) (void*) = event.user.data1;
35                 p(event.user.data2);
36                 break;
37             }
38         }
39     }
40 ...
41 }                

 1 void CheckMouseHover(void)
 2 {
 3     int mouse_x, mouse_y;
 4
 5     SDL_PumpEvents();
 6
 7     SDL_GetMouseState(&mouse_x, &mouse_y);
 8     if ( (mouse_x < 32) && (mouse_y < 32) ) {
 9         printf("鼠标在左上角!\n");
10     }
11 }

检测鼠标事件例子:

 1 #include <stdio.h>
 2 #include <SDL/SDL.h>
 3 #include <SDL/SDL_ttf.h>
 4
 5 #define bool int
 6 #define false 0
 7 #define true 1
 8
 9 SDL_Surface  * screen = NULL;
10 const   int  SCREEN_BPP = 32 ;
11
12 int  main(  int  argc,  char *  args[] )
13 {
14     // Start SDL
15
16     bool  quit = false ;
17     SDL_Rect rectLeft;
18     SDL_Rect rectRight;
19     rectLeft.x = 0 ;
20     rectLeft.y = 0 ;
21     rectLeft.w = 320 ;
22     rectLeft.h = 480 ;
23     rectRight.x = 320 ;
24     rectRight.y = 0 ;
25     rectRight.w = 640 ;
26     rectRight.h = 480 ;
27
28     SDL_Init( SDL_INIT_EVERYTHING );
29
30     screen  =  SDL_SetVideoMode(  600 ,  480 , SCREEN_BPP, SDL_SWSURFACE );
31     if (screen == NULL)
32         return   false ;
33
34     Uint32 colorBlue = SDL_MapRGB(screen -> format, 0 , 0 , 255 );
35     Uint32 colorGreen = SDL_MapRGB(screen -> format, 0 , 255 , 0 );
36     Uint32 colorRed = SDL_MapRGB(screen -> format, 255 , 0 , 0 );
37     Uint32 colorBlack = SDL_MapRGB(screen -> format, 0 , 0 , 0 );
38
39     SDL_Event  event ;
40     while ( ! quit) {
41         if (SDL_PollEvent( & event )) {
42             switch (event.type) {
43                 case SDL_MOUSEMOTION:
44                     {
45                         Uint16 x = event .motion.x;
46                         Uint16 y = event .motion.y;
47
48                         if (x > 0   &&  x < 320   &&  y > 0   &&  y < 480  ) {
49                             SDL_FillRect(screen, & rectLeft,colorBlue);
50                             SDL_FillRect(screen, & rectRight,colorBlack);
51                         }
52
53                         if (x > 320   &&  x < 640   &&  y > 0   &&  y < 480  ) {
54                             SDL_FillRect(screen, & rectRight,colorGreen);
55                             SDL_FillRect(screen, & rectLeft,colorBlack);
56                         }
57                         break;
58                     }
59
60                 case SDL_MOUSEBUTTONDOWN:
61                     {
62                         Uint16 x = event .motion.x;
63                         Uint16 y = event .motion.y;
64                         if ( event .button.button  ==  SDL_BUTTON_LEFT) {
65                             if (x > 0   &&  x < 320   &&  y > 0   &&  y < 480  )
66                                 SDL_FillRect(screen, & rectLeft,colorRed);
67
68                             if (x > 320   &&  x < 640   &&  y > 0   &&  y < 480  )
69                                 SDL_FillRect(screen, & rectRight,colorRed);
70                         }
71                         break;
72                     }
73                 case SDL_QUIT:
74                     quit = true ;
75                     break;
76
77                 default :
78                     break;
79             }
80         }
81
82         if (SDL_Flip(screen)  ==   - 1 )
83             return   false ;
84     }
85
86     SDL_FreeSurface(screen);
87     SDL_Quit();
88
89     return   0 ;
90 }

4.SDL_LoadBMP解析图片

例子:

 1 #include <stdio.h>
 2 #include <SDL/SDL.h>
 3
 4 SDL_Surface *screen = NULL;
 5 const int SCREEN_BPP = 32;
 6
 7 void display_bmp(char* file_name)
 8 {
 9     SDL_Surface* image = NULL;
10
11     /* Load the BMP file into a surface */
12     image = SDL_LoadBMP(file_name);
13     if (image == NULL) {
14         fprintf(stderr, "Couldn‘t load %s: %s\n", file_name, SDL_GetError());
15         return;
16     }
17
18     /*
19      * Palettized screen modes will have a default palette (a standard
20      * 8*8*4 colour cube), but if the image is palettized as well we can
21      * use that palette for a nicer colour matching
22      */
23     if (image->format->palette && screen->format->palette) {
24         SDL_SetColors(screen, image->format->palette->colors, 0, image->format->palette->ncolors);
25     }
26
27     /* Blit onto the screen surface */
28     if (SDL_BlitSurface(image, NULL, screen, NULL) < 0)
29         fprintf(stderr, "BlitSurface error: %s\n", SDL_GetError());
30
31     /* Update the modified region of the screen */
32     SDL_UpdateRect(screen, 0, 0, image->w, image->h);
33
34     /* Free the allocated BMP surface */
35     SDL_FreeSurface(image);
36 }
37
38 int main(int argc, char **argv)
39 {
40     SDL_Init(SDL_INIT_EVERYTHING);
41
42     screen = SDL_SetVideoMode(  600 ,  480 , SCREEN_BPP, SDL_SWSURFACE );
43     if (screen == NULL)
44         return -1;
45
46     display_bmp("test.bmp");
47
48     getchar();
49     return 0;
50 }

5.OPENGL&SDL

  1 /*
  2  * SDL OpenGL Tutorial.
  3  * (c) Michael Vance, 2000
  4  * [email protected]
  5  *
  6  * Distributed under terms of the LGPL.
  7  */
  8
  9 #include <SDL/SDL.h>
 10 #include <GL/gl.h>
 11 #include <GL/glu.h>
 12
 13 #include <stdio.h>
 14 #include <stdlib.h>
 15
 16 static GLboolean should_rotate = GL_TRUE;
 17
 18 static void quit_tutorial( int code )
 19 {
 20     /*
 21      * Quit SDL so we can release the fullscreen
 22      * mode and restore the previous video settings, etc.
 23      */
 24     SDL_Quit( );
 25
 26     /* Exit program. */
 27     exit( code );
 28 }
 29
 30 static void handle_key_down( SDL_keysym* keysym )
 31 {
 32     /*
 33      * We‘re only interested if ‘Esc‘ has been presssed.
 34      *
 35      * EXERCISE:
 36      * Handle the arrow keys and have that change the
 37      * viewing position/angle.
 38      */
 39     switch( keysym->sym ) {
 40         case SDLK_ESCAPE:
 41             quit_tutorial( 0 );
 42             break;
 43         case SDLK_SPACE:
 44             should_rotate = !should_rotate;
 45             break;
 46         default:
 47             break;
 48     }
 49 }
 50
 51 static void process_events( void )
 52 {
 53     /* Our SDL event placeholder. */
 54     SDL_Event event;
 55
 56     /* Grab all the events off the queue. */
 57     while( SDL_PollEvent( &event ) ) {
 58         switch( event.type ) {
 59         case SDL_KEYDOWN:
 60             /* Handle key presses. */
 61             handle_key_down( &event.key.keysym );
 62             break;
 63
 64         case SDL_QUIT:
 65             /* Handle quit requests (like Ctrl-c). */
 66             quit_tutorial( 0 );
 67             break;
 68
 69         default:
 70             break;
 71         }
 72     } /* while */
 73 }
 74
 75 static void draw_screen( void )
 76 {
 77     /* Our angle of rotation. */
 78     static float angle = 0.0f;
 79     /*
 80      * EXERCISE:
 81      * Replace this awful mess with vertex
 82      * arrays and a call to glDrawElements.
 83      *
 84      * EXERCISE:
 85      * After completing the above, change
 86      * it to use compiled vertex arrays.
 87      *
 88      * EXERCISE:
 89      * Verify my windings are correct here ;).
 90      */
 91
 92     static GLfloat v0[] = { -1.0f, -1.0f,  1.0f };
 93     static GLfloat v1[] = {  1.0f, -1.0f,  1.0f };
 94     static GLfloat v2[] = {  1.0f,  1.0f,  1.0f };
 95     static GLfloat v3[] = { -1.0f,  1.0f,  1.0f };
 96     static GLfloat v4[] = { -1.0f, -1.0f, -1.0f };
 97     static GLfloat v5[] = {  1.0f, -1.0f, -1.0f };
 98     static GLfloat v6[] = {  1.0f,  1.0f, -1.0f };
 99     static GLfloat v7[] = { -1.0f,  1.0f, -1.0f };
100     static GLubyte red[]    = { 255,   0,   0, 255 };
101     static GLubyte green[]  = {   0, 255,   0, 255 };
102     static GLubyte blue[]   = {   0,   0, 255, 255 };
103     static GLubyte white[]  = { 255, 255, 255, 255 };
104     static GLubyte yellow[] = {   0, 255, 255, 255 };
105     static GLubyte black[]  = {   0,   0,   0, 255 };
106     static GLubyte orange[] = { 255, 255,   0, 255 };
107     static GLubyte purple[] = { 255,   0, 255,   0 };
108
109     /* Clear the color and depth buffers. */
110     glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
111
112     /* We don‘t want to modify the projection matrix. */
113     glMatrixMode( GL_MODELVIEW );
114     glLoadIdentity( );
115
116     /* Move down the z-axis. */
117     glTranslatef( 0.0, 0.0, -5.0 );
118
119     /* Rotate. */
120     glRotatef( angle, 0.0, 1.0, 0.0 );
121
122     if ( should_rotate ) {
123         if ( ++angle > 360.0f ) {
124             angle = 0.0f;
125         }
126     }
127
128     /* Send our triangle data to the pipeline. */
129     glBegin( GL_TRIANGLES );
130
131     glColor4ubv( red );
132     glVertex3fv( v0 );
133     glColor4ubv( green );
134     glVertex3fv( v1 );
135     glColor4ubv( blue );
136     glVertex3fv( v2 );
137
138     glColor4ubv( red );
139     glVertex3fv( v0 );
140     glColor4ubv( blue );
141     glVertex3fv( v2 );
142     glColor4ubv( white );
143     glVertex3fv( v3 );
144     glColor4ubv( green );
145     glVertex3fv( v1 );
146     glColor4ubv( black );
147     glVertex3fv( v5 );
148     glColor4ubv( orange );
149     glVertex3fv( v6 );
150
151     glColor4ubv( green );
152     glVertex3fv( v1 );
153     glColor4ubv( orange );
154     glVertex3fv( v6 );
155     glColor4ubv( blue );
156     glVertex3fv( v2 );
157     glColor4ubv( black );
158     glVertex3fv( v5 );
159     glColor4ubv( yellow );
160     glVertex3fv( v4 );
161     glColor4ubv( purple );
162     glVertex3fv( v7 );
163
164     glColor4ubv( black );
165     glVertex3fv( v5 );
166     glColor4ubv( purple );
167     glVertex3fv( v7 );
168     glColor4ubv( orange );
169     glVertex3fv( v6 );
170     glColor4ubv( yellow );
171     glVertex3fv( v4 );
172     glColor4ubv( red );
173     glVertex3fv( v0 );
174     glColor4ubv( white );
175     glVertex3fv( v3 );
176
177     glColor4ubv( yellow );
178     glVertex3fv( v4 );
179     glColor4ubv( white );
180     glVertex3fv( v3 );
181     glColor4ubv( purple );
182     glVertex3fv( v7 );
183     glColor4ubv( white );
184     glVertex3fv( v3 );
185     glColor4ubv( blue );
186     glVertex3fv( v2 );
187     glColor4ubv( orange );
188     glVertex3fv( v6 );
189
190     glColor4ubv( white );
191     glVertex3fv( v3 );
192     glColor4ubv( orange );
193     glVertex3fv( v6 );
194     glColor4ubv( purple );
195     glVertex3fv( v7 );
196     glColor4ubv( green );
197     glVertex3fv( v1 );
198     glColor4ubv( red );
199     glVertex3fv( v0 );
200     glColor4ubv( yellow );
201     glVertex3fv( v4 );
202     glColor4ubv( green );
203     glVertex3fv( v1 );
204     glColor4ubv( yellow );
205     glVertex3fv( v4 );
206     glColor4ubv( black );
207     glVertex3fv( v5 );
208     glEnd( );
209
210     /*
211      * EXERCISE:
212      * Draw text telling the user that ‘Spc‘ pauses the rotation and ‘Esc‘ quits.
213      * Do it using vetors and textured quads.
214      */
215
216     /*
217      * Swap the buffers. This this tells the driver to
218      * render the next frame from the contents of the
219      * back-buffer, and to set all rendering operations
220      * to occur on what was the front-buffer.
221      *
222      * Double buffering prevents nasty visual tearing
223      * from the application drawing on areas of the
224      * screen that are being updated at the same time.
225      */
226     SDL_GL_SwapBuffers( );
227 }
228
229 static void setup_opengl( int width, int height )
230 {
231     float ratio = (float) width / (float) height;
232
233     /* Our shading model--Gouraud (smooth). */
234     glShadeModel( GL_SMOOTH );
235
236     /* Culling. */
237     glCullFace( GL_BACK );
238     glFrontFace( GL_CCW );
239     glEnable( GL_CULL_FACE );
240
241     /* Set the clear color. */
242     glClearColor( 0, 0, 0, 0 );
243
244     /* Setup our viewport. */
245     glViewport( 0, 0, width, height );
246
247     /*
248      * Change to the projection matrix and set
249      * our viewing volume.
250      */
251     glMatrixMode( GL_PROJECTION );
252     glLoadIdentity( );
253
254     /*
255      * EXERCISE:
256      * Replace this with a call to glFrustum.
257      */
258     gluPerspective( 60.0, ratio, 1.0, 1024.0 );
259 }
260
261 int main( int argc, char* argv[] )
262 {
263     /* Information about the current video settings. */
264     const SDL_VideoInfo* info = NULL;
265
266     /* Dimensions of our window. */
267     int width = 0;
268     int height = 0;
269
270     /* Color depth in bits of our window. */
271     int bpp = 0;
272
273     /* Flags we will pass into SDL_SetVideoMode. */
274     int flags = 0;
275
276     /* First, initialize SDL‘s video subsystem. */
277     if ( SDL_Init( SDL_INIT_VIDEO ) < 0 ) {
278         /* Failed, exit. */
279         fprintf( stderr, "Video initialization failed: %s\n", SDL_GetError( ) );
280         quit_tutorial( 1 );
281     }
282
283     /* Let‘s get some video information. */
284     info = SDL_GetVideoInfo( );
285
286     if ( !info ) {
287         /* This should probably never happen. */
288         fprintf( stderr, "Video query failed: %s\n", SDL_GetError( ) );
289         quit_tutorial( 1 );
290     }
291
292     /*
293      * Set our width/height to 640/480 (you would of course let the user
294      * decide this in a normal app). We get the bpp we will request from
295      * the display. On X11, VidMode can‘t change resolution, so this is
296      * probably being overly safe. Under Win32, ChangeDisplaySettings
297      * can change the bpp.
298      */
299
300     width = 640;
301     height = 480;
302     bpp = info->vfmt->BitsPerPixel;
303
304     /*
305      * Now, we want to setup our requested
306      * window attributes for our OpenGL window.
307      * We want *at least* 5 bits of red, green
308      * and blue. We also want at least a 16-bit
309      * depth buffer.
310      *
311      * The last thing we do is request a double
312      * buffered window. ‘1‘ turns on double
313      * buffering, ‘0‘ turns it off.
314      *
315      * Note that we do not use SDL_DOUBLEBUF in
316      * the flags to SDL_SetVideoMode. That does
317      * not affect the GL attribute state, only
318      * the standard 2D blitting setup.
319      */
320
321     SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 5 );
322     SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 5 );
323     SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 5 );
324     SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 );
325     SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
326
327     /*
328      * We want to request that SDL provide us
329      * with an OpenGL window, in a fullscreen
330      * video mode.
331      *
332      * EXERCISE:
333      * Make starting windowed an option, and
334      * handle the resize events properly with
335      * glViewport.
336      */
337     flags = SDL_OPENGL | SDL_FULLSCREEN;
338
339     /*
340      * Set the video mode
341      */
342     if ( SDL_SetVideoMode( width, height, bpp, flags ) == 0 ) {
343         /*
344          * This could happen for a variety of reasons,
345          * including DISPLAY not being set, the specified
346          * resolution not being available, etc.
347          */
348         fprintf( stderr, "Video mode set failed: %s\n", SDL_GetError( ) );
349         quit_tutorial( 1 );
350     }
351
352     /*
353      * At this point, we should have a properly setup
354      * double-buffered window for use with OpenGL.
355      */
356     setup_opengl( width, height );
357
358     /*
359      * Now we want to begin our normal app process--
360      * an event loop with a lot of redrawing.
361      */
362     setup_opengl( width, height );
363
364     /*
365      * Now we want to begin our normal app process--
366      * an event loop with a lot of redrawing.
367      */
368     while (1) {
369         /* Process incoming events. */
370         process_events( );
371
372         /* Draw the screen. */
373         draw_screen( );
374
375         /* Avoid to eat all the CPU power */
376         SDL_Delay( 50 );
377     }
378
379     /*
380      * EXERCISE:
381      * Record timings using SDL_GetTicks() and
382      * and print out frames per second at program
383      * end.
384      */
385
386     /* Never reached. */
387     return 0;
388 }

时间: 2024-11-08 06:49:33

SDL学习的相关文章

SDL 学习及相关API

SDL_PeepEvents() 在事件队列中搜索特定类型的事件. int SDL_PeepEvents(SDL_Event *events, int numevents, SDL_eventaction action, Uint32 mask);DescriptionChecks the event queue for messages and optionally returns them.If action is SDL_ADDEVENT, up to numevents events w

[原]零基础学习SDL开发之在Android使用SDL2.0显示BMP图

关于如何移植SDL2.0到安卓上面来参考我的上一篇文章:[原]零基础学习SDL开发之移植SDL2.0到Android 在一篇文章我们主要使用SDL2.0来加载一张BMP图来渲染显示. 博主的开发环境:Ubuntu 14.04 64位,Eclipse + CDT + ADT+NDK 博主曾经自己使用NDK编译出了libSDL2.so,然后使用共享库的方式来调用libSDL2中的函数,结果发现SDL\src\core\android\SDL_android.c 这个jni函数写的实在是不够自己另外做

[原]零基础学习SDL开发之在Android使用SDL2.0显示BMP叠加图

关于如何移植在android上使用SDL,可以参考[原]零基础学习SDL开发之移植SDL2.0到Android 和 [原]零基础学习SDL开发之在Android使用SDL2.0显示BMP图 . 在一篇文章我们主要使用SDL2.0来加载一张BMP图来渲染显示,同时叠加一张图作为背景图. 博主的开发环境:Ubuntu 14.04 64位,Eclipse + CDT + ADT+NDK 在前面两篇文章我们知道了如何移植SDL2.0到android上面来,并且可以在Android上面来显示一张图片,这篇

[原]零基础学习SDL开发之在Android使用SDL2.0加载字体

在上一篇文章我们知道了如何在android使用SDL2.0来渲染显示一张png图,而且在上上一篇我们知道如何使用sdl来渲染输出bmp图,那么sdl是否可以渲染输出自己喜爱的字体库的字体呢?答案是当然可以. 我们需要移植SDL_ttf字体库来支持相应的字体的渲染输出. 一.移植SDL_ttf库: 使用如下命令,从SDL Mercurial获取SDL_image的源码: hg clone https://hg.libsdl.org/SDL_ttf/ 将SDL_ttf拷贝到在上一篇文章中的andro

[原]零基础学习在Android进行SDL开发系列文章

[原]零基础学习SDL开发之移植SDL2.0到Android [原]零基础学习SDL开发之在Android使用SDL2.0显示BMP图 [原]零基础学习SDL开发之在Android使用SDL2.0显示BMP叠加图 [原]零基础学习SDL开发之在Android使用SDL2.0渲染PNG图片 [原]零基础学习SDL开发之在Android使用SDL2.0加载字体 [原]零基础学习在Android进行SDL开发后记 [原]零基础学习在Android进行SDL开发系列文章,布布扣,bubuko.com

[原]零基础学习在Android进行SDL开发后记

本着学习交流记录的目的编写了这个系列文章,主要用来记录如何从零开始学习SDL开发的过程,在这个过程中遇到了很多问题,差点就放弃了.首先是SDL的Android移植的时候遇到了比较坑的是SDL移植到Android的JNI文件编写比较坑,刚开始想着如何将SDL编译成动态共享库,在别的地方直接调用该动态共享库,结果发现死活崩溃在SDL_Init()这个函数,最后发现SDL的JNI文件直接使用SDLActivity的函数,并且JNI采用静态注册的方式.直接在别的地方调用该动态库就跪了,博主能力又有限,又

SDL 简单入门学习

write by 九天雁翎(JTianLing) -- blog.csdn.net/vagrxie 讨论新闻组及文件 概要 实际学习使用SDL创建窗体,并绘制图形. 前言 今天想要做一个简单的demo,由于一部分须要使用objective C,所以还须要跨平台,我才发现,我了解的东西还真没有一个适合做这样事情的,Cocos2D For IPhone只能在IPhone下跑,HGE只能在Windows下跑,Orx尽管可以跨平台,可是非常显然,用于做简单的demo太麻烦了,由于我须要的不过一个简单的D

[原]零基础学习SDL开发之移植SDL2.0到Android

在[原]SDL开发教程我们知道了如何在pc下使用SDL进行开发,在android上面是否一样可以使用呢?答案是肯定的. 下面我们进行移植SDL到Android,这里都是基于SDL最新版进行移植的,在Eclipse中编译. 开发环境:Ubuntu 14.04 64位,Eclipse + CDT + ADT,NDK 一.到官网下载http://www.libsdl.org/hg.php 下载2.0的源码也可以通过hg来clone最新的源码 hg clone http://hg.libsdl.org/

【音视频连载-001】基础学习篇- SDL 介绍以及工程配置

技术开发故事会连载 这是音视频基础学习系列的第一篇文章,主要讲解 SDL 是什么以及为什么要用到它,看似和音视频没啥卵关系,其实必不可少. SDL 简介 SDL 是 "Simple DirectMedia Layer" 的缩写,它是一个跨平台的多媒体库,可以在 Mac.Windows.Linux 以及更多的系统上运行. SDL 提供了统一的针对音频.视频.键盘.鼠标.控制杆以及 3D 硬件的低级别访问接口,我们利用这些接口就能在不同系统上播放出音频.视频内容,而无需懂得系统特定的音视频