Gewusst wie: Verwenden von Sprites

Aktualisiert: November 2007

Mithilfe von Sprites können Bilder und Text auf den Bildschirm gezeichnet werden. In diesem Beispiel werden das Zeichnen und Rendern veranschaulicht.

Das Formular für dieses Codebeispiel enthält die folgenden Objekte:

In diesem Codebeispiel wird eine Textur aus einer Datei geladen und das Sprite erstellt. Bauen Sie in das Projekt eine kleine Bitmap ein (wird für das Gerät/den Emulator bereitgestellt).

Der Konstruktor des Formulars legt die Einstellungen für die PresentationParameters-Eigenschaft des Geräts fest. Er erstellt ein Device-Objekt und ruft die Reset-Methode des Geräts auf. Er erstellt auch ein Font-Objekt.

In der folgenden Tabelle werden die Beispielmethoden beschrieben, die das Sprite rendern.

Hinweis:

Für verwaltete Direct3D Mobile-Anwendungen ist Windows Mobile, Version 5.0, für Pocket PCs und Smartphones erforderlich. Informationen über Windows Mobile-Software und SDKs finden Sie unter Externe Ressourcen für .NET Compact Framework.

Methode

Aktionen

OnDeviceReset

  • Lädt aus einer Bitmapdatei eine Textur.

OnPaint

  1. Startet die Szene.

  2. Gibt SpriteFlags-Flags an. Weitere Informationen dazu erhalten Sie im Abschnitt "Robuste Programmierung" im weiteren Verlauf dieses Themas.

  3. Zeichnet das Sprite und den Text auf den Bildschirm.

  4. Beendet die Szene.

Beispiel

Das folgende Codebeispiel enthält ein vollständiges Formular. Mithilfe einer bereitgestellten Bitmap wird ein Sprite gezeichnet.

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

Kompilieren des Codes

Für dieses Beispiel sind Verweise auf die folgenden Namespaces erforderlich:

Robuste Programmierung

Erstellen Sie im Konstruktor des Formulars Sprites und Schriftarten. Sie brauchen dann nach dem Zurücksetzen des Geräts nicht neu erstellt zu werden.

Um möglichst gute Leistungen zu erzielen, verwenden Sie zum Zeichnen von Text ein Sprite. Andernfalls führt das Schriftartobjekt bei jedem Aufruf von DrawText intern die Begin-Methode und die End-Methode für Sprites aus.

Soweit möglich sollte in den Fällen, in denen pro Frame 1 Sprite verwendet wurde, der Sprite in einem einzigen Aufruf der Begin-Methode und der End-Methode enthalten sein.

Geben Sie die folgenden SpriteFlags-Werte an, um das Rendern zu optimieren und die Leistung zu verbessern:

  • SortTexture sortiert Bilder, bevor sie auf den Bildschirm gezeichnet werden. Dadurch kann schneller zwischen Texturen umgeschaltet werden.

  • AlphaBlend rendert Schriftarten ordnungsgemäß, insbesondere wenn Sprites verwendet werden, die transparente oder lichtdurchlässige Bereiche haben.

  • SortDepthBackToFront sortiert Sprites in inverser Reihenfolge. Dies ist besonders dann hilfreich, wenn mehrere lichtdurchlässige oder transparente Sprites übereinander gezeichnet werden sollen.

  • DoNotSaveState verbessert die Leistung bei Anwendungen, die angegebene Renderingzustände nicht verwenden können.

  • DoNotModifyRenderState optimiert die Leistung durch Verwendung des aktuellen Renderingzustands; für Spezialeffekte geeignet.

  • ObjectSpace und Billboard ermöglichen das Zeichnen von Bildern mit unterschiedlichen Spezialeffekten.

Siehe auch

Konzepte

Gewusst-wie-Themen für .NET Compact Framework

Weitere Ressourcen

Mobile Direct3D-Programmierung in .NET Compact Framework