如果对该程序进行编译运行,那么只能得到一闪而过的一个黑色的窗口。我们需要对窗口进行绘制,并且对基本的键盘鼠标事件进行处理。
绘制的基本原理是,先在缓冲区绘制,再一次性将缓冲区绘制到屏幕上。这样比起一次一个象素点在屏幕上绘图的方式效率更高,速度更快,也不易出错。首先使 用循环在screen所指向的surface(缓冲区)上绘制,然后调用SDL_Flip函数将screen surface绘制到真实电脑屏幕上。SDL_Flip函数的作用是:在支持双缓冲(double-buffering)的硬件上,建立flip并返回。 硬件将等待vertical retrace,然后在下一个视频surface blit或者执行锁定返回前交换视频缓冲区。如果硬件不支持双缓冲,那么等同于调用SDL_UpdateRect(screen, 0, 0, 0, 0),即对整个screen的绘制区域进行刷新。
void DrawScene(SDL_Surface *screen) { Slock(screen); for(int x=0;x<640;x++) { for(int y=0;y<480;y++) { DrawPixel(screen, x,y,y/2,y/2,x/3); } } Sulock(screen); SDL_Flip(screen); }
在SDL中对采用结构SDL_Event来描述事件,并采用轮询的机制对事件进行处理,程序中使用一个SDL_Event的实例(Instance)来检查事件的发生:
SDL_Event event;
轮询采用while循环来检查:
while ( SDL_PollEvent(&event)) { if ( event.type == SDL_QUIT) { //code here?. } if ( event.type == SDL_KEYDOWN) { //code here?. } //?.. }
事件轮询完毕之后,调用DrawScene(sreen)进行一次绘制。
本例中的源代码如下:
#include #include #include \ void Slock(SDL_Surface *screen) { if ( SDL_MUSTLOCK(screen) ) { if ( SDL_LockSurface(screen) < 0 ) { return; } } } void Sulock(SDL_Surface *screen) { if ( SDL_MUSTLOCK(screen) ) { SDL_UnlockSurface(screen); } } void DrawPixel(SDL_Surface *screen, int x, int y, Uint8 R, Uint8 G, Uint8 B) { Uint32 color = SDL_MapRGB(screen->format, R, G, B); switch (screen->format->BytesPerPixel) { case 1: // Assuming 8-bpp { Uint8 *bufp; bufp = (Uint8 *)screen->pixels + y*screen->pitch + x; *bufp = color; } break; case 2: // Probably 15-bpp or 16-bpp { Uint16 *bufp; bufp = (Uint16 *)screen->pixels + y*screen->pitch/2 + x; *bufp = color; } break; case 3: // Slow 24-bpp mode, usually not used { Uint8 *bufp; bufp = (Uint8 *)screen->pixels + y*screen->pitch + x * 3; if(SDL_BYTEORDER == SDL_LIL_ENDIAN) { bufp[0] = color; bufp[1] = color >> 8; bufp[2] = color >> 16; } else { bufp[2] = color; bufp[1] = color >> 8; bufp[0] = color >> 16; } } break; case 4: // Probably 32-bpp { Uint32 *bufp; bufp = (Uint32 *)screen->pixels + y*screen->pitch/4 + x; *bufp = color; } break; } } void DrawScene(SDL_Surface *screen) { Slock(screen); for(int x=0;x<640;x++) { for(int y=0;y<480;y++) { DrawPixel(screen, x,y,y/2,y/2,x/3); } } Sulock(screen); SDL_Flip(screen); } int main(int argc, char *argv[]) { if ( SDL_Init(SDL_INIT_AUDIO|SDL_INIT_VIDEO) < 0 ) { printf(\exit(1); } atexit(SDL_Quit); SDL_Surface *screen; screen=SDL_SetVideoMode(640,480,32,SDL_HWSURFACE|SDL_DOUBLEBUF); if ( screen == NULL ) { printf(\exit(1); } int done=0; while(done == 0) { SDL_Event event; while ( SDL_PollEvent(&event) ) { if ( event.type == SDL_QUIT ) { done = 1; } if ( event.type == SDL_KEYDOWN ) { if ( event.key.keysym.sym == SDLK_ESCAPE ) { done = 1; } } } DrawScene(screen); }