domingo, 15 de febrero de 2009

El XNA Content Pipeline

Actualmente el contenido gráfico y sonoro es una pieza clave para el desarrollo de videojuegos. Cuando surgieron los primeros juegos de ordenador, el contenido del que disponian era francamente limitado, en parte por que la tecnología no daba más de si, sin embargo, hoy en día, y gracias a los grandes avances que se han realizado en hardware, los juegos muestran un generoso contenido digital, mezclando imagenes 2D, modelos 3D, efectos, sonidos, etc...

Todo este contenido, a parte de ser creado por los diseñadores, debe introducirse en el juego. Esta tarea no es algo que podamos definir como sencilla, y por ello es común que en un equipo de desarrollo exista un grupo especializado únicamente en este área, pues implica una gran carga de trabajo. Hay que realizar exportaciones o programas de exportación de este contenido a un formato legible para el juego, realizar la codificación para cargarlo y en resumen, hacer todo el trabajo necesario para reproducirlo correctamente en el juego.

El Content Pipeline de XNA(desde ahora CPL) hace este trabajo por nosotros. Desde el propio Visual Studio, al igual que añadimos archivos de código al proyecto, podemos añadir contenido(archivos de imagen, sonido, efectos, etc..) a nuestro proyecto de XNA. Esto nos permite organizar todo el juego desde una única solución, indiferentemente del número de proyectos que contenga.

El CPL permite a los desarrolladores incorporar contenidos multimedia a los proyectos XNA. Los diseñadores crean estos archivos(Digital content creation) desde numerosas y variadas herramientas, guardando este contenido multimedia en numerosos tipos de formatos de archivo diferentes , .gif, .jpg, .fbx, .x, wav, mp3, etc... El CPL esta diseñado para ayudar al desarrollador a incluir estos ficheros en el juego de una manera facil y automática, indiferentemente del formato del archivo.

Soporta una amplia gama de formatos de archivos para importar a nuestro proyecto, básicamente se trata de los formatos mas utilizados en la creación de videojuegos. No obstante, podemos encontrarnos con la necesidad de cargar otros formatos de archivos que no son soportados por el CPL, de hecho, y muy comunmente, en la industria de los videojuegos, los desarrolladores utilizan archivos personalizados para sus proyectos. Por ello, el CPL de XNA es extensible, incorpora un marco de trabajo estandarizado que permite facilmente incluir soporte a diferentes tipos de archivo.

Pero ¿que es lo que ocurre internamente cuando importamos un archivo a nuestro proyecto?. ¿Que clase de transformaciones sufre y como se llevan a cabo?, y no menos importante, ¿quien hace estas transformaciones?. De esto hablaremos a continuación.

En el transcurso de construcción de un archivo de contenido digital , el CPL invoca cuatro componentes principales para transformar el archivo original de contenido en un archivo binario para el juego. Veamos esto mediante una imagen que muestra la arquitectura del CPL de XNA para mayor comprensión.


Content Importer

Cuando se añade un contenido, este lo recoge un importador. El importador es el encargado de obtener los datos y normalizarlos. Después de que el importador ha hecho su trabajo , los datos existen en un DOM fuertemente tipado, es decir, se encuentran en un formato conocido.

*DOM(Document Object Model), es el término que se utiliza para indicar una colección de clases o un esquema(por ejemplo un xml).

Este DOM devuelto por el importador será el que utilizará el content processor(Procesador de contenido). En ocasiones, no tiene porque devolver un DOM, sino que podría también retornar un objeto personalizado creado por el desarrollador.

XNA proporciona un número limitado de importadores de contenido estándar para los formatos de archivo comunmente más utilizados en la creación de videojuegos. Para los formatos de archivo que no estén soportados por estos importadores estándar, podemos crear nuestro propio importador personalizado.


Content Processor

El procesador de contenido recibe los datos que el importador ha generado y crea un objeto para su uso en tiempo de ejecución. Este objeto puede ser tan simple como un modelo o mucho más complejo.

Los procesadores estan diseñados para que sean faciles de escribir, compartir y reutilizar. Los transformadores tiran de los datos del contenido DOM. Es decir, el procesador funciona con independencia del formato del archivo original, debido a que todos sus datos están almacenados en un formato conocido. Además existen métodos de ayuda que permiten manipular y generar nuevos datos de contenido DOM.

