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

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

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

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

1
  device . VertexFormat = CustomVertex . PositionColored . Format ;

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

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 позиций выше треугольника и в направлении начала координат, вокруг которого расположены вершины треугольника.

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

1
  device . RenderState . Lighting = false ;

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

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

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

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

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

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

1
  device . RenderState . CullMode = Cull . None ;

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

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