Треугольник является элементарным полигоном в трехмерной графике. Как вы, вероятно, помните их курса геометрии, для однозначного описания плоскости достаточно всего трех координат. Собственно поэтому треугольник полностью удовлетворяет этим требованиям.
Для отрисовки любой поверхности можно пользоваться только треугольниками. Единственный вопрос в их количестве. Т.е. чем больше количество треугольником, тем более гладкой будет смотреться поверхность.
Итак, мы решили нарисовать самую примитивную фигуру - треугольник. На самом деле это не такая уж тривиальная задача в рамках DirectX. Рассмотрим эту задачку подробнее.
Для начала нам необходима собственно среда разработки (IDE). Я использую MS Visual Studio 2005.
Теперь по шагам, что же необходимо сделать:
Шаг 1:
Создать обычное Windows Application.
Шаг 2:
Добавление ссылок в проект:
Необходимо выбрать библиотеки Microsoft.DirectX и Microsoft.DirectX.Direct3D. У меня их несколько, я выбрал последние версии их того, что было.
После этого для более компактного написания приложения добавим 2 директивы в файл созданной формы:
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;
Шаг 3:
Непосредственное создание устройства:Устройство в контексте DirectX является аналогом графического устройства, установленного на компьютере. Естественно этих устройств, как и графических устройств может быть несколько. Сначала добавим private член Device в нашу форму:
private Device device = null;
Теперь необходимо написать функцию инициализации устройства:
public void InitializeGraphics()
{
// Параметры представления
PresentParameters presentParams = new PresentParameters();
// указание того, что работать будем в оконном режиме
presentParams.Windowed = true;
// Указание по работе с буфером. В нашем случае будет производится сброс
// буфера если он не готов к представлению
presentParams.SwapEffect = SwapEffect.Discard;
// Создание устройства
device = new Device(0, DeviceType.Hardware, this, CreateFlags.SoftwareVertexProcessing, presentParams);
}
Подробнее о создании устройства:
1) первый параметр (adapter) конструктора определяет с каким abpbxtcrbv устройством необходимо работать. Нулевое значение указывает на устройство по умолчанию.
2) Второй параметр DeviceType указывает на тип устройства. Мы будем использовать Hardware, т.е. аппаратное.
3) третий параметр renderWindow связывает указанное окно с устройством рендеринга. Так как у нас окно уже есть, то ключевое слово this указывает на текущий объект типа Form.
4) Параметр behaviorFlags для управления режимами устройства после его создания. Значение SoftwareVertexProcessing говорит о том, что обработку вершин необходимо передать ЦП.
5) presentationParameters - параметры представления. Более подробное описание используемых свойств в комментариях.
Далее необходимо изменить код входной точки приложения:
static void Main()
{
using (Form1 triangeForm = new Form1())
{
triangeForm.Show();
triangeForm.InitializeGraphics();
Application.Run(triangeForm);
}
}
После этого мы получаем работающую форму без каких-либо отличий :)
Срочно надо добавить что-нибудь в наш проект. И это будет перегрузка функции OnPaint, которая вызывается при перерисовке окна.
protected override void OnPaint(PaintEventArgs e)
{
device.Clear(ClearFlags.Target, Color.Chocolate, 1.0f, 0);
device.Present();
}
Тут мы указываем, что хотим залить наше окно сплошным цветом.

Хм, уже что-то, по крайней мере видны хоть какие-то результаты нашей работы.
Ну а где же треугольник? Вот именно отрисовкой его мы и займемся прямо сейчас.
Шаг 4:
Рисование треугольника:Для этого необходимо немного изменить код функции перерисовки окна:
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
{
device.Clear(ClearFlags.Target, System.Drawing.Color.CornflowerBlue, 1.0f, 0);
CustomVertex.TransformedColored[] verts = new CustomVertex.TransformedColored[3];
verts[0].SetPosition(new Vector4(this.Width / 2.0f, 50.0f, 0.5f, 1.0f));
verts[0].Color = System.Drawing.Color.White.ToArgb();
verts[1].SetPosition(new Vector4(this.Width - (this.Width / 5.0f), this.Height - (this.Height / 5.0f), 0.5f, 1.0f));
verts[1].Color = System.Drawing.Color.Blue.ToArgb();
verts[2].SetPosition(new Vector4(this.Width / 5.0f, this.Height - (this.Height / 5.0f), 0.5f, 1.0f));
verts[2].Color = System.Drawing.Color.Red.ToArgb();
device.BeginScene();
device.VertexFormat = CustomVertex.TransformedColored.Format;
device.DrawUserPrimitives(PrimitiveType.TriangleList, 1, verts);
device.EndScene();
device.Present();
this.Invalidate();
}
Для описания данного кода не буду изголяться, а просто приведу слова автора:
Так как каждый элемент массива, который мы создали, представляет
одну точку в нашем треугольнике, таким образом будет создано три элемента.
Затем, используя структуру Vector4, мы вызываем метод SetPosition
для каждого элемента массива. Местоположение преобразованной вершины
определяется значениями X и Y в координатах экрана (относительно
начала координат окна 0,0), а также значениями глубины Z и rhw-
(обратная величина «homogenous w»). Последние два значения для нашей
выборки игнорируются. Структура Vector4 очень удобна для задания
информации о треугольнике.
Далее мы устанавливаем цвет каждой вершины. Следует обратить
внимание на то, что мы должны вызвать используемый для этого метод
задания стандартных цветов ToArgb. В приложении Direct3D подразумевается,
что цвета будут определяться 32-разрядными целыми числами, и
данный алгоритм преобразует базовый цвет в этот формат.
Важно помнить и то, что для определения координат нашего треугольника
мы используем ширину и высоту текущего окна и должны это
учитывать при изменении размеров треугольника.
Теперь нужно указать, каким образом мы хотим рисовать наш треугольник.
Это делается путем вызова кода
device.BeginScene();
device.VertexFormat = CustomVertex.TransformedColored.Format;
device.DrawUserPrimitives(PrimitiveType.TriangleList, 1, verts);
device.EndScene();
Первая строка - сообщаем о том, что мы готовы к отрисовке сцены.
Вторая строка - сообщаем что мы хотим рисовать.
Третья строка - описание фигуры, которую необходимо нарисовать. У нас это набор треугольников с единственным числом с указанием вершин.
Четвертая строка - указание о окончании процедуры рисования.
Это еще не все, для корректного отображения при изменении размеров окна необходимо добавить строчку
this.Invalidate();
Эта строка заставит осуществлять принудительную перерисовку нашего окна.
И еще одна строчка поставит точку в наших мытарствах:
this.SetStyLe(ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque, true);
Ее необходимо вставить в конструктор формы.
В итоге получаем такое вот приложение.

В следующем посте мы заставим треугольник летать и крутиться.