windows - Overlaying på et 3D fuldskærmsprogram

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg vil gerne vise nogle brugerdefineret grafik oven på en 3-parters fuldskærm Windows-applikation.


Har du spillet nogle dampspil? Den har en eksekverbar, GameOverlayUI.exe, som giver dig adgang til Steam-vinduer fra et spil. (GUI-elementerne er skræddersyede, jeg ved ikke, om det er en nødvendighed, men de ser nøjagtigt det samme inden for et spil som de gør på skrivebordet.) Det går endda lige så langt at 'dæmpe' spilgrafikgraden i baggrunden.


Jeg undrer mig over, hvordan man kunne gå på at skrive en sådan ansøgning.


Jeg undrer mig også over, hvor bredt omfanget af løsninger ville være. Kan du bruge en metode til alle OpenGL-applikationer? For alle Direct3D minus DirectDraw-applikationer? Til alle Windows-applikationer i fuldskærm?


Jeg søger mere 'moderne' og generiske løsninger - overlaying en kommandoprompt eller et indekseret farveprogram på 320x240 er ikke et problem.


Rediger: Nogle præciseringer: Fullscreen applikationen er ikke min. Det kan være noget. Det vil nok være et 3D-spil. Jeg vil vise, sige et digitalt ur i nederste højre hjørne af skærmen, oven på spilgrafik. Jeg vil gerne undgå tricks, såsom indsprøjtning af kode eller debugging af processen, hvis det er muligt.

Bedste reference


Nå er her et andet eksempel. Xfire er et chatprogram, der overlejrer sin grænseflade til spil, så du kan modtage beskeder mens du spiller. Sådan gør du det ved at redigere d3d/opengl DLL på procesminne niveau, som f.eks. . Jeg ved det, fordi deres metode forårsagede mit mod at gå ned, og jeg så faktisk den mærkelige forsamlingskode, de injicerede i d3d9.dll.


Så her er hvordan Xfire gør dette:



  1. mål processen i spillet

  2. Søg i proceshukommelsen for d3d.dll/opengl.dll

  3. indsprøjt i processen en DLL indeholdende brugerdefineret interface logik

  4. Tilslut grænsefladens funktioner til programflowet ved manuelt at skrive samlespring i d3d/opengl-funktionerne, der findes i proceshukommelsen



Der er ingen anden tænkelig måde, da du skal kapre den grafiske enhed, der hører til det pågældende spil. Jeg er villig til at satse på, at Steam gør det på samme måde som Xfire. Så ja, ingen nem måde at gøre dette på, medmindre nogen lavede et nyttigt bibliotek til at gøre alt, hvad du skal gøre på det lave niveau.


Du har også spurgt om at dæmpe spilgrafik under dit overlay. Dette er blot et simpelt DrawPrimitive opkald for at tegne et fyldt transparent rektangel over skærmen.

Andre referencer 1


Opret et Gist med fuld kode her [6]


Dette er en smuk esoterisk kunst, og der er flere måder at gøre dette på. Jeg foretrækker, hvad der hedder en Direct3D Wrapper . Det har været år siden jeg har gjort det, men jeg gjorde det med et spil en gang. Jeg har muligvis udeladt nogle detaljer, men jeg håber bare at illustrere ideen.


Alle Direct3D9-spil skal ringe til IDirect3DDevice9 :: EndScene, når skærmen er gengivet og klar til at blive tegnet. Så i teorien kan vi sætte brugerdefineret kode inde i EndScene, der trækker hvad vi ønsker over spillet. Dette gør vi ved at oprette en klasse, der ligner IDirect3DDevice9 til spillet, men det er virkelig en wrapper, der videresender alle funktionsopkald til den rigtige klasse. Så nu i vores brugerklasse, vores indpakningsfunktion til EndScene ser sådan ud: [7]


HRESULT IDirect3DDevice9::EndScene()
{
   // draw overlays here

   realDevice.EndScene();
}


Så kompilerer vi det til en DLL, der hedder d3d9.dll, og slettes det i den kørekatalog, der er eksekverbart. Den rigtige d3d9.dll skal være i mappen/system32, men spillet ser først ud i den nuværende mappe og lægger i stedet vores Når spillet er lastet, bruger det vores DLL til at skabe en forekomst af vores wrapper klasse. Og nu kaldes hver gang EndScene, vores kode udføres for at tegne det, vi ønsker på skærmen.


Jeg tror, ​​du kan prøve det samme princip med OpenGL. Men for at forhindre manipulation tror jeg, at nogle moderne spil forsøger at forhindre dette.

Andre referencer 2


Jeg er ikke sikker på, hvordan denne applikation tilsidesætter processen, fordi jeg er ved at undersøge koden endnu, men checkit, jeg tror, ​​at dette er et godt projekt [8].

Andre referencer 3


Jeg har tænkt på dette. For OpenGL knytter jeg WGLs SwapBuffers med omkørsler, tegner mine ting efter spillet og skifter selv buffere.

Andre referencer 4


Jeg har lavet overlejringer med både DirectX og WPF viewports (samme ting, virkelig), ved at bruge overlejret til at male nogle fine 2D GDI + ting oven på 3D visualiseringer.


Jeg formåede at bruge et panel oven på den 'egentlige' visualisering, idet farven blev gennemsigtig bortset fra de bits, jeg ønskede overlaid. Arbejdet ret godt, men det var lidt af en smerte ved at klikke, trække og andre begivenheder gennem 'tegning' laget til 3D-kontrollen.