OpBitmap mit Formaten Version 1.0

Zur Vorstellung von Komponenten und Units für Lazarus
Antworten
shokwave
Beiträge: 470
Registriert: Do 15. Nov 2007, 16:58
OS, Lazarus, FPC: Win11/Ubuntu Budgie (L 3.0 FPC 3.2.2)
CPU-Target: i386, x64
Wohnort: Gera

Re: OpBitmap mit Formaten Version 1.0

Beitrag von shokwave »

Schwedenbitter hat geschrieben:
Ich habe das mit # 0.9.24 Beta vom 10.09.2008 (SVN-Revision: 12752) probiert und bekomme genau dieselben Fehlermeldungen:


Ähm..0.9.24? :idea: Dann müsste doch die V1.6 von opBitmap anstandslos laufen....
mfg Ingo

Benutzeravatar
theo
Beiträge: 10467
Registriert: Mo 11. Sep 2006, 19:01

Re: OpBitmap mit Formaten Version 1.0

Beitrag von theo »

shokwave hat geschrieben:
Schwedenbitter hat geschrieben:
Ich habe das mit # 0.9.24 Beta vom 10.09.2008 (SVN-Revision: 12752) probiert und bekomme genau dieselben Fehlermeldungen:


Ähm..0.9.24? :idea: Dann müsste doch die V1.6 von opBitmap anstandslos laufen....


Achso, stimmt. Wie sagt man doch: "Wer lesen kann ist klar im Vorteil". ;-)
Mich hat das "SVN-Revision: xxxxx" wohl irritiert.
Merci!

t-z
Beiträge: 49
Registriert: So 22. Nov 2009, 18:12
OS, Lazarus, FPC: Windows 7 Professional 64Bit / Kubuntu 10.04 (Lazarus 0.9.28.2 64 Bit FPC 2.2.4)
CPU-Target: Intel i5-760

Re: OpBitmap mit Formaten Version 1.0

Beitrag von t-z »

Hallo,

ich habe Lazarus 0.9.28.2 64 Bit unter Windows 7 Pro 64 Bit installiert. Nun wollte ich opbitmap1_7 bzw. opbitmap64 installieren. Allerdings bekomme ich bei beiden folgende Fehlermeldung:

Code: Alles auswählen

D:\Dokumente\XXXX\Dokumente\Lazarus\opbitmap1_7\imglibs\resample.pas(532,44) Error: Argument can't be assigned to

Daneben bekomme ich noch fünf Warnmeldungen die so Aussehen:

Code: Alles auswählen

D:\Dokumente\XXXX\Dokumente\Lazarus\opbitmap1_7\imglibs\resample.pas(536,48) Warning: Conversion between ordinals and pointers is not portable

Benutzeravatar
theo
Beiträge: 10467
Registriert: Mo 11. Sep 2006, 19:01

Re: OpBitmap mit Formaten Version 1.0

Beitrag von theo »

Keine Ahnung. Hast du denn auch opbitmapforlazcompat.lpk ausgewählt?
Ich hab im Moment kein 64bit System zum testen. Kannst du rausfinden, was da schief läuft?
P.S. Die Warnungen sind nicht von Interesse.

t-z
Beiträge: 49
Registriert: So 22. Nov 2009, 18:12
OS, Lazarus, FPC: Windows 7 Professional 64Bit / Kubuntu 10.04 (Lazarus 0.9.28.2 64 Bit FPC 2.2.4)
CPU-Target: Intel i5-760

Re: OpBitmap mit Formaten Version 1.0

Beitrag von t-z »

