3d - Estrategia de representación para un sistema de ventanas en XNA(rendimiento de RenderTarget)
direct3d xbox360 (3)
Actualmente estoy creando un sistema de ventanas para juegos XNA desde cero. Me estoy desarrollando principalmente para Windows, pero quién sabe qué plataformas podría apoyar en el futuro. No dude en responder si sabe esto para Direct3D nativo, ya que la semántica de rendimiento debe ser similar. Si es posible, considere qué cambiaría si la plataforma objetivo fuera X-Box 360.
Estoy haciendo un buen progreso, pero ahora no estoy seguro de cómo renderizar exactamente las ventanas. Se me ocurrió cuatro enfoques:
Simplemente renderice todos los controles directamente en la pantalla. Esto es lo que hago ahora. Los controles pueden ser animados mezclando entre estados siempre que no sean semitransparentes. No encontré una buena manera de animar entre un número arbitrario de estados (supongamos que un botón que está actualmente animando desde el botón hasta el botón y desde el mouse hasta el mouse, y luego está deshabilitado. Combine suavemente desde su último estado hasta el nuevo estado. Con este enfoque, esto solo funciona si se reproduce una animación después de que finalizó la última, o si tiene saltos en la animación.
Renderice cada ventana de nivel superior y todos los controles en un objetivo de renderizado, y luego use eso para mostrar las ventanas de nivel superior con semitransparencia en la pantalla. Esto hace que la semi transparencia en el trabajo de alto nivel sea fácil de administrar, pero no cambia la cosa con las animaciones.
Renderice cada control en un objetivo de renderizado, que solo se actualiza cuando el control se ensucia (es decir, debe animarse o el texto ha sido modificado). De esta forma, la semitransparencia por control funcionaría.
Al igual que el anterior, pero además de resolver el problema de animación, tiene un segundo objetivo de renderizado para cada control. Cada vez que se inicia una animación, intercambia los objetivos de renderizado, de modo que tenemos el estado cuando se inicia la animación y lo combinamos con el estado de destino en el otro objetivo de renderizado. Esto no debería agregar sobrecarga en el enfoque anterior, solo teníamos el doble de objetivos de renderizado, de los cuales en uno solo se representaría uno (como máximo). Pero aquí viene el problema: para que esto funcione, necesitaría que el objetivo de renderizado "antiguo" preserve sus contenidos. Esto debería funcionar con un buen rendimiento en Windows, pero parece tener un grave impacto en el rendimiento de X-Box 360. Por otro lado, el bit de "preservar" solo es necesario cuando hay una animación activa.
Y aquí vienen las preguntas reales. Cualquier cosa que aclare es bienvenida. Con las preguntas de rendimiento, recuerde que este sería el sistema de ventanas de un juego: el juego que está detrás podría usar muchos objetivos de renderizado y también mejorar el rendimiento, y probablemente mucho más que el sistema de ventanas. Supongamos que podríamos tener cinco ventanas de nivel superior con 20-40 controles cada una en la pantalla en el peor de los casos.
- ¿Cuál de estos enfoques, si alguno, recomendaría y por qué? Siéntase libre, por supuesto, para agregar otro enfoque.
- ¿Hay un impacto en el rendimiento cuando solo digamos 200 o 400 objetivos de renderizado disponibles, siempre que solo 20 de ellos se estén renderizando en cada fotograma?
- ¿Es realmente tan malo el impacto en el rendimiento de PreserveContents en X-Box 360? ¿Qué tan malo es en Windows?
- La propiedad RenderTarget2D.RenderTargetUsage se puede escribir en. ¿Es una buena idea cambiar esto en el tiempo de ejecución para habilitar PreserveContents solo cuando sea necesario?
- ¿Te importaría (como jugador) pensar que las animaciones de control saltasen en ciertas situaciones, como al pasar el mouse por encima de un botón, mover el mouse y luego volver a activarlo, por lo que la animación "normal->" se reproducirá dos veces desde el principio porque es más lento que tú?
- Si quieres ese nivel de control con animaciones (es decir, tener múltiples pasando el mismo control a la vez), entonces tendrás múltiples pases. Así que habilite este tipo de cosas en un sombreado y realice varias pasadas con el sombreador, o realice el ciclo estándar Render-> Resolver-> Rerender.
- De hecho, hay un golpe de rendimiento que crea muchos rendertargets. No es una buena idea crear tantos. Es mejor tener una cantidad menor de objetivos de renderización de mayor tamaño y escribir múltiples controles para ese objetivo.
- Han pasado años desde la última vez que hice un dev 360 (bugger :(), pero por lo que puedo recordar, no es tan genial. Evitaría esta opción a menos que sea absolutamente necesario. Afortunadamente, alguien con experiencia más actualizada puede ayudar aquí.
- Esto podría funcionar en tiempo de ejecución, pero puede implicar un poco de trabajo detrás de escena. No esperaría que funcione demasiado bien. Estoy seguro de que está bien si no lo haces en medio de un ciclo de renderizado.
- Creo que las animaciones saltarinas definitivamente apestarían. En mi humilde opinión :)
Si está desarrollando para Xbox 360, debe tener cuidado con los objetivos de renderizado. Xbox 360 tiene una memoria especial (10 MB) para contener objetivos de renderizado, incluido el que se utiliza para representar en la pantalla.
Siempre que no supere los 10 MB, cambiar de un objetivo de renderizado a otro no tiene impacto, incluso con PreserveContents, porque todos los destinos de renderización se almacenan en esta memoria especial.
Sin embargo, cuando tiene más de 10MB de objetivos de renderizado con PreserveContents, este atributo debe ser emulado al cambiar constantemente un destino de renderizado hacia atrás y desde la memoria normal.
Por lo tanto, el número de objetivos de renderización no es tan importante como el tamaño total de esos. Puede conocer el tamaño de un objetivo de renderizado con esta fórmula:
size (bits) = width x height x color data size (bits)
El tamaño de los datos de color es de 32 bits en Xbox 360, por lo que, como ejemplo, si el usuario de tu biblioteca está desarrollando su juego en HD con solo un objetivo de renderización diferente al principal, usará:
3,515625MB = 29491200 bits = 1280 x 760 x 32 bits
Además, debes evitar crear objetivos de render dinámicamente. Cuesta demasiado. Debería crear un grupo de objetivos de renderizado estáticos asignados al comienzo del juego y solicitarlos a los componentes de su GUI.
El Xbox360 tiene 10 MB de memoria especial utilizada para el objetivo de renderización actual. Pero el resto dijo que su funcionamiento no es del todo exacto. Cualquier objetivo de renderizado que se use se encuentra en esos 10MB de espacio. De lo contrario, puede tener tantos objetivos de renderización como desee. Si el objetivo de su renderizado es mayor que los 10MB (como 1280x720 con algo de multiensaje AA), entonces el xbox360 usa una técnica llamada Tile Predicado: http://msdn.microsoft.com/en-us/library/bb464139.aspx
Estoy bien en la escritura de un sistema de ventanas. Estoy renderizando los widgets en un destino de renderizado, y luego transfiero el objetivo del widget al objetivo de la ventana, el objetivo de la ventana al backbuffer. Esto me permite agregar fácilmente barras de desplazamiento y representar solo una parte del objetivo de renderizado de widgets en el objetivo de renderizado de ventana. Si hay una mejor manera de lidiar con el desplazamiento del contenido de la ventana, házmelo saber. No estoy seguro si este es el mejor en rendimiento.