C ++ & DirectX - вопрос геометрии - PullRequest
1 голос
/ 16 сентября 2010

Я работаю над своим собственным 3d-движком и задаю следующий вопрос:

У меня есть абстрактный объект, который обрабатывает геометрию (вершины и грани) . Он использует внутреннее хранилище для этой геометрии, позволяет редактировать, и у моего объекта рендерера есть метод RenderGeometry.

С этим дизайном мой процесс рендеринга включает в себя шаг geometry caching. Итак, у рендерера есть какой-то картоподобный контейнер

std::map<Geometry*, CachedGeometry*> map;

и здесь Geometry обозначает мое собственное хранилище геометрии, а CachedGeometry означает пару аппаратных индексов и буферов вершин, которые затем можно отобразить (в случае DirectX 9 это будут IDirect3D9VertexBuffer* и IDirect3D9IndexBuffer*.


И, ну, все выглядит отлично и очень удобно. Тем не менее, каждый вызов рендеринга Geometry* требует огромных затрат времени - найти этот Geometry* объект в моем внутреннем хранилище и только потом рендерить CachedGeometry*.

.

В случае простых сцен эти накладные расходы были, конечно, минимальными, но когда я попытался визуализировать ландшафт с огромным количеством небольших пространственных объектов (пятен), профилирование показало, что около 20% затраченного времени в рендеринге фактически использовался для std::map поисков.

Контейнеры на основе хэша (на самом деле boost::unordered_map) показали еще худшую производительность (почему?) , и этот процент вырос до 35%.


Итак - чтобы подвести итог - что мне делать в этой ситуации? Полагаю, этот дизайн действительно удобен и "уместен" , но имеет снижение производительности абстракции.

Я думаю, что, вероятно, мне следует попробовать "более противный" подход и ввести в моем рендере методы, подобные StoreGeometry, которые будут возвращать индекс объекта (например, int), чтобы метод RenderGeometry выглядел как RenderGeometry(int stored_geometry_index).

Хотя это выглядит очень плохо, возможно, это могло бы помочь мне сократить количество поисков.

Как вы думаете? Может быть, какой-то альтернативный подход? Что современные двигатели делают с предэкранированием геометрии?

1 Ответ

2 голосов
/ 16 сентября 2010

Я удивлен, что std::map работает так плохо. Возможно, стоит задать вопрос (сначала искать существующие ответы!), В частности, о производительности std :: map для указателей.

Учитывая, что Geometry и CachedGeometry являются объектами, которыми вы управляете, вы можете делать все, что хотите, чтобы поддерживать связи между ними. Один из способов - сделать ссылку двухсторонней: и Geometry, и CachedGeometry имеют указатели друг на друга, и если CachedGeomitry уничтожен, он говорит Geometry обнулить ссылку на CachedGeometry. Если ваше приложение однопоточное, это может быть очень просто. Если нет, то это все еще выполнимо, но вам потребуется подумать, как вы справляетесь (или предотвращаете) ситуации, когда объект удаляется в воздухе.

...