Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi schnelles Kopieren von Direct3DSurface -> DirectDrawSurface (https://www.delphipraxis.net/76908-schnelles-kopieren-von-direct3dsurface-directdrawsurface.html)

JamesTKirk 11. Sep 2006 22:03


schnelles Kopieren von Direct3DSurface -> DirectDrawSurfa
 
Abend Leutz!

Ausgehend von diesen Quellcodes, arbeite ich momentan an einem Programm, dass es mir ermöglicht Direct3D Inhalte "live" als Desktophintergrund anzeigen zu lassen. (Fragt nicht nach dem warum... - Also schön... ich wollte schon immer einen Desktop mit tollen 3D Animationen im Hintergrund :mrgreen: ) Von der Theorie her funktioniert das ganze schon mal.

Mein Problem ist aber, das die Geschwindigkeit des Kopiervorgangs vom Direct3DSurface zum DirectDrawSurface äußerst zu wünschen übrig lässt (~90-120ms pro Kopiervorgang), vor allem, wenn man zumindest eine Auflöung von 640x480 als Surface Auflösung möchte. (320x240 ist zwar von der Geschwindigkeit her OK (~30ms), allerdings sieht das von 320x240 auf 1024x758 gestreckte Resultat nicht mehr schön aus :zwinker: )
Deswegen frage ich euch, was es alles für Möglichkeiten gibt, den Kopiervorgang zu beschleunigen oder ob es gar die Möglichkeit gibt mehr oder weniger direkt in das DirectDrawSurface zu renden. :gruebel:


Hier noch die primitivste,langsamste, aber am besten aussehendste Kopierprozedur (natürlich - wie üblich - um das unnötigste gekürzt ;) ):

Delphi-Quellcode:
procedure CopyImageToSurface(surface:IDirectDrawSurface7;src:IDirect3DSurface9);
var
  ddsd:DDSURFACEDESC2;
  hr:HResult;
  LockedRect:D3DLOCKED_RECT;
  dest:PDWord;
begin
  ZeroMemory(@ddsd,SizeOf(ddsd));
  ddsd.dwSize:=SizeOf(ddsd);
  if FAILED(surface.Lock(NIL, ddsd, DDLOCK_SURFACEMEMORYPTR or DDLOCK_WAIT, 0)) then
    raise Exception.Create('...');

  if Failed(src.LockRect(LockedRect,NIL,D3DLOCK_READONLY)) then
    raise Exception.Create('...');

  dest:=PDWORD(ddsd.lpSurface);

  //Dies ist DER zeitaufwendigste Part... Das warum ist mir allerdings klar ;)
  Move(LockedRect.pBits^,dest^,IMG_W*IMG_H*4);

  src.UnlockRect;

  surface.Unlock(NIL);
end;

JamesTKirk 18. Nov 2006 23:14

Re: schnelles Kopieren von Direct3DSurface -> DirectDrawS
 
Hallo Leute!

Ich habe mich heut (genau genommen müsste man gestern sagen ;) ) wieder mit meinem oben genannten Problem beschäftigt und habe, nachdem ich ein wenig mit verschiedensten HDCs und BitBlt rumgespielt hab, es doch tatsächlich hinbekommen, dass ich mein Gerendertes auch hinter den Icons wiederfinde. :bouncing4:

Dazu erstelle ich das D3DDevice mit dem Handle einer extra Form, besorg mir von der den DC per GetDC(D3DForm.Handle) und BitBlte dieses in den DC des DirectDraw Surfaces. Funzt sogar 1a bei 640x480. Allerdings hab ich da jetzt ein anderes Problem, nach dem ich erstmal nach einer Lösung suchen werde. Falls ich nichts dazu finde, melde ich mich mit einem neuen Thread :mrgreen:

JamesTKirk 20. Nov 2006 16:33

Re: schnelles Kopieren von Direct3DSurface -> DirectDrawS
 
Nochmal Hi!

Ich habe das ganze noch einmal verbessern können! Ich habe es mittlerweile geschafft auf den DC des Backbuffer-3D-Surfaces zugreifen zu können (wenn man das Surface mit 32bit und 3 Farbkanälen, das 3DDevice allerdings mit 32Bit, aber 4 Farbkanälen erstellt und man sich dann wundert, warum des nicht funzt, is des kei Wunder :mrgreen: ). Dadurch konnte ich mir den Umweg über ein anderes Form sparen (damit fällt auch das oben genannte Problem weg) und, nachdem ich sogar das Austauschen des 3D-Frontbuffers durch den Backbuffer entfernt habe, hat des Prog nahezu keine CPU-Auslastung mehr (mal schauen, was das sich in komplexeren Szenen auswirkt :wink: ). Selbst bei 800x600 läuft des ganze noch "verhältnismäßig" flüssig... wobei mir dann doch eher 640x480 lieber ist ;)

Was ich jetzt noch versuchen möchte, ist, DirectDraw komplett auszuklammern, aber dazu muss ich noch ein wenig mit BitBlt/MaskBlt/StretchBlt rumspielen... vor allem den ROPs :gruebel:

Aber nichts desto trotz werd ich mich mal daran machen das ganze mit nem Pluginsystem und ner TrayKomponente zu versehen und dann ab damit in den Open-Source Bereich :zwinker:


Alle Zeitangaben in WEZ +1. Es ist jetzt 06:11 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz