Schermata del video di gioco


8

Vorrei "agganciarmi" a un gioco in esecuzione, ad esempio Mario Bros, e catturare ogni fotogramma reso ... salvando quel fotogramma in un file di immagine. Un buon esempio di qualcosa di simile è FRAPS. - Nota: non voglio catturare l'intero schermo / desktop. Voglio catturare una finestra mirata.

Ho dato un'occhiata a OBS (Open Broadcasting Software) ma non è particolarmente veloce. Non fraintendetemi, è un ottimo software, ma sfortunatamente non c'è / scarsa documentazione, il che rende un progetto enorme scritto in c e c ++ quasi inaccessibile per un programmatore da nuovo a c ++.

Ho anche dato un'occhiata a GamingAnywhere , ma sfortunatamente non riesco a farlo funzionare, c'è pochissima / nessuna documentazione, funziona solo su VS2010 ed è disordinato (con un nome variabile scarso). Tuttavia, è un progetto di ricerca e quindi è comprensibilmente privo di documenti e disordinato.

So che questo può essere fatto con OpenGL, GDI e con Direct3D, ma non riesco a trovare alcuni buoni esempi in rete.

Ho letto che glReadlPixels (usando OpenGL) può essere usato e ho letto la documentazione , ma il post non menzionava nulla sull'aggancio a una grafica di gioco / applicazione in esecuzione.

Domande:

  1. Posso agganciarmi alla grafica di un gioco sviluppato con OpenGL, usando, per esempio, Direct3D? La libreria utilizzata per l'aggancio deve essere uguale a quella utilizzata dal gioco?

  2. Come posso collegarmi ai frame renderizzati del gioco in modo da poterli output su file di immagine o su un file video? (Solo alcuni link o una breve spiegazione di ciò che devo fare sarebbe fantastico)

  3. BackBuffer - Ho letto che è molto veloce accedere al BackBuffer per recuperare i frame. Qualcuno ha un esempio per me su come farlo con le ultime librerie? Ho scoperto che la maggior parte degli esempi non sono aggiornati.

  4. Per i miei scopi, c'è chiaramente "questo è più veloce di così"? Quello che voglio dire è, sarebbe, dire OpenGL, essere più veloce per i miei scopi?

Se qualcuno è a conoscenza di un progetto open source (che fa essenzialmente ciò di cui ho bisogno) che è attivamente sviluppato e ben documentato, mi piacerebbe saperlo.


Ora questo sembra essere solo Mac, che potrebbe non funzionare per te con Direct3D, ma Siphon Inject che OBS utilizza su Mac può catturare finestre di gioco che utilizzano OpenGL molto più velocemente della normale acquisizione video. Il sifone "consente alle applicazioni di condividere fotogrammi - video full frame rate o immagini fisse - tra loro in tempo reale" per citare il sito Web.
Gliderman,

@Gliderman Grazie, lo controllerò!
pookie,

Risposte:


7

È possibile fare ciò che descrivi, ma temo che non sia un processo banale. In realtà, questo sarà molto legato ai Sistemi Operativi che stai prendendo di mira e forse richiederà anche modifiche specifiche per il gioco / l'applicazione in questione.

Vorrei iniziare a esaminare le tecniche di iniezione DLL , che dovrebbero consentire, ad esempio, l'intercettazione delle chiamate alle API Direct3D (Windows) o OpenGL, che è quindi possibile utilizzare per copiare i framebuffer dell'applicazione. Una rapida ricerca su Internet rivela questo e questo con spiegazioni dettagliate.

Una volta ho scritto un intercettore OpenGL su piccola scala su MacOS iniettando un modulo condiviso personalizzato, ma era in circostanze molto controllate e facendo molte ipotesi, come avere i privilegi di root nel sistema, quindi per uno strumento di produzione, sarebbe molto più complicato. Puoi trovare un altro progetto molto interessante qui sull'intercettazione dell'API D3D per installare un bot AI automatizzato su Starcraft, che dovrebbe toccare concetti molto simili a quello che stai cercando.

Una volta che riesci a intercettare l'API di rendering sottostante, potresti forse agganciare il tuo codice a ciascuna SwapBufferschiamata o equivalente per copiare il framebuffer precedente prima dello scambio, quindi salvarlo (è qui glReadPixelsche entrerebbe in gioco qualcosa di simile ).

Anche copiare e salvare il framebuffer in modo efficiente è una sfida. Il modo più semplice è scaricare ogni frame come un'immagine RGB non compressa, ma poi ti ritroverai con centinaia di gigabyte di dati per un paio di minuti di gioco, quindi a meno che tu non abbia un buon array di HDD seduto all'angolo di il tuo tavolo ;), dovrai cercare di comprimere i frame in qualche modo.

L'aspetto negativo di comprimere i frame ora è che richiede molta elaborazione, quindi un approccio ingenuo potrebbe trasformare l'applicazione una volta interattiva che si sta tentando di registrare in una presentazione interattiva :(. Quindi a questo punto dovresti iniziare a pensare alle ottimizzazioni.

Non conosco progetti là fuori che forniscano una libreria per un'acquisizione efficiente dei frame per i giochi, ma questo sarebbe sicuramente qualcosa di bello da avere! Penso che una cosa che potrebbe trattenere tale progetto sia, come ho detto all'inizio, che questa è una cosa molto dipendente dal sistema, quindi i casi d'uso saranno molto probabilmente limitati a una singola piattaforma o sistema operativo.


Grazie per la risposta. Penso che alla fine, invece di salvare le immagini, le farò in streaming su una macchina remota, quindi la copia del framebuffer potrebbe essere la strada da percorrere. Sembra che tu abbia una discreta esperienza con queste cose. Sei in grado di espandere una delle domande che ho posto? Grazie per l'aiuto!
pookie,

1
@pookie Hey! Certo, posso espandere questo. C'è qualcosa in particolare su cui vorresti che io commentassi? Per le tue domande, penso che 1 e 2 possano essere fatti con gli hook DLL, quindi assicurati di leggere i collegamenti che ho incluso (specialmente quello su Starcraft). 3 e 4 saranno specifici dell'API, ma su OpenGL, puoi iniziare con glReadPixels e lavorare da lì se lo trovi troppo lento. La mia esperienza è quella di registrare fotogrammi dai miei giochi più un po 'di hacking DLL fatto in passato, ma non ho mai combinato entrambi nel tentativo di registrare fotogrammi da un'app di terze parti;)
glampert

Grazie! Ho controllato i collegamenti: l'iniezione di Windows DLL e il collegamento a Starcraft (piuttosto fantastico) sembrano essere buoni punti di partenza. Daremo un'occhiata anche a glReadPixels. Secondo te, con quale hai trovato più facile lavorare e quale hai trovato più velocemente: DirectX o OpenGL?
pookie,

@pookie, se hai qualche esperienza di programmazione, penso che Direct3D sarà molto più facile da usare, le librerie sono progettate meglio. Secondo me anche OpenGL potrebbe avere dei "bordi irregolari" (questo proviene da qualcuno che usa OpenGL più di D3D). D3D è solo Windows, quindi potrebbe essere negativo per te, non lo so. Per quanto riguarda le prestazioni, non credo che farà molta differenza quale usi. Il miglior consiglio che posso darti probabilmente è: prima scopri come farlo funzionare, poi preoccupati delle ottimizzazioni.
glampert

1
Ah, ok, se hai familiarità con la programmazione OOP, D3D sarà sicuramente più facile. OpenGL è tutto procedurale e utilizza un sacco di stato globale, questo è principalmente ciò che intendevo per bordi grezzi. Buona fortuna a te!
glampert
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.