Практическое руководство. Использование спрайтов

Обновлен: Ноябрь 2007

Спрайты можно использовать для рисования изображений и текста на экране. В следующем примере демонстрируются рисование и отрисовка.

Форма для этого примера кода содержит следующие объекты:

Данный пример кода загружает из файла текстуру для создания спрайта. В проект, предназначенный для развертывания на устройстве или эмуляторе, потребуется включить небольшое растровое изображение.

Конструктор формы задает настройки свойства PresentationParameters устройства, создает объект Device и вызывает метод Reset устройства. Он также создает объект Font.

В следующей таблице описываются примеры методов, выполняющих рендеринг спрайта.

ms229680.alert_note(ru-ru,VS.90).gifПримечание.

Управляемым мобильным приложениям Direct3D требуется программа Windows Mobile версии 5.0 для карманных ПК и смартфонов. Сведения о программе Windows Mobile и пакетах SDK см. в разделе Внешние ресурсы для платформы .NET Compact Framework.

Метод

Действия

OnDeviceReset

  • Загружает текстуру из файла растрового изображения.

OnPaint

  1. Запускает сцену.

  2. Задает флаги SpriteFlags. Дополнительные сведения см. в приведенном ниже разделе "Надежное программирование".

  3. Отображает на экране спрайт и текст.

  4. Завершает сцену.

Пример

В следующем примере кода приведена полная форма. Она рисует спрайт с помощью заданного растрового изображения.

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

Компиляция кода

Для этого примера требуются ссылки на следующие пространства имен:

Отказоустойчивость

Данная функция позволяет создавать в конструкторе формы спрайты и шрифты, которые не потребуется создавать повторно при перезагрузке устройства.

Для повышения производительности используйте спрайт для рисования текста. В противном случае для каждого вызова DrawText внутри объекта шрифта будут выполняться методы спрайта Begin и End.

Если это возможно, то при использовании одного спрайта на фрейм вкладывайте этот спрайт в один вызов методов Begin и End.

Для оптимизации отрисовки и повышения производительности задайте следующие значения SpriteFlags:

  • SortTexture — для сортировки изображений перед рисованием на экране, чтобы переключение текстур могло выполняться быстрее.

  • AlphaBlend — для правильного рендеринга шрифтов, особенно для спрайтов, имеющих прозрачные и полупрозрачные области.

  • SortDepthBackToFront — для сортировки спрайтов от переднего плана к фону, что особенное удобно при отрисовке нескольких прозрачных или полупрозрачных спрайтов друг поверх друга.

  • DoNotSaveState — для повышения производительности приложений, которые не могут использовать определенные состояния рендеринга.

  • DoNotModifyRenderState — для оптимизации производительности с помощью текущего состояния рендеринга и для специальных эффектов.

  • ObjectSpace и Billboard — для отрисовки изображений с различными специальными эффектами.

См. также

Основные понятия

Разделы руководства по платформе .NET Compact Framework

Другие ресурсы

Мобильное программирование Direct3D в .NET Compact Framework