El CPL de XNA incluye algunos procesadores, por ejemplo, Model (para objetos simples con texturas), Texture2D(para sprites o combinaciones con modelos), Effect (para manejar los materiales de los modelos), etc... Pero puede que queramos mas flexibilidad todavía para nuestro contenido, quizás el mundo de nuestro juego no puede ser construido únicamente con modelos simples, podríamos desarrollar un procesador que dados múltiples objetos, generará uno que los englobara a todos (si, como el anillo del señor oscuro :D) .Por ejemplo:

Si estuvieramos haciendo un juego de coches. Tendremos varios archivos de contenido que forman la pista. En la pista podemos tener todo tipo de datos. Puntos de inicio y final, sitios de control cuando pasa el coche, etc... Entonces, en lugar de tener la pista en cientos de trozos, podemos simplemente escribir un procesador que consumirá todos esos datos y hacer que directamente devolviera un objeto pista. Claro, luego nuestro motor de juego deberá comprender ese objeto pista para saber que hace con él, pero eso ya es otra cosa.

Content Type Writer

El content Type Writer es el responsable de recoger el objeto generado por el procesador y grabarlo físicamente en disco. Este archivo binario se guardará en un formato especifico de XNA con la extensión .xnb

Content Type Reader

El content Type Reader es el encargado de almacenar el objeto en memoria cuando queramos acceder al contenido, dicho de otra manera, deserializa el archivo creado por el writer y lo almacena en un objeto en memoria para su uso. El reader es llamado por xna mediante el componente Content Manager.

_____________________________________________________

Hasta aquí, la construcción de un objeto desde un archivo de contenido importado a XNA. Los cuatro componentes que he citado pueden programarse, pero no hace falta implementarlos todos, es decir, en ocasiones puede que únicamente nos interese crear un importador y un procesador, o sólo un procesador, etc..

Por último, indicar que tanto el importador como el procesador de contenido y el writer, se ejecutan en tiempo de compilación, generando en el paso final el archivo .xnb. Por otra parte, el Content reader es invocado siempre en tiempo de ejecución, cuando el juego ya está ejecutándose. Lo que sigue a continuación puede aclarar ciertas cosas.

- Las partes contenidas en la zona amarilla de la imagen, siempre se ejecutan en windows y por consiguiente, en el ordenador en el que se está desarrollando, o mejor dicho, compilando el juego.

- Las partes contenidas en la zona lila de la imagen, se ejecutan en windows, XBox o Zune, pues es donde se ejecuta el juego.

- La zona amarilla utiliza clases contenidas en el ensamblado Microsoft.Xna.Framework.Content.Pipeline

-Las partes de la zona roja no tienen la referencia al ensamblado de la CPL.

-Cuando se distribuye un juego hecho en XNA, todas las partes de la zona roja deben incluirse, mientras que las partes de la zona amarilla no son necesarias en la distribución.

Despues de esto, la pregunta que podemos hacernos es: ¿como accedemos a ese contenido desde nuestro juego?. Pues como adelantaba anteriormente, lo haremos con el Content Manager.

Content Manager

El content Manager es un componente diseñado para cargar los archivos de contenido rápida y facilmente. Maneja todos los pequeños detalles, como velar para que todos los activos asociados esten cargados al mismo tiempo.

Ejemplo de código.

Texture2D miTextura = Content.Load<Texture2D>("MiImagen");

En esta linea de código se carga un archivo que previamente hemos importado a XNA. El content Manager localizará el archivo asignado al nombre "MiImagen", para luego invocar al Content Type Reader que nos devolverá un objeto del tipo Texture2D.

En otro artículo veremos un ejemplo de como implementar lo expuesto en esta entrada.

Referencias:

- Xna Team Blog: The XNA Framework Content Pipeline
http://blogs.msdn.com/xna/archive/2006/08/29/730168.aspx

-MSDN : Content Pipeline Architecture
http://msdn.microsoft.com/en-us/library/bb447745.aspx

-Shawn Hargreaves Blog: Content Pipeline assemblies
http://blogs.msdn.com/shawnhar/archive/2008/11/24/content-pipeline-assemblies.aspx

- Ideas de un conejo: El XNA Content Pipeline
http://juank.black-byte.com/xna-content-pipeline/

1 comentario:

  1. He escrito un peque;o tutorial para guardar y cargar archivos en el XBOX 360, aqui les dejo la pag:

    http://www.ikisoftware.com/2009/02/26/xna-game-studio-como-guardar-y-cargar-saves-en-el-xbox360/

    ResponderEliminar