How to: Use Sprites

You can use sprites for drawing images and text to the screen. This example demonstrates drawing and rendering.

The form for this code example has the following objects:

This code example loads a texture from a file to create the sprite. You will need to include a small bitmap in your project to be deployed to the device or emulator.

The form's constructor specifies settings for the device's PresentationParameters property, creates a Device object, and calls the device's Reset method. It also constructs a Font object.

The following table describes the sample methods that render the sprite.

Note

Managed Direct3D mobile applications require Windows Mobile version 5.0 software for Pocket PCs and Smartphones. See External Resources for the .NET Compact Framework for information about Windows Mobile software and SDKs.

Method

Actions

OnDeviceReset

  • Loads a texture from a bitmap file.

OnPaint

  1. Begins the scene.

  2. Specifies SpriteFlags flags. See the "Robust Programming" section later in this topic for details.

  3. Draws the sprite and text to the screen.

  4. Ends the scene.

Example

The following code example provides a complete form. It draws a sprite using a provided bitmap.

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());
    }
}

Compiling the Code

This example requires references to the following namespaces:

Robust Programming

Create sprites and fonts in the form's constructor so that they do not need to be re-created when the device is reset.

For good performance, use a sprite to draw text. Otherwise, the font object internally performs sprite Begin and End methods for each call to DrawText.

If possible, when using one sprite per frame, nest the sprite within one call to the Begin and End methods for a sprite.

Specify the following SpriteFlags values to optimize rendering and to improve performance:

  • SortTexture sorts images before drawing to the screen so that switching textures can be faster.

  • AlphaBlend renders fonts correctly, especially for sprites that have transparent or translucent areas.

  • SortDepthBackToFront sorts sprites in front-to-back order, which is useful if you have several translucent or transparent sprites to be drawn on top of each other.

  • DoNotSaveState improves performance for applications that cannot use specified render states.

  • DoNotModifyRenderState optimizes performance by using the current render state and can be used for special effects.

  • ObjectSpace and Billboard enable drawing images with different special effects.

See Also

Concepts

.NET Compact Framework How-to Topics

Other Resources

Mobile Direct3D Programming in the .NET Compact Framework