Login
Immer anmelden
SSL Login

 
Newsletter
Werbung
Shopping
International Shopping
 
 


Yatego Shopping bei über 10000 Händlern und über
3 Mio. Artikel.


Linux

:

Linux-Bücher

Handy
Shop

  und Computer.

Viele Services

:

Apple iPad Reader,


Ratgeber,

 

Techniktops,

 

Yatego Clicks

  & über 3000

Gutscheine.

 
Fr, 2. August 2002, 00:00

Multimedia-Entwicklung mit SDL

Bilder anzeigen

SDL kann ohne zusätzliche Bibliotheken nur Bitmapbilder anzeigen. Dies reicht im Normalfall nicht aus. Deshalb weise ich bereits jetzt auf die Standardbibliothek SDL_image hin, die wir auch gleich verwenden werden:

Anmerkung: Bild tux.jpg kann HIER heruntergeladen werden

#include "sdl_image.h"
[...]
SDL_Surface *image;
[...]
image = IMG_Load("tux.jpg");
if (image == NULL)
{
 fprintf(stderr, "Das Bild konnte nicht geladen werden:%s\n",
 SDL_GetError());
 exit(-1);
}
// kopiere das Bild-Surface auf das display-surface
SDL_BlitSurface(image, NULL, display, NULL);
// den veraenderten Bereich des display-surface auffrischen
SDL_Flip(display);
SDL_Delay(3000);
// Das Bitmap-Surface löschen
SDL_FreeSurface(image);
[...]

Die Funktion IMG_Load() wird von sdl_image bereit gestellt. Dies erfordert, dass man SDL_image.h inkludiert und dem Linker ein "-lSDL_image" als Flag mitgibt, wie bei der libsdl oben bereits beschrieben.

Wir deklarieren ein neues Surface mit dem Namen "image". Mittels IMG_Load() weisen wir diesem neuen Surface dann das gewünschte Bild zu. Diese Surface hat nun die Größe der geladenen Grafik.

Da wir meist mehr über die Surfaceformatierung erfahren wollen, wie zum Beispiel die Größe und Farbtiefe, hier die interne Struktur des Surfaces:

typedef struct SDL_Surface {
// allgemeine Surface-Informationen
 Uint32 flags; // Read-only
 SDL_PixelFormat *format; // Read-only
 int w, h; // Read-only
 Uint16 pitch; // Read-only
 void *pixels; // Read-write
 int offset; // Private
// hardwarespezifisches Surface-Informationen
 struct private_hwdata *hwdata;
// Clipping-Informationen
 int clip_minx; // Read-only
 int clip_maxx; // Read-only
 int clip_miny; // Read-only
 int clip_maxy; // Read-only
// surface-interne Kopierinformationen
 struct SDL_BlitMap *map; // Private
// Liste der surfaces
 struct map_list *mapped; // Private
// Reference-Counter
 int refcount; // Read-mostly
} SDL_Surface;

In der Struktur des Surfaces wird über die Integer-Werte w und h, die Breite und die Höhe gespeichert. Zu Kontrollzwecken wird man daher oft z.B. "image->w" und "image->h" mit ausgeben, um über die zu ändernde Bildgröße informiert zu sein.

Nachdem das Bild nun in sein eigenes Surface geladen wurde, und wir vorerst keine weiteren Veränderungen mehr daran vornehmen wollen, müssen wir es auf das display-surface kopieren. Dies geschieht über SDL_BlitSurface(). BlitSurface nimmt als Parameter:

SDL_BlitSurface(QuellSurface, Quellbereich, ZielSurface, Zielbereich)

Die Parameter Quell- und Zielbereich werden später genauer erklärt, wenn wir die Grafikroutinen intensiver nutzen. Wir gebrauchen SDL_BlitSurface() im Moment so, dass wir als Parameter für die Bereiche einfach 0 übergeben und somit das gesamte Surface kopiert wird.

Als letzten Schritt wollen wir nun das durch das Blitting veränderte display-surface auch zur Anzeige bringen. Die einfachste Möglichkeit ist, dies durch int SDL_Flip(SDL_Surface *display) zu machen. Hierbei wird (wie schon beim Blit) einfach das gesamte display-surface neu geladen.

Um das Programm speichertechnisch sauber beenden zu lassen, rufen wir für alle Surfaces (außer dem display) die Funktion SDL_FreeSurface() auf, um den allokierten Speicher dafür wieder frei zu geben.

Bildbereiche

Wie bereits im letzten Kapitel kurz angeschnitten, sind im SDL-Grafikbereich sogenannte "rectangular areas" (dt.: rechteckige Bereiche) von wichtiger Bedeutung. Diese (kurz) SDL_Rects sind einfache Strukturen, die Positionen und Größenangaben gespeichert haben:

typedef struct {
 Sint16 x, y;
 Uint16 w, h;
} SDL_Rect;

Zur Erklärung der Struktur:

Die signed Integers x und y sind Positionsangaben auf dem Bildschirm, beginnend in der linken oberen Ecke mit 0,0. x kann den Maximalwert display->w und y display->h annehmen, also die maximale Grösse des display-surfaces. w und h sind wie bereits gehabt die Ausschnittsgrössen.

Für was benötigt man also die SDL_Rects? Die Antwort ist eigentlich klar. Wir wollen nicht immer (wie im letzten Beispiel) das ganze Surface kopieren oder updaten. Schon aus Performancegründen ist es unsinnig, das komplette Display zu refreshen oder ein komplettes Surface x-mal zu kopieren, wenn es sich nur um ein paar Pixel großes Bild handelt, was dargestellt werden soll.

Wir nehmen wieder unser Beispiel zu Hand, und kopieren das halbe Bild mit Hilfe von SDL_Rects etwas eingerückt (200x100 Pixel) auf das display-surface. Danach updaten wir nur den auf dem display wirklich durch den Blit geänderten Bereich: wieder durch SDL_Rects.

Anmerkung: Bild tux.jpg kann HIER heruntergeladen werden

Kommentare (Insgesamt: 0 || Kommentieren )
Pro-Linux
Newsletter
Neue Nachrichten