Screenshot
Inhaltsverzeichnis
Screenshot erstellen
Einleitung
Ein Screenshot ist ein Abbild des aktuellen Bildschrim Inhaltes. In dem Falle von OpenGL greifen wir aber nicht auf das Fenster zurück sondern auf den Framebuffer. Neben dem eigentlichen Vorgang, nämlich der Besorgung der Bilddaten, ist meißtens auch noch sinnvoll diese erworbenen Daten dem Benutzer verfügbar zu machen. Dies geschieht meistens in Form einer Bild-Datei oder in Form eines Eintrages in der Zwischenablage.
Bilddaten besorgen
Mit Hilfe des glReadPixels Befehl kann der Framepuffer ausgelesen werden. Für einen Screenshot sind meißtens die RGB-Werte interessant. Bei diesen Werten ergibt sich auch schon das erste Problemm OpenGL speichert die Daten in der Reinfolge Rot Grün Blau, wärend es in vielen Bildformaten üblich ist die Daten in der Reinfolge Blau Grün Rot zu speichern. Glücklicherweise kann man in aktuellen OpenGL Versionen glReadPixels anweisen die Daten auch in dieser Reinfolge zu liefern.
Der glReadPixels Befehl für neue Grafikarten könnte in etwa so aussehen:
// ungünstige Reinfolge Rot Grün Blau glReadPixels( 0, 0, Breite, Hoehe, GL_RGB, GL_UNSIGNED_BYTE, Daten ); // auf neuren Grafikarten: glReadPixels( 0, 0, Breite, Hoehe, GL_BGR, GL_UNSIGNED_BYTE, Daten );
Was die einzelen Parameter bedeuten könnt, ihr im glReadPixels Artikel nachlesen. Es sei hier nur gesagt das das letzte Argument der Speicherplatz ist, an den OpenGL die Daten abspeichern soll(meißt ein Pointer teilweise auch ein Array).
Speichern im TGA Format
Eine TGA-Datei hat einen relativ einfachen Aufbau. Als erstes kommen Header-Informationen und dannach die Daten. Der Header sieht so aus:
type TTGAHEADER = packed record tfType : Byte; tfColorMapType : Byte; tfImageType : Byte; tfColorMapSpec : Array[0..4] of Byte; tfOrigX : Word; //Array [0..1] of Byte; tfOrigY : Word; tfWidth : Word; tfHeight : Word; tfBpp : Byte; tfImageDes : Byte; end;
Nun zur Speicherfunktion für ein Screenshot ohne Alpha Wert
procedure ScreenShot(const Name : string); var DataBuffer : array of Byte; f : file; tgaHeader : TTGAHEADER; width, height : integer; DataSize:Integer; viewport : Array[0..3] of integer; begin glGetIntegerv(GL_VIEWPORT, @viewport); width := viewport[2]; height := viewport[3]; DataSize := ffWidth * ffHeight * 3; SetLength(DataBuffer,DataSize); // TGA Kopf mit Daten füllen ZeroMemory(@tgaHeader, SizeOf(tgaHeader)); tgaHeader.tfImageType := 2; // TGA_RGB = 2 tgaHeader.tfWidth := Width tgaHeader.tfHeight := Height; tgaHeader.tfBpp := 24; glReadPixels(0,0,Width, Height, GL_BGR, GL_UNSIGNED_BYTE, @DataBuffer[0]); //Datei erstellen AssignFile(f, Name); Rewrite( f,1 ); try // TGA Kopf in die Datei reinschreiben BlockWrite(F, tgaHeader, SizeOf(tgaHeader)); // Die eigentlichen Bilddaten in die Datei schreiben BlockWrite(f, DataBuffer[0], DataSize ); finally CloseFile(f); end; end;