Je voudrais "accrocher" à un jeu en cours, par exemple Mario Bros, et capturer chaque image rendue ... en enregistrant cette image dans un fichier image. FRAPS est un bon exemple de quelque chose de similaire. --Remarque: je ne veux pas capturer l'ensemble de l'écran / du bureau. Je veux capturer une fenêtre ciblée.
J'ai jeté un œil à OBS (Open Broadcasting Software) mais ce n'est pas particulièrement rapide. Ne vous méprenez pas, c'est un excellent logiciel, mais malheureusement il n'y a pas / peu de documentation, ce qui rend un projet massif écrit en c et c ++ presque inaccessible pour un programmeur débutant en c ++.
J'ai également jeté un œil à GamingAnywhere , mais malheureusement, je ne peux pas le faire fonctionner, il y a très peu / pas de documentation, ne fonctionne que dans VS2010 et est désordonné (avec un mauvais nom de variable). Cependant, il s'agit d'un projet de recherche et il est donc compréhensible que ce soit sans papiers et en désordre.
Je sais que cela peut être fait avec OpenGL, GDI et Direct3D, mais je ne trouve pas de bons exemples sur le net.
J'ai lu que glReadlPixels (en utilisant OpenGL) peut être utilisé et j'ai lu la documentation , mais le post ne mentionnait rien sur la connexion à un jeu / une application graphique en cours d'exécution.
Des questions:
Puis-je me connecter aux graphismes d'un jeu développé avec OpenGL, en utilisant, par exemple, Direct3D? La bibliothèque utilisée pour le hook doit-elle être la même que celle utilisée par le jeu?
Comment puis-je me connecter aux images rendues du jeu afin de pouvoir exporter ces images vers des fichiers image ou vers un fichier vidéo? (Juste quelques liens ou une brève explication de ce que je dois faire serait génial)
BackBuffer - J'ai lu qu'il est très rapide d'accéder au BackBuffer pour récupérer les images. Quelqu'un a-t-il un exemple pour moi sur la façon de procéder avec les dernières bibliothèques? J'ai constaté que la plupart des exemples sont obsolètes.
Pour mes besoins, y a-t-il clairement «c'est plus rapide que ça»? Ce que je veux dire, par exemple, serait OpenGL, serait plus rapide pour mes besoins?
Si quelqu'un connaît un projet open source (qui fait essentiellement ce dont j'ai besoin) qui est activement développé et bien documenté, j'aimerais le savoir.
Réponses:
Il est possible de faire ce que vous décrivez, mais je crains que ce ne soit pas un processus trivial. En fait, cela sera très lié aux systèmes d'exploitation que vous ciblez et nécessitera peut-être également des ajustements spécifiques pour le jeu / l'application donné.
Je commencerais à étudier les techniques d' injection de DLL , qui devraient permettre, par exemple, d'intercepter les appels aux API Direct3D (Windows) ou OpenGL, que vous pouvez ensuite utiliser pour copier les tampons de cadre de l'application. Une recherche rapide sur Internet révèle ceci et cela avec une explication détaillée.
J'ai écrit une fois un intercepteur OpenGL à petite échelle sur MacOS en injectant un module partagé personnalisé, mais c'était dans des circonstances très contrôlées et en faisant beaucoup d'hypothèses, comme avoir des privilèges root dans le système, donc pour un outil de production, ce serait beaucoup plus compliqué. Vous pouvez trouver un autre projet très intéressant ici sur l'interception de l'API D3D pour installer un bot AI automatisé sur Starcraft, qui devrait aborder des concepts très similaires à ce que vous recherchez.
Une fois que vous avez réussi à intercepter l'API de rendu sous-jacente, vous pouvez alors peut-être accrocher votre code à chaque
SwapBuffers
appel ou équivalent pour simplement copier le tampon de trame précédent avant le swap, puis l'enregistrer (c'est là que quelque chose comme celaglReadPixels
entrerait en jeu).Copier et enregistrer le framebuffer de manière efficace est également difficile. Le moyen le plus simple est de simplement vider chaque image sous forme d'image RVB non compressée, mais vous vous retrouverez ensuite avec des centaines de gigaoctets de données pour seulement quelques minutes de jeu, donc à moins que vous n'ayez un joli réseau de disques durs assis au coin de votre table
;)
, vous aurez besoin de regarder dans la compression des cadres en quelque sorte.L'inconvénient de la compression des images maintenant est que cela prend beaucoup de traitement, donc une approche naïve pourrait transformer l'application une fois interactive que vous essayez d'enregistrer en un diaporama interactif
:(
. À ce stade, vous devez donc commencer à penser aux optimisations.Je ne connais aucun projet proposant une bibliothèque pour une capture d'images efficace pour les jeux, mais ce serait certainement quelque chose de bien! Je pense qu'une chose qui pourrait empêcher un tel projet est, comme je l'ai mentionné au début, que c'est une chose très dépendante du système, donc les cas d'utilisation seront très probablement limités à une seule plate-forme ou un seul système d'exploitation.
la source