Как правильно обновить буферы вершин в DirectX 10

Небольшая предыстория: я работаю над проектом на C++, в котором я пытаюсь рисовать трехмерные представления объектов на основе данных профиля в реальном времени. Данные профилирования собираются с внешнего оборудования для профилирования. Система движется вдоль объекта и со скоростью 300 раз в секунду предоставляет моему программному обеспечению срез профиля. Каждый срез состоит из списка примерно из 8000 точек X-Y. Движение профилировщика фиксируется энкодером. Информация кодировщика обеспечивает 3-е измерение сканирования.

Еще одна важная вещь, которую следует отметить, это то, что профилировщик может двигаться вперед и назад по объекту. Когда это происходит, я хочу заменить ранее прочитанные/нарисованные фрагменты новыми (в зависимости от положения энкодера). На данный момент я добиваюсь этого с помощью кругового буфера срезов, которые я сохраняю по счетчику кодировщика. Это также означает, что я буду выбрасывать слайсы, когда буфер заполнится и начнет перезаписывать старые слайсы. Чтобы отобразить на экране нужное количество предметной части, мне нужно рисовать 1000 срезов данных профиля за раз. Сейчас я визуализирую объект как облако точек. В будущем мы можем попытаться присоединить соседние фрагменты и отобразить их в виде треугольного списка.

Я новичок в DirectX, но, используя книги и онлайн-примеры, я дошел до того, что рисую объект в 3D, но я убежден, что неэффективно/правильно использую Vertex Buffers. Большинство примеров, которые я нашел, работают с очень статичными моделями. Поэтому они обычно создают один буфер вершин со своим списком точек, а затем просто манипулируют матричными преобразованиями. Я, с другой стороны, буду очень быстро обновлять сцену, поскольку я получаю данные профиля с нашего оборудования.

В настоящее время я создаю новый буфер вершин для каждого среза, который я считываю. Когда я рисую сцену, я перебираю свой список до 1000 буферов и вызываю Draw() для каждого из них. Я заметил, что если я уменьшил вдвое количество отрисовываемых буферов вершин за раз, мой FPS значительно увеличился, в то время как при уменьшении вдвое количества вершинных точек на буфер улучшение было незначительным, поэтому я принимаю это как указание на то, что несколько буферов вершин это не правильный подход к этому.

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

Спасибо за ваше время. Любые советы будут высоко оценены!


person Tim Coolman    schedule 01.04.2011    source источник


Ответы (1)


Вы всегда можете обновить точки в буфере вершин, если вы делаете буфер динамическим (укажите D3D10_USAGE_DYNAMIC и используйте ID3D10Device::CopySubresourceRegion для эффективного обновления только частей буфера). Это должно быть более эффективно, чем слишком частое пересоздание буферов.

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

person Alexander Gessler    schedule 01.04.2011
comment
Спасибо за ответ. Ваше предложение использовать динамический буфер звучит очень многообещающе. Что касается наличия переменного количества точек на срез, есть ли способ указать промежутки в буфере - нулевые или неиспользуемые вершины? Я знаю, что IASetVertexBuffers позволяет вам устанавливать несколько буферов и какие вершины в каждом буфере рисовать. Я надеялся, что будет похожая опция для указания определенных диапазонов в одном буфере для рисования, но пока ничего подобного не нашел. - person Tim Coolman; 01.04.2011
comment
Вы можете просто оставить их как есть и не рисовать пробелы, не так ли? - person Alexander Gessler; 02.04.2011
comment
После дополнительных поисков и чтения я обнаружил, что многие люди предлагают использовать UpdateSubresource для обновления части буфера вершин, и VB даже не должен быть динамическим. Я прочитал документацию в MSDN (msdn.microsoft.com/en-us /library/bb173621.aspx), но я все еще пытаюсь понять, как правильно настроить параметры, которые передаются в этот метод, в частности, pDstBox, SrcRowPitch и SrcDepthPitch. Мой буфер вершин имеет длину 1 миллион вершин (1000 «срезов» по ​​1000 максимальных точек на срез). Вы когда-нибудь использовали этот метод? Спасибо. - person Tim Coolman; 05.04.2011