Cómo: Utilizar sprites

Actualización: noviembre 2007

Puede utilizar sprites para dibujar imágenes y escribir texto en la pantalla. En este ejemplo se muestran el dibujo y la representación.

El formulario de este ejemplo de código contiene los objetos siguientes:

Este ejemplo de código carga una textura de un archivo para crear el sprite. Deberá incluir un mapa de bits pequeño en el proyecto que se vaya a implementar en el dispositivo o emulador.

El constructor del formulario especifica la configuración de la propiedad PresentationParameters del dispositivo, crea un objeto Device y llama al método Reset del dispositivo. Además, construye un objeto Font.

La tabla siguiente describe los métodos de ejemplo que representan el sprite.

Nota:

Las aplicaciones móviles Direct3D administradas requieren el software de Windows Mobile versión 5.0 para dispositivos Pocket PC y Smartphone. Vea Recursos externos de .NET Compact Framework para obtener información sobre el software de Windows Mobile y los SDK.

Método

Acciones

OnDeviceReset

  • Carga una textura de un archivo de mapa de bits.

OnPaint

  1. Empieza la escena.

  2. Especifica los indicadores SpriteFlags. Consulte la sección "Programación eficaz" más adelante en este tema para obtener más detalles.

  3. Dibuja el sprite y escribe el texto en la pantalla.

  4. Finaliza la escena.

Ejemplo

El ejemplo de código siguiente proporciona un formulario completo. Dibuja un sprite utilizando un mapa de bits proporcionado.

Class Sprites
    Inherits Form
    ' The objects that will be used to show
    ' the uses of the Sprite class
    Private device As Device
    Private d3dFont As Microsoft.WindowsMobile.DirectX.Direct3D.Font
    Private sprite As Sprite
    Private texture As Texture


    Public Sub New() 
        Dim present As PresentParameters
        Dim gdiFont As System.Drawing.Font

        Me.Text = "Using Sprites"

        ' Give the application a way to be closed.
        ' This must be done before the device is created
        ' as it will cause the hwnd of the Form to change.
        Me.MinimizeBox = False

        present = New PresentParameters()
        present.Windowed = True
        present.SwapEffect = SwapEffect.Discard

        device = New Device(0, DeviceType.Default, Me, CreateFlags.None, present)
        AddHandler device.DeviceReset, AddressOf OnDeviceReset

        ' Construct a new Sprite.
        ' Sprites do not need to be recreated
        ' when a device is reset.
        sprite = New Sprite(device)

        gdiFont = New System.Drawing.Font(FontFamily.GenericSansSerif, 10F, FontStyle.Regular)

        ' Construct a new font. Fonts do not need
        ' to be recreated when a device is reset.
        d3dFont = New Microsoft.WindowsMobile.DirectX.Direct3D.Font(device, gdiFont)

        OnDeviceReset(Nothing, EventArgs.Empty)

    End Sub


    Private Sub OnDeviceReset(ByVal sender As Object, ByVal e As EventArgs) 
        ' Textures must be recreated whenever a device is reset
        ' no matter what pool they are created in.
        texture = TextureLoader.FromFile(device, "image.bmp")

    End Sub


    Protected Overrides Sub OnPaintBackground(ByVal e As PaintEventArgs) 
        ' Do nothing.
    End Sub

    Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
        ' Begin the scene and clear the back buffer to black
        device.BeginScene()
        device.Clear(ClearFlags.Target, Color.Black, 1.0F, 0)

        ' When using sprites it is important to
        ' specify sprite flags passed to Sprite.Begin
        sprite.Begin(SpriteFlags.SortTexture Or SpriteFlags.AlphaBlend)

        ' Draw an image to the screen using Sprite.Draw
        Dim spriteY As Integer = 5

        sprite.Draw(texture, Vector3.Empty, New Vector3(0, spriteY, 0), Color.White.ToArgb())
        spriteY += texture.GetLevelDescription(0).Height + 5

        ' Draw a portion of an image to the screen
        ' using Sprite.Draw. This shall be drawn such
        ' that the image is modulated with the color green.
        sprite.Draw(texture, New Rectangle(4, 4, 24, 24), Vector3.Empty, New Vector3(0, spriteY, 0), Color.Green)

        spriteY += 30

        ' Draw text to the screen. Using a sprite to draw text
        ' to the  screen is essential for good performance.
        ' Otherwise the font object will perform a
        ' Sprite.Begin/Sprite.End internally for
        ' each call to Font.DrawText. This can cause severe
        ' performance problems.
        spriteY = 150

        d3dFont.DrawText(sprite, "This is text.", 5, spriteY, Color.Red)
        spriteY += d3dFont.Description.Height + 5

        d3dFont.DrawText(sprite, "This is another line of text.", 5, spriteY, Color.Green)
        spriteY += d3dFont.Description.Height + 5

        d3dFont.DrawText(sprite, "Only one call to Sprite.Begin.", 5, spriteY, Color.Blue)

        ' End drawing using this sprite. This will cause the
        ' sprites to be flushed to the graphics driver and will
        ' reset the transformation matrices, textures states,
        ' and renderstates if the SpriteFlags specified in Begin
        ' call for that to happen.
        sprite.End()

        ' Finish the scene and present it on the screen.
        device.EndScene()
        device.Present()

    End Sub


    Shared Sub Main() 
        Application.Run(New Sprites())

    End Sub
