Есть ли способ использовать глубину буфер в Direct2D или аналогичный метод , который позволяет мне использовать несколько потоков для рисования фигур ?
Ответ здесь нет. Хотя библиотека Direct2D построена поверх Direct3D, она не предоставляет пользователю такую функцию через API, поскольку примитивы, которые вы можете рисовать, описываются только двумерными координатами.Последний примитив, который вы рисуете для цели рендеринга, становится видимым, поэтому не проводится глубокое тестирование. Кроме того, буфер глубины в Direct3D не имеет большого отношения к многопоточности на стороне процессора.
Также обратите внимание, что даже если вы выдаете команды рисования с использованием нескольких потоков, они будут сериализованы драйвером Direct3D и выполняться последовательно. Некоторые новые графические API, такие как Direct3D 12 и Vulkan, предоставляют многопоточные драйверы, которые позволяют эффективно использовать различный контент из разных потоков, но они имеют более высокую сложность.
Итак, в конце концов, если вы придерживаетесь Direct2D, у вас останется возможность рисовать каждую фигуру последовательно с помощью одного потока.
Но что можно сделать, так это то, что вы можете устранить эффективно окклюдированные фигуры путем тестирования на окклюзию каждой формы против всех остальных. Таким образом, окклюдированные формы могут быть отброшены из списка и никогда не отображаться вообще. Трюк здесь заключается в том, что некоторые формы не заполняют свои границы полностью, из-за прозрачных областей (например, текста) или если фигура является сложным многоугольником. Такие формы не могут быть легко протестированы или потребуются более сложные алгоритмы.
Таким образом, вы должны повторять thourgh всех форм и, если текущая форма представляет собой прямоугольник только затем выполнить тестирование окклюзии всех предыдущих форм границы прямоугольников.
Следующий код следует рассматривать как псевдокод, он предназначен только для демонстрации идеи.
#define RECTANGLE 0
#define TEXT 1
#define TRIANGLE 2
//etc
typedef struct {
int type; //We have a type field
Rect bounds_rect; //Bounds rect
Rect coordinates; //Coordinates, which count vary according to shape type
//Probably you have many other fields here
} Shape;
//We have all shapes in a vector
std::vector<Shape> shapes;
Итерация всех форм.
for (int i=1; i<shapes.size; i++) {
if(shape[i].type != RECTANGLE) {
//We will not perform testing if the current shape is not rectangle.
continue;
}
for(int j=0; j<i; j++) {
if(isOccluded(&shape[j], &shape[i])) {
//shape[j] is totally invisible, so remove it from 'shapes' list
}
}
}
тестирование Occlusion что-то вроде этого
bool isOccluded(Shape *a, Shape *b) {
return (a.bounds_rect.left > b.coordinates.left && a.bounds_rect.right < b.coordinates.right &&
a.bounds_rect.top > b.coordinates.to && a.bounds_rect.bottom < b.coordinates.bottom);
}
И вы не должны повторять все формы с одной нитью, вы можете создать несколько потоков для выполнения тестов для различных частей списка формы , Конечно, вам понадобится некоторая технология блокировки, такая как мьютекс при удалении фигур из списка, но это еще одна тема.
Я не уверен непосредственно в 'Direct2D', но обычно вы назначаете форму' z', сортируете по этой координате и затем визуализируете соответственно, тем самым реализуя простой Z-буфер. – rhughes
@rhughes Мне не нужно их сортировать, так как они уже отсортированы, когда я читаю файл. Кроме того, использование этого метода предотвращает использование нескольких потоков. – Nick
Я имею в виду сортировку по z-координате. Вам не нужно отображать их на отдельных потоках. Сначала визуализируйте фигуру с наименьшим z-cood, а затем проделайте свой путь к фигуре с наивысшим z-координатом. – rhughes