Fragen zu SDL-Beispielen

Simple Directmedia Layer: Portable Spieleprogrammierung
Antworten
nufan
Wiki-Moderator
Beiträge: 2448
Registriert: Sa Jul 05, 2008 3:21 pm

Fragen zu SDL-Beispielen

Beitrag von nufan » Fr Dez 26, 2008 11:14 pm

So, nun ist es soweit, ich kapier ein Programm nicht :)

Zuerst der Code:

Code: Alles auswählen

#include <SDL/SDL.h>
#include <stdio.h>
#include <stdlib.h>


Uint16 CreateHicolorPixel (SDL_PixelFormat *fmt, Uint8 red, Uint8 green, Uint8 blue);


int main ()
{

  SDL_Surface *screen;
  Uint16 *raw_pixels;
  int x, y;
  
  
  if (SDL_Init (SDL_INIT_VIDEO) != 0)
  {
  
    printf ("Unable to initialize SDL: %s\n", SDL_GetError ());
    
    return 1;
  
  }
  
  
  screen = SDL_SetVideoMode (256, 256, 16, 0);
  
  if (screen == NULL)
  {
  
    printf ("Unable to set video mode: %s\n", SDL_GetError ());
    
    return 1;
  
  }
  
  
  SDL_LockSurface (screen);
  
  raw_pixels = (Uint16 *) screen -> pixels;
  
  
  for (x = 0; x < 256; x++)
  {
  
    for (y = 0; y < 256; y++)
    {
    
      Uint16 pixel_color;
      int offset;
      
      pixel_color = CreateHicolorPixel (screen -> format, x, 0, y);
      
      offset = (screen -> pitch /2 * y + x);
      
      raw_pixels [offset] = pixel_color;  
    
    }
  
  }
  
  
  SDL_UnlockSurface (screen);
  
  SDL_UpdateRect (screen, 0, 0, 0, 0);
  
  SDL_Delay (3000);
  
  
  return 0;

}


Uint16 CreateHicolorPixel (SDL_PixelFormat *fmt, Uint8 red, Uint8 green, Uint8 blue)
{

  Uint16 value;
  
  value = ((red >> fmt -> Rloss) << fmt -> Rshift) +
          ((green >> fmt -> Gloss) << fmt -> Gshift) +
          ((blue >> fmt -> Bloss) << fmt -> Bshift);

  return value;          

}
Ich versuchs jetzt mal selbst...

Code: Alles auswählen

  SDL_Surface *screen;
  Uint16 *raw_pixels;
  int x, y;
Das erste und das letzte sind klar, aber was ist das für ein Pointer?

Die ifs sind klar. Dann das Surface sperren um es bearbeiten zu können.

Code: Alles auswählen

  raw_pixels = (Uint16 *) screen -> pixels;
Hängt wohl sehr mit der ersten Frage zusammen ;)
Jedenfalls werden die Pixel-Informationen von screen gecastet und raw_pixels zeigt dann auf diese Informationen.

Code: Alles auswählen

  for (x = 0; x < 256; x++)
  {
  
    for (y = 0; y < 256; y++)
    {
    
      Uint16 pixel_color;
      int offset;
      
      pixel_color = CreateHicolorPixel (screen -> format, x, 0, y);
      
      offset = (screen -> pitch /2 * y + x);
      
      raw_pixels [offset] = pixel_color;  
    
    }
  
  }
Wieder so ein Uint16... ist das Farbe oder was?
Jedenfalls werden danach die Format-Informationen von screen, x und y Koordinaten an die Funktion übergeben. Die Werte stehen wahrscheinlich für die Farben. Grün bleibt 0 (auch am Ergebnis ersichtlich.).
offset ist wahrscheinlich die Nummer des Pixels und dieses Pixel bekommt dann die Farbe. Den Rest von main versteh ich auch.

Aber dann die Funktion...

Code: Alles auswählen

