Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Do Mai 13, 2021 17:04

Foren-Übersicht » Programmierung » Einsteiger-Fragen
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 3 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: Kommentar zu ~ / Fehler in glBitmap
BeitragVerfasst: Mo Apr 12, 2021 15:48 
Offline
DGL Member

Registriert: Mo Jul 17, 2006 13:16
Beiträge: 67
Zunächst auf jeden Fall einen Herzlichen Dank an Lossy eX und Bergmann89 für die hervorragene Arbeit an und mit glBitmap und allem drumherum! Ohne diese Unit würde "es" bei mir definitiv nicht gehen, und ich betrachte sie als einen essentiellen Bestandteil von OpenGL im Delphi-Bereich.

Nachdem ich nun nach vielen Jahren endlich dazu komme, auf die aktuelle Version von dglOpenGL und glBitmap umzusteigen, hatte ich natürlich wieder mit ein paar Einsteiger-Fragen zu kämpfen, die sich aber in sofern klären ließen, dass man "nur" verstehen muss, dass TglBitmap2D und TglBitmapData nun getrennt voneinander sind, man TglBitmapData nur temporär zum laden/speichern/verändern der Textur benötigt, und "GenTexture" scheinbar automatisch im Hintergrund passiert.

Ich möchte gerne Anmerkungen machen, wie man die Unit für den (Neu-) Einstieg verbessern sollte:

-Aktiviert man in der .inc Datei
Code:
  1. {$DEFINE OPENGL_ES_1_1}
oder neuere Erweiterungen, ist die Prozedur DownloadData nicht mehr verfügbar. Das liegt natürlich an
Code:
  1. {$IFNDEF OPENGL_ES}
  2.     { download texture data from video card and store it into given data object
  3.         @returns @true when download was successfull, @false otherwise }
  4.     function DownloadData(const aDataObj: TglBitmapData): Boolean; virtual;
  5. {$ENDIF}
, was laut Compiler-Schalter also diese Prozedur deaktiviert. Technisch hat das sicherlich seine Richtigkeit oder zumindest Notwendigkeit, rein Menschen-Logisch ist das eher blöd. Ich weiß jetzt natürlich nicht, was genau der Unterschied zwischen OpenGL ES 1.1, 2.0, 3.0 und "ohne" ist, aber ich denke zunächst, das sind Erweiterungen, die mir mehr ermöglichen - sofern die Hardware das mitmacht. Dass man mit einer "Erweiterung" eine Kernfunktionalität deaktiviert, ist kontra-intuitiv. Ich arbeite (nun) komplett ohne irgendwelche OPENGL_ES, und alles geht - in sofern kein Problem. (Jaja, nicht einfach alles aktivieren, von dem man nicht weiß, was es macht, aber irgendwas muss ich ja aktivieren, um die Unit zum laufen zu bekommen, wenn man noch nicht so tief in der Materie ist...)

-Genau wie andere Entwickler habe ich auch das Problem (https://delphigl.com/forum/viewtopic.php?f=14&t=7457&start=120), dass an vielen Stellen die notwendigen Farbformate nicht gefunden werden. Als Beispiel habe ich in der .inc nur GLB_PNGIMAGE und GLB_DELPHI_JPEG definiert. Natürlich kann man sich helfen, indem man die entsprechenden Zeilen der glBitmap.pas auskommentiert, die sich nicht kompilieren lassen. Falls irgendwann die Unit mal wieder überarbeitet wird, wäre es für alle (Neu-)Einsteiger hervorragend, wenn an den verschiedenen Stellen nur auf die Farbformate etc. Bezug genommen wird, die laut "Define" tatsächlich bekannt sind. D.h. dass der berühmte Problemabschnitt z.B. mit "$IFDEF" eine Umrahmung bekommt. Da ich in diesem Fall die konkrete Abhängigkeit nicht kenne, kann ich hierfür keine bespielhafte Lösung anbieten, sondern nur die Idee:
Code:
  1.     procedure TglBitmapData.SavePNG(const aStream: TStream);
  2.     var
  3.       Png: TPNGObject;
  4.      
  5.       pSource, pDest: pByte;
  6.       X, Y, PixSize: Integer;
  7.       ColorType: Cardinal;
  8.       Alpha: Boolean;
  9.      
  10.       pTemp: pByte;
  11.       Temp: Byte;
  12.     begin
  13.       if not (ftPNG in FormatGetSupportedFiles (Format)) then
  14.         raise EglBitmapUnsupportedFormat.Create(Format); // dieser Exceptiontyp ist glaube ich auch nirgendwo definiert und sollte mit IFDEF umgeben werden
  15.      
  16.       case Format of
  17.         tfAlpha8ub1, tfLuminance8ub1: begin
  18.           ColorType := COLOR_GRAYSCALE;
  19.           PixSize   := 1;
  20.           Alpha     := false;
  21.         end;
  22.         {$IFDEF KEINE_AHNUNG_WAS}
  23.         tfLuminance8Alpha8us1: begin   //<= gibt es nicht
  24.           ColorType := COLOR_GRAYSCALEALPHA;
  25.           PixSize   := 1;
  26.           Alpha     := true;
  27.         end;
  28.         {$IFEND}
  29. [...]


-Das nächste und vorläufig letzte was ich anmerken möchte, scheint tatsächlich ein Bug zu sein:
Ich möchte meine bearbeitete Textur wieder auf der Festplatte speichern. Sehen wir mal von der Tatsache ab, dass ich kein Grafiker und auch kein OpenGL-Profi bin, und mit den ganzen verschiedenen Farbformaten, Pixelformaten etc. nichts anzufangen weiß. Durch try-and-error wandele ich nach DownloadData die TglBitmatData mit ConvertTo so um, dass ich mit SaveToFile(_Filename, TglBitmapFileType.ftPNG) als PNG bzw. ftJPEG=JPG speichern kann. Problem: Mit allen bei "TglBitmapData.SavePNG" akzeptierten Formaten schaffe ich es nicht, ein "normales" .png zu erzeugen, dass alle RGBA Informationen hat. Ich bekomme entweder nur die Graustufen, die AlphaMap oder eine Fehlermeldung.

1) Es wird durch "ftPNG in FormatGetSupportedFiles (Format)" und "case Format of" eine doppelte Filterung vorgenommen.
FormatGetSupportedFiles erlaubt zum Schreiben von PNG-Dateien
Zitat:
tfAlpha8ub1, tfLuminance8ub1, tfLuminance8Alpha8ub2, tfRGB8ub3, tfRGBA8ui1, tfBGR8ub3, tfBGRA8ui1
,
die Case-Anweisung aber
Zitat:
tfAlpha8ub1, tfLuminance8ub1, tfLuminance8Alpha8us1, tfBGR8ub3, tfRGB8ub3, tfBGRA8ub4, tfRGBA8ub4

