Den Videomodus setzten (Ein Fenster erstellen)

Jetzt wird es langsam einmal Zeit das wir uns ein Fenster erstellen, da wir ja irgendwas brauchen wo wir hineinzeichnen können. Dazu schauen wir uns einfach einmal folgenden Code an, der den bereits bekannten Code aus dem ersten Programm um ein paar interessante Teile erweitert:

#include <iostream>
#include "SDL.h"
 
// Unbedingt mit argc und argv, da es sonst
// mit MinGW wahrscheinlich nicht kompiliert.
int main( int argc, char **argv )
{
  // Video und Timersubsystem initialisieren
  if( SDL_Init( SDL_INIT_VIDEO | SDL_INIT_TIMER ) )
  {
    // Irgendwas ist schiefgegangen. SDL_GetError weiß mehr
    std::cerr << "Konnte SDL nicht initialisieren: " << SDL_GetError() << std::endl;
    return 1;
  }
 
  // SDL_Quit registrieren
  atexit(&SDL_Quit);
 
  // Ein Fenster erstellen
  SDL_Surface *screen = SDL_SetVideoMode( 800, 600, 32, SDL_DOUBLEBUF );
 
  if( !screen )
  {
    std::cerr << "Konnte Videomodus nicht setzen: " << SDL_GetError() << std::endl;
    return 1;
  }
 
  SDL_Event event;
 
  // Auf Events warten
  while( SDL_WaitEvent(&event) )
  {
    switch( event.type )
    {
      // Programm sollte beendet werden ('x' im Fenster wurde geklickt)
      case SDL_QUIT:
        return 0;
    }
  }
 
  // Wenn SDL_WaitEvent 0 zurück gibt dann ist ein Fehler aufgetreten...
  std::cerr << "Fehler in der Nachrichtenbehandlung: " << SDL_GetError() << std::endl;
  return 1;
}

Das Fenster erstellen

Als erstes fällt sofort die Zeile mit SDL_SetVideoMode auf. Diese Funktion dient dazu den Videomodus zu setzen oder wenn wir keinen Vollbildmodus verwenden ein Fenster mit den entsprechenden Maßen zu erstellen. Unser Fenster sollte also eine Auflösung von 800×600 Pixeln bei 32 Bits pro Pixel haben. Wir können bei diesen drei Werten auch 0 angeben, wodurch dann die entsprechenden Werte der aktuellen Auflösung verwendet werden. Als letzten Parameter geben wir noch eine Kombination aus Flags an. Wir geben hier vorerst einmal nur SDL_DOUBLEBUF an, was bewirkt das wir einen zweiten Bildpuffer erhalten der genau die gleiche Größe hat wie unser Fenster. Der Sinn ist das wir dann immer auf den nicht sichtbaren Puffer zeichnen und dann die beiden Puffer vertauschen, so dass man nicht den Aufbau des Bildes erkennen kann sondern nur direkt das fertige Bild zu sehen bekommt. Wenn das Erstellen des Fenster fehlgeschlagen ist dann bekommen wir NULL zurück, worauf wir einfach einen Fehler ausgeben und das Programm beenden. Wir könnten hier aber auch einfach versuchen ob es mit anderen Parametern vielleicht doch funktioniert. Für weitere Flags und Erklärungen einfach unter SDL_SetVideoMode in der Referenz nachschauen.

Nachrichten behandeln

Das SDL Eventsystem

Anschließen kommt im Code ein sehr wichtiger Datentyp vor nämlich SDL_Event. Dieser Datentyp beschreibt eine Nachricht die das Betriebssystem bzw. der Fenstermanager an unsere Anwendung zu bestimmten Anlässen verschickt. Diese Events, oder auch Messages genannt, werden auf die sogenannte Message- oder Eventqueue gelegt, von der wir mit dann die Nachrichten herausholen können.

In der Grafik auf der rechten Seite können wir diesen Ablauf gut erkennen. Dabei kommen vom Betriebssystem oder Fenstermanager systemspezifische Nachrichten bei der SDL an, die diese dann in plattformunabhängige Nachrichten von Typ SDL_Event umwandelt. Anschließend werden diese auf eine FIFO-Queue 1) gelegt, aus der wir dann uns die Nachrichten holen können.

Polling oder auf Nachrichten warten

Jetzt haben wir zwei Möglichkeiten an diese Nachrichten zu gelangen. Entweder wir holen uns die älteste Nachricht aus der Queue mit SDL_WaitEvent bzw. falls es keine Nachricht gibt warten wir so lange bis eine kommt, oder wir verwenden SDL_PollEvent, welches sofort zurückkehrt auch wenn keine Nachrichten vorhanden sind.

Da wir bei diesem einfachen Programm noch keine Interaktion eingebaut haben reicht es wenn wir solange keine Nachrichten vorhanden sind einfach nichts tun, weshalb wir hier SDL_WaitEvent verwenden. Als Parameter erwartet SDL_WaitEvent eine Referenz auf eine SDL_Event Struktur, die bei eintreffen eines Events entsprechend gefüllt wird. In der Membervariablen 'type' steht dann der Typ der Nachricht, wobei wir hier vorerst nur auf 'SDL_QUIT' prüfen, welche gesendet wird wenn das Programm beendet werden soll, was der Fall ist wenn zum Beispiel das Fenster über einen Klick auf das 'X' geschlossen wird. Dannach könnten wir noch wichtige Daten speichern und sollten dann das Programm beenden, was wir auch mit dem 'return 0' machen.

Jetzt sind wir wieder einen großen Schritt weiter gekommen und gehen gleich weiter und laden ein Bild welches wir dann natürlich auch anzeigen werden.


Ein erstes Programm mit der SDL ← | ↑ SDL Start ↑ | → Bitmap Grafiken anzeigen und laden

Diskussion

1)
First In - First Out: Die erste Nachricht die in der Schlange steht kommt auch als erstes wieder heraus