• Viernes 8 de Noviembre de 2024, 20:11

Autor Tema:  Xna Content Pipeline  (Leído 2509 veces)

JuanK

  • Miembro de ORO
  • ******
  • Mensajes: 5393
  • Nacionalidad: co
    • Ver Perfil
    • http://juank.io
Xna Content Pipeline
« en: Martes 20 de Marzo de 2007, 04:59 »
0
[dohtml]<style type="text/css">
<!--
body.hl { background-color:#ffffff; }
pre.hl { color:#000000; background-color:#FFFFFF; font-size:smaller; font-family:Courier New;}
.num { color:#000000; }
.esc { color:#000000; }
.str { color:#000000; }
.dstr { color:#000000; }
.slc { color:#008000; font-style:italic; }
.com { color:#008000; font-style:italic; }
.dir { color:#0000ff; }
.sym { color:#000000; }
.line { color:#008000; }
.kwa { color:#0000ff; font-weight:bold; }
.kwb { color:#0000ff; }
.kwc { color:#0000ff; font-weight:bold; }
.kwd { color:#000000; }
.clasMark { color:#339999 }
.stringMark { color: #660066 }
.Estilo1 {
   font-family: verdana;
   font-size: 85%;
}
.Estilo14 {font-size: smaller; font-family: verdana; text-align:justify}
.Estilo16 {font-size: large; font-family: verdana; font-weight: bold; }
.Estilo17 {font-size: medium}
.Estilo19 {font-size: smaller; font-family: verdana; color: #0000FF; }
.Estilo21 {font-size: smaller; font-family: verdana; color: rgb(51,153,153); }
//-->
</style>
<p class="Estilo16">
El XNA Content Pipeline</p>
<p class="Estilo16 Estilo17">
Que es el Content Pipeline?</p>
<p class="Estilo14">
    El content pipeline es una API que permite a los desarrolladores y diseñadores incorporar
    contenidos multimedia en los proyectos creados con XNA framework, estos contenidos
multimedia son por ejemplo:</p>
<ul>
  <li class="Estilo14">imágenes</li>
    <li class="Estilo14">sonidos</li>
    <li class="Estilo14">contenido 3d</li>
    <li class="Estilo14">efectos</li>
</ul>
<span class="Estilo14">Por defecto el content pipeline soporta una amplia gama de formatos
    de archivo diferentes los cuales son usualmente usados en la industria de los videojuegos,
    el content pipeline (en adelante CPL) facilita el acceso a estos archivos y brinda
    un interfaz de acceso unificada que permite acceder a dichos recursos desde cualquier
    objeto utilizado dentro del juego sin necesidad de hacer uso de múltiples referencias
    cruzadas lo cual desde luego va en favor de la independencia de cada componente
    lo cual en un juego generalmente es una tarea muy difícil de hacer. Sin embargo
    las capacidades del CPL podrían verse limitadas por la cantidad de archivos que
    soporta puesto que es muy común que en la industria de los videojuegos se usen formatos
    de archivo independientes de acuerdo a las necesidades particulares de cada proyecto,
    es aquí donde reside una de las mas importantes características del CPL... es <strong>
        extensible</strong>.
    <br />
    <br />
    El CPL incorpora un marco de trabajo que permite fácilmente incorporar soporte a
    diferentes tipos de archivo e incluso extender la funcionalidad de un tipo de archivo
ya soportado.</span>
<p class="Estilo16 Estilo17 ">
Como Funciona el Content PipeLine?</p>
<p>
  <span class="Estilo14">Lo primero ha tener en cuenta son los elementos con los cuales
trabaja:</span></p><p>
            <span class="Estilo19">Namespace: Microsoft.Xna.Framework.Content.Pipeline </span>
            <span class="Estilo21">
                <br />
                ContentImporter
                <br />
                ContentProcessor</span>
            <br />
            <span class="Estilo19">Namespace: Microsoft.Xna.Framework.Content </span>
            <br />
            <span class="Estilo21">ContentTypeReader</span><br />
            <span class="Estilo19">Namespace: Microsoft.Xna.Framework.Content.Pipeline.Serialization.Compile            </span>
            <br />
            <span class="Estilo21">ContentTypeWriter</span>
</p>
<p class="Estilo14">
                El camino comienza con el ContentImporter este es el encargado de realizar lectura
                física del archivo a importar y colocar la información en un objeto capaz de almacenarla.
                Seguidamente la información colocada en el objeto es pasada a través de un ContentProcessor
                el cual se encarga de realizar transformaciones en la información cargada en el
                paso anterior. El <span class="Estilo21">ContentTypeWriter</span> se encarga de
                escribir ese objeto en un archivo con el formato del CPL. Todos los pasos anteriores
                suceden en tiempo de compilación, el ultimo paso sucede en tiempo de ejecución cuando
                el juego ya esta ejecutándose, es allí donde el <span class="Estilo21">ContentTypeReader</span>
                lee los archivos creados por el CPL para cargar en memoria el recurso almacenado.
                Debido a que se debe adicionar una referencia a estas clases en el CPL es necesario
                que los tres primeros objetos existan compilados en una librería dinámica, mientras
                que el ultimo puede hacer parte el juego directamente.</p>
            <p>
              <a style="color: rgb(0, 0, 0);" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"
                    href="http://bp0.blogger.com/_SpDJXReOOTs/Rf2RfHjZDuI/AAAAAAAAAAM/8fYWjN1MDIc/s1600-h/CPL.PNG">
              <img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;"
                        src="http://bp0.blogger.com/_SpDJXReOOTs/Rf2RfHjZDuI/AAAAAAAAAAM/8fYWjN1MDIc/s400/CPL.PNG"
                        alt="" id="BLOGGER_PHOTO_ID_5043347121514286818" border="0" /></a>
            </p>
            <span class="Estilo16 Estilo17">Como hacer que el Content Pipeline soporte un archivo
  diferente? </span>
  <p>
    <span class="Estilo14">Normalmente con tan solo el </span><span class="Estilo21">ContentImporter</span><span
                    class="Estilo14"> y el </span><span class="Estilo21">ContentProcessor</span><span
                        class="Estilo14"> es suficiente para cargar un tipo de archivo ya que basicamente
                        lo que se hace es utilizar estos objetos para convertir los datos del archivo en
                        uno de los tipos de dato ya soportados por el CPL, sin embargo si se requiere información
                        adicional que no es contenida en el tipo soportado es entonces necesario que el
                        desarrollador establezca la forma en que el CPL escribe esos datos en un archivo
                        del CPL y la forma en que el CPL debe cargarlos una vez se solicite desde el juego,
                        para ello son las clases </span><span class="Estilo21">ContentTypeWriter</span><span
                            class="Estilo14"> y </span><span class="Estilo21">ContentTypeReader</span><span class="Estilo14">.
                                La buena noticia es que para adicionar soporte a un nuevo tipo de archivo estas
                                clases proveen los mecanismos necesarios para implementarlo de manera relativamente
                                fácil, la mala noticia es que todas son clases abstractas así que la mayoría del
                                trabajo lo debe hacer uno mismo. :P </span>
</p>
            <p class="Estilo14">
                A continuación un ejemplo de Implementación de un nuevo tipo de archivo para el
                CPL.
                <br />
                <br />
                Supongamos existe un tipo de arhivo bmp2 dicho archivo posee la información habitual
                de un archivo bmp más tres datos muy importantes que requerimos (todos los campos
  son un ejemplo):</p>
            <ul class="Estilo14">
              <li>Color de Máscara</li>
                <li>Número de Colores</li>
                <li>Prioridad</li>
            </ul>
            <span class="Estilo14">La tarea nro 1 crear un </span><span class="Estilo21">ContentImporter</span><span
                class="Estilo14"> . Hay que recordar que </span><span class="Estilo21">ContentImporter</span><span
                    class="Estilo14"> es una clase abstracta asi que se debe crear una clase que herede
                    de </span><span class="Estilo21">ContentImporter</span><span class="Estilo14"> , adicionalmente
                        esta clase es genérica por lo cual debemos pasar el parámetro del tipo de dato que
                        se soportara para importar.</span>
            <pre><span class="kwa">public class</span> <span class="clasMark">BMP2Importer</span> <span
                class="sym">:</span> <span class="clasMark">ContentImporter</span>
    <span class="sym">{ }</span></pre>
            <span class="Estilo14">pero un momento... de donde salio </span><span class="Estilo21">
                BMP2Content</span><span class="Estilo14">? bueno dado que se esta incorporando un nuevo
                    tipo de archivo es necesario que crear un objeto contenedor de los datos que se
                    cargan desde ese archivo, teniendo en cuenta que el formato bmp2 lo usaremos para
                    crear texturas 2D lo mejor que se puede hacer es crear una clase que herede de un
                    contenedor existente, para este caso </span><span class="Estilo21">Texture2DContent</span><span
                        class="Estilo14"> :</span>
 <pre><span class="kwa">using</span> Microsoft<span class="sym">.</span>Xna<span class="sym">.</span>Framework<span
                class="sym">;</span>
<span class="kwa">using</span> Microsoft<span class="sym">.</span>Xna<span class="sym">.</span>Framework<span
    class="sym">.</span>Graphics<span class="sym">;</span>
<span class="kwa">using</span> Microsoft<span class="sym">.</span>Xna<span class="sym">.</span>Framework<span
    class="sym">.</span>Content<span class="sym">.</span>Pipeline<span class="sym">;</span>
<span class="kwa">using</span> Microsoft<span class="sym">.</span>Xna<span class="sym">.</span>Framework<span
    class="sym">.</span>Content<span class="sym">.</span>Pipeline<span class="sym">.</span>Graphics<span
        class="sym">;</span>

<span class="kwa">public class</span> <span class="clasMark">BMP2Content</span> <span
    class="sym">:</span> <span class="clasMark">Texture2DContent</span>
<span class="sym">{</span>
  <span class="kwa">public</span> <span class="kwd">BMP2Content</span><span class="sym">():</span> <span
      class="kwa">base</span><span class="sym">()</span>
  <span class="sym">{}</span>
  <span class="kwa">private</span> <span class="clasMark">Color</span> maskColor<span
      class="sym">;</span>
  <span class="kwa">public</span> <span class="clasMark">Color</span> MaskColor
  <span class="sym">{</span>
      <span class="kwa">get</span>
      <span class="sym">{</span>
          <span class="kwa">return</span> maskColor<span class="sym">;</span>
      <span class="sym">}</span>
      <span class="kwa">set</span>
      <span class="sym">{</span>
          maskColor <span class="sym">=</span> <span class="kwa">value</span><span class="sym">;</span>
      <span class="sym">}</span>
  <span class="sym">}</span>

  <span class="kwa">private</span> <span class="kwb">int</span> numColores<span class="sym">;</span>
  <span class="kwa">public</span> <span class="kwb">int</span> NumColores
  <span class="sym">{</span>
      <span class="kwa">get</span>
      <span class="sym">{</span>
          <span class="kwa">return</span> numColores<span class="sym">;</span>
      <span class="sym">}</span>
      <span class="kwa">set</span>
      <span class="sym">{</span>
          numColores <span class="sym">=</span> <span class="kwa">value</span><span class="sym">;</span>
      <span class="sym">}</span>
  <span class="sym">}</span>
  <span class="kwa">private</span> <span class="kwb">byte</span> prioridad<span class="sym">;</span>
  <span class="kwa">public</span> <span class="kwb">byte</span> Prioridad
  <span class="sym">{</span>
      <span class="kwa">get</span>
      <span class="sym">{</span>
          <span class="kwa">return</span> prioridad<span class="sym">;</span>
      <span class="sym">}</span>
      <span class="kwa">set</span>
      <span class="sym">{</span>
          prioridad <span class="sym">=</span> <span class="kwa">value</span><span class="sym">;</span>
      <span class="sym">}</span>
  <span class="sym">}</span>
<span class="sym">}</span></pre>
<p class="Estilo14">
                Este contenedor permite manipular los datos desde su cargue hasta su transformacion
                y escritura en un archivo del content pipeline, sin embargo se requiere de una estructura
                adicional para manipularlo, porque? bueno el contenedor puede ser realmente cualquier
                estructura pero se requiere que sea liviana puesto que la cantidad de recursos que
                tengamos puede incrementar dramaticamente el tiempo que se invcierta en la compilacion
                del proyecto ya que cada uno de los recursos pasara por un importer, un processor
                y un writer, ya cuando se va a utilizar esa informacion en un objeto util para el
                juego si debemos disponer de toda la infromacion necesaria.
                <br />
                <br />
                Para este ejemplo, debido a que el archivo de tipo bmp2 va a ser usado como textura
                se pueden usar dos opciones, una es crear una clase de textura nueva (poco recomendable)
                y la otra es crear una clase que herede de un tipo de textura ya existente, para
                el caso lo que mas nos conviene es crear una clase que herede de <span class="Estilo21">
Texture2D</span>.</p>
<pre><span class="kwa">public class</span> <span class="clasMark">BMP2Texture2D</span> <span
                class="sym">:</span> <span class="clasMark">Texture2D</span>
<span class="sym">{</span>
    <span class="kwa">public</span> <span class="clasMark">BMP2Texture2D</span><span
        class="sym">(</span><span class="clasMark">GraphicsDevice</span> device<span class="sym">,</span> <span
            class="kwb">int</span> height<span class="sym">,</span> <span class="kwb">int</span> with<span
                class="sym">,</span>
                         <span class="kwb">int</span> numberLevels<span class="sym">,</span> <span class="clasMark">ResourceUsage</span> usage<span
                             class="sym">,</span> <span class="clasMark">SurfaceFormat</span> format<span class="sym">)</span>
           <span class="sym">:</span> <span class="kwa">base</span><span class="sym">(</span>device<span
               class="sym">,</span> with<span class="sym">,</span> height<span class="sym">,</span> numberLevels<span
                   class="sym">,</span> usage<span class="sym">,</span> format<span class="sym">)</span>
    <span class="sym">{}</span>

    <span class="kwa">public</span> <span class="kwd">BMP2Texture2D</span><span class="sym">(</span><span
        class="clasMark">GraphicsDevice</span> device<span class="sym">,</span> <span class="kwb">int</span> height<span
            class="sym">,</span> <span class="kwb">int</span> with<span class="sym">,</span> <span
                class="kwb">int</span> numberLevels<span class="sym">,</span>
                         <span class="clasMark">ResourceUsage</span> usage<span class="sym">,</span> <span
                             class="clasMark">SurfaceFormat</span> format<span class="sym">,</span>
                         <span class="clasMark">ResourceManagementMode</span> resourceManagementMode<span
                             class="sym">)</span>
           <span class="sym">:</span> <span class="kwa">base</span><span class="sym">(</span>device<span
               class="sym">,</span> with<span class="sym">,</span> height<span class="sym">,</span> numberLevels<span
                   class="sym">,</span> usage<span class="sym">,</span> format<span class="sym">,</span> resourceManagementMode<span
                       class="sym">)</span>
    <span class="sym">{</span>
    <span class="sym">}</span>

    <span class="kwa">private</span> <span class="clasMark">Color</span> maskColor<span
        class="sym">;</span>
    <span class="kwa">public</span> <span class="clasMark">Color</span> MaskColor
    <span class="sym">{</span>
        <span class="kwa">get</span>
        <span class="sym">{</span>
            <span class="kwa">return</span> maskColor<span class="sym">;</span>
        <span class="sym">}</span>
        <span class="kwa">set</span>
        <span class="sym">{</span>
            maskColor <span class="sym">=</span> <span class="kwa">value</span><span class="sym">;</span>
        <span class="sym">}</span>
    <span class="sym">}</span>
    <span class="kwa">private</span> <span class="kwb">int</span> numColores<span class="sym">;</span>
    <span class="kwa">public</span> <span class="kwb">int</span> NumColores
    <span class="sym">{</span>
        <span class="kwa">get</span>
        <span class="sym">{</span>
            <span class="kwa">return</span> numColores<span class="sym">;</span>
        <span class="sym">}</span>
        <span class="kwa">set</span>
        <span class="sym">{</span>
            numColores <span class="sym">=</span> <span class="kwa">value</span><span class="sym">;</span>
        <span class="sym">}</span>
    <span class="sym">}</span>
    <span class="kwa">private</span> <span class="kwb">byte</span> prioridad<span class="sym">;</span>
    <span class="kwa">public</span> <span class="kwb">byte</span> Prioridad
    <span class="sym">{</span>
        <span class="kwa">get</span>
        <span class="sym">{</span>
            <span class="kwa">return</span> prioridad<span class="sym">;</span>
        <span class="sym">}</span>
        <span class="kwa">set</span>
        <span class="sym">{</span>
            prioridad <span class="sym">=</span> <span class="kwa">value</span><span class="sym">;</span>
        <span class="sym">}</span>
    <span class="sym">}</span>
<span class="sym">}</span>
</pre>
<p class="Estilo14">
                Esta clase ya trae todo lo que necesita una textura 2d más las cosas propias del
                formato bmp2 de el ejemplo.
                <br />
                Ahora si se puede crear el <span class="Estilo21">ContentImporter</span> indicando
                el tipo de contenido a almacenar.
</p>
<pre>
<span class="sym">[</span><span class="kwd">ContentImporter</span><span class="sym">(</span><span
    class="stringMark">".bmp2"</span><span class="sym">,</span> DisplayName <span
        class="sym">=</span> <span class="stringMark">"Imagen BMP2"</span><span
            class="sym">,</span> DefaultProcessor <span class="sym">=</span> <span class="stringMark">"Procesador
                para imagenes BMP2"</span><span class="sym">)]</span>
<span class="kwa">public class</span> <span class="clasMark">BMP2Importer</span> <span
    class="sym">:</span> <span class="clasMark">ContentImporter</span><span class="sym"><</span><span
        class="clasMark">BMP2Content</span><span class="sym">></span>
<span class="sym">{</span>
    <span class="kwa">public override</span> <span class="clasMark">BMP2Content</span> <span
        class="kwd">Import</span><span class="sym">(</span><span class="kwb">string</span> filename<span
            class="sym">,</span> <span class="clasMark">ContentImporterContext</span> context<span
                class="sym">)</span>
    <span class="sym">{</span>
        <span class="clasMark">BPM2</span> miBmp <span class="sym">=</span> <span class="kwa">new</span> <span
            class="clasMark">BMP2</span><span class="sym">(</span>filename<span class="sym">);</span>
        <span class="slc">//Este objeto es de ayuda para recuperar la informacion de color y
            llevarla facilmente al</span>
        <span class="slc">//MipmapChain del objeto textureContent</span>
        <span class="clasMark">PixelBitmapContent</span><span class="sym"><</span><span
            class="clasMark">Rgb24</span><span class="sym">></span> pixelHelper<span class="sym">;</span>
        <span class="slc">//Array de textura a retornar</span>
        <span class="clasMark">BMP2Content</span> textureContent<span class="sym">;</span>
        <span class="slc">//Array de bytes para capturar la informacion del archivo JKI</span>
        <span class="kwb">byte</span><span class="sym">[]</span> byteArray<span class="sym">;</span>
        <span class="slc">//Inicializa un nuevo contenedor de datos de pixeles</span>
        pixelHelper <span class="sym">=</span> <span class="kwa">new</span> <span class="clasMark">PixelBitmapContent</span><span
            class="sym"><</span><span class="clasMark">Rgb24</span><span class="sym">>(</span>miBmp<span
                class="sym">.</span>Width<span class="sym">,</span>miBmp<span class="sym">.</span>Height<span
                    class="sym">);</span>
        <span class="slc">//Cargar la informacion de bytes para el archivo</span>
        byteArray <span class="sym">=</span> miBmp<span class="sym">.</span><span class="kwd">GetBytes</span><span
            class="sym">();</span>
        <span class="slc">//Envia los datos de bytes al pixel helper</span>
        pixelHelper<span class="sym">.</span><span class="kwd">SetPixelData</span><span class="sym">(</span>byteArray<span
            class="sym">);</span>
        <span class="slc">//Inicializa un nuevo contenedor para la textura</span>
        textureContent <span class="sym">=</span> <span class="kwa">new</span> <span class="clasMark">BMP2Content</span><span
            class="sym">();</span>
        <span class="slc">//Carga la informacion de la imagen en la textura</span>
        textureContent<span class="sym">.</span>Mipmaps <span class="sym">=</span> <span
            class="kwa">new</span> <span class="clasMark">MipmapChain</span><span class="sym">(</span>pixelHelper<span
                class="sym">);</span>
        <span class="slc">//Guarda el color de mascara de la imagen</span>
        textureContent<span class="sym">.</span>MaskColor <span class="sym">=</span> <span
            class="kwa">new</span> <span class="clasMark">Color</span><span class="sym">(</span>miBmp<span
                class="sym">.</span>ColorMascara<span class="sym">.</span>R<span class="sym">,</span>miBmp<span
                    class="sym">.</span>ColorMascara<span class="sym">.</span>G<span class="sym">,</span>
                                             miBmp<span class="sym">.</span>ColorMascara<span class="sym">.</span>B<span class="sym">);</span>
        <span class="slc">//Establecer el numero de colores</span>
        textureContent<span class="sym">.</span>NumColores <span class="sym">=</span> miBmp<span
            class="sym">.</span>Palette<span class="sym">.</span>Count<span class="sym">;</span>
        textureContent<span class="sym">.</span>Prioridad <span class="sym">=</span> <span
            class="num">0</span><span class="sym">;</span>
        <span class="kwa">return</span> textureContent<span class="sym">;</span>
    <span class="sym">}</span>
<span class="sym">}</span>
</pre>
<p class="Estilo14">
                La primera linea es un atributo de la clase, la cual le permitira al Content Pipeline
                identificar que esta es un <span class="Estilo21">ContentImporter</span> y le proporcionara
                informacion adicional acerca de que informacion debe mostrar desde el IDE de Visual
                Studio respecto a los archivos que este ContentImporter es capaz de utilizar asi
                como un nombre descriptivo de la funcionalidad. Seguidamente lo que se hace cargar
                desde archvo un objeto BMP2 el cual desde luego es un objeto que ya es capaz de
                cargar un archivo bmp2, el objeto pixelHelper es utilizado como una 'Helper Class'
                ya que si bien no se necesita de manera directa, si es un excelente atajo para poder
                crear un <span class="Estilo21">MipmapChain</span> el cual es requerido para cargar
                en un objeto <span class="Estilo21">Texture2DContent</span> con la informacion de
                la imagen que se requiere, finalmente en la parte inferior del método se asignan
                la informacion adicional que se requiere.
                <br />
                <br />
                Una vez se ha importado la informacion desde el archivo esta debe pasar por el processor,
                el procesor se debe hacer para que funcione igual que funciona un procesor para
                una imagen BMP normal asi que se puede reutilizar un processor que ya este creado
                en XNA y eso es todo ya que sobre el resto de la informacion no se requiere hacer
                ninguna modificacion. El processor en este caso es bastante sencillo:
</p>
<pre>
<span class="sym">[</span><span class="kwd">ContentProcessor</span><span class="sym">(</span>DisplayName <span
    class="sym">=</span> <span class="stringMark">"Procesador para imagenes BMP2"</span><span
        class="sym">)]</span>
<span class="kwa">class</span> <span class="clasMark">BMP2Processor</span> <span
    class="sym">:</span> <span class="clasMark">ContentProcessor</span><span class="sym"><</span><span
        class="clasMark">BMP2Content</span><span class="sym">,</span> <span class="clasMark">BMP2Content</span><span
            class="sym">></span>
<span class="sym">{</span>
    <span class="kwa">public override</span> <span class="clasMark">BMP2Content</span> <span
        class="kwd">Process</span><span class="sym">(</span><span class="clasMark">BMP2Content</span> input<span
            class="sym">,</span> <span class="clasMark">ContentProcessorContext</span> context<span
                class="sym">)</span>
    <span class="sym">{</span>
       input<span class="sym">[</span>i<span class="sym">] = (</span><span class="clasMark">BMP2Content</span><span
           class="sym">)</span>context<span class="sym">.</span>Convert<span class="sym"><</span><span
               class="clasMark">TextureContent</span><span class="sym">,</span><span class="clasMark">TextureContent</span><span
                   class="sym">>(</span>
                           <span class="sym">(</span><span class="clasMark">TextureContent</span><span class="sym">)</span>input<span
                               class="sym">[</span>i<span class="sym">],</span>
                           <span class="stringMark">"SpriteTextureProcessor"</span><span class="sym">);</span>
       <span class="kwa">return</span> input<span class="sym">;</span>
    <span class="sym">}</span>
<span class="sym">}</span>
</pre>
<p class="Estilo14">
                El atributo inicial tiene la misma funcionalidad que en el importer y es proveer
                una pequeña descripcion del ContentProcessor para que aparezca en el IDE de Visual
                Studio. Se llama al metodo context.Convert indicandole que debe usar el builting
                processor <span class="Estilo21">SpriteTextureProcessor</span>, esto hara que la
                informacion inherente a una textura 2d sea procesada de la manera habitual . Finalmente
se procede a crear el <span class="Estilo21">ContentTypeWriter</span>.</p>
            <pre>
<span class="sym">[</span>ContentTypeWriter<span class="sym">]</span>
<span class="kwa">public class</span> <span class="clasMark">BMP2ContentWriter</span> <span
    class="sym">:</span> <span class="clasMark">ContentTypeWriter</span><span class="sym"><</span><span
        class="clasMark">BMP2Content</span><span class="sym">></span>
<span class="sym">{</span>
    <span class="kwa">protected override</span> <span class="kwb">void</span> <span class="kwd">Write</span><span
        class="sym">(</span><span class="clasMark">ContentWriter</span> output<span class="sym">,</span> <span
            class="clasMark">BMP2Content</span> <span class="kwa">value</span><span class="sym">)</span>
    <span class="sym">{</span>
        <span class="slc">//Buffer para la informacion de la imagen</span>
        <span class="kwb">byte</span><span class="sym">[]</span> pixelData<span class="sym">;</span>
        <span class="slc">//Escribe alto y ancho</span>
        output<span class="sym">.</span><span class="kwd">Write</span><span class="sym">(</span><span
            class="kwa">value</span><span class="sym">.</span>Mipmaps<span class="sym">[</span><span
                class="num">0</span><span class="sym">].</span>Height<span class="sym">);</span>
        output<span class="sym">.</span><span class="kwd">Write</span><span class="sym">(</span><span
            class="kwa">value</span><span class="sym">.</span>Mipmaps<span class="sym">[</span><span
                class="num">0</span><span class="sym">].</span>Width<span class="sym">);</span>
        <span class="slc">//Obtiene el contenido de la imagen</span>
        pixelData <span class="sym">=</span> <span class="kwa">value</span><span class="sym">.</span>Mipmaps<span
            class="sym">[</span><span class="num">0</span><span class="sym">].</span><span class="kwd">GetPixelData</span><span
                class="sym">();</span>
        <span class="slc">//Escribe el tamaño de datos de la imagen</span>
        output<span class="sym">.</span><span class="kwd">Write</span><span class="sym">(</span>pixelData<span
            class="sym">.</span>Length<span class="sym">);</span>
        <span class="slc">//Escribe la informacion de la imagen</span>
        output<span class="sym">.</span><span class="kwd">Write</span><span class="sym">(</span>pixelData<span
            class="sym">);</span>
        <span class="slc">//Escribe el color de mascara de la imagen</span>
        output<span class="sym">.</span>WriteObject<span class="sym"><</span><span class="clasMark">Color</span><span
            class="sym">>(</span><span class="kwa">value</span><span class="sym">.</span>MaskColor<span
                class="sym">);</span>
    <span class="sym">}</span>
    <span class="kwa">public override</span> <span class="kwb">string</span> <span class="kwd">GetRuntimeReader</span><span
        class="sym">(</span><span class="clasMark">TargetPlatform</span> targetPlatform<span
            class="sym">)</span>
    <span class="sym">{</span>
        <span class="kwa">return</span> <span class="kwb">typeof</span><span class="sym">(</span><span
            class="clasMark">BMP2ContentReader</span><span class="sym">).</span>AssemblyQualifiedName<span
                class="sym">;</span>
    <span class="sym">}</span>
<span class="sym">}</span>
</pre>
<p class="Estilo14">
                El atributo inicial tiene la misma funcionalidad que en el importer. El método write
                lo que hace es escribir en el archivo del CPL la informacion relacionada con el
                archivo ya previamente cargado en el <span class="Estilo21">BMP2Content</span>,
                el objeto output recibido como parametro posee metodos para escribir a nivel de
                tipos nativos y soporta una amplia gama de tipos incluidos en el xna framework,
                el método GetRuntimeReader Almacena informacion que le indica el CPL en tiempo dejecucion
                que clase debe instanciar para poder convertir un archivo del CPL en el objeto que
                se desea, es decir indica cual implementacion de <span class="Estilo21">ContentTypeReader</span>
                debe utilizarce para tal fin. Esta es la implementacion de <span class="clasMark">ContentTypeReader</span>
                para leer en tiempo de ejecucion lo que el ContentTypeWriter ha guardado en tiempo
                de compilacion, el objeto input recibido como parametro posee metodos para leer
                a nivel de tipos nativos y soporta una amplia gama de tipos incluidos en el xna
framework.</p>
            <pre>
<span class="kwa">public class</span> <span class="Estilo13">BMP2ContentReader</span> <span
    class="sym">:</span> <span class="Estilo13">ContentTypeReader</span><span class="sym"><</span>BMP2Texture2D<span
        class="sym">></span>
<span class="sym">{</span>
    <span class="kwa">protected override</span> <span class="Estilo13">BMP2Texture2D</span> <span
        class="kwd">Read</span><span class="sym">(</span><span class="Estilo13">ContentReader</span> input<span
            class="sym">,</span> <span class="Estilo13">BMP2Texture2D</span> existingInstance<span
                class="sym">)</span>
    <span class="sym">{</span>
        <span class="slc">//Se obtiene el dispositivo grafico</span>
        <span class="Estilo13">GraphicsDevice</span> graphics <span class="sym">= ((</span>IGraphicsDeviceService<span
            class="sym">)</span>
                                   input<span class="sym">.</span>ContentManager<span class="sym">.</span>ServiceProvider<span
                                       class="sym">.</span><span class="kwd">GetService</span><span class="sym">(</span><span
                                           class="kwb">typeof</span><span class="sym">(</span><span class="Estilo13">IGraphicsDeviceService</span><span
                                               class="sym">))</span>

                                  <span class="sym">).</span>GraphicsDevice<span class="sym">;</span>
        <span class="slc">//Inicializa la instancia actual, lee el ancho y alto de la imagen</span>
        existingInstance <span class="sym">=</span> <span class="kwa">new</span> <span class="Estilo13">BMP2Texture2D</span><span
            class="sym">(</span>graphics<span class="sym">,</span>
                                             input<span class="sym">.</span><span class="kwd">ReadInt32</span><span class="sym">(),</span> input<span
                                                 class="sym">.</span><span class="kwd">ReadInt32</span><span class="sym">(),</span>
                                             <span class="num">1</span><span class="sym">,</span> <span class="Estilo13">ResourceUsage</span><span
                                                 class="sym">.</span>AutoGenerateMipMap<span class="sym">,</span> <span class="Estilo13">SurfaceFormat</span><span
                                                     class="sym">.</span>Color<span class="sym">);</span>

        <span class="slc">//Establece el contenido de la imagen</span>
        <span class="slc">//lee el tamaño de la informacion en bytes a leer</span>
        <span class="slc">//y lee la informacion en bytes</span>
        existingInstance<span class="sym">[</span>i<span class="sym">].</span>SetData<span
            class="sym"><</span><span class="kwb">byte</span><span class="sym">>(</span>input<span
                class="sym">.</span><span class="kwd">ReadBytes</span><span class="sym">(</span>input<span
                    class="sym">.</span><span class="kwd">ReadInt32</span><span class="sym">()));</span>
        <span class="slc">//Establece el color de mascara</span>
        existingInstance<span class="sym">[</span>i<span class="sym">].</span>maskColor <span
            class="sym">=</span> input<span class="sym">.</span>ReadObject<span class="sym"><</span><span
                class="Estilo13">Color</span><span class="sym">>();</span>
        <span class="kwa">return</span> existingInstance<span class="sym">;</span>
    <span class="sym">}</span>
<span class="sym">}</span>
</pre>
<p class="Estilo14">
                Eso es todo, para hacerlo funcionar, se requiere compilar estas clases en una dll
                la cual se debe adicionar al content pipeline, para hacer eso se debe ir a las propiedades
                del proyecto y luego a la ultima pestaña la cual desde luego se llama Content Pipeline,
                desde alli presionar el boton Add y seleccionar la dll creada. Para que desde el
                juego se peuda cargar la informacion se debe incluir referencia por lo menos al
                ensamblado donde se compilo el <span class="Estilo21">ContentTypeReader</span>.
                En adelante tan solo se accede al recurso a travez de un content manager como se
hace de manera habitual:</p>
            <pre>
        <span class="clasMark">ContentManager</span> content<span class="sym">;</span>
        <span class="sym">...</span>
        <span class="sym">...</span>
        <span class="sym">...</span>

        <span class="clasMark">BMP2Texture</span> myTexture <span class="sym">=</span> content<span
            class="sym">.</span>Load<span class="sym"><</span><span class="clasMark">BMP2Texture</span><span
                class="sym">>(</span><span class="stringMark">@"myImage.bmp2"</span><span
                    class="sym">);</span></pre>
        <p class="Estilo14">
Espero les sea de utilidad. Saludos.</p>
[/dohtml]
[size=109]Juan Carlos Ruiz Pacheco
[/size]
Microsoft Technical Evangelist
@JuanKRuiz
http://juank.io

PENTEX

  • Miembro activo
  • **
  • Mensajes: 89
    • Ver Perfil
    • http://black-byte.com/
Re: Xna Content Pipeline
« Respuesta #1 en: Miércoles 21 de Marzo de 2007, 03:22 »
0
Esta muy bueno el articulo JuanK. En general eso siempre ha sido un problema en la industria, la "cositeria" de formatos. Por ejemplo ahora que estoy trabajando un poco con irrlicht , la "solución"  que pusieron ellos fue que el engine leyera cuanto formato pudiera, mientras que por ejemplo Ogre se basa en exporters, todo a mesh.

Aunque en Xna Team Blog muestran que por ahora solo hay unos pocos formatos soportados.

 Creo que una buena alternativa en es Collada, que esta basada en XML, por lo que en teoría debería ser extensible entre herramientas, lenguajes y funcionalidades. Por el momento hay un buen soporte al asunto aunque no falta el que pasa de agache (cof cof, lightwave).


Camilo
Black Byte

JuanK

  • Miembro de ORO
  • ******
  • Mensajes: 5393
  • Nacionalidad: co
    • Ver Perfil
    • http://juank.io
Re: Xna Content Pipeline
« Respuesta #2 en: Miércoles 21 de Marzo de 2007, 04:32 »
0
Asi es es un poco chico, pero el chart que muestran alli se queda bastante corto con la realidad.

Por cierto que opinas de la propuesta que les hice para el alojamiento de mis articulos?
Si hay que pagar me cuentan .
[size=109]Juan Carlos Ruiz Pacheco
[/size]
Microsoft Technical Evangelist
@JuanKRuiz
http://juank.io

JuanK

  • Miembro de ORO
  • ******
  • Mensajes: 5393
  • Nacionalidad: co
    • Ver Perfil
    • http://juank.io
Re: Xna Content Pipeline
« Respuesta #3 en: Jueves 22 de Marzo de 2007, 13:27 »
0
[size=109]Juan Carlos Ruiz Pacheco
[/size]
Microsoft Technical Evangelist
@JuanKRuiz
http://juank.io