Uint16 CreateHicolorPixel (SDL_PixelFormat *fmt, Uint8 red, Uint8 green, Uint8 blue)
{

  Uint16 value;
  
  value = ((red >> fmt -> Rloss) << fmt -> Rshift) +
          ((green >> fmt -> Gloss) << fmt -> Gshift) +
          ((blue >> fmt -> Bloss) << fmt -> Bshift);

  return value;          

}
Es wird wieder so eine Farbvariable (ich nenns halt mal so ^^) deklariert. Von den nächsten 3 Zeilen versteh ich 0. Laut Buch werden da irgendwelche Bits verschoben. Aber kann mir das bitte jemand im Detail erklären? Bis jetzt hab ich so was noch nie verwendet.
Und dann wird value zurückgegeben. Das ist dann die Farbe des Pixels in main mit dem Index offset.

Wenn ich irgendwas falsch verstanden habe, bitte korrigieren :)


Vollständigkeitshalber hier der Downloadlink zu einem Archiv mit allen Beispielcodes vom Buch:
http://nostarch.com/plg.htm
source listings ist das Archiv mit den Codes. Dann auf SDL und listing4-2.c.


PS: Die Betreff ist absichtlich in der Mehrzahl formuliert, da dies sicher nicht die letzte Frage ist :)


EDIT: Hier sieht man den ungefähren Code mit Kommentaren und dem Ergebnis.

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8489
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Fragen zu SDL-Beispielen

Beitrag von Xin » Sa Dez 27, 2008 9:52 am

dani93 hat geschrieben:So, nun ist es soweit, ich kapier ein Programm nicht :)
Ich versuchs jetzt mal selbst...

Code: Alles auswählen

  SDL_Surface *screen;
  Uint16 *raw_pixels;
  int x, y;
Das erste und das letzte sind klar, aber was ist das für ein Pointer?

Code: Alles auswählen

  raw_pixels = (Uint16 *) screen -> pixels;
Hängt wohl sehr mit der ersten Frage zusammen ;)
Jedenfalls werden die Pixel-Informationen von screen gecastet und raw_pixels zeigt dann auf diese Informationen.
Du arbeitest mit einer HiColor-Grafik (16Bit). Also hat jeder Pixel eine 16 Bit Farbinformation.

dani93 hat geschrieben:Es wird wieder so eine Farbvariable (ich nenns halt mal so ^^) deklariert. Von den nächsten 3 Zeilen versteh ich 0. Laut Buch werden da irgendwelche Bits verschoben. Aber kann mir das bitte jemand im Detail erklären? Bis jetzt hab ich so was noch nie verwendet.
Und dann wird value zurückgegeben. Das ist dann die Farbe des Pixels in main mit dem Index offset.
Du machst aus den einelnen Farbwerten einen Integer-Farbwert, der dann in die Bitmap geschrieben werden kann.
dani93 hat geschrieben:PS: Die Betreff ist absichtlich in der Mehrzahl formuliert, da dies sicher nicht die letzte Frage ist :)
Soweit kann ich vielleicht helfen, ansonsten, bitte ich auch Dich, Deine Erfahrungen ins Wiki zu setzen.
Ich bin jetzt seit 30 Stunden auf Tour... die Pixelgeschichte erkläre ich dann lieber ein andermal, falls da Bedarf besteht ;-)
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

nufan
Wiki-Moderator
Beiträge: 2448
Registriert: Sa Jul 05, 2008 3:21 pm

Re: Fragen zu SDL-Beispielen

Beitrag von nufan » Sa Dez 27, 2008 1:46 pm

Xin hat geschrieben:Also hat jeder Pixel eine 16 Bit Farbinformation.
D. h. ich habe 65536 (2^16) Farben, oder? Die 65536 könnte man dann als eine zweidimensionale Matrix sehen (Farbpalette). Das würde dann auch die Schleife erklären (256 * 256 = 65536). So bekomm ich dann jede Farbe.