Ich kann mal versuchen das heraus zu bekommen. Allerdings benötige ich diese Info nun nicht mehr, da ich meine Komponente nun basierend auf der LazIntfImage erstelle. Mit GetDataLineStart ist diese Komponente um etwa einen Faktor 5 schneller, als mit Colors[x,y]. Damit ist diese Lösung vermutlich sogar schneller als mit der OPBitmap - jedenfalls wenn sich die Daten aus dem Thread [url=://www.lazarusforum.de/viewtopic.php?f=9&t=1823]Benchmark Test bzw ein Versuch dazu^^[/url] mit meinen Gegebenheiten vergleichen lasen. Zusätzlich steigere ich die Bearbeitungsgeschwindigkeit nun mit Multithreading, sodass ich bei Full HD und 4 Threads immer noch 17 Fps bekomme (Bei 2en 15 Fps, bei einem 10 Fps).

Edit: Ich habe die Last für den GUI-Thread nun deutlich senken können, sodass die Worker-Threads nun nahezu ihre volle Leistung entfalten können. Dadurch erreiche ich nun 33/18/10 Fps.

Benutzeravatar
theo
Beiträge: 10467
Registriert: Mo 11. Sep 2006, 19:01

Re: OpBitmap mit Formaten Version 1.0

Beitrag von theo »

t-z hat geschrieben:Damit ist diese Lösung vermutlich sogar schneller als mit der OPBitmap


Das glaube ich eher nicht, aber Hauptsache du hast eine Lösung.

t-z
Beiträge: 49
Registriert: So 22. Nov 2009, 18:12
OS, Lazarus, FPC: Windows 7 Professional 64Bit / Kubuntu 10.04 (Lazarus 0.9.28.2 64 Bit FPC 2.2.4)
CPU-Target: Intel i5-760

Re: OpBitmap mit Formaten Version 1.0

Beitrag von t-z »

Für meine Vermutung habe ich eigene Tests mit den beiden Varianten herangezogen und diese anschließend mit den drei gezeigten Varianten aus dem Benchmark verglichen. Wenn ich mit den so mir zur Verfügung stehenden Zahlen rechne, hätte ich für die reine Pixelverarbeitung sogar einen Geschwindigkeitsvorteil von ca. 10%. Wie das bei der Konvertierung aussieht weiß ich natürlich nicht. Das für die Kopiervorgänge deutlich Zeit benötigt wird, kann man an den Unterschieden zwischen den verschieden Multithreading-Varianten sehen. Wenn ich OP-Bitmap ans laufen bekomme, werde ich dies aber noch einmal testen (sowohl die Pixelverarbeitung, als auch die Konvertierung). Beim Echtzeit-Rendern von Animationen kommt es halt auf jede Millisekunde weniger für eine Berechnung der Einzelbilder an - gerade bei hohen Auflösungen und/oder schwachen Rechnern. Da lasse ich natürlich nichts unversucht. Zur zeit habe ich aber noch kleine Probleme mit dem Multithreading, denn unter bestimmten Voraussetzungen dürfen Parameter nicht während der Bearbeitung geändert werden, ohne dass es zu Bildfehler, Rucklern, oder gar Ausnahmen oder gar dem Aufhängen des gesamten Programms kommt (letzteres liegt an der Übernahme von altem Code, der mit Nachrichten anstatt von Endlosschleife/-n arbeitete). Die Änderungen müssen also gebuffert und zu geeigneter Zeit in die Threads übertragen werden.

MAC
Beiträge: 770
Registriert: Sa 21. Feb 2009, 13:46
OS, Lazarus, FPC: Windows 7 (L 1.3 Built 43666 FPC 2.6.2)
CPU-Target: 32Bit

Re: OpBitmap mit Formaten Version 1.0

Beitrag von MAC »

ich kenn mich zwar auch nicht gut mi opbitmap aus. aber da gibt es bestimmt schnelle (wirklich schnelle) funktionen wie alle daten direkt aus array einlesen ,auslesen.
Aber wenn du wirklich objekte schnell rendern willst --> frag die Grafikkarte --> OpenGL

Gerade wenn du damit Animationen machen willst , kp. Man zeichne einmal ein rechteck welches den gesammten bildschirm ausfüllt. laded ein Bild (animation) und zeigt dann erst die obere linke ecke, oben rechts, unten links unten recht. 4 Bilder á la Grafikkarte. ( kann man natürlich immer weiter aufteilen...

Code: Alles auswählen

Signatur := nil;

t-z
Beiträge: 49
Registriert: So 22. Nov 2009, 18:12
OS, Lazarus, FPC: Windows 7 Professional 64Bit / Kubuntu 10.04 (Lazarus 0.9.28.2 64 Bit FPC 2.2.4)
CPU-Target: Intel i5-760

Re: OpBitmap mit Formaten Version 1.0

Beitrag von t-z »

Ich habe nun alle Probleme in meinem Projekt beseitigt. Nun also zu OPBitmap:

Das Kompilieren schlägt fehl an der folgenden Typkonvertierung: Integer(DestPixel). DestPixel hat den Typ PBGRA, der folgendermaßen definiert ist:

Code: Alles auswählen

PBGRA = ^TBGRA;
  TBGRA = packed record
   B, G, R, A: Byte;
  end;


Neue Erkenntnisse:
Wenn ich den Code

Code: Alles auswählen

Inc(Integer(DestPixel), DestDelta);
in

Code: Alles auswählen

Inc((DestPixel), DestDelta);
ändere, lässt sich die opdemo kompilieren, ab es entsteht eine Speicherverletzung direkt nach dem Start.
Die Installation schlägt scheinbar fehl, da die Unit componenttreeview.pas fehlt.
In eigenen Projekten werden die OP-Komponenten nicht gefunden.

Zu OpenGL: Da schon ich Probleme dabei habe Glut überhaupt ans laufen zu bekommen, möchte ich dies nicht dem Anwender meines Programms zumuten. Bis jetzt habe ich es jedenfalls nicht geschafft, dass ein Testprogramm (z.B. aus den Beispielen) die dll findet. Mit einer normalen Anwendung habe ich eine solche Abhängigkeit nicht. Hinzu kommt noch, dass ich mit OpenGL bisher noch gar keine Erfahrung habe und von daher weder weiß, ob ich Code von einer vor einigen Jahren geschriebenen Delphi-Komponente wiederverwenden kann, noch wie ich z.B. zwei Bilder überblenden könnte. Diese hat knapp 100 Übergangseffekte, rendert auf der CPU mit nur einem Thread und erreichte vergleichbare Geschwindigkeiten wie die jetzt in Arbeit befindliche mit nur einem Thread erreichte. Problematisch sind nur die Effekte, die auf die Pixel Multiplikationen/Divisionen anwenden. Alle andere sind um einen Faktor 10-20 schneller.
Zuletzt geändert von t-z am Di 25. Jan 2011, 19:50, insgesamt 1-mal geändert.

MAC
Beiträge: 770
Registriert: Sa 21. Feb 2009, 13:46
OS, Lazarus, FPC: Windows 7 (L 1.3 Built 43666 FPC 2.6.2)
CPU-Target: 32Bit

Re: OpBitmap mit Formaten Version 1.0

Beitrag von MAC »

ich schätze mal das man das eventuell durch DestPixel.a*256*256*256 + DestPixel.b*256*256+ DestPixel.g*256 + DestPixel.red ersetzen kann.

Richtig, Glut kommt garnicht erst drauf :)
hat bei mir auch nen bisl gedaurt, aber man packts auch ohne glut ( sogar recht einfach)
Überblenden ist auch einfach machbar. --> glcolor4f(1,1,1,0.5) {Zeichnen } glcolor4f(1,1,1,1) und das aktuelle wurde mit 50 % tranzparenzgezeichnet.
ich mach dir mal gerade nen beispiel code: (ich brauch immoment aber die unit windows wegen der funktion swapbuffers, die das bild "zeichnet"

Code: Alles auswählen

var
DC: HDC;  //Handle auf Zeichenfläche
RC: HGLRC;//


OnFormCreate:

Code: Alles auswählen

DC:= GetDC(Form1.Handle)// start OpenGL
if not InitOpenGL then Application.Terminate;
RC:= CreateRenderingContext(DC,[opDoubleBuffered],32,24,0,0,0,0);
ActivateRenderingContext(DC, RC); // fertig mit starten
 
// optional nicht im timer rendern sinder onidle ... Application.OnIdle := @IdleHandler; 
 
 
glClearColor(1,1,1,0); //Hintergrundfarbe:weiß
glDisable(GL_DEPTH_TEST);          //Tiefentest
glDisable(GL_CULL_FACE);           //Backface Culling
glEnable (GL_BLEND);                                 //alpha
glEnable (GL_NORMALIZE);
glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);   //Licht
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_TEXTURE_2D);
glShadeModel(GL_SMOOTH);
glAlphaFunc ( GL_GREATER, 0.01 )// 99%-100% transperente obj werden nicht in den z-buffer geschrieben
glEnable ( GL_ALPHA_TEST ) ;
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
 
