2009-05-29 17 views
36

Desidero visualizzare alcuni elementi grafici personalizzati su un'applicazione Windows a schermo intero di terze parti.Sovrapposizione su un'applicazione a schermo intero 3D

Hai mai giocato a Steam? Ha un eseguibile, GameOverlayUI.exe che ti consente di accedere a Steam windows all'interno di un gioco. (Gli elementi della GUI sembrano disegnati su misura, non so se è una necessità, ma hanno lo stesso aspetto all'interno di un gioco come fanno sul desktop.) Si spinge fino a "oscurare" la grafica del gioco in lo sfondo.

Mi chiedo come si possa scrivere una tale applicazione.

Mi chiedo anche come sarebbe ampia la portata delle soluzioni. Potresti usare un metodo per tutte le applicazioni OpenGL? Per tutte le Direct3D meno le applicazioni DirectDraw? Per tutte le applicazioni Windows a schermo intero?

Sto cercando soluzioni più "moderne" e generiche: la sovrapposizione di un prompt dei comandi o di un'applicazione di colore indicizzata 320x240 non è un problema.

Modifica: alcuni chiarimenti: l'applicazione a schermo intero non è mia. Può essere qualsiasi cosa. Molto probabilmente, sarà un gioco 3D. Voglio mostrare, diciamo un orologio digitale nell'angolo in basso a destra dello schermo, in cima alla grafica del gioco. Vorrei evitare trucchi come l'iniezione di codice o il debug del processo, se possibile.

+0

Fino a che punto è riuscito ad andare con l'approccio di cui sopra. Sono bloccato in una situazione simile e voglio disegnare visualizzazioni web incorporate con cromo come sovrapposizione. Pensi che sia possibile? – alDiablo

risposta

18

Bene, ecco un altro esempio.Xfire è un programma di chat che si sovrappone alla sua interfaccia in giochi in modo da poter ricevere messaggi durante il gioco. Il modo in cui lo fanno è modificando la DLL d3d/opengl a livello di memoria di processo, come l'iniezione di salti di assieme. Lo so perché il loro metodo stava causando il crash del mio mod, e in effetti ho visto lo strano codice assembly che stavano iniettando nel d3d9.dll.

quindi ecco come Xfire fa questo:

  1. bersaglio il processo del gioco
  2. cerca la sua memoria di processo per d3d.dll/opengl.dll
  3. iniettare nel processo di una DLL che contiene il costume logica di interfaccia
  4. collegare le funzioni dell'interfaccia al flusso del programma scrivendo manualmente i salti di assieme nelle funzioni d3d/opengl presenti nella memoria di processo

Non c'è altro modo immaginabile dal momento che è necessario dirottare il dispositivo grafico che appartiene a quel gioco. Sono disposto a scommettere che Steam lo fa allo stesso modo di Xfire. Quindi sì, non è un modo semplice per farlo a meno che qualcuno non abbia creato una libreria utile per fare tutto ciò che è necessario fare a basso livello.

Hai anche chiesto di oscurare la grafica del gioco sotto il tuo overlay. Questa è solo una semplice chiamata DrawPrimitive per disegnare un rettangolo trasparente pieno sullo schermo.

+0

eccellente. Accoppiato con la tua altra risposta, questo è quello che stavo cercando. Grazie. – aib

+9

Fai attenzione quando fai questo con giochi multiplayer che richiedono software anti cheat come Punkbuster! L'iniezione di librerie personalizzate in giochi in esecuzione è considerata una manipolazione intrusiva di giochi e imbrogli. I programmi (come Xfire, Teamspeak Overlay, ...) sono elencati in bianco e non causeranno più violazioni fraudolente, ma è un processo di apprendimento svolto da Anti-Cheat-Vendor che può richiedere molto tempo in cui il tuo programma non può essere efficacemente usato. – Robert

-1

ho fatto sovrapposizioni con entrambe le DirectX & finestre WPF (stessa cosa, in realtà), con la sovrapposizione di dipingere qualche bel GDI + 2D roba in cima visualizzazioni 3D.

Sono riuscito utilizzando un pannello sopra la visualizzazione "effettiva", impostando il colore su trasparente eccetto per i bit che volevo sovrapposti. Ha funzionato abbastanza bene, ma è stato un po 'fastidioso passare clic, trascinare e altri eventi attraverso il livello "disegno" al controllo 3D.

+0

Mi dispiace se la mia domanda non è chiara: la visualizzazione "effettiva" viene disegnata da un'app di terze parti, nel mio caso. Ho fatto quello che hai detto, una volta, nel contesto di una singola applicazione. Non so se la tua risposta è pertinente nel contesto di due diverse applicazioni; se lo è, come andrei sulla creazione di un pannello secondario nel contesto del genitore a schermo intero? – aib

18

creato un Gist con piena codice here

Questa è un'arte piuttosto esoterica, e ci sono diversi modi per farlo. Preferisco quello che viene chiamato Wrapper Direct3D. Sono passati anni da quando l'ho fatto, ma l'ho fatto con un gioco una volta. Potrei aver omesso alcuni dettagli, ma spero solo di illustrare l'idea.

Tutti i giochi Direct3D9 devono chiamare IDirect3DDevice9::EndScene dopo che la schermata è stata renderizzata e pronta per essere disegnata. Quindi, in teoria, possiamo inserire il codice personalizzato all'interno di EndScene che disegna ciò che vogliamo nel gioco. Lo facciamo creando una classe simile a IDirect3DDevice9 al gioco, ma in realtà è solo un wrapper che inoltra tutte le chiamate di funzione alla classe reale. Così ora, nella nostra classe personalizzata, la nostra funzione wrapper per EndScene assomiglia a questo:

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

    realDevice.EndScene(); 
} 

Poi abbiamo compilarlo in una DLL chiamata d3d9.dll, e rilasciarlo nella directory del file eseguibile del gioco. Il vero d3d9.dll dovrebbe essere nella cartella/system32, ma il gioco prima guarda nella directory corrente, e invece carica il nostro. Una volta caricato il gioco, utilizza la nostra DLL per creare un'istanza della nostra classe wrapper. E ora ogni volta che viene chiamato EndScene, il nostro codice viene eseguito per disegnare ciò che vogliamo sullo schermo.

Penso che si possa provare lo stesso principio con OpenGL. Ma per evitare manomissioni, penso che alcuni giochi moderni provano a impedirlo.

+0

Il wrapping della DLL è una buona tecnica che ho fatto in passato; grazie per i puntatori D3D. Tuttavia, penso che Steam abbia un modo migliore per farlo. Credo che dovrei fare qualche altra ricerca. – aib

+1

Potrebbe indicarmi una risorsa per i principianti? La mia idea per un mod di gioco è applicare determinati effetti shader in determinate situazioni e questo sembra essere il modo per farlo. Tuttavia, non ho mai fatto alcuna programmazione con DirectX, quindi sono al buio da dove cominciare. –

0

Ci stavo pensando. Per OpenGL, collegherei gli SwapBuffer di WGL con Detours, disegnando le mie cose dopo il gioco e poi scambiando i buffer personalmente.

2

un progetto di software libero il suo nome è taksi link text. non sono sicuro di come questa applicazione prevale sul processo perché sto esaminando il codice, ma penso che questo sia un buon progetto

Problemi correlati