(gelöst)[D3D 9] Screenshot der Anwendung machen
- Krishty
- Establishment
- Beiträge: 8350
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
(gelöst)[D3D 9] Screenshot der Anwendung machen
Hi,
Ich möchte innerhalb meines Programms einen Schnappschuss des Bildes machen, das just gezeichnet wurde. Wie mache ich das am besten? (Das Antialiasing soll nicht leiden; und sowohl Vollbild als auch Fenstermodus sollen funktionieren!)
Soweit ich das sehe, ist das viel Gefrickel mit GetBackBuffer() und Hin- und Herkopieren. Einfacher ist es mit GetFrontBufferData(), aber da bekomme ich einen Schnappschuss des kompletten Desktops und muss mein Fenster darin erstmal finden (und ich denke, falls es verdeckt ist, wird die Verdeckung mit auf dem Bild landen).
Wie macht man es richtig / falsch?
Gruß
Ich möchte innerhalb meines Programms einen Schnappschuss des Bildes machen, das just gezeichnet wurde. Wie mache ich das am besten? (Das Antialiasing soll nicht leiden; und sowohl Vollbild als auch Fenstermodus sollen funktionieren!)
Soweit ich das sehe, ist das viel Gefrickel mit GetBackBuffer() und Hin- und Herkopieren. Einfacher ist es mit GetFrontBufferData(), aber da bekomme ich einen Schnappschuss des kompletten Desktops und muss mein Fenster darin erstmal finden (und ich denke, falls es verdeckt ist, wird die Verdeckung mit auf dem Bild landen).
Wie macht man es richtig / falsch?
Gruß
Zuletzt geändert von Krishty am 29.01.2013, 21:30, insgesamt 1-mal geändert.
- dot
- Establishment
- Beiträge: 1746
- Registriert: 06.03.2004, 18:10
- Echter Name: Michael Kenzel
- Kontaktdaten:
Re: [D3D 9] Screenshot der Anwendung machen
Ich würde sagen, das hängt konkret von deiner Renderpipeline ab. Evtl. hast du den Frame sowieso schon in einem Buffer, den du einfach kopieren könntest oder evtl. könntest du einfach das Postprocessing in einen anderen Buffer umleiten? Ansonsten würd ich GetBackBuffer() verwenden; dass das mit dem Herumkopieren bei GPUs nunmal eine fact of life ist, is dir klar, denk ich... ;)
- Schrompf
- Moderator
- Beiträge: 5161
- Registriert: 25.02.2009, 23:44
- Benutzertext: Lernt nur selten dazu
- Echter Name: Thomas
- Wohnort: Dresden
- Kontaktdaten:
Re: [D3D 9] Screenshot der Anwendung machen
Ich mach das über GetBackBuffer(). Allerdings noch DX9, und es ist mir manchmal schon passiert, dass meine Screenshots dann einheitlich lila oder grün waren, also die D3D-DebugRuntime-Leerfarben. Ist mir aber schon lange nicht mehr begegnet, vielleicht 2007 das letzte Mal. Vielleicht war es nur eine Treiberungenauigkeit.
Zu AntiAliasing kann ich Dir da aber keine Informationen geben. Aber ich vermute, die Details dazu sähen bei DX11 eh anders aus.
Zu AntiAliasing kann ich Dir da aber keine Informationen geben. Aber ich vermute, die Details dazu sähen bei DX11 eh anders aus.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
- dot
- Establishment
- Beiträge: 1746
- Registriert: 06.03.2004, 18:10
- Echter Name: Michael Kenzel
- Kontaktdaten:
Re: [D3D 9] Screenshot der Anwendung machen
Kanns sein, dass du die Screenshots damals einfach nach dem Present() gemacht hast? ;)Schrompf hat geschrieben:Ich mach das über GetBackBuffer(). Allerdings noch DX9, und es ist mir manchmal schon passiert, dass meine Screenshots dann einheitlich lila oder grün waren, also die D3D-DebugRuntime-Leerfarben.
- Schrompf
- Moderator
- Beiträge: 5161
- Registriert: 25.02.2009, 23:44
- Benutzertext: Lernt nur selten dazu
- Echter Name: Thomas
- Wohnort: Dresden
- Kontaktdaten:
Re: [D3D 9] Screenshot der Anwendung machen
Die Idee ist gut, aber: nein :-) Es ist statischer Code, der schon seit ~2004 nicht mehr verändert wurde. Und der halt nur aller x Monate mal benutzt wurde. Und irgendwann zwischendurch gab es mal ein paar Bilder, die einfarbig lila/grün rauskamen.
[edit] Vielleicht kommt das auch, wenn man GetBackBuffer() während invalidem Device macht?
[edit] Vielleicht kommt das auch, wenn man GetBackBuffer() während invalidem Device macht?
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
- dot
- Establishment
- Beiträge: 1746
- Registriert: 06.03.2004, 18:10
- Echter Name: Michael Kenzel
- Kontaktdaten:
Re: [D3D 9] Screenshot der Anwendung machen
gut möglich^^Schrompf hat geschrieben:[edit] Vielleicht kommt das auch, wenn man GetBackBuffer() während invalidem Device macht?
- Krishty
- Establishment
- Beiträge: 8350
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: [D3D 9] Screenshot der Anwendung machen
Nein; ich nutze kein Post Processing.
Der offensichtliche Nachteil von GetFrontBufferData() ist nämlich, dass ich einen Schnappschuss des kompletten Desktops kriege. Verdeckt im Augenblick des Speicherns ein anderes Fenster meine Anwendung, ist eben das auf dem gespeicherten Bild …
Unterscheidet die Dokumentation zwischen Screen Shot und einem Speichern des Back Buffers? Oder ist AA wirklich nur damit möglich? Hat damit einer Erfahrungen?http://msdn.microsoft.com/de-de/library/windows/desktop/bb174388 hat geschrieben:IDirect3DDevice9::GetFrontBufferData method (Windows)
[…]
Remarks
[…]
This method is the only way to capture an antialiased screen shot.
Der offensichtliche Nachteil von GetFrontBufferData() ist nämlich, dass ich einen Schnappschuss des kompletten Desktops kriege. Verdeckt im Augenblick des Speicherns ein anderes Fenster meine Anwendung, ist eben das auf dem gespeicherten Bild …
- dot
- Establishment
- Beiträge: 1746
- Registriert: 06.03.2004, 18:10
- Echter Name: Michael Kenzel
- Kontaktdaten:
Re: [D3D 9] Screenshot der Anwendung machen
Hast du einen multisampled BackBuffer? Falls ja, dann eben den Inhalt per StretchRect() kopieren, das sollte auf jeden Fall resolven. Alles andere würd mich zumindest extrem wundern...
- Krishty
- Establishment
- Beiträge: 8350
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: [D3D 9] Screenshot der Anwendung machen
Direct3D9: (ERROR) :If the destination surface is an offscreen plain surface, the source must also be an offscreen plain. StretchRect failed
Wie muss ich das Ziel denn sonst anlegen? Sonst sehe ich nur CreateDepthStencilSurface(), und das kann es ja schlecht sein …
Wie muss ich das Ziel denn sonst anlegen? Sonst sehe ich nur CreateDepthStencilSurface(), und das kann es ja schlecht sein …
- dot
- Establishment
- Beiträge: 1746
- Registriert: 06.03.2004, 18:10
- Echter Name: Michael Kenzel
- Kontaktdaten:
Re: [D3D 9] Screenshot der Anwendung machen
Versuchs mal mit Level 0 einer Texture statt einer rohen Surface.
- Krishty
- Establishment
- Beiträge: 8350
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: [D3D 9] Screenshot der Anwendung machen
Ich habe es dank der Katze!
Aaaaaaaalso:
Aaaaaaaalso:
- Via CreateRenderTarget() eine temporäre Render-Target-Textur anlegen (ohne AA und in dem Format, das man haben will). Das ist das einzige, wo StretchRect() den Back Buffer reinkopieren kann.
- Via StretchRect() den Back Buffer in das temporäre Render Target kopieren. Dabei wird das Antialiasing aufgelöst.
- Via CreateOffscreenPlainSurface() einen Systemspeicherpuffer anlegen. Muss unbedingt im D3DPOOL_SYSTEMMEM liegen, weil GetRenderTargetData() nur dorthin kopieren kann; und dasselbe Format haben wie das temporäre Render Target.
- Via GetRenderTargetData() das temporäre Render Target in den Systemspeicherpuffer kopieren.
- Lock() benutzen, um auf die Daten zuzugreifen.