/// program to compare SFML vs SDL performance /// written by Matthias Grobe ( teeteehaa {at} gmx.de ) /// written on 17. December 2007 /// feel free to use this code as you want, /// hopefully it helps you in some way :) /// SFML version: subversion repository as of 1. December 2007 /// SDL version: 1.2.11 /// SDLgfx version: 2.0.16 // --- includes --- // windows #include // SFML #include "SFML/Graphics.hpp" // SDL #include "SDL.h" #include "SDL_rotozoom.h" #include "SDL_gfxPrimitives.h" // STL #include // --- defines --- #define FONT_FILE "frzquadn.ttf" #define IMAGE_FILE "image_3x3.bmp" const int SCREEN_WIDTH = 800; const int SCREEN_HEIGHT = 600; const int SPRITE_WIDTH_DEST = 32; const int SPRITE_HEIGHT_DEST = 32; // --- signal handler --- BOOL WINAPI MyHandlerRoutine(DWORD dwCtrlType) { std::cout << "exiting the hard way" << std::endl; exit(0); return TRUE; } // --- run --- bool runSFML() { // variables bool Switch(true); bool Looping(true); unsigned long CurrentTime(timeGetTime()); unsigned long LastTime(CurrentTime); unsigned long CurrentFrameCounter(0); unsigned long LastFrameCounter(0); char Buffer[128]; int X(0); int Y(0); sf::Event MyEvent; // image sf::Image MyImage; if (!MyImage.LoadFromFile(IMAGE_FILE)) { std::cout << "failed to load image '" << IMAGE_FILE << "'" << std::endl; return false; } // sprite int SpriteWidthSource(MyImage.GetWidth() / 3); int SpriteHeightSource(MyImage.GetHeight() / 3); sf::Sprite MySprite; MySprite.SetImage( MyImage); MySprite.SetSubRect( sf::IntRect( SpriteWidthSource, SpriteHeightSource, SpriteWidthSource * 2, SpriteHeightSource * 2)); MySprite.Scale( (float) SPRITE_WIDTH_DEST / (float) SpriteWidthSource, (float) SPRITE_HEIGHT_DEST / (float) SpriteHeightSource); // render window sf::RenderWindow MyRenderWindow(sf::VideoMode(SCREEN_WIDTH, SCREEN_HEIGHT), "run SFML", sf::Style::Close); MyRenderWindow.SetBackgroundColor(sf::Color(255, 0, 255)); // big loop while (Looping) { // loop over screen for (Y = 0; Y < SCREEN_HEIGHT; Y += SPRITE_HEIGHT_DEST) { for (X = 0; X < SCREEN_WIDTH; X+= SPRITE_WIDTH_DEST) { // draw sprite MySprite.SetPosition((float) X, (float) Y); MyRenderWindow.Draw(MySprite); } } // calculate FPS CurrentTime = timeGetTime(); if (CurrentTime - LastTime > 1000) { LastFrameCounter = CurrentFrameCounter; CurrentFrameCounter = 0 ; LastTime = CurrentTime; } ++CurrentFrameCounter; // display FPS string _snprintf_s(Buffer, 128, "Space: switch | Escape: exit | Mode: SFML | FPS: %u", LastFrameCounter); sf::String MyString(Buffer, FONT_FILE, 24); MyString.SetPosition(10, 10); MyRenderWindow.Draw(MyString); // display screen MyRenderWindow.Display(); // poll events while (MyRenderWindow.GetEvent(MyEvent)) { // check whether window was closed if (MyEvent.Type == sf::Event::Close) { Looping = false; Switch = false; } // check whether escape was pressed if ((MyEvent.Type == sf::Event::KeyReleased) && (MyEvent.Key.Code == sf::Key::Escape)) { Looping = false; Switch = false; } // check whether space was pressed if ((MyEvent.Type == sf::Event::KeyReleased) && (MyEvent.Key.Code == sf::Key::Space)) { Looping = false; Switch = true; } } } return Switch; } bool runSDL() { // variables bool Switch(true); bool Looping(true); unsigned long CurrentTime(timeGetTime()); unsigned long LastTime(CurrentTime); unsigned long CurrentFrameCounter(0); unsigned long LastFrameCounter(0); char Buffer[128]; int X(0); int Y(0); SDL_Event MyEvent; // initialize SDL's subsystems if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) { std::cout << "failed to init SDL: " << SDL_GetError() << std::endl; return false; } /// screen surface SDL_Surface* pScreenSurface(SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, 32, SDL_SWSURFACE)); if (pScreenSurface == NULL) { std::cout << "failed to set up video: " << SDL_GetError() << std::endl; return false; } // load image SDL_Surface* pTempSurface(SDL_LoadBMP(IMAGE_FILE)); if (pTempSurface == NULL) { std::cout << "failed to load image '" << IMAGE_FILE << "': " << SDL_GetError() << std::endl; SDL_QuitSubSystem(SDL_INIT_VIDEO); return false; } // convert image SDL_Surface* pImageSurface(SDL_DisplayFormatAlpha(pTempSurface)); SDL_FreeSurface(pTempSurface); if (pImageSurface == NULL) { std::cout <<"failed to convert image to display format: " << SDL_GetError() << std::endl; SDL_QuitSubSystem(SDL_INIT_VIDEO); return false; } // get sprite from image SDL_Surface* pSpriteSurface(zoomSurface(pImageSurface, (double) SPRITE_WIDTH_DEST * 3.0 / (double) pImageSurface->w, (double) SPRITE_HEIGHT_DEST * 3.0 / (double) pImageSurface->h, SMOOTHING_ON)); if (pSpriteSurface == NULL) { std::cout << "failed to zoom surface: " << SDL_GetError() << std::endl; SDL_FreeSurface(pImageSurface); SDL_QuitSubSystem(SDL_INIT_VIDEO); return false; } // source rect (note: 3x3 sprites in image) SDL_Rect SourceRect; SourceRect.x = SPRITE_WIDTH_DEST; SourceRect.y = SPRITE_HEIGHT_DEST; SourceRect.w = SPRITE_WIDTH_DEST; SourceRect.h = SPRITE_HEIGHT_DEST; // destination rect SDL_Rect DestinationRect; DestinationRect.x = 0; DestinationRect.y = 0; DestinationRect.w = SPRITE_WIDTH_DEST; DestinationRect.h = SPRITE_HEIGHT_DEST; // big loop while (Looping) { // loop over screen for (Y = 0; Y < SCREEN_HEIGHT && Looping; Y += SPRITE_HEIGHT_DEST) { for (X = 0; X < SCREEN_WIDTH && Looping; X+= SPRITE_WIDTH_DEST) { // draw sprite DestinationRect.x = X; DestinationRect.y = Y; if (SDL_BlitSurface(pSpriteSurface, &SourceRect, pScreenSurface, &DestinationRect) != 0) { std::cout << "failed to blit surface: " << SDL_GetError() << std::endl; Looping = false; Switch = false; break; } } } // calculate FPS CurrentTime = timeGetTime(); if (CurrentTime - LastTime > 1000) { LastFrameCounter = CurrentFrameCounter; CurrentFrameCounter = 0 ; LastTime = CurrentTime; } ++CurrentFrameCounter; // display FPS string _snprintf_s(Buffer, 128, "Space: switch | Escape: exit | Mode: SDL | FPS: %u", LastFrameCounter); stringColor(pScreenSurface, 10, 10, Buffer, 0xFFFFFFFF); // display screen if (SDL_Flip(pScreenSurface) < 0) { std::cout << "flip failed: " << SDL_GetError() << std::endl; Looping = false; Switch = false; break; } // poll events while (SDL_PollEvent(&MyEvent)) { // check whether window was closed if (MyEvent.type == SDL_QUIT) { Looping = false; Switch = false; } // check whether escape was pressed if ((MyEvent.type == SDL_KEYUP) && (MyEvent.key.keysym.sym == SDLK_ESCAPE)) { Looping = false; Switch = false; } // check whether space was pressed if ((MyEvent.type == SDL_KEYUP) && (MyEvent.key.keysym.sym == SDLK_SPACE)) { Looping = false; Switch = true; } } } // free up surfaces SDL_FreeSurface(pSpriteSurface); SDL_FreeSurface(pImageSurface); // quit SDL's subsystems SDL_QuitSubSystem(SDL_INIT_VIDEO); return Switch; } // --- main --- int main(int argc, char *argv[]) { // add signal handler routine // (note: this seems to be overwritten by the SDL event handling // in case graphic engine is started!) if (!SetConsoleCtrlHandler(MyHandlerRoutine, TRUE)) { std::cout << "failed to add signal handler routine" << std::endl; exit(1); } // start std::cout << "started" << std::endl; // big loop while (true) { if (!runSFML()) break; if (!runSDL()) break; } // stopped std::cout << "stopped" << std::endl; return 0; }