Главная » Разработка для Windows Phone 7 » Сохранение содержимого целевого объекта прорисовки Windows Phone 7

0

Ранее я упоминал, что для описания каждого пиксела заднего буфера Windows Phone 7 – и самого экрана – выделяется лишь 16 бит. Так какого же формата растровое изображение создает RenderTarget2D?

По умолчанию RenderTarget2D создается с разрешением 32 бита на пиксел – по 8 бит для красного, зеленого, синего и альфа каналов – соответственно члену перечисления SurfaceFormat.Color. Больше об этом формате я смогу сказать в конце данной главы, но в наши дни данный 32-разрядный формат считается достаточно стандартным. Это единственный формат цвета, поддерживаемый растровыми изображениями Silverlight, например.

Для повышения производительности можно создать объект RenderTarget2D или Texture2D с таким же форматом пикселов, что и в заднем буфере и экране устройства. Оба класса поддерживают конструкторы, включающие аргументы типа SurfaceFormat для обозначения формата цвета.

Использование объекта RenderTarget2D с форматом SurfaceFormat.Bgr565 в приложении PinwheelText не приведет ни к чему хорошему. В этом формате не предусмотрен альфа- канал, поэтому фон RenderTarget2D не сможет быть прозрачным. Его придется специально закрашивать определенным цветом соответственно цвету фона заднего буфера.

В следующем приложении создается объект RenderTarget2D, который имеет не только такой же размер, что и задний буфер, но и такой же формат цвета. Однако это приложение довольно старомодно, и вот почему.

На заре Microsoft Windows на торговых выставках, где демонстрировалось множество компьютеров, очень часто можно было увидеть приложения, просто отображающие непрерывные последовательности прямоугольников разных размеров и цветов. Как реализовать такую программу на XNA? Стратегия ее написания не так очевидна. Имеет смысл добавлять новый прямоугольник в коллекцию в ходе выполнения метода Update, но мы не хотим создавать приложение, подобное DragAndDraw. Каждую секунду мы будем увеличивать коллекцию прямоугольников на 30 объектов. Через час перегруженный метод Draw уже будет пытаться сформировать визуальное представление более ста тысяч прямоугольников каждые 33 миллисекунды!

Вместо этого, вероятно, вы захотите создавать прямоугольники случайного размера и цвета на RenderTarget2D, размер которого соответствует размеру заднего буфера. В основе этих прямоугольников, которые будут успешно накладываться на RenderTarget2D, может лежать все то же белое растровое изображение 1×1, используемое в DragAndDraw.

Эти два растровых изображения хранятся как поля приложения RandomRectangles (Случайные прямоугольники) вместе с объектом Random:

Проект XNA: RandomRectangles Файл: Game1.cs (фрагмент, демонстрирующий поля)

public class Game1 : Microsoft.Xna.Framework.Game {

GraphicsDeviceManager graphics; SpriteBatch spriteBatch;

Random rand = new Random(); RenderTarget2D tinyTexture; RenderTarget2D renderTarget;

}

Метод LoadContent создает два объекта RenderTarget2D. Для большого требуется развернутый конструктор, некоторые аргументы которого ссылаются на свойства, рассмотрение которых выходит за рамки данной книги:

Проект XNA: RandomRectangles Файл: Game1.cs (фрагмент)

protected override void LoadContent() {

// Создаем новый SpriteBatch, который может использоваться для отрисовки текстур spriteBatch = new SpriteBatch(GraphicsDevice);

tinyTexture = new RenderTarget2D(this.GraphicsDevice, 1, 1); this.GraphicsDevice.SetRenderTarget(tinyTexture); this.GraphicsDevice.Clear(Color.White); this.GraphicsDevice.SetRenderTarget(null);

renderTarget = new RenderTarget2D( this.GraphicsDevice,

this.GraphicsDevice.PresentationParameters.BackBufferWidth,

this.GraphicsDevice.PresentationParameters.BackBufferHeight,

false,

this.GraphicsDevice.PresentationParameters.BackBufferFormat, DepthFormat.None, 0, RenderTargetUsage.PreserveContents);

}

В конструкторе можно увидеть ссылку на BackBufferFormat. Но также стоит обратить внимание на последний аргумент: член перечисления RenderTargetUsage.PreserveContents (Сохранять содержимое). Это не опция по умолчанию. Обычно при задании RenderTarget2D в GraphicsDevice существующее содержимое растрового изображения игнорируется и, буквально, аннулируется. Опция PreserveContents обеспечивает сохранение существующих данных целевого объекта прорисовки и отображение каждого нового прямоугольника поверх всех предыдущих.

В методе Update определяются некоторые случайные значения координат и цвета, задается большой объект RenderTarget2D в GraphicsDevice, и поверх существующего содержимого отрисовывается крошечная структура с использованием этих случайных значений Rectangle и Color:

Проект XNA: RandomRectangles Файл: Game1.cs (фрагмент)

protected override void Update(GameTime gameTime) {

// Обеспечиваем возможность выхода из игры

if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed) this .Exit();

int x1 = rand.Next(renderTarget.Width); int x2 = rand.Next(renderTarget.Width); int y1 = rand.Next(renderTarget.Height); int y2 = rand.Next(renderTarget.Height); int r = rand.Next(25 6); int g = rand.Next(25 6); int b = rand.Next(256); int a = rand.Next(25 6);

Rectangle rect = new Rectangle(Math.Min(x1, x2), Math.Min(y1, y2),

Math.Abs(x2 – x1), Math.Abs(y2 – y1)); Color clr = new Color(r, g, b, a);

this.GraphicsDevice.SetRenderTarget(renderTarget); spriteBatch.Begin();

spriteBatch.Draw(tinyTexture, rect, clr); spriteBatch.End();

this.GraphicsDevice.SetRenderTarget(null); base.Update(gameTime);

}

Перегруженный Draw просто выводит на экран большой RenderTarget2D целиком: Проект XNA: RandomRectangles Файл: Game1.cs (фрагмент)

protected override void Draw(GameTime gameTime) {

spriteBatch.Begin();

spriteBatch.Draw(renderTarget, Vector2.Zero, Color.White); spriteBatch.End();

base.Draw(gameTime);

}

Буквально через минуту экран уже выглядит следующим образом:

Цвета, используемые для прямоугольников, включают случайное значение альфа-канала, поэтому (как мы видим) прямоугольники частично прозрачные. Что любопытно, мы можем получить это значение прозрачности, даже несмотря на то что у создаваемого прямоугольника нет альфа-канала. Изменим конструктор для tinyTexture следующим образом:

tinyTexture = new RenderTarget2D(this.GraphicsDevice, 1, 1, false,

SurfaceFormat.Bgr5 65, DepthFormat.None);

Теперь сам tinyTexture не имеет характеристики прозрачности, но по-прежнему его визуальное представление может быть сформировано на текстуре большего размера с частично прозрачным цветом посредством вызова метода Draw объекта SpriteBatch.

Источник: Чарльз Петзольд, Программируем Windows Phone 7, Microsoft Press, © 2011.

По теме:

  • Комментарии