В прошлой части наших уроков, мы рассмотрели процесс рисования простейшей фигуры – треугольника. Тогда мы использовали специальные, трансформированные координаты, которые были равны точкам на форме (если вы когда-нибудь рисовали с помощью Graphics или Canvas, то это тоже самое). Однако, чаще всего при выводе графической информации на экран с помощью DirectX, используют не трансформированные координаты. С помощью них можно создать полноценную 3D сцену, при должном усердии это может быть полноценный 3D мир, и расположить внутри него камеру для отображения нужной информации на экран.

Этот урок мы начнем с того, что изменим координаты треугольника на не трансформированные. Измените код метода OnPaint на следующий:

C#
1
2
3
4
5
6
7
 CustomVertex.PositionColored[] vertices = new CustomVertex.PositionColored[3];
 vertices[0].Position = new Vector3(0f, 0f, 0f);
 vertices[0].Color = Color.Red.ToArgb();
 vertices[1].Position = new Vector3(10f, 0f, 0f);
 vertices[1].Color = Color.Green.ToArgb();
 vertices[2].Position = new Vector3(5f, 10f, 0f);
 vertices[2].Color = Color.Yellow.ToArgb();

Также необходимо заменить тип вершин на нормальные:

C#
1
 device.VertexFormat = CustomVertex.PositionColored.Format;

Если вы запустите сейчас свой код, то увидите, что треугольника не стало. Это произошло из-за того, что не заданы координаты камеры. Это легко исправить, добавив следующие строки в начало OnPaint метода:

C#
1
2
 device.Transform.Projection = Matrix.PerspectiveFovLH((float)Math.PI/4, this.Width/this.Height, 1f, 50f);
 device.Transform.View = Matrix.LookAtLH(new Vector3(0,0,30), new Vector3(0,0,0), new Vector3(0,1,0));

В первой строчке задается, как камера будет вести себя на сцене: первый параметр устанавливает угол обзора в 90 градусов, второй устанавливает отношение сторон, последние два параметра устанавливают минимальное и максимальное расстояние обрезки объектов. В нашем случае это 1 и 50, т.е. объекты ближе 1 и дальше 50 не будут показаны.

Вторая строка – позиция камеры. Камера установлена на 30 позиций выше треугольника и в направлении начала координат, вокруг которого расположены вершины треугольника.

Теперь мы уже можем увидеть треугольник, но, если запустить код, то окажется, что все стало черным. Это произошло из-за того, что сейчас сцена стала чуточку более сложной, чем в прошлом уроке. Теперь нам необходимо определить также источник света, но этому будет непосредственно посвящена своя глава, поэтому сейчас просто добавьте ниже определения камеры следующую строчу:

C#
1
 device.RenderState.Lighting = false;

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

Важно отметить, что если мы перевернем камеру:

C#
1
 device.Transform.View = Matrix.LookAtLH(new Vector3(0,0,-30), new Vector3(0,0,0), new Vector3(0,1,0));

то снова треугольник не будет виден, т.к. DirectX рисует только те полигоны, которые обращены к камере, чего в данном случае не произойдет. Решением в данном случае станет или переворот треугольника:

C#
1
2
3
4
5
6
 vertices[2].Position = new Vector3(0f, 0f, 0f);
 vertices[2].Color = Color.Red.ToArgb();
 vertices[0].Position = new Vector3(5f, 10f, 0f);
 vertices[0].Color = Color.Yellow.ToArgb();
 vertices[1].Position = new Vector3(10f, 0f, 0f);
 vertices[1].Color = Color.Green.ToArgb();

или сделать прямое указание устройству отображать все полигоны, вне зависимости от их положения:

C#
1
 device.RenderState.CullMode = Cull.None;

Но вы должны запомнить, что второе решение никогда не  должно применяться в финальном продукте, т.к. это существенно замедляет процесс построения сцены.

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