Aber wie bekomm ich Grün? 16 Bit = 5 Bit Rot, 6 Bit Grün und 5 Bit Blau (im Normalfall). Dann wäre es dreidimensional... Vorher dann auch, aber da war Grün immer 0.
Dann bräuchte ich noch eine Schleife z mit 256. 256 * 256 * 256 = 16 777 216, was aber schon 2^24 (24 Bit) entspricht... *verwirrt*
Aber wenn ich die 16 Bit auf drei aufteile, kann ich nicht 3 mal 8 Bit (256) nehmen. Dann wären es 32, 64 und 32. *noch mehr verwirrt*

Sehe ich das alles zu kompliziert? Fange ich zu fantasieren an? Wahrscheinlich ist es so einfach, dass ich es nicht versteh...
Xin hat geschrieben:Du machst aus den einelnen Farbwerten einen Integer-Farbwert, der dann in die Bitmap geschrieben werden kann.
Sowas hab ich mir schon gedacht. Müsste dann eine Zahl zwischen 0 und 65536 sein, oder?

Aber was genau hier

Code: Alles auswählen

  value = ((red >> fmt -> Rloss) << fmt -> Rshift) +
          ((green >> fmt -> Gloss) << fmt -> Gshift) +
          ((blue >> fmt -> Bloss) << fmt -> Bshift);
passiert versteh ich immer noch nicht.
Xin hat geschrieben:Soweit kann ich vielleicht helfen, ansonsten, bitte ich auch Dich, Deine Erfahrungen ins Wiki zu setzen.
Zuerst muss ich das erst selbst einmal verstehen ;)
Xin hat geschrieben:die Pixelgeschichte erkläre ich dann lieber ein andermal, falls da Bedarf besteht ;-)
Denke schon :)

Benutzeravatar
Kerli
Beiträge: 1456
Registriert: So Jul 06, 2008 10:17 am
Wohnort: Österreich
Kontaktdaten:

Re: Fragen zu SDL-Beispielen

Beitrag von Kerli » Sa Dez 27, 2008 4:49 pm

dani93 hat geschrieben:
Xin hat geschrieben:Also hat jeder Pixel eine 16 Bit Farbinformation.
D. h. ich habe 65536 (2^16) Farben, oder? Die 65536 könnte man dann als eine zweidimensionale Matrix sehen (Farbpalette). Das würde dann auch die Schleife erklären (256 * 256 = 65536). So bekomm ich dann jede Farbe.
Du hast einfache ein Array aus 16 Bit Integern (Uint16 ist nur ein typedef für einen 16 Bit unsigned short). Jeder dieser Pixel hat nun einen der 65536 codierten Farbwerte.

Die Schleife hat jedoch nichts damit zu tun, sondern du hast ja ein Fenster der Größe 256 * 256 Pixeln angelegt, und tust in dieser Schleife nun die Farbe jedes einzelnen Pixel setzen.
dani93 hat geschrieben:Aber wie bekomm ich Grün? 16 Bit = 5 Bit Rot, 6 Bit Grün und 5 Bit Blau (im Normalfall).
[...] Sehe ich das alles zu kompliziert? Fange ich zu fantasieren an? Wahrscheinlich ist es so einfach, dass ich es nicht versteh...
Ich glaube du siehst es zu kompliziert ;) Es stimmt schon so wie du es geschrieben hast. Die Aufteilung wie viel Bit jede Farbkomponente hat bzw. eine dazugehörige Bitmaske enthält die Struktur 'SDL_PixelFormat'.
dani93 hat geschrieben: Aber was genau hier

Code: Alles auswählen

  value = ((red >> fmt -> Rloss) << fmt -> Rshift) +
          ((green >> fmt -> Gloss) << fmt -> Gshift) +
          ((blue >> fmt -> Bloss) << fmt -> Bshift);
passiert versteh ich immer noch nicht.
Hier tust du dir aus den einzelnen 8-Bit Farbkomponenten eine 16-Bit Farbe zusammenstellen. Hier noch ein Beispiel für die rote Komponente:

