Координаты и камера
В прошлой части наших уроков, мы рассмотрели процесс рисования простейшей фигуры – треугольника. Тогда мы использовали специальные, трансформированные координаты, которые были равны точкам на форме (если вы когда-нибудь рисовали с помощью 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; |
Но вы должны запомнить, что второе решение никогда не должно применяться в финальном продукте, т.к. это существенно замедляет процесс построения сцены.
В следующей главе мы подробно разберем организацию вращения треугольника.