{ licht brauchen wir nicht. ansonsten ist light_ambient ein array [0..3] of real mit werten von 0..1
glLightfv(GL_LIGHT0, GL_AMBIENT,  @light_ambient[0]);
glLightfv(GL_LIGHT0, GL_DIFFUSE,  @light_diffuse[0]);
glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 1);
glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.0001);
glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, 0);     }


beim Rendern , wahlweise Timer (schlecht, aber einfach) oder OnIdle (mehr fps, weil nicht so lahm wie timer, aber nen ticken komplezer (eigt nicht komplezer aber egal xD))


Code: Alles auswählen

glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
glViewport(0, 0, Form1.ClientWidth, Form1.ClientHeight)// große = größe des fensters
glmatrixmode(GL_PROJECTION);
glloadidentity();
gluperspective(45,Form1.ClientWidth/ Form1.ClientHeight,0.001,10); // von 0.001 bis entfernung von 10   
glmatrixmode(GL_MODELVIEW);
glloadidentity();
 
// ursprung herstellen
 
 
// das eigentliche
glbegin(GL_TRIANGLES); // ab jetzt werden dreiecke gezeichnet.
 
glcolor4f(random,random,random,1); // farbe rgba
glvertex3f(-1,0,-2);
glvertex3f(0,1,-2);
glvertex3f(1,0,-2);
glcolor4f(1,1,1,1);   
 
