Reference = add reference, в висуал студия 2010 не могу найти в вкладке Solution Explorer, Microsoft.Xna.Framework. Его нету. |
Введение в XNA Framework
Итак, для создания графического устройства мы должны объявить в тексте класса формы поле класса
GraphicsDevice: GraphicsDevice device=null;
Затем в обработчик события Load формы необходимо вставить код создания нового экземпляра класса GraphicsDevice c заданными параметрами листинг 1.1).
private void MainForm_Load(object sender, EventArgs e) { // Инициализируем все поля структуры presentParams значениями по умолчанию PresentationParameters presentParams = new PresentationParameters(); // Мы будем осуществлять вывод на поверхность формы, то есть в оконном режиме presentParams.IsFullScreen = false; // Включаем двойную буферизацию presentParams.BackBufferCount = 1; // Переключение буферов должно осуществляться с максимальной эффективностью presentParams.SwapEffect = SwapEffect.Discard; // Задаем ширину и высоту клиентской области окна. Если присвоить этим полям значение 0 (что // и происходит по умолчанию), то конструктор класса GraphivsDevice автоматически рассчитает // значение этих полей и занесeт их в структуру presentParams. Поэтому эти две строки, в // принципе, можно и опустить. presentParams.BackBufferWidth = ClientSize.Width; presentParams.BackBufferHeight = ClientSize.Height; // Создаем новое устройство, обладающее следующими характеристиками: // - Устройство будет использовать видеоадаптер по умолчанию // - Устройство будет аппаратным // - Вывод будет осуществляться на поверхность текущей формы // – Обработка вершин будет осуществляться средствами GPU // - Представление данных на экране задаeтся структурой presentParams (см. выше) // – Доступ к устройству возможен только из одного потока приложения device = new GraphicsDevice(GraphicsAdapter.DefaultAdapter, DeviceType.Hardware, Handle, CreateOptions.SoftwareVertexProcessing | CreateOptions.SingleThreaded, presentParams); }Листинг 1.1.
Создав объект устройства, можно приступать к реализации закраски формы синим цветом. Для этого воспользуемся методом Clear класса GraphicsDevice, который очищает форму путeм закраски еe заданным цветом:
public void Clear(ClearOptions options, Color color, float depth, int stencil);
где
- options - набор битовых флагов, указывающих какие буферы необходимо очистить. Для очистки экранного буфера используется флаг ClearOptions.Target. Остальные флаги ClearOptions.DepthBuffer и ClearOptions.Stencil, используемые для очистки соответственно буфера глубины и буфера шаблона, которые будут рассмотрены в следующих лекциях.
- color - цвет, которым будет закрашен экран. Задаeтся с использованием структуры Microsoft.Xna.Framework.Graphics.Color, являющейся функциональным аналогом структуры System.Drawing.Color. Появление такого брата-близнеца обусловлено необходимостью сделать XNA Framework независимым от функциональности платформы Windows.
- depth - значение, которым будет "закрашен" буфер глубины.
- stencil - значение, которым будет заполнен буфер шаблона.
Вызов метода Clear необходимо вставить в обработчик события Paint, вызываемый каждый раз при необходимости перерисовки содержимого формы:
private void MainForm Paint(object sender, PaintEventArgs e) { device.Clear(ClearOptions.Target, Microsoft.Xna.Framework. Graphics.Color.CornflowerBlue, 0.0f, 0) ; }
Обратите внимание на использование полного имени структуры Microsoft.Xna.Framework.Graphics.Color с указанием пространства имен. Если это не сделать, возникнет конфликт с одноименной структурой из пространства имен System.Drawing.
Класс GraphicsDevice имеет и более простую перегрузку ( override ) метода, предназначенную для очистки исключительно экранного буфера:
public void Clear(Color color);
где
color - цвет, которым заполняется весь экран
Использование данного варианта перегрузки метода позволяет несколько упростить код приложения:
private void MainFormPaint(object sender, PaintEventArgs e) { device.Clear(Microsoft.Xna.Framework.Graphics.Color.CornflowerBlue); }
По окончанию работы приложение должно удалить графическое устройство при помощи метода Dispose. Для этой цели идеально подходит обработчик события FormClosed (листинг 1.2).
private void MainForm_FormClosed(object sender, FormClosedEventArgs e) { // Если устройство существует if (device != null) { // Удаляем (освобождаем) устройство device.Dispose(); // На всякий случай присваиваем ссылке на устройство значение null device = null; } }Листинг 1.2.
Если вы забудете удалить объект устройства, .NET самостоятельно попытается вызвать метод Dispose экземпляра класса GraphicsDevice в процессе сборки мусора (если быть более точным, сборщик мусора вызывает метод Finalize, который довольно часто реализует вызов метода Dispose ). Но здесь имеется один нюанс. Как известно, сборщик мусора для вызова методов Finalize удаляемых объектов создаeт отдельный поток, в то время как на платформе Windows устройство Direct3D имеет право удалить только поток, создавший это устройство. Соответственно, деструктор объекта GraphicsDevice, вызываемый из параллельного потока, не сможет корректно удалить устройство Direct3D.
Примечание
Даже если вы не укажете при создании устройства флаг CreateOptions.SingleThreaded, сборщик мусора всe равно не сможет корректно удалить объект.
Вроде бы всe. Давайте попробуем запустить полученное приложение на выполнение (клавиша F5 ). Не смотря на то, что метод Clear вызывается при каждой перерисовке окна (в этом легко убедится, установив точку останова на строку с вызовом этого метода при помощи клавиши F9 ) , на внешнем виде формы это никак не отражается. Интересно, с чем это может связано?
Всe дело в том, что мы используем двойную буферизацию, то есть наше приложение выполняет все графические построения в невидимом вспомогательном буфере. После окончания визуализации необходимо скопировать информацию из этого вспомогательного буфера на форму. Эту операцию выполняет метод Present класса GraphicsDevice:
void Present()