Встроенный импортер содержимого XNA FBX / model и дескриптор процессора "обращены" так же, как это делает практически каждая программа моделирования - в виде списков вершин и индексов.(Как примечание, ваш графический процессор также изначально поддерживает эту схему, и современные игры полагаются на нее по соображениям производительности.)
Например, рассмотрим простой четырехугольник с четырьмя треугольниками.Вершины могут быть:
v0 (0,0,0)
v1 (1,0,0)
v2 (1,1,0)
v3 (0,1,0)
или
v0--v1
| / |
| / |
v3--v2
Чтобы представить это в форме «лица», вам потребуется список данных, эквивалентный
треугольник 1 (верхний левый): (0,0,0), (1,0,0), (0,1,0) = (v0, v1, v3)
треугольник 2 (нижнийсправа): (1,0,0), (1,1,0), (0,1,0) = (v1, v2, v3)
, что требует шести записей вершин.
Используя нативные структуры XNA, Vector3 имеет три элемента, каждый из которых является плавающей точкой одинарной точности (4 байта), так что каждый равен 3 * 4 = 12 байтов, и вам нужно шесть из них, так что72 байта.
Или вы можете использовать индексирование.В дополнение к четырем вершинам, вы храните список индексов:
f1: 0,1,3
f2: 1,2,3
Индексы могут быть сохранены с использованием шорт (16-битных целых).Итак, давайте рассмотрим разницу:
Нет индексов: две грани * 3 вершины * 3 компонента (xyz) * 4 байта каждая = 2 * 3 * 3 * 4 = 72 байта.
Индексируется:
вершин: 4 вершины * по 3 компонента * 4 байта на компонент = 48 байт,
индексы (3 шорта на треугольник): 6 индексов * 2 байта = 12 байт.
48 + 12 = 60, что немного меньше 72 байт для неиндексированной модели.
Эти 12 байтов могут показаться не слишком большими, пока вы не рассмотрите весь уровень с 100 000+ треугольников.В этот момент вы видите разницу в 1,2 МБ.Хотя ваша видеокарта может занимать около 2 ГБ памяти, перемещение этих данных назад и вперед между ОЗУ хоста и ОЗУ графического процессора стоит дорого.
Итак, как вы получаете эти данные?
Посмотрите наModel.Meshes[].MeshParts[].VertexBuffer.GetData()
и Model.Meshes[].MeshParts[].IndexBuffer.GetData()
.Вы можете использовать эти методы для извлечения вершин и индексов, а затем перекрестные ссылки на них, чтобы получить список треугольников.
Вы не можете просто получить прямой доступ к элементам VertexBuffer
и IndexBuffer
поскольку они хранятся в ОЗУ графического процессора, разрешение случайного доступа к элементам может привести к снижению производительности почти до отрицательной скорости.
Также обратите внимание на метод GraphicsDevice.DrawIndexedPrimitives()
.
IПри необходимости можете опубликовать пример кода позже.