Code: Alles auswählen

Uint8 red = 90; // 01011010
// fmt -> Rloss == 3 (3 stellen Genauigkeitsverlust, wenn rot 5 Bit hat)
red = red >> fmt -> Rloss; // um 3 Bit nach rechts schieben (die letzten 3 Bit werden abgeschnitten)
// red == 000 01011 (010 -> abgeschnittener Rest)

// rote Farbkomponente an die richtige Stelle im Ergebniswert schieben (fmt -> Rshift == 11 == Anteil grün + Anteil blau)
Uint16 color = red << fmt -> Rshift; //  color == (abgeschnitten -> 000) 01011 000000 00000
"Make it idiot-proof and someone will invent an even better idiot." (programmers wisdom)

OpenGL Tutorials und vieles mehr rund ums Programmieren: http://www.tomprogs.at

nufan
Wiki-Moderator
Beiträge: 2448
Registriert: Sa Jul 05, 2008 3:21 pm

Re: Fragen zu SDL-Beispielen

Beitrag von nufan » Sa Dez 27, 2008 5:21 pm

Kerli hat geschrieben:Du hast einfache ein Array aus 16 Bit Integern (Uint16 ist nur ein typedef für einen 16 Bit unsigned short). Jeder dieser Pixel hat nun einen der 65536 codierten Farbwerte.
Und in diesem Array stehen nur Binärwerte?
Kerli hat geschrieben:Hier tust du dir aus den einzelnen 8-Bit Farbkomponenten eine 16-Bit Farbe zusammenstellen.
Also ich schneide einfach den Teil weg, damit ich auf die gewünschten 5 bzw. 6 Bit komme und füge sie dann in einem Uint16 zusammen?
Und dieses Rshift gibt einfach die Position der Bifolge an? Ich nehme an in die typische RGB-Folge.

Und in meinem Beispiel bleibt dann bei Grün einfach immer 0, da hilft kein verschieben ;)

Ich glaube langsam komm ich der Lösung nahe :)

Benutzeravatar
Kerli
Beiträge: 1456
Registriert: So Jul 06, 2008 10:17 am
Wohnort: Österreich
Kontaktdaten:

Re: Fragen zu SDL-Beispielen

Beitrag von Kerli » Sa Dez 27, 2008 5:38 pm

dani93 hat geschrieben:
Kerli hat geschrieben:Du hast einfache ein Array aus 16 Bit Integern (Uint16 ist nur ein typedef für einen 16 Bit unsigned short). Jeder dieser Pixel hat nun einen der 65536 codierten Farbwerte.
Und in diesem Array stehen nur Binärwerte?
Ja, und diese Werte werden als die Farben des jeweiligen Pixels interpretiert. Es sind also immer 16 Bit die eine Farbe bestimmen und dabei eben 5 Bit Rot bzw. Blau und 6 Bit für Grün.
dani93 hat geschrieben:
Kerli hat geschrieben:Hier tust du dir aus den einzelnen 8-Bit Farbkomponenten eine 16-Bit Farbe zusammenstellen.
Also ich schneide einfach den Teil weg, damit ich auf die gewünschten 5 bzw. 6 Bit komme und füge sie dann in einem Uint16 zusammen?
Und dieses Rshift gibt einfach die Position der Bifolge an? Ich nehme an in die typische RGB-Folge.

Und in meinem Beispiel bleibt dann bei Grün einfach immer 0, da hilft kein verschieben ;)
Genau :)
"Make it idiot-proof and someone will invent an even better idiot." (programmers wisdom)

OpenGL Tutorials und vieles mehr rund ums Programmieren: http://www.tomprogs.at

nufan
Wiki-Moderator
Beiträge: 2448
Registriert: Sa Jul 05, 2008 3:21 pm

Re: Fragen zu SDL-Beispielen

Beitrag von nufan » Sa Dez 27, 2008 6:00 pm

Ich glaube ich habs kapiert :)

Danke für die Erklärung.

Antworten