2 - Rita ut bilder

Del 2, rita ut bilder



Nu är det äntligen dags för del 2 utav denna guide om SDL med C++. I förra delen ägnade vi oss åt att komma igång med utvecklandet genom att konfigurera kompilatorn så att man kan programmera spel som använder sig utav SDL-biblioteket. Nu är det dags att faktiskt använda SDL lite. Vi ska börja med att ladda in bilder. Jag har valt att börja med inladdning utav bilder eftersom detta är den mest användbara funktionen när man gör spel enligt mig. Att kunna rita sträck och rektanglar kan ju vara kul en stund, men det har inga direkta användningsområden i ett spel. SDL har endast stöd för att ladda in bilder i formatet BMP, men med ett litet tillägg som heter SDL_Image kan man ladda in de flesta bildtyper. Men vi börjar med att ladda in BMP-bilder.

Innan man kan rita bilder behöver man förklara för datorn vilken upplösning programmet ska använda, vilket färgdjup som skall användas, om hårdvaruacceleration ska användas och en del andra saker. Det är det dom första raderna i koden nedan gör. En mer noggrann förklaring kommer efter. Här är koden:

  1.  
  2. #ifdef WIN32
  3. #pragma comment(lib, "SDL.lib")
  4. #pragma comment(lib, "SDLmain.lib")
  5. #endif
  6.  
  7. #include "SDL.h"
  8. #include <iostream>
  9.  
  10. using namespace std;
  11.  
  12. int main(int argc, char *argv[])
  13. {
  14. SDL_Surface *screen; // En yta
  15.  
  16. // Initiera SDL
  17. if ( SDL_Init(SDL_INIT_AUDIO|SDL_INIT_VIDEO) < 0 )
  18. {
  19. cout << "Error, unable to initialize SDL: " << SDL_GetError() << endl;
  20. SDL_Quit();
  21. return 1;
  22. }
  23. else
  24. {
  25. cout << "SDL initialized successfully!" << endl;
  26. }
  27.  
  28. screen = SDL_SetVideoMode(640, 480, 16, SDL_HWSURFACE|SDL_DOUBLEBUF);
  29.  
  30. if (screen == NULL)
  31. {
  32. cout << "Unable to set video mode: " << SDL_GetError() << endl;
  33. SDL_Quit();
  34. return 1;
  35. }
  36. else
  37. {
  38. cout << "Successfully set video mode!" << endl;
  39. }
  40.  
  41. // Rita ut en bild
  42. SDL_Surface* image;
  43. image = SDL_LoadBMP("test.bmp");
  44. if (image == NULL)
  45. {
  46. cout << "Image could not be loaded!" << endl;
  47. SDL_Quit();
  48. return 1;
  49. }
  50. SDL_BlitSurface(image, NULL, screen, NULL);
  51. SDL_Flip(screen);
  52.  
  53. SDL_Delay(2000); // Pausar i 2000 ms (2 sekunder)
  54.  
  55. // Stäng ner SDL och frigör resurser
  56. SDL_Quit();
  57.  
  58. return 0;
  59. }


De översta fyra raderna berättar för länkaren vart den ska leta efter de olika SDL-funktionerna. Utan dessa rader skulle länkaren inte veta vad den skulle göra av anrop till SDL_LoadBMP() t ex.

Efter att vi inkluderat några behövliga headerfiler kommer vi till huvudfunktionen. Den börjar med en variabeldeklaration, variabeltypen är troligtvis okänd för dig just nu. Det är SDL_Surface* jag pratar om. Detta är en pekare till en så kallad yta. Varje yta innehåller information om grafik, en yta kan till exempel innehålla en bild. Just denna yta, screen, kommer dock att innehålla slutresultatet av alla saker vi vill visa på skärmen. Vi kopierar alltså över alla våra bilder från sina ytor över till denna yta, och sedan ber vi SDL visa denna yta på skärmen.

Efter denna lite variabeldeklaration kommer vi till biten där vi initierar SDL. Vi anropar funktionen SDL_Init och skickar med en parameter som förklarar att det är ljud och grafikbiten vi vill initiera. Detta funktionsanrop står i sin tur i ett uttryck till en if-sats. Om SDL_Init returnerar ett värde som är under 0 så betyder det att ett fel har uppstått, vi fortsätter då genom att skriva ut vad felet var och avsluta programmet. Uppstod inget fel rapporterar vi istället att inget fel inträffat.

Raden därefter initierar våran yta som jag pratade om innan. Vi anropar då funktionen SDL_SetVideoMode och anger upplösning, färgdjup samt några ytterligare inställningar som parametrar. Vi har alltså valt upplösningen 640x480 med 16 bitars färgdjup. Vi väljer också att ytan ska vara hårdvaruaccelererad och dubbelbuffrad. Detta gör att vi får lite bättre prestanda i spelet samt att det inte kommer flimra.

Efter detta kollar vi att funktionsanropet SDL_SetVideoMode var lyckat genom att kolla om våran yta faktiskt innehåller något. ,,r ytan tom så avslutar vi programmet.

Nu kommer vi äntligen när till biten där vi ritar ut en bild!
Vi börjar med att skapa en ny yta som vi döper till image. Denna yta kommer att innehålla våran bild. Därefter anropar vi en funktion som heter SDL_LoadBMP(), den funktionen tar ett bildnamn som argument. Funktionen returnerar en pekare till en yta med en bild, adressen till denna pekare sparar vi i pekarvariabeln image.

Om bilden inte kunde laddas (om den inte hittades t ex) så kommer pekarvariabeln vara lika med NULL. ,,r den det så avslutar vi programmet.

Har vi lyckats initiera SDL och ladda bilden kommer vi ner till steget då vi ska kopiera över bilden från våran yta image till ytan screen för att sedan visa den på skärmen. För att kopiera en yta till en annan använder vi funktionen SDL_BlitSurface. Den tar egentligen fyra argument; det första argumentet är ytan vi vill kopiera ifrån, det andra argumentet är vilken del utav den ytan vi vill kopiera, det tredje argumentet är ytan vi vill kopiera till och det sista argumentet är vart på ytan vi kopierar till den grafiken från den nya ytan ska placeras. Eftersom vi vill kopiera hela våran bild kan vi skicka NULL som det andra argumentet, då kommer hela ytan kopieras. Man kan annars specificera att bara övre högra hörnet ska kopieras t ex. Det sista argumentet kommer vi också att sätta till NULL, det betyder att bilden kopieras in vid pixel 0,0 på ytan screen. Det resulterar i att bilden visas längst upp till vänster på skärmen eftersom man börjar räkna pixlarna där. 0,0 är alltså längst upp till vänster. Här kan man såklart ange ett värde för att få bilden att visas i mitten av bildskärmen t ex.

Sedan anropar vi SDL_Flip() med ett argument, ytan screen. Detta gör att ytan screen kommer att visas på skärmen. Efter det anropar vi en liten funktion som gör att programmet pausas en liten stund så att vi hinner se resultatet innan det avslutas.

Testa att kompilera och köra programmet, det borde visa en bild i övre vänsta hörnet och sedan avslutas efter en liten stund. Om programmet avslutas direkt är det troligtvis för att bilden inte kunde hittas. Kör du Visual Studio ska bilden ligga i samma katalog som källkodsfilerna.

Källa: http://blinkenlights.se/