La Web del Programador: Comunidad de Programadores
 
    Pregunta:  11441 - RECUPERACIóN DE SUPERFICIES BAJO DIRECTX
Autor:  Pablo Iglesias Craviotto
Soy un aprendiz de DirectX y programo en Visual C++. No se si por aquí habrá alguien familiarizado con el uso de las SDK.

Mi duda es en lo referente a la recuperación de superficies perdidas. Ocurre que cuando minimizo la ventana de mi juego o me salgo temporalmente del mismo con Alt+TAB, me resulta imposible volver al mismo por la pérdida de las superficies en la memoria, que ha sido sobreescrita con infrmación de otras aplicaciones.

Yo se que para paliar éste problema, DirectX proporciona un método llamado "recover", que permite recuperar los punteros originales para volver a cargar el material gráfico de las superficies en sus respectivos lugares.
No tengo ni idea de como funciona esto. ¿ Alguien puede aclarármelo ?

Otra cosa que se me había ocurrido es hacer que mi videojuego (que funciona a pantalla completa) se ejecute en modo "exclusivo", es decir, que no se pueda salir del mismo con Alt+TAB ni minimizar la ventana bajo ningún concepto. Creo que esto ya no sería cosa de DirectX sino de la propia ventana principal del programa. ¿Como conseguir éste comportamiento?

  Respuesta:  Googol Plex
En general, las superficies que solicitas estarán en la memoria de video. Es decir que tú tienes un puntero a una superficie, con una serie de información almacenada, y ella tendrá internamente un puntero o algo por el estilo a la zona de la memoria de video donde almacena la propia imagen.
Cuando pierdes las superficies, se debe a que la información que había en la memoria de video la has perdido. Direct X gestiona la memoria de video internamente, controlando qué zonas están ocupadas, cuales están libres, y todo eso. Cuando pierdes la superficie se debe a que el espacio que tu superficie tenía en la memoria de video a tenido que ser utilizada por una aplicación que pasaba a primer plano (o por el propio Windows), por lo que el espacio que tenías tú reservado lo has perdido.
Eso supone que la superficie que tú tienes tenga un puntero a memoria de video donde estuvo tu imagen que ha dejado de ser válido. Tienes que solicitar a Direct X que se te vuelva a asignar espacio en la memoria para tu superficie, para volver a disponer de un hueco donde poner tu imagen. Y además, tienes que volver a cargar esa imagen.
Llamando a Restore (o RestoreAll) consigues que los punteros se vuelvan a inicializar, y tus superficies ya tienen, gracias a eso, un hueco donde guardar la imagen.

Controlar las superficies perdidas es insoportable, ciertamente. La solución "limpia" es controlar durante todo el programa los valores devueltos por las llamadas a las funciones de Direct X, y si te indican que no se pueden realizar porque las superficies involucradas se han perdido, solicitas que se restauren, y vuelves a cargar tus imágenes.
Esto puede hacerse, pero puede llegar a ser bastante incómodo, y peligroso, porque si no se hace la comprobación en un sitio de los múltiples en los que hay que hacerla, la aplicación podría fallar en situaciones inesperadas, y se convierte en un problema dificil de depurar.

La solución cómoda, pero más fea, es, aprovechando que estás a pantalla completa, capturar el evento en el que se te avisa que la aplicación a recuperado el foco. Al estar a pantalla completa, solo perderás las superficies cuando la aplicación pierda el foco y se vuelva al escritorio. El evento se llamará cuando se vuelva del escritorio a la aplicación, momento en el que podrás recuperar tus superficies.
Quizá eso te de problemas, y lo que tengas que hacer sea capturar el evento en el que se te avisa que has perdido el foco, activar un flag interno, y utilizarlo en la siguiente llamada al evento OnPaint, que se llamará cuando vuelvas a tener el foco y el modo de video se haya ya establecido. En el OnPaint compruebas el flag, ves que tienes que restaurar las superficies, lo haces, y se acabó.

Espero que te sirva, y que la respuesta no llegue demasiado tarde...