glend; // ende mit dreiecke zeichnen.
Swapbuffers(DC); //ausgabe


ansonsten eine funktion googlen.
Wichtig. Hohl dir den Header auf dgl, link : oben, der soll besser sein.
Ich teste das projekt gleich.

Edit:
4 "fehler" beseitigt

klappt schonmal, nicht schön das bild,aber läuft :)

Code: Alles auswählen

Signatur := nil;

t-z
Beiträge: 49
Registriert: So 22. Nov 2009, 18:12
OS, Lazarus, FPC: Windows 7 Professional 64Bit / Kubuntu 10.04 (Lazarus 0.9.28.2 64 Bit FPC 2.2.4)
CPU-Target: Intel i5-760

Re: OpBitmap mit Formaten Version 1.0

Beitrag von t-z »

Das Problem mit der OP Bitmap habe ich nun gelöst so gelöst: Die Zeile

Code: Alles auswählen

Inc(Integer(DestPixel), DestDelta);
habe ich durch

Code: Alles auswählen

DestPixel:=PBGR(Integer(DestPixel)+DestDelta);
ersetzt.
MAC hat geschrieben:ich schätze mal das man das eventuell durch DestPixel.a*256*256*256 + DestPixel.b*256*256+ DestPixel.g*256 + DestPixel.red ersetzen kann.
Das kann nicht Klappen, da es sich hier bei um eine Zeigeroperation handelt. Durch die Typkonvertierung soll die Adresse nur um DestDelta erhöht werden und nicht um DestDelta*AnzahlBit(TBGR).

@MAC: Danke für dein Beispiel. Nach ein bisschen Suchen, was du mit dgl meinst habe ich die Komponente dglopengl.pas gefunden. Dein Beispiel läuft nun auch bei mir.

