DirectX: Auf ein anderes Fenster zeichnen?



  • Hey,

    ist es möglich auf ein Spiel zu zeichnen, welches in einem anderen Prozess läuft?
    Ich habe versucht einfach das HWND des anderen Spiels zu nehmen und dort drauf zu zeichnen. Das Problem war jedoch, dass mein "Zeichnen" nicht mit dem gezeichnetem von dem Spiel überlappt, sondern es komplett löscht und auf den schwarzen Hintergrund zeichnet. Es ist dann also immer ein hin-und-her zwischen einem Frame von dem Spiel und einem Frame von meinem Prozess mit schwarzen Hintergrund.
    Kann man es so machen, dass nur das auf dem Spiel erscheint, dass auch gezeichnet wird, und nicht dass der Frame vom Spiel komplett gelöscht wird und durch meinen ersetzt wird? Kann man sich so wie ein "Overlay" vorstellen. Ich habe nicht sehr viel Ahnung von DirectX 9 aber würde es toll finden, wenn einer eine Möglichkeit kennt!

    Danke.



  • Stichwort: Direct3D Hook



  • einen Direct3D Hook kenne ich, aber ich würde das wirklich wenn dann nur von außerhalb machen ohne irgendwie in den anderen Prozess einzugreifen. Aber das geht wohl nicht, oder?



  • Nope, das geht nicht...



  • Du kannst das Bild/Screenshot des Spiels nehmen (mit http://pastebin.com/VxyfPDa7 oder wahrscheinlich gibt es dafür eine DirectX-Funktion), dann in dem Bild rummalen, dann das ganze Bild auf das Zielfenster malen.
    Du kannst das Bild auch in ein neues Fenster malen, dann zeigt es immer nur dein Bild an und es flackert nicht.

    Eine andere Möglichkeit wäre einfach dein eigenes Fenster über das des Spiels zu legen und es dann für überall, wo du nichts zeichnest, durchsichtig/transparent zu machen. Man kann die Mausklicks/Tastendrücke, die jetzt an dein Fenster statt an das Spiel gehen, auch an das Spiel weitergeben.



  • nwp3 schrieb:

    Du kannst das Bild/Screenshot des Spiels nehmen (mit http://pastebin.com/VxyfPDa7 oder wahrscheinlich gibt es dafür eine DirectX-Funktion), dann in dem Bild rummalen, dann das ganze Bild auf das Zielfenster malen.
    Du kannst das Bild auch in ein neues Fenster malen, dann zeigt es immer nur dein Bild an und es flackert nicht.

    Eine andere Möglichkeit wäre einfach dein eigenes Fenster über das des Spiels zu legen und es dann für überall, wo du nichts zeichnest, durchsichtig/transparent zu machen. Man kann die Mausklicks/Tastendrücke, die jetzt an dein Fenster statt an das Spiel gehen, auch an das Spiel weitergeben.

    Das hört sich doch schon mal ganz gut an!
    Um ehrlich zu sein, ich könnte sogar in den Prozessraums des anderen Spiels, jedoch muss das zeichnen mit meinem eigenen D3ddevice passieren.
    Hmm angenommen ich habe das d3ddevices von dem Spiel, kann ich dann irgendwie alles was bisher mit diesem device gezeichnet wurde auf mein device kopieren, dann könnte ich weiterzeichnen und diesen frame dann darstellen.



  • THEREAVER schrieb:

    nwp3 schrieb:

    Du kannst das Bild/Screenshot des Spiels nehmen (mit http://pastebin.com/VxyfPDa7 oder wahrscheinlich gibt es dafür eine DirectX-Funktion), dann in dem Bild rummalen, dann das ganze Bild auf das Zielfenster malen.
    Du kannst das Bild auch in ein neues Fenster malen, dann zeigt es immer nur dein Bild an und es flackert nicht.

    Eine andere Möglichkeit wäre einfach dein eigenes Fenster über das des Spiels zu legen und es dann für überall, wo du nichts zeichnest, durchsichtig/transparent zu machen. Man kann die Mausklicks/Tastendrücke, die jetzt an dein Fenster statt an das Spiel gehen, auch an das Spiel weitergeben.

    Das hört sich doch schon mal ganz gut an!

    Wird bloss nicht funktionieren.

    Um ehrlich zu sein, ich könnte sogar in den Prozessraums des anderen Spiels, jedoch muss das zeichnen mit meinem eigenen D3ddevice passieren.
    Hmm angenommen ich habe das d3ddevices von dem Spiel, kann ich dann irgendwie alles was bisher mit diesem device gezeichnet wurde auf mein device kopieren, dann könnte ich weiterzeichnen und diesen frame dann darstellen.

    Wieso meinst du ein eigenes Device zu brauchen?

    * Du hookst die Direct3DCreate Funktion
    * Deine Direct3DCreate gibt ein Wrapper-Interface zurück
    * Dein Wrapper-Interface implementiert die CreateDevice Funktion so, dass diese wieder ein Wrapper-Interface zurückgibt
    * Und im Present() des Wrapper-Interfaces für das Device zeichnest du dann: State-sichern (State-Block) -> alles malen was du malen willst -> State-widerherstellen -> Present

    Anders wird es nix werden. Zwei (oder mehr) D3D Devices im selben Prozess sind zwar grundsätzlich problemlos möglich -- aber nur so lange sie nicht halbtransparent "übereinander" malen wollen.

    Wenn es dein Ziel ist ein"kreativ flimmerndes" Programm zu basteln, dann nur zu, verwende ein eigenes Device.

    Wenn du was haben willst was sauber aussieht und nicht rumzickt wirst du vermutlich das machen müssen was alle machen - also so wie oben beschrieben.

    ps: Resourcen (Texturen, Frame-Buffer etc.) zwischen verschiedenen Devices sharen geht mit D3D9 schonmal gar nicht. Von daher...



  • Ich kenne die Methode aber bei diesem Spiel funktioniert es leider so nicht 😕
    Wenn ich in einem Present hook mein Zeichnen erledige, hat dies seltsamerweise Auswirkungen auf das Spiel. Grass wird anders dargestellt, die Map ist nicht mehr zu erkennen usw., so seltsam es auch klingt.

    Und es liegt nicht daran, dass ich states oder so verändere, denn was ich zeichnen will ist eine GUI und diese benutzt

    m_D3DDev->CreateStateBlock(D3DSBT_ALL, &m_StateBlock);
    

    ( http://bullet.googlecode.com/svn/trunk/Extras/CDTestFramework/AntTweakBar/src/TwDirect3D9.cpp )

    Darum brauche ich einen Ausweg, wie ich zeichnen kann, ohne in irgendeiner Form mit dem zeichnen von dem Spiel in Berührung zu kommen.



  • Hook es doch in die EndScene von d3d rein da kannst machen was du willst und das eigentliche Programm wird nichts davon mitbekommen



  • nein da geht es auch nicht, genau das ist ja das Problem.



  • Und eine dll über einen detour hook in den Prozess injectn und dann auf die EndScene sollte gehn hab ich auch immer gemacht um Overlay Menüs zu erstellen



  • Die am weitesten benutzte Overlay Bibliothek ist das Steam Overlay in einer DLL verpackt. Das wird von Steam selbst verwendet um Community Overlays einzublenden. Einige Beiträge erklären wie man diese DLL für sich verwendet.
    Hooks werden meist erkannt.
    Ich würde auch gerne meine eigenen Overlays erweitern, was ist den im Moment der gebräuchlichste Weg? Welche SDK wird bevorzugt?
    EasyHook, Detours 3?


Log in to reply