End Class
class Sprites : Form
{
    // The objects that will be used to show
    // the uses of the Sprite class
    private Device device;
    private Microsoft.WindowsMobile.DirectX.Direct3D.Font d3dFont;
    private Sprite sprite;
    private Texture texture;

    public Sprites()
    {
        PresentParameters present;
        System.Drawing.Font gdiFont;

        this.Text = "Using Sprites";

        // Give the application a way to be closed.
        // This must be done before the device is created
        // as it will cause the hwnd of the Form to change.
        this.MinimizeBox = false;

        present = new PresentParameters();
        present.Windowed = true;
        present.SwapEffect = SwapEffect.Discard;

        device = new Device(0, DeviceType.Default, this,
            CreateFlags.None, present);
        device.DeviceReset += new EventHandler(OnDeviceReset);

        // Construct a new Sprite.
        // Sprites do not need to be recreated
        // when a device is reset.
        sprite = new Sprite(device);

        gdiFont = new System.Drawing.Font
            (FontFamily.GenericSansSerif,
        10.0f, FontStyle.Regular);

        // Construct a new font. Fonts do not need
        // to be recreated when a device is reset.
        d3dFont= new Microsoft.WindowsMobile.DirectX.Direct3D.Font
            (device, gdiFont);

        OnDeviceReset(null, EventArgs.Empty);
    }

    private void OnDeviceReset(object sender, EventArgs e)
    {
        // Textures must be recreated whenever a device is reset
        // no matter what pool they are created in.
        texture = TextureLoader.FromFile(device, "image.bmp");
    }

    protected override void OnPaintBackground(PaintEventArgs e)
    {
        // Do nothing.
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        // Begin the scene and clear the back buffer to black
        device.BeginScene();
        device.Clear(ClearFlags.Target, Color.Black, 1.0f, 0);

        // When using sprites it is important to
        // specify sprite flags passed to Sprite.Begin

        sprite.Begin(SpriteFlags.SortTexture | SpriteFlags.AlphaBlend);

        // Draw an image to the screen using Sprite.Draw

        int spriteY = 5;

        sprite.Draw(texture, Vector3.Empty, new Vector3(0,
            spriteY, 0),
            Color.White.ToArgb());
        spriteY += texture.GetLevelDescription(0).Height + 5;

        // Draw a portion of an image to the screen
        // using Sprite.Draw. This shall be drawn such
        // that the image is modulated with the color green.

        sprite.Draw(texture, new Rectangle(4, 4, 24, 24),
            Vector3.Empty,
            new Vector3(0, spriteY, 0), Color.Green);

        spriteY+= 30;

        // Draw text to the screen. Using a sprite to draw text
        // to the  screen is essential for good performance.
        // Otherwise the font object will perform a
        // Sprite.Begin/Sprite.End internally for
        // each call to Font.DrawText. This can cause severe
        // performance problems.

        spriteY = 150;

        d3dFont.DrawText(sprite, "This is text.",
            5, spriteY, Color.Red);
        spriteY += d3dFont.Description.Height + 5;

        d3dFont.DrawText(sprite, "This is another line of text.",
            5, spriteY, Color.Green);
        spriteY += d3dFont.Description.Height + 5;

        d3dFont.DrawText(sprite, "Only one call to Sprite.Begin.",
            5, spriteY, Color.Blue);

        // End drawing using this sprite. This will cause the
        // sprites to be flushed to the graphics driver and will
        // reset the transformation matrices, textures states,
        // and renderstates if the SpriteFlags specified in Begin
        // call for that to happen.
        sprite.End();

        // Finish the scene and present it on the screen.
        device.EndScene();
        device.Present();
    }

    static void Main()
    {
        Application.Run(new Sprites());
    }
}

Compilar el código

Para este ejemplo se requieren referencias a los siguientes espacios de nombres:

Programación eficaz

Se crean sprites y fuentes en el constructor del formulario; por tanto, no se deben volver a crear al restablecer el dispositivo.

Para obtener un buen rendimiento, utilice un sprite para escribir el texto. De lo contrario, el objeto de fuente ejecuta los métodos Begin y End del sprite por cada llamada a DrawText.

Si es posible, cuando utilice un sprite por marco, anide el sprite en una llamada a los métodos Begin y End de un sprite.

Especifique los siguientes valores de SpriteFlags para optimizar la representación y mejorar el rendimiento:

  • SortTexture ordena las imágenes antes de dibujar en la pantalla para que el cambio de texturas pueda ser más rápido.

  • AlphaBlend representa las fuentes correctamente, sobre todo para los sprites que tienen áreas transparentes o translúcidas.

  • SortDepthBackToFront ordena los sprites en orden descendente, que es un proceso útil si se dispone de varios sprites translúcidos o transparentes que se van a dibujar uno sobre otro.

  • DoNotSaveState mejora el rendimiento de las aplicaciones que no pueden utilizar los estados de representación especificados.

  • DoNotModifyRenderState optimiza el rendimiento mediante el estado de representación actual y se puede utilizar para realizar efectos especiales.

  • ObjectSpace y Billboard habilitan el dibujo de imágenes con distintos efectos especiales.

Vea también

Conceptos

.Temas "Cómo..." de .NET Compact Framework

Otros recursos

Programar Mobile Direct3D en .NET Compact Framework