Ach so: Ich bevorzuge für Animationen die Methode eine while-Schleife zu starten, nach spätestens jedem Rechendurchgang setze ich dann ein Application.ProcessMessages;. Um das ganze dann an die Zeit anzupassen hohle ich mir die Zeitdifferenz zum Startzeitpunkt mit GetTickCount (ist zwar nicht extrem genau, aber es reicht für diesen Zweck; Wichtig: Int64 zum speichern benutzen!). Wenn ich nun noch die Prozessorlast steuern möchte setze ich nach jedem Durchgang noch ein zuvor berechnetes sleep(#); (# ist Platzhalter).
Mit Multitreading hat man automatisch eine while-Schleife. Da das GUI auf einem anderen Thread läuft ist es nicht schlimm, dass dieser Thread keine Nachrichten abfangen könnte. Dafür gibt es reichlich Probleme bei der Synchronisation bzw. mit dem Verhindern von ungewollten Variablenänderungen. Besonders ekelig ist der Umgang mit komplexen Datentypen auf mehr als einem Thread - da hagelt es ganz schnell mal Speicherverletzungen.

t-z
Beiträge: 49
Registriert: So 22. Nov 2009, 18:12
OS, Lazarus, FPC: Windows 7 Professional 64Bit / Kubuntu 10.04 (Lazarus 0.9.28.2 64 Bit FPC 2.2.4)
CPU-Target: Intel i5-760

Re: OpBitmap mit Formaten Version 1.0

Beitrag von t-z »

Nun habe ich einen Benchmark durchführen können:

OpBitmap: 1326ms
LazIntfImg: 1139ms
LazIntfImg2: 515ms
TBitmap: 14913ms

Näheres dazu hier.

Benutzeravatar
theo
Beiträge: 10467
Registriert: Mo 11. Sep 2006, 19:01

Re: OpBitmap mit Formaten Version 1.0

Beitrag von theo »

Hast du den hier auch wiederholt?

viewtopic.php?p=21251#p21251

t-z
Beiträge: 49
Registriert: So 22. Nov 2009, 18:12
OS, Lazarus, FPC: Windows 7 Professional 64Bit / Kubuntu 10.04 (Lazarus 0.9.28.2 64 Bit FPC 2.2.4)
CPU-Target: Intel i5-760

Re: OpBitmap mit Formaten Version 1.0

Beitrag von t-z »

Nein, den hatte ich übersehen. Damit geht es tatsächlich etwas schneller. Komischerweise fällt der Geschwindigkeitszuwachs aber deutlich geringer aus, als im alten Benchmark - dabei ist der Code zwischen der Zeitmessung exakt identisch.

Hier die Werte:
OpBitmap: 1326ms
OPScanline: 452ms
LazIntfImg: 1139ms
LazIntfImg2: 531ms
TBitmap: 14726ms

Frage: Gibt es in OP-Bitmap auch eine Möglichkeit die Bitmap direkt auf die Canvas zu schreiben, oder muss ich über ein TBitmap gehen, wie auch beim TLazIntfImage? Spätestens dann dürfte die OP-Bitmap überlegen sein. Beim Laden der Bilder ist sie dies auf jedem Fall, da ich keine Konvertierung von TBitmap nach TLazIntfImage mehr benötige.

Benutzeravatar
theo
Beiträge: 10467
Registriert: Mo 11. Sep 2006, 19:01

Re: OpBitmap mit Formaten Version 1.0

Beitrag von theo »

t-z hat geschrieben:Frage: Gibt es in OP-Bitmap auch eine Möglichkeit die Bitmap direkt auf die Canvas zu schreiben, oder muss ich über ein TBitmap gehen, wie auch beim TLazIntfImage? Spätestens dann dürfte die OP-Bitmap überlegen sein. Beim Laden der Bilder ist sie dies auf jedem Fall, da ich keine Konvertierung von TBitmap nach TLazIntfImage mehr benötige.


In der Unit lazbridge32 sind direkte Fkt. für Win32, Qt und GTK2.
Geht aber nur für Pixelformat 32bit. Also unbedingt von Anfang an damit arbeiten, umwandeln kostet Zeit.
In der alpha32demo siehst du wie man's benutzt.
Ohne Alpha ist es aber schneller, falls nicht benötigt (OpBitmapPaint32 ohne A am Schluss).

Ist nicht extrem oft getestet, sollte aber schon funzen.
Sonst bist du ja nicht auf den Kopf gefallen, und kannst das bestimmt verbessern. ;-)

Antworten