ALLE Farbformate außer tfAlpha8ub1, tfLuminance8ub1 führen also zwangsläufig dazu, dass diese Prozedur mit Fehlermeldung abgebrochen wird - entweder bedingt durch FormatGetSupportedFiles oder die Case-Anweisung.
Ich war so frei und habe bei mir in "function FormatGetSupportedFiles(const aFormat: TglBitmapFormat): TglBitmapFileTypes;" die Zeilen 1955ff wie folgt angepasst:
Code:
  1. {$IFDEF GLB_SUPPORT_PNG_WRITE}
  2.   if aFormat in [
  3.       tfAlpha8ub1, tfLuminance8ub1, tfLuminance8Alpha8ub2,
  4.       tfRGB8ub3, tfRGBA8ui1, tfRGBA8ub4,
  5.       tfBGR8ub3, tfBGRA8ui1] then
  6.     result := result + [ftPNG];
  7. {$ENDIF}
  8.  

, sprich: ich habe tfRGBA8ub4 explizit in die Liste mit aufgenommen. Ich konnte es noch nicht bzgl. Alpha-Kanal etc. im Detail testen, aber es scheint nun eine korrekte .png-Datei erstellt zu werden. Es stellt sich halt die Frage, ob das überhaupt so sein darf, und ob hier in der Liste noch die anderen Formate der case-Anweisung stehen müssten/sollten. Hier ist meine Bitte: Schaut mal danach! Auf die Idee mit tfRGBA8ub4 kam ich übrigens durch die Prozedur TglBitmapData.LoadPNG, dementsprechend denke ich mal schon, dass dies das richtige Format ist:
Code:
  1.       case png_get_color_type(png, png_info) of
  2.         PNG_COLOR_TYPE_GRAY:
  3.           Format := tfLuminance8ub1;
  4.         PNG_COLOR_TYPE_GRAY_ALPHA:
  5.           Format := tfLuminance8Alpha8us1;
  6.         PNG_COLOR_TYPE_RGB:
  7.           Format := tfRGB8ub3;
  8.         PNG_COLOR_TYPE_RGB_ALPHA:
  9.           Format := tfRGBA8ub4;
  10.         else
  11.           raise EglBitmapException.Create ('LoadPng - Unsupported Colortype found.');
  12.       end;


Nochmals vielen Dank für die Arbeit an glBitmap.




Edit: Ich beziehe mich auf die aktuelle Version der glBitmap von https://git.bergmann89.de/opengl/glBitm ... Bitmap.pas .


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Di Apr 13, 2021 08:33 
Offline
DGL Member
Benutzeravatar

Registriert: Di Apr 29, 2008 18:56
Beiträge: 1213
Programmiersprache: Delphi/FPC
Hi berens,

