Bilder/Fotos in schneller folge ausgeben

Rund um die LCL und andere Komponenten
Michl
Beiträge: 2505
Registriert: Di 19. Jun 2012, 12:54

Re: Bilder/Fotos in schneller folge ausgeben

Beitrag von Michl »

Nur falls noch weitere Ideen benötigt werden. Mit OpenGL kann man sehr schnell Bilder nacheinander anzeigen. BGRABitmap bietet z.B. einen Wrapper dazu. 2016 hatte ich damit beim Graphic Contest Erfolg (quasi eine Slideshow, wo mehrere Bilder zoomend überlagernd angezeigt werden). Da das Laden der Bilder am längsten dauert, werden diese in einem Workerthread geladen, und, sobald verfügbar, im Mainthread angezeigt. Siehe http://forum.lazarus.freepascal.org/index.php/topic,32626.msg212079.html#msg212079

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection; 

Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Bilder/Fotos in schneller folge ausgeben

Beitrag von Mathias »

Mit OpenGL kann man sehr schnell Bilder nacheinander anzeigen.

Besonders, wen man die Bilder als Textur in das VRAM lädt. Für so was einfaches, bräuchte man nicht mal eine Package.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

marcov
Beiträge: 1100
Registriert: Di 5. Aug 2008, 09:37
OS, Lazarus, FPC: Windows ,Linux,FreeBSD,Dos (L trunk FPC trunk)
CPU-Target: 32/64,PPC(+64), ARM
Wohnort: Eindhoven (Niederlande)

Re: Bilder/Fotos in schneller folge ausgeben

Beitrag von marcov »

Ich lade 28MByte (Kamera-)Bilder in etwa 3-5ms hoch nach OpenGL auf moderne integrierter GPU. Siehe http://forum.lazarus.freepascal.org/ind ... #msg194484 für Code.

Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Bilder/Fotos in schneller folge ausgeben

Beitrag von Mathias »

Besonders, wen man die Bilder als Textur in das VRAM lädt. Für so was einfaches, bräuchte man nicht mal eine Package.
Ich habe dies gerade ausprobiert, mit etwas mehr als 800 Fotos mit einer Auflösung von 2048x1536. Das geht so schnell, das man Augenkrebs bekommt. :mrgreen:


Code: Alles auswählen

unit unit1;
 
{$mode objfpc}{$H+}
 
interface
 
uses
  Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
  ExtCtrls, StdCtrls, ComCtrls, OpenGLContext, dglOpenGL, oglTextur;
 
type
 
  { TForm1 }
 
  TForm1 = class(TForm)
    Timer1: TTimer;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
  private
    OpenGLControl1: TOpenGLControl;
  public
  end;
 
var
  Form1: TForm1;
 
implementation
 
{ TForm1 }
 
const
  FotoPfad = '/n4800/Multimedia/Pictures/Fotos/Bregenzerwaldbahn';
 
var
  FotoTextur: array of TTexturBuffer;
 
procedure TForm1.Timer1Timer(Sender: TObject);
const
  p: integer = 0;
 
  procedure Draw(puf: TTexturBuffer);
  begin
    puf.ActiveAndBind;
    glEnable(GL_TEXTURE_2D);
    glBegin(GL_QUADS);
    glTexCoord2f(0.0, 0.0);
    glVertex3f(-1.0, -1.0, 0.99);
    glTexCoord2f(1.0, 0.0);
    glVertex3f(-1.0, 1.0, 0.99);
    glTexCoord2f(1.0, 1.0);
    glVertex3f(1.0, 1.0, 0.99);
    glTexCoord2f(0.0, 1.0);
    glVertex3f(1.0, -1.0, 0.99);
    glEnd();
  end;
 
begin
  glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
  glEnable(GL_DEPTH_TEST);
  glEnable(GL_TEXTURE_2D);
 
  glRotatef(-90.0, 0.0, 0.0, 1.0);
  Inc(p);
  if p >= Length(FotoTextur) then begin
    p := 0;
  end;
  Draw(FotoTextur[p]);
 
  OpenGLControl1.SwapBuffers;
end;
 
 
procedure TForm1.FormCreate(Sender: TObject);
var
  sl: TStringList;
  i: integer;
begin
  OpenGLControl1 := TOpenGLControl.Create(Self);
  OpenGLControl1.Parent := Self;
  OpenGLControl1.Align := alClient;
  OpenGLControl1.AutoResizeViewport := True;
 
  InitOpenGL;
  OpenGLControl1.MakeCurrent;
  ReadExtensions;
  ReadImplementationProperties;
 
  sl := FindAllFiles(FotoPfad);
  SetLength(FotoTextur, sl.Count);
  for i := 0 to Length(FotoTextur) - 1 do begin
    FotoTextur[i] := TTexturBuffer.Create;
    FotoTextur[i].LoadTextures(sl[i])// Foto ins VRAM
  end;
  sl.Free;
 
  Timer1.Enabled := True;
