Superposition sur une application 3D Plein écran

Je veux afficher des graphiques personnalisés au-dessus d'une application Windows en plein écran 3rd party.

Avez-vous joué à des jeux Steam? Il a un exécutable, GameOverlayUI.exe qui vous permet d'accéder aux fenêtres Steam à partir d'un jeu. (Les éléments de L'interface graphique ont l'air dessinés sur mesure, Je ne sais pas si c'est une nécessité; mais ils ont exactement la même apparence dans un jeu que sur le bureau.) Il va même jusqu'à 'dim' les graphismes du jeu en arrière-plan.

Je me demande comment on pourrait aller sur l'écriture d'une telle demande.

Je me demande aussi à quel point la portée des solutions serait large. Pourriez-vous utiliser une méthode pour toutes les applications OpenGL? Pour toutes les applications Direct3D moins DirectDraw? Pour toutes les applications Windows plein écran?

Je cherche des solutions plus "modernes" et génériques-superposer une invite de commande ou une application de couleur indexée 320x240 n'est pas un problème.

Edit: quelques éclaircissements: L'application Plein écran n'est pas à moi. Il peut être n'importe quoi. Très probablement, ce sera un jeu en 3D. Je veux afficher, dire une horloge numérique dans le coin inférieur droit de l'écran, au-dessus des graphismes du jeu. Je voudrais éviter les astuces telles que l'injection de code ou le débogage du processus, si possible.

37
demandé sur Lodle 2009-05-29 17:32:12

5 réponses

Eh bien, voici un autre exemple. Xfire est un programme de chat qui superpose son interface dans les jeux afin que vous puissiez recevoir des messages tout en jouant. La façon dont ils le font est d'éditer la DLL D3D / opengl au niveau de la mémoire du processus, comme l'injection de sauts d'assemblage. Je le sais parce que leur méthode provoquait le crash de mon mod, et j'ai en fait vu l'étrange code d'assemblage qu'ils injectaient dans le d3d9.DLL.

Voici Donc comment Xfire fait ceci:

  1. cibler le processus de la jeu
  2. Recherche sa mémoire de processus pour D3D. dll / opengl.dll
  3. injectez dans le processus une DLL contenant la logique d'interface personnalisée
  4. Connectez les fonctions de l'interface au flux du programme en écrivant manuellement des sauts d'assemblage dans les fonctions D3D / opengl trouvées dans la mémoire du processus

Il n'y a pas d'autre moyen concevable puisque vous avez besoin de détourner le périphérique graphique qui appartient à ce jeu. Je suis prêt à parier que Steam le fait de la même manière que Xfire. Donc oui, pas facile pour ce faire, à moins que quelqu'un a créé un utile bibliothèque pour faire tout ce que vous devez faire au niveau bas.

Vous avez également posé des questions sur la gradation des graphismes du jeu sous votre superposition. Ceci est juste un simple appel DrawPrimitive pour dessiner un rectangle transparent rempli sur l'écran.

21
répondu Shaun Lebron 2009-11-05 20:54:30

Créé une Gist avec le plein code ici

C'est un art assez ésotérique, et il y a plusieurs façons de le faire. Je préfère ce qu'on appelle un Wrapper Direct3D. Cela fait des années que je ne l'ai pas fait, mais je l'ai fait avec un jeu une fois. J'ai peut-être laissé de côté certains détails, mais j'espère juste pour illustrer l'idée.

Tous les jeux Direct3D9 doivent appeler IDirect3DDevice9:: EndScene Une fois l'écran rendu et prêt à être dessiné. Donc, en théorie, nous peut mettre du code personnalisé à l'intérieur de EndScene qui dessine ce que nous voulons sur le jeu. Nous le faisons en créant une classe qui ressemble à IDirect3DDevice9 au jeu, mais c'est vraiment juste un wrapper qui transmet tous les appels de fonction à la classe réelle. Alors maintenant, dans notre classe personnalisée, notre fonction wrapper pour EndScene ressemble à ceci:

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

   realDevice.EndScene();
}

Ensuite, nous le compilons dans une DLL appelée D3D9.dll, et déposez-le dans le répertoire de l'exécutable du jeu. Le vrai d3d9.dll devrait être dans le dossier / system32, mais le jeu en premier regarde dans le répertoire courant, et charge à la place le nôtre. Une fois le jeu chargé, il utilise notre DLL pour créer une instance de notre classe wrapper. Et maintenant, chaque fois que EndScene est appelé, notre code est exécuté pour dessiner ce que nous voulons à l'écran.

Je pense que vous pouvez essayer le même principe avec OpenGL. Mais pour éviter la falsification, je pense que certains jeux modernes essaient d'empêcher cela.

19
répondu Shaun Lebron 2015-08-07 13:45:14

Therers un projet de logiciel libre son nom taksi texte du lien. Je ne sais pas comment cette application remplace le processus parce que j'examine encore le code mais checkit je pense que c'est un bon projet

2
répondu Car 2010-05-06 15:52:30

J'y ai réfléchi. Pour OpenGL, j'accrocherais les SwapBuffers de WGL avec des détours, dessinant mes trucs après le jeu, puis échangeant des tampons moi-même.

0
répondu 2009-11-16 18:11:33

J'ai fait des superpositions avec les deux fenêtres DirectX et WPF (la même chose, vraiment), en utilisant la superposition pour peindre de belles choses 2D GDI+ au - dessus des visualisations 3D.

J'ai réussi en utilisant un panneau au - dessus de la visualisation "réelle", en définissant la couleur sur transparent sauf pour les bits que je voulais superposer. Cela a plutôt bien fonctionné, mais c'était un peu pénible en passant le clic, le glisser et d'autres événements à travers le calque "dessin" au contrôle 3D.

-1
répondu moobaa 2009-05-29 13:39:45