Hace un tiempo escribí sobre la visibilidad de capas desde lo que había podido aprender observando los ejemplos de F1 pero quedaba mucho por rascar.

Como comentaba el orden a la hora de dibujar influye en la visibilidad de las capas haciendo que la primera dibujada este en el fondo y la última dibujada este en el frente. Esto es así en los valores por defecto que trae el método SpriteBatch.Begin.

Aunque si bien comentaba que depende del orden de los Begin-End, en realidad depende del orden de las texturas dibujadas dentro de este ya que se pueden dibujar tantas texturas como queramos dentro de Begin-End.

Bien, las posibilidades de XNA en la gestión de capas es bastante sencilla pero da bastante juego. Hay 3 tipos de parámetros que se le pueden pasar al SpriteBatch.Begin y dependiendo de los valores que le pasemos actuará de un modo u otro.

El primer tipo, SpriteBlendMode, trata la transparencia de las capas y la combinación de estas. Los valores que puede tener SpriteBlendMode son:

  • None que hace que se elimine la capa alfa haciendo que no haya transparencias y donde hubiese se vuelve blanco.
  • AlphaBlended es el valor por defecto y permite el uso de transparencias.
  • Por último esta Additive que combina los colores de las capas y es como si todas las capas fuese semitransparentes de modo que son translucidas.

El segundo tipo de parámetro que se le pasa a Begin es SpriteSortMode que trata de como se ordenan las capas y puede tener 5 valores distintos:

  • Deferred el cual es por defecto no dibuja los sprites hasta que SpriteBatch.End no ha sido llamado enviando las peticiones al dispositivo gráfico después en el orden que han sido creados. Permite varios SpriteBatch simultáneos sin conflictos.
  • Con Inmediate Begin llama al dispositivo gráfico y a medida que se van creando se van dibujando. Solo un SpriteBatch permitido y es el más rápido de todos.
  • En texture manda la prioridad de capa (que explicaré más abajo) y su funcionamiento es igual que con Deferred.
  • BackToFront dibuja de la capa del fondo a la capa del frente y su funcionamiento es el mismo que el de Deferred.
  • FrontToBack es, como se puede suponer, el contrario que BackToFront y dibuja del frente al fondo de modo que el fondo queda encima y funciona como Deferred.

Por último solo queda pasarle a Begin el último parámetro que necesita, SafeSateMode que guarda el estado de Begin antes y después de hacer un efecto. Puede tener 2 posibles valores:

  • None que no guarda nada.
  • SaveState que guarda el estado antes de llamar a Begin y es restaurado después de llamar a End

Para cambiar la profundidad de las texturas en Z debemos llamar al método override de 9 parámetros de spriteBatch.Draw (si utilizamos XNA Game Studio sería el 6/7 de las posibles llamadas) y en su último parámetro, LayerDepth le ponemos un float entre 0 y 1 siendo 0 lo más cerca y 1 lo más lejos.

Ejemplo de spriteBatch.Begin:
spriteBatch.Begin(SpriteBlendMode.Additive,
SpriteSortMode.Immediate,
SaveStateMode.None);

Ejemplo de spriteBatch.Draw:
spriteBatch.Draw(textura, new Vector2(
(Window.ClientBounds.Width / 3),
(Window.ClientBounds.Height / 4)),
null,
Color.White,
0,
Vector2.Zero,
1,
SpriteEffects.None,
1);

XNA: Visibilidad de capas

diciembre 3, 2008

Para dibujar un texto se puede hacer de dos modos: utilizando la misma capa para el font como para sprite o utilizarar una nueva capa solo para el string. Si utilizamos la misma capa no habrá interferencias entre estas pues todo se dibuja en un mismo buffer por decirlo de algún modo.

Si utilizamos distintas capas son 2 buffer a la hora de dibujar por lo que, dependiendo de como lo hagamos uno estará superpeusto al otro. Como sabemos que una capa será superpuesta a la anterior? pues de un modo muy sencillo, la última capa dibujada es la capa más arriba.

ForegroundBatch.Begin();
ForegroundBatch.Draw(SpriteTexture, pos, Color.White);
ForegroundBatch.End();

spriteBatch.Begin();
spriteBatch.DrawString(spriteFont, output, posFont, Color.LightGreen,
0, FontOrigin, 1.0f, SpriteEffects.None, 0.
spriteBatch.End();

De este modo, la capa ForegroundBatch estará en el fondo mientras spriteBatch se superpondrá. Para hacer lo contrario simplemente darle la vuelta.

spriteBatch.Begin();
spriteBatch.DrawString(spriteFont, output, posFont, Color.LightGreen,
0, FontOrigin, 1.0f, SpriteEffects.None, 0.
spriteBatch.End();

ForegroundBatch.Begin();
ForegroundBatch.Draw(SpriteTexture, pos, Color.White);
ForegroundBatch.End();