end;
 
procedure TForm1.FormDestroy(Sender: TObject);
var
  i: integer;
begin
  for i := 0 to Length(FotoTextur) - 1 do begin
    FotoTextur[i].Free;
  end;
end;
 
initialization
 
  {$I unit1.lrs}
 
end.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Warf
Beiträge: 1908
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

Re: Bilder/Fotos in schneller folge ausgeben

Beitrag von Warf »

marcov hat geschrieben:Ich lade 28MByte (Kamera-)Bilder in etwa 3-5ms hoch nach OpenGL auf moderne integrierter GPU. Siehe http://forum.lazarus.freepascal.org/ind ... #msg194484 für Code.

Dann hast du sie aber nicht von der Platte geladen oder? 30 MB in 5ms wäre eine Lesegeschwindigkeit von c.a. 6 GB pro Sekunde, c.a. 10 mal so viel eine gute moderne SSD kann. Oder meinst du damit die Abspielgeschwindigkeit?

Warf
Beiträge: 1908
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

Re: Bilder/Fotos in schneller folge ausgeben

Beitrag von Warf »

Mathias hat geschrieben:Ich habe dies gerade ausprobiert, mit etwas mehr als 800 Fotos mit einer Auflösung von 2048x1536. Das geht so schnell, das man Augenkrebs bekommt. :mrgreen:


Und wenn man ganz motiviert ist kann man damit auch noch gute Effekte erzeugen. Aber leider ist alles was über simples Zeichnen hinausgeht richtig aufwendig. Eventuell könnte man auch ZenGL für so etwas gut nutzen, ich habe aber noch nie damit gearbeitet, aber da war der letzte Commit "nur" 3,5 Jahre alt.
FPC müsste doch auch die SDL header drin haben, ich meine mich zu erinnern das SDL in einigen dingen deutlich einfacher war als reines OpenGL.

Delphi hat mit FireMonkey ja sogar ein echt gutes Framework was auf hardwarebeschleunigtes Rendern setzt. Leider ist so etwas super aufwendig umzusetzen, allein nur eine kleine Version, ohne die ganzen Features die FireMonkey hat, würde praktisch einmal alle LCL Komponenten neu schreiben bedeuten.

marcov
Beiträge: 1100
Registriert: Di 5. Aug 2008, 09:37
OS, Lazarus, FPC: Windows ,Linux,FreeBSD,Dos (L trunk FPC trunk)
CPU-Target: 32/64,PPC(+64), ARM
Wohnort: Eindhoven (Niederlande)

Re: Bilder/Fotos in schneller folge ausgeben

Beitrag von marcov »

Warf hat geschrieben:
marcov hat geschrieben:Ich lade 28MByte (Kamera-)Bilder in etwa 3-5ms hoch nach OpenGL auf moderne integrierter GPU. Siehe http://forum.lazarus.freepascal.org/ind ... #msg194484 für Code.

Dann hast du sie aber nicht von der Platte geladen oder?


Nein, die kommen vom Netz (GigE camera). Es meint auch nicht das man denn 1000/5 = 200fps auf dieser weise kann schauen kann, es ist mehr eine Zahl die angebt wie lange der Mainthread aufgehalten wird

30 MB in 5ms wäre eine Lesegeschwindigkeit von c.a. 6 GB pro Sekunde, c.a. 10 mal so viel eine gute moderne SSD kann. Oder meinst du damit die Abspielgeschwindigkeit?


Von wenn man das Bild in ein eigene Datastructur hat (zb TBitmap) bis es auf dem Schirm steht. Also OpenGL upload+VCL.paint(draw)

Warf
Beiträge: 1908
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

Re: Bilder/Fotos in schneller folge ausgeben

Beitrag von Warf »

marcov hat geschrieben:Von wenn man das Bild in ein eigene Datastructur hat (zb TBitmap) bis es auf dem Schirm steht. Also OpenGL upload+VCL.paint(draw)

Ja das geht schön schnell. Das Problem ist immer sie erst mal in die Datenstruktur zu laden. Aber das kann man in einem separaten Thread erledigen wenn es zu viele Daten sind um sie auf einmal zu laden.

Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Bilder/Fotos in schneller folge ausgeben

Beitrag von Mathias »

Und wenn man ganz motiviert ist kann man damit auch noch gute Effekte erzeugen. Aber leider ist alles was über simples Zeichnen hinausgeht richtig aufwendig.
Wen man GLSL beherscht, kann man viele Effekte mit OpenGL machen.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

