2009-05-29 22 views
36

Quiero mostrar algunos gráficos personalizados en la parte superior de una aplicación de Windows de pantalla completa de terceros.Superposición en una aplicación de pantalla completa en 3D

¿Has jugado algún juego de Steam? Tiene un ejecutable, GameOverlayUI.exe que te permite acceder a las ventanas de Steam desde dentro de un juego. (Los elementos de la GUI parecen dibujados a medida, no sé si eso es necesario, pero se ven exactamente igual dentro de un juego que en el escritorio). Incluso llega a oscurecer los gráficos del juego en el fondo.

Me pregunto cómo se podría escribir una aplicación de este tipo.

También me pregunto qué tan amplio sería el alcance de las soluciones. ¿Podría usar un método para todas las aplicaciones OpenGL? Para todas las aplicaciones Direct3D menos DirectDraw? Para todas las aplicaciones de Windows a pantalla completa?

Estoy buscando soluciones más 'modernas' y genéricas: superponer un símbolo del sistema o una aplicación de color indexada de 320x240 no es una preocupación.

Editar: Algunas aclaraciones: La aplicación a pantalla completa no es mía. Puede ser cualquier cosa. Lo más probable es que sea un juego en 3D. Quiero mostrar, digamos un reloj digital en la esquina inferior derecha de la pantalla, en la parte superior de los gráficos del juego. Me gustaría evitar trucos como inyectar código o depurar el proceso, si es posible.

+0

¿Qué tan lejos logró llegar al enfoque anterior? Estoy atrapado en una situación similar y quiero dibujar vistas web incrustadas de cromo como superposición. ¿Crees que eso es posible? – alDiablo

Respuesta

18

Bueno, aquí hay otro ejemplo.Xfire es un programa de chat que superpone su interfaz en juegos para que puedas recibir mensajes mientras juegas. La forma en que lo hacen es editando la DLL d3d/opengl en el nivel de memoria de proceso, como inyectar saltos de ensamblaje. Lo sé porque su método estaba causando que mi mod se bloquee, y realmente vi el extraño código de ensamblado que estaban inyectando en el d3d9.dll.

Así que aquí es como Xfire hace esto:

  1. objetivo del proceso del juego
  2. buscar su memoria para el proceso de d3d.dll/opengl.dll
  3. inyectar en el proceso de una DLL que contiene la costumbre interfaz lógica
  4. conecte las funciones de la interfaz al flujo del programa escribiendo manualmente saltos de conjunto en las funciones d3d/opengl encontradas en la memoria de proceso

No hay otra forma concebible ya que es necesario secuestrar el dispositivo gráfico que pertenece a ese juego. Estoy dispuesto a apostar que Steam lo hace de la misma manera que Xfire. Así que sí, no es una forma fácil de hacerlo a menos que alguien haya creado una biblioteca útil para hacer todo lo que necesita hacer en el nivel bajo.

También ha preguntado sobre atenuar los gráficos del juego debajo de su plantilla. Esta es una simple llamada a DrawPrimitive para dibujar un rectángulo transparente lleno sobre la pantalla.

+0

excelente. Junto con su otra respuesta, esto es lo que he estado buscando. Gracias. – aib

+9

¡Tenga cuidado al hacer esto con juegos multijugador que requieren un software anti trampa como Punkbuster! Inyectar bibliotecas personalizadas en juegos en ejecución se considera manipulación intrusiva y trampas. Los programas (como Xfire, Teamspeak Overlay, ...) aparecen en la lista blanca y ya no causarán infracciones por trampas, pero es un proceso de aprendizaje realizado por Anti-Cheat-Vendor, que puede consumir mucho tiempo y su programa no puede ser procesado. efectivamente utilizado. – Robert

-1

He hecho superposiciones con ambos DirectX & WPF viewports (lo mismo, en realidad), usando la superposición para pintar algunas bonitas cosas 2D GDI + en la parte superior de las visualizaciones 3D.

Logré usando un panel en la parte superior de la visualización "real", estableciendo el color como transparente a excepción de los bits que quería superpuestos. Funcionó bastante bien, pero fue un poco doloroso pasar clic, arrastre y otros eventos a través de la capa de "dibujo" al control 3D.

+0

Lo siento si mi pregunta no era clara: la visualización "real" es extraída por una aplicación de terceros, en mi caso. He hecho lo que dijiste, una vez, en el contexto de una sola aplicación. No sé si su respuesta es relevante en el contexto de dos aplicaciones diferentes; si es así, ¿cómo podría crear un panel secundario en el contexto del elemento primario de pantalla completa? – aib

18

Creado Un Gist con código completo here

Este es un arte muy esotérica, y hay varias maneras de hacer esto. Prefiero lo que se llama Contenedor Direct3D. Han pasado años desde que hice esto, pero lo hice con un juego una vez. Puede que haya omitido algunos detalles, pero solo espero ilustrar la idea.

Todos los juegos de Direct3D9 deben llamar al IDirect3DDevice9::EndScene después de que la pantalla se represente y esté lista para dibujarse. Entonces, en teoría, podemos poner código personalizado dentro de EndScene que dibuje lo que queremos sobre el juego. Hacemos esto creando una clase que se parece a IDirect3DDevice9 para el juego, pero en realidad es solo un contenedor que reenvía todas las llamadas a la clase real. Así que ahora, en nuestra clase personalizada, nuestra función de contenedor para EndScene se ve así:

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

    realDevice.EndScene(); 
} 

Luego compilarlo en un archivo DLL llamado d3d9.dll, y colocarlo en el directorio del ejecutable del juego. El archivo d3d9.dll real debe estar en la carpeta/system32, pero el juego primero se ve en el directorio actual y, en su lugar, carga el nuestro. Una vez que se carga el juego, utiliza nuestra DLL para crear una instancia de nuestra clase contenedora. Y ahora cada vez que se llama a EndScene, nuestro código se ejecuta para dibujar lo que queremos para la pantalla.

Creo que puedes probar el mismo principio con OpenGL. Pero para evitar manipulaciones, creo que algunos juegos modernos intentan evitar esto.

+0

El ajuste de archivos DLL es una buena técnica que he hecho en el pasado; gracias por los punteros D3D. Sin embargo, creo que Steam tiene una mejor manera de hacerlo. Creo que debería investigar un poco más. – aib

+1

¿Podría indicarme un recurso para principiantes? Mi idea para un mod de juego es aplicar ciertos efectos de sombreado en ciertas situaciones, y esta parece ser la manera de hacerlo. Sin embargo, nunca he hecho ninguna programación con DirectX, así que estoy en la oscuridad de por dónde empezar. –

0

He estado pensando en esto. Para OpenGL, conectaría SwapBuffers de WGL con Detours, dibujaría mis cosas después del juego y luego intercambiaría búferes yo mismo.

2

existe un proyecto de software libre, su nombre es taksi link text. No estoy seguro de cómo esta aplicación anula el proceso porque todavía estoy examinando el código, pero compruebe que este es un buen proyecto

Cuestiones relacionadas