Lesen von Pixeln aus der OpenGL / GLUT-Anwendung

8

Ich habe eine Anwendung, die OpenGL und GLUT verwendet, um etwas auf dem Bildschirm anzuzeigen. Ich würde gern auf die Farben zugreifen, die "Pixel für Pixel" angezeigt werden, aber ich habe Probleme, die zur Verfügung gestellten Methoden zu verstehen.

Der Zugang zu solchen Daten scheint mit der Funktion zu funktionieren: %Code% Das ist entschieden nicht-Haskelly, da es das C-Muster verwendet, einen Zielzeiger zu nehmen und auf diesen Zeiger zu schreiben.

Das dritte Argument ist der wichtige Teil und wird wie readPixels :: Position -> Size -> PixelData a -> IO () konstruiert. PixelData PixelFormat DataType (Ptr a) und PixelFormat sind beide Enums, wobei erstere Werte wie DataType und letztere Werte wie RGBAInteger, RGBA, CMYK, etc annimmt. Die Auswahl ist verwirrend für mich, aber das ist nicht das eigentliche Problem. Wo ich wirklich mit dem Zeiger kämpfe. Ich habe keine Ahnung, welche Art von UnsignedByte, Short, Float, etc. Daten zu Storable den Zeiger zu erstellen, oder wie viele Bytes zuzuweisen, wenn ich malloc verwenden.

Ich habe eine Funktion, mit der ich herumspiele, die momentan ungefähr so ​​aussieht:

%Vor%

Es läuft gut, ich habe keine Ahnung, wie ich die Daten verwenden soll, die ich von mallocBytes bekomme. Vielleicht verstehe ich die Dokumentation nicht vollständig, aber wie kann ich die Art der Daten am Zeiger bestimmen und wie kann ich sie in meinem Programm verwenden? Beachten Sie, dass meine Auswahl der Argumente Ptr und RGBA willkürlich war, sie klang einfach harmlos genug. Was ich wirklich will, ist eine Liste oder mehrdimensionale Liste von RGBA-Pixelwerten in einem bestimmten Format ( Int oder etwas in dieser Art). Jede Hilfe würde sehr geschätzt werden, ich scheine in meinem Kopf zu sein.

    
Sam Stern 09.01.2013, 01:22
quelle

2 Antworten

7

Sie verwenden Low-Level-Bindungen, seien Sie nicht überrascht, dass sie Low-Level-Bindungen sind. readPixels entspricht direkt glReadPixels (sie verwenden MathML, verwenden Sie also ein Browser, der es unterstützt , um es anzuzeigen).

Was Sie zurückbekommen, ist ein Array von 32-Bit-Ganzzahlen, von denen jede einen RGBA-Farbwert enthält. Sie benötigen dazu nur width * height * 4 bytes, Sie haben viel zu viel.

Das Auslesen wird von FFI-Maschinen ziemlich einfach gemacht - es liefert peekArray , das verwendet werden kann, um die Pixeldaten in eine Haskell-Liste zu extrahieren. Sie müssen auch mit einem Zeiger vom richtigen Typ arbeiten. mallocBytes gibt einen Zeiger vom speziellen Typ zurück, der void* entspricht. Ich benutze ForeignPtr , so dass Runtime sich um die Fertigstellung kümmert (mit mallocBytes müsstest du castPtr und auch bracket benutzen, um Ausnahmen zu berücksichtigen).

%Vor%

Jetzt haben Sie ein eindimensionales Array von Farbwerten. Wir können es auf einen Typ wie diesen aufteilen:

%Vor%     
Cat Plus Plus 09.01.2013, 13:16
quelle
1

Hier ist eine Version, die das Bild in ein JuicyPixels Bild liest, das leicht in einer PNG-Datei usw. gespeichert werden kann:

%Vor%     
yairchu 05.04.2016 11:49
quelle

Tags und Links