marcov
Beiträge: 1100
Registriert: Di 5. Aug 2008, 09:37
OS, Lazarus, FPC: Windows ,Linux,FreeBSD,Dos (L trunk FPC trunk)
CPU-Target: 32/64,PPC(+64), ARM
Wohnort: Eindhoven (Niederlande)

Re: Bilder/Fotos in schneller folge ausgeben

Beitrag von marcov »

Warf hat geschrieben:
marcov hat geschrieben:Von wenn man das Bild in ein eigene Datastructur hat (zb TBitmap) bis es auf dem Schirm steht. Also OpenGL upload+VCL.paint(draw)

Ja das geht schön schnell. Das Problem ist immer sie erst mal in die Datenstruktur zu laden. Aber das kann man in einem separaten Thread erledigen wenn es zu viele Daten sind um sie auf einmal zu laden.


In Theorie kann man auch Texture upload in ein andere Thread tun, mit neueren OpenGL Versionen. Aber das war in Praxis für meine Situation (mit mehrere solchen Kamera Views mit beliebig schalten dazwischen) zu schwierig, also damit habe ich nie wirklich angefangen.

Laden/Speichern kann man aber recht einfach in Threads lagern.

marcov
Beiträge: 1100
Registriert: Di 5. Aug 2008, 09:37
OS, Lazarus, FPC: Windows ,Linux,FreeBSD,Dos (L trunk FPC trunk)
CPU-Target: 32/64,PPC(+64), ARM
Wohnort: Eindhoven (Niederlande)

Re: Bilder/Fotos in schneller folge ausgeben

Beitrag von marcov »

Mathias hat geschrieben:
Und wenn man ganz motiviert ist kann man damit auch noch gute Effekte erzeugen. Aber leider ist alles was über simples Zeichnen hinausgeht richtig aufwendig.
Wen man GLSL beherscht, kann man viele Effekte mit OpenGL machen.


Ja, aber man kann mit den Geometrie Shader auch dichte Data auspacken nach Vertices. Oder ein Zirkel zeichnen mit nur x,y + radius usw.

Oder Text machen ohne Textures für jeder Zeichensequenz kraften und hoch laden.

Warf
Beiträge: 1908
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

Re: Bilder/Fotos in schneller folge ausgeben

Beitrag von Warf »

Mathias hat geschrieben:Wen man GLSL beherscht, kann man viele Effekte mit OpenGL machen.

Ja mit Shadern kann man viel anstellen, ist aber trotzdem aufwendiger als z.B. FireMonkey, bei dem du einfach Framework Effekte wie TGaussianBlurEffect verwenden kannst. FireMonkey hat zwar auch sehr viele schwächen, aber so ein grundlegendes Hardwarebeschleunigtes GUI Framework wäre schon ganz praktisch. Mittlerweile sind auch CPU und Handy Grafikprozessoren gut genug, sodass man praktisch ganze Programme damit rendern kann, und es läuft dennoch auf allen gebräuchlichen Rechnern. Moderne Browser nutzen wenn vorhanden Hardwarebschläunigung, Discord, Visual Studio, praktisch der Großteil moderner C# Anwendungen, damit kann man echt gute Qualität erreichen. OpenGL pur ist aber sehr kleinschrittig.

Ich glaube BGRA Bitmaps verwenden auch Hardwarebeschleunigte Effekte und der Entwickler hatte 2016 auch angefangen mit BGRA Controls FX eine bibliothek an OpenGL gezeichneten Controls zu bauen, habe aber bisher nur ein paar mal BGRAControls verwendet und kann nicht wirklich sagen wie gut das ist.

marcov
Beiträge: 1100
Registriert: Di 5. Aug 2008, 09:37
OS, Lazarus, FPC: Windows ,Linux,FreeBSD,Dos (L trunk FPC trunk)
CPU-Target: 32/64,PPC(+64), ARM
Wohnort: Eindhoven (Niederlande)

Re: Bilder/Fotos in schneller folge ausgeben

Beitrag von marcov »

Warf hat geschrieben: Moderne Browser nutzen wenn vorhanden Hardwarebschläunigung, Discord, Visual Studio, praktisch der Großteil moderner C# Anwendungen, damit kann man echt gute Qualität erreichen. OpenGL pur ist aber sehr kleinschrittig.


Fast alles nutzt Hardwarebeschleunigung seit Vista, weil der Desktop Compositer DWM.EXE hardware beschleunigt ist :-)

Aber das haben von eine Compositor macht etwas noch nicht echt eine GPU zentrische gui. Es kann ja noch immer reine Bitmap Manipulation sein, die dann im Ende etwas mit Beschleunigung zusammen geblendet wird.

Ich kenne FM nicht, aber durchaus wird es als "buggy" und limitiert bezeichnet.

Antworten