Leider kann ich dir da aktuell nicht helfen, weil ich privat gerade viel zu tun habe und mir die Zeit fehlt die glBitmap nebenbei noch zu patchen. Sorry :(

Vlt kannst du ja mit den anderen Membern von DGL einen Patch zusammenstellen. Dann würde ich den einfach mit ins Repo pushen. Bzw. haben die Admins auch Schreib-Rechte auf's DGL Repository.

Kurze Anmerkung zu deinen Punkten:
- glDownloadData gab es damals für GLES nicht. Deshalb gibt es die Funktion auch nicht. Kann sein dass es in der aktuellen Version von GLES eine Möglichkeit gibt, die Textur Daten trotzdem runter zu laden. Das müsste man mal recherchieren.
- Bei den IFDEFs sollte natürlich sichergestellt sein, das nur die Formate genutzt werden, die durch GL bzw. GLES definiert sind. Kann sein, dass da nicht alle Kombinationen getestet sind. Hier sollte man mal einen Integrationstest mit allen möglichen Kombinationen schreiben.
- Den Bug hab ich mir jetzt nich genau angeschaut, aber klingt laut deiner Beschreibung erstmal schlüssig.

MfG Bergmann89.

_________________
Aktuelle Projekte: BumpMapGenerator, Massive Universe Online
Auf meiner Homepage gibt auch noch paar Projekte und Infos von mir.


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mi Apr 14, 2021 12:57 
Offline
DGL Member

Registriert: Mo Jul 17, 2006 13:16
Beiträge: 67
Ich habe gerade noch ein gravierendes Fehlverhalten entdeckt:
TglBitmap.DownloadData hat Datenverlust zur Folge, im Sinne von: auf einmal hat die Textur nur noch 8, max. 16 Bit Farbtiefe.

DownloadData wird von mir für zwei Sachen verwendet: Nachdem ich einen FrameBuffer erstellt und "abfotografiert" habe, muss die Textur vertikal gespiegelt werden, damit sie richtig herum lesbar ist. Zudem möchte ich das fertige, gespiegelte Ergebnis dann als Datei (PNG) abspeichern lassen.

Sobald ich die Flip-Funktion aktiviere, wird auch auf dem Bildschirm alles falsch dargestellt, da mit UploadData die "beschädigten" Daten falsch hochgeladen werden. Die PNG-Datei wird immer falsch abgespeichert.

Hier kann man es selbst ausprobieren:
Code:
  1. procedure TTextur.FlipV;
  2. const
  3. var
  4.   data: TglBitmapData;
  5. begin
  6.   data := TglBitmapData.Create;
  7.   if DownloadData(data) then begin
  8.     UploadData(data);
  9.   end;
  10.  


Nach langer, lange Suche bin ich darauf gestoßen, dass wenn ich ein bestimmtes Format für den Download forciere, dass es dann klappt. Ich hätte hier mit 1000 Exceptions und Pointer-Fehlern gerechnet, weil er nun Arbeitsspeicher irgendwie ausliest und es "stupide" in ein Datenmodell presst, aber in der Praxis klappt es:
Code:
  1. function TglBitmap.DownloadData(const aDataObj: TglBitmapData): Boolean;
  2. var
  3.   Temp: PByte;
  4.   TempWidth, TempHeight: Integer;
  5.   TempIntFormat: GLint;
  6.   IntFormat: TglBitmapFormat;
  7.   FormatDesc: TFormatDescriptor;
  8. begin
  9.   result := false;
  10.   Bind;
  11.  
  12.   // Request Data
  13.   glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_WIDTH,           @TempWidth);
  14.   glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_HEIGHT,          @TempHeight);
  15.   glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_INTERNAL_FORMAT, @TempIntFormat);
  16.                                                              
  17.                                                              
  18.   FormatDesc := (TglBitmapFormatDescriptor.GetByFormat(TempIntFormat) as TFormatDescriptor);
  19.   IntFormat  := FormatDesc.Format;
  20.   // ACHTUNG, PATCH, weil sonst nur 256 Farben!
  21.   IntFormat := tfRGBA8ub4;


Ich denke, tfRGBA8ub4 wird nicht pauschal für jeden Programmierer passen. Ich könnte mir sogar vorstellen, dass es Probleme gibt, wenn ich bei einer anderen Textur den Download durchführe, weil die evtl. tatsächlich nicht im Format tfRGBA8ub4 war.

Das merkwürdige ist halt, dass glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_INTERNAL_FORMAT, @TempIntFormat) hier definitiv einen falsch Wert zurückliefert, in Bezug auf die Textur die tatsächlich in der Grafikkarte gerade vorhanden ist. Setze ich einen Haltepunkt auf meine gepatchte Zeile, ist IntFormat = tfEmpty, und TempIntFormat=32856.

Vielleicht hat jemand hierzu eine Idee?


Richtig nach Patch:
Dateianhang:
Richtig.png


Falsche Darstellung; ohne Patch
Dateianhang:
Falsch.png


Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 3 Beiträge ] 
Foren-Übersicht » Programmierung » Einsteiger-Fragen


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 6 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
cron
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.056s | 19 Queries | GZIP : On ]