//sdl 工程历程
http://www.libsdl.org/projects/
===============================================================================================
apt-get install g++
g++ sdl1.cpp -I/usr/local/include/SDL -L/usr/local/lib -lSDL
===============================================================================================
一、安装:
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
二、下载地址(用步骤一中的即可):
http://www.libsdl.org/download-1.2.php
三、函数详解:
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()
#include <stdio.h> #include <SDL/SDL.h> SDL_Surface *screen = NULL; const int SCREEN_BPP = 32; void display_bmp(char* file_name) { SDL_Surface* image = NULL; /* Load the BMP file into a surface */ image = SDL_LoadBMP(file_name); if (image == NULL) { fprintf(stderr, "Couldn't load %s: %s\n", file_name, SDL_GetError()); return; } /* * Palettized screen modes will have a default palette (a standard * 8*8*4 colour cube), but if the image is palettized as well we can * use that palette for a nicer colour matching */ if (image->format->palette && screen->format->palette) { SDL_SetColors(screen, image->format->palette->colors, 0, image->format->palette->ncolors); } /* Blit onto the screen surface */ if (SDL_BlitSurface(image, NULL, screen, NULL) < 0) fprintf(stderr, "BlitSurface error: %s\n", SDL_GetError()); /* Update the modified region of the screen */ SDL_UpdateRect(screen, 0, 0, image->w, image->h); /* Free the allocated BMP surface */ SDL_FreeSurface(image); } int main(int argc, char **argv) { SDL_Init(SDL_INIT_EVERYTHING); screen = SDL_SetVideoMode(600, 480, SCREEN_BPP, SDL_SWSURFACE); if (screen == NULL) return -1; display_bmp("test.bmp"); SDL_Event event; bool gameRunning = true; while (gameRunning) { if (SDL_PollEvent(&event)) { if (event.type == SDL_QUIT) { gameRunning = false; } } } SDL_Quit(); //getchar(); return 0; }
例子:
{ ... delay = 10; my_timer_id = SDL_AddTimer(delay, my_callbackfunc, my_callback_param); ... } Uint32 my_callbackfunc(Uint32 interval, void *param) { SDL_Event event; SDL_UserEvent userevent; userevent.type = SDL_USEREVENT; userevent.code = 0; userevent.data1 = &my_func; userevent.data2 = NULL; event.type = SDL_USEREVENT; event.user = userevent; SDL_PushEvent(&event); return(interval); } { ... SDL_Event event; while (SDL_PollEvent (&event)) { switch(event.type) { case SDL_USEREVENT: { void (*p) (void*) = event.user.data1; p(event.user.data2); break; } } } ... } void CheckMouseHover(void) { int mouse_x, mouse_y; SDL_PumpEvents(); SDL_GetMouseState(&mouse_x, &mouse_y); if ( (mouse_x < 32) && (mouse_y < 32) ) { printf("鼠标在左上角!\n"); } }
检测鼠标事件例子:
#include <stdio.h> #include <SDL/SDL.h> #include <SDL/SDL_ttf.h> #define bool int #define false 0 #define true 1 SDL_Surface * screen = NULL; const int SCREEN_BPP = 32 ; int main( int argc, char * args[] ) { // Start SDL bool quit = false ; SDL_Rect rectLeft; SDL_Rect rectRight; rectLeft.x = 0 ; rectLeft.y = 0 ; rectLeft.w = 320 ; rectLeft.h = 480 ; rectRight.x = 320 ; rectRight.y = 0 ; rectRight.w = 640 ; rectRight.h = 480 ; SDL_Init( SDL_INIT_EVERYTHING ); screen = SDL_SetVideoMode( 600 , 480 , SCREEN_BPP, SDL_SWSURFACE ); if (screen == NULL) return false ; Uint32 colorBlue = SDL_MapRGB(screen -> format, 0 , 0 , 255 ); Uint32 colorGreen = SDL_MapRGB(screen -> format, 0 , 255 , 0 ); Uint32 colorRed = SDL_MapRGB(screen -> format, 255 , 0 , 0 ); Uint32 colorBlack = SDL_MapRGB(screen -> format, 0 , 0 , 0 ); SDL_Event event ; while ( ! quit) { if (SDL_PollEvent( & event )) { switch (event.type) { case SDL_MOUSEMOTION: { Uint16 x = event .motion.x; Uint16 y = event .motion.y; if (x > 0 && x < 320 && y > 0 && y < 480 ) { SDL_FillRect(screen, & rectLeft,colorBlue); SDL_FillRect(screen, & rectRight,colorBlack); } if (x > 320 && x < 640 && y > 0 && y < 480 ) { SDL_FillRect(screen, & rectRight,colorGreen); SDL_FillRect(screen, & rectLeft,colorBlack); } break; } case SDL_MOUSEBUTTONDOWN: { Uint16 x = event .motion.x; Uint16 y = event .motion.y; if ( event .button.button == SDL_BUTTON_LEFT) { if (x > 0 && x < 320 && y > 0 && y < 480 ) SDL_FillRect(screen, & rectLeft,colorRed); if (x > 320 && x < 640 && y > 0 && y < 480 ) SDL_FillRect(screen, & rectRight,colorRed); } break; } case SDL_QUIT: quit = true ; break; default : break; } } if (SDL_Flip(screen) == - 1 ) return false ; } SDL_FreeSurface(screen); SDL_Quit(); return 0 ; }
SDL_LoadBMP解析图片
例子:
#include <stdio.h> #include <SDL/SDL.h> SDL_Surface *screen = NULL; const int SCREEN_BPP = 32; void display_bmp(char* file_name) { SDL_Surface* image = NULL; /* Load the BMP file into a surface */ image = SDL_LoadBMP(file_name); if (image == NULL) { fprintf(stderr, "Couldn't load %s: %s\n", file_name, SDL_GetError()); return; } /* * Palettized screen modes will have a default palette (a standard * 8*8*4 colour cube), but if the image is palettized as well we can * use that palette for a nicer colour matching */ if (image->format->palette && screen->format->palette) { SDL_SetColors(screen, image->format->palette->colors, 0, image->format->palette->ncolors); } /* Blit onto the screen surface */ if (SDL_BlitSurface(image, NULL, screen, NULL) < 0) fprintf(stderr, "BlitSurface error: %s\n", SDL_GetError()); /* Update the modified region of the screen */ SDL_UpdateRect(screen, 0, 0, image->w, image->h); /* Free the allocated BMP surface */ SDL_FreeSurface(image); } int main(int argc, char **argv) { SDL_Init(SDL_INIT_EVERYTHING); screen = SDL_SetVideoMode( 600 , 480 , SCREEN_BPP, SDL_SWSURFACE ); if (screen == NULL) return -1; display_bmp("test.bmp"); getchar(); return 0; }
OPENGL&SDL
/* * SDL OpenGL Tutorial. * (c) Michael Vance, 2000 * briareos@lokigames.com * * Distributed under terms of the LGPL. */ #include <SDL/SDL.h> #include <GL/gl.h> #include <GL/glu.h> #include <stdio.h> #include <stdlib.h> static GLboolean should_rotate = GL_TRUE; static void quit_tutorial( int code ) { /* * Quit SDL so we can release the fullscreen * mode and restore the previous video settings, etc. */ SDL_Quit( ); /* Exit program. */ exit( code ); } static void handle_key_down( SDL_keysym* keysym ) { /* * We're only interested if 'Esc' has been presssed. * * EXERCISE: * Handle the arrow keys and have that change the * viewing position/angle. */ switch( keysym->sym ) { case SDLK_ESCAPE: quit_tutorial( 0 ); break; case SDLK_SPACE: should_rotate = !should_rotate; break; default: break; } } static void process_events( void ) { /* Our SDL event placeholder. */ SDL_Event event; /* Grab all the events off the queue. */ while( SDL_PollEvent( &event ) ) { switch( event.type ) { case SDL_KEYDOWN: /* Handle key presses. */ handle_key_down( &event.key.keysym ); break; case SDL_QUIT: /* Handle quit requests (like Ctrl-c). */ quit_tutorial( 0 ); break; default: break; } } /* while */ } static void draw_screen( void ) { /* Our angle of rotation. */ static float angle = 0.0f; /* * EXERCISE: * Replace this awful mess with vertex * arrays and a call to glDrawElements. * * EXERCISE: * After completing the above, change * it to use compiled vertex arrays. * * EXERCISE: * Verify my windings are correct here ;). */ static GLfloat v0[] = { -1.0f, -1.0f, 1.0f }; static GLfloat v1[] = { 1.0f, -1.0f, 1.0f }; static GLfloat v2[] = { 1.0f, 1.0f, 1.0f }; static GLfloat v3[] = { -1.0f, 1.0f, 1.0f }; static GLfloat v4[] = { -1.0f, -1.0f, -1.0f }; static GLfloat v5[] = { 1.0f, -1.0f, -1.0f }; static GLfloat v6[] = { 1.0f, 1.0f, -1.0f }; static GLfloat v7[] = { -1.0f, 1.0f, -1.0f }; static GLubyte red[] = { 255, 0, 0, 255 }; static GLubyte green[] = { 0, 255, 0, 255 }; static GLubyte blue[] = { 0, 0, 255, 255 }; static GLubyte white[] = { 255, 255, 255, 255 }; static GLubyte yellow[] = { 0, 255, 255, 255 }; static GLubyte black[] = { 0, 0, 0, 255 }; static GLubyte orange[] = { 255, 255, 0, 255 }; static GLubyte purple[] = { 255, 0, 255, 0 }; /* Clear the color and depth buffers. */ glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); /* We don't want to modify the projection matrix. */ glMatrixMode( GL_MODELVIEW ); glLoadIdentity( ); /* Move down the z-axis. */ glTranslatef( 0.0, 0.0, -5.0 ); /* Rotate. */ glRotatef( angle, 0.0, 1.0, 0.0 ); if ( should_rotate ) { if ( ++angle > 360.0f ) { angle = 0.0f; } } /* Send our triangle data to the pipeline. */ glBegin( GL_TRIANGLES ); glColor4ubv( red ); glVertex3fv( v0 ); glColor4ubv( green ); glVertex3fv( v1 ); glColor4ubv( blue ); glVertex3fv( v2 ); glColor4ubv( red ); glVertex3fv( v0 ); glColor4ubv( blue ); glVertex3fv( v2 ); glColor4ubv( white ); glVertex3fv( v3 ); glColor4ubv( green ); glVertex3fv( v1 ); glColor4ubv( black ); glVertex3fv( v5 ); glColor4ubv( orange ); glVertex3fv( v6 ); glColor4ubv( green ); glVertex3fv( v1 ); glColor4ubv( orange ); glVertex3fv( v6 ); glColor4ubv( blue ); glVertex3fv( v2 ); glColor4ubv( black ); glVertex3fv( v5 ); glColor4ubv( yellow ); glVertex3fv( v4 ); glColor4ubv( purple ); glVertex3fv( v7 ); glColor4ubv( black ); glVertex3fv( v5 ); glColor4ubv( purple ); glVertex3fv( v7 ); glColor4ubv( orange ); glVertex3fv( v6 ); glColor4ubv( yellow ); glVertex3fv( v4 ); glColor4ubv( red ); glVertex3fv( v0 ); glColor4ubv( white ); glVertex3fv( v3 ); glColor4ubv( yellow ); glVertex3fv( v4 ); glColor4ubv( white ); glVertex3fv( v3 ); glColor4ubv( purple ); glVertex3fv( v7 ); glColor4ubv( white ); glVertex3fv( v3 ); glColor4ubv( blue ); glVertex3fv( v2 ); glColor4ubv( orange ); glVertex3fv( v6 ); glColor4ubv( white ); glVertex3fv( v3 ); glColor4ubv( orange ); glVertex3fv( v6 ); glColor4ubv( purple ); glVertex3fv( v7 ); glColor4ubv( green ); glVertex3fv( v1 ); glColor4ubv( red ); glVertex3fv( v0 ); glColor4ubv( yellow ); glVertex3fv( v4 ); glColor4ubv( green ); glVertex3fv( v1 ); glColor4ubv( yellow ); glVertex3fv( v4 ); glColor4ubv( black ); glVertex3fv( v5 ); glEnd( ); /* * EXERCISE: * Draw text telling the user that 'Spc' pauses the rotation and 'Esc' quits. * Do it using vetors and textured quads. */ /* * Swap the buffers. This this tells the driver to * render the next frame from the contents of the * back-buffer, and to set all rendering operations * to occur on what was the front-buffer. * * Double buffering prevents nasty visual tearing * from the application drawing on areas of the * screen that are being updated at the same time. */ SDL_GL_SwapBuffers( ); } static void setup_opengl( int width, int height ) { float ratio = (float) width / (float) height; /* Our shading model--Gouraud (smooth). */ glShadeModel( GL_SMOOTH ); /* Culling. */ glCullFace( GL_BACK ); glFrontFace( GL_CCW ); glEnable( GL_CULL_FACE ); /* Set the clear color. */ glClearColor( 0, 0, 0, 0 ); /* Setup our viewport. */ glViewport( 0, 0, width, height ); /* * Change to the projection matrix and set * our viewing volume. */ glMatrixMode( GL_PROJECTION ); glLoadIdentity( ); /* * EXERCISE: * Replace this with a call to glFrustum. */ gluPerspective( 60.0, ratio, 1.0, 1024.0 ); } int main( int argc, char* argv[] ) { /* Information about the current video settings. */ const SDL_VideoInfo* info = NULL; /* Dimensions of our window. */ int width = 0; int height = 0; /* Color depth in bits of our window. */ int bpp = 0; /* Flags we will pass into SDL_SetVideoMode. */ int flags = 0; /* First, initialize SDL's video subsystem. */ if ( SDL_Init( SDL_INIT_VIDEO ) < 0 ) { /* Failed, exit. */ fprintf( stderr, "Video initialization failed: %s\n", SDL_GetError( ) ); quit_tutorial( 1 ); } /* Let's get some video information. */ info = SDL_GetVideoInfo( ); if ( !info ) { /* This should probably never happen. */ fprintf( stderr, "Video query failed: %s\n", SDL_GetError( ) ); quit_tutorial( 1 ); } /* * Set our width/height to 640/480 (you would of course let the user * decide this in a normal app). We get the bpp we will request from * the display. On X11, VidMode can't change resolution, so this is * probably being overly safe. Under Win32, ChangeDisplaySettings * can change the bpp. */ width = 640; height = 480; bpp = info->vfmt->BitsPerPixel; /* * Now, we want to setup our requested * window attributes for our OpenGL window. * We want *at least* 5 bits of red, green * and blue. We also want at least a 16-bit * depth buffer. * * The last thing we do is request a double * buffered window. '1' turns on double * buffering, '0' turns it off. * * Note that we do not use SDL_DOUBLEBUF in * the flags to SDL_SetVideoMode. That does * not affect the GL attribute state, only * the standard 2D blitting setup. */ SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 5 ); SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 5 ); SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 5 ); SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 ); SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); /* * We want to request that SDL provide us * with an OpenGL window, in a fullscreen * video mode. * * EXERCISE: * Make starting windowed an option, and * handle the resize events properly with * glViewport. */ flags = SDL_OPENGL | SDL_FULLSCREEN; /* * Set the video mode */ if ( SDL_SetVideoMode( width, height, bpp, flags ) == 0 ) { /* * This could happen for a variety of reasons, * including DISPLAY not being set, the specified * resolution not being available, etc. */ fprintf( stderr, "Video mode set failed: %s\n", SDL_GetError( ) ); quit_tutorial( 1 ); } /* * At this point, we should have a properly setup * double-buffered window for use with OpenGL. */ setup_opengl( width, height ); /* * Now we want to begin our normal app process-- * an event loop with a lot of redrawing. */ setup_opengl( width, height ); /* * Now we want to begin our normal app process-- * an event loop with a lot of redrawing. */ while (1) { /* Process incoming events. */ process_events( ); /* Draw the screen. */ draw_screen( ); /* Avoid to eat all the CPU power */ SDL_Delay( 50 ); } /* * EXERCISE: * Record timings using SDL_GetTicks() and * and print out frames per second at program * end. */ /* Never reached. */ return 0; }
make又出现以下问题:
./src/video/x11/SDL_x11sym.h:168:17: error: conflicting types for _XData32?
SDL_X11_SYM(int,_XData32,(Display *dpy,register long *data,unsigned len),(dpy,data,len),return)
^
./src/video/x11/SDL_x11dyn.c:95:5: note: in definition of macro 釹DL_X11_SYM?
rc fn params { ret p##fn args ; }
^
In file included from ./src/video/x11/SDL_x11dyn.h:34:0,
from ./src/video/x11/SDL_x11dyn.c:26:
/usr/include/X11/Xlibint.h:568:12: note: previous declaration of 鈅XData32?was here
extern int _XData32(
^
make: *** [build/SDL_x11dyn.lo] Error 1
解决方案:查阅了一些资料,发现是libx11-dev版本问题(查看版本如图),版本>1.5.99,所以需要修改src/video/x11/SDL_x11sym.h 文件,按照提示修改168行,
修改如下:
原来是:SDL_X11_SYM(int,_XData32,(Display *dpy,register long *data,unsigned len),(dpy,data,len),return)
改后添加一个单词即可:(_Xconst)
SDL_X11_SYM(int,_XData32,(Display *dpy,register _Xconst long *data,unsigned len),(dpy,data,len),return)
再make 和 sudo make install就可以了。