netlib.narod.ru | < Назад | Оглавление | Далее > |
Буфер глубины (depth buffer, также часто называемый z-буфер или w-буфер) — это способ хранения в Direct3D информации о «глубине», необходимой для визуализации. Эта информация о глубине используется при растеризации для того, чтобы определить, какие пиксели блокируют (закрывают) другие. Сейчас в нашем приложении нет буфера глубины, поэтому перекрывания пикселей при растеризации не происходит. Однако, у нас вообще нет перекрывающихся пикселей, так что давайте нарисуем побольше кубов, чтобы они заслоняли друг друга. Добавьте после вызовов DrawBox следующий фрагмент кода:
DrawBox(angle / (float)Math.PI, angle / (float)Math.PI * 2.0f, angle / (float)Math.PI / 4.0f, 0.0f, (float)Math.Cos(angle), (float)Math.Sin(angle)); DrawBox(angle / (float)Math.PI, angle / (float)Math.PI / 2.0f, angle / (float)Math.PI * 4.0f, 5.0f, (float)Math.Sin(angle), (float)Math.Cos(angle)); DrawBox(angle / (float)Math.PI, angle / (float)Math.PI / 2.0f, angle / (float)Math.PI / 2.0f, -5.0f, (float)Math.Cos(angle), (float)Math.Sin(angle));
Здесь мы просто добавляем три дополнительных куба, которые будут вращаться вокруг среднего горизонтального ряда кубов. Запустив это приложение вы сразу заметите, что кубы перекрываются, но невозможно визуально определить, где заканчивается один куб и начинается другой. Все выглядит так, будто кубы слипоись в комок. Здесь на помощь приходит буфер глубины.
Добавление буфера глубины к нашему приложению является простой задачей. Вы помните параметры показа, которые мы передавали нашему конструктору устройства? Так вот, здесь мы и включаем информацию о нашем буфере глубины. Для того, чтобы добавить к устройству буфер глубины, нам надо заполнить два новых параметра:
public Microsoft.DirectX.Direct3D.DepthFormat AutoDepthStencilFormat [get, set] public bool EnableAutoDepthStencil [get, set]
Присвойте параметру EnableAutoDepthStencil значение true, чтобы включить буфер глубины на вашем устройстве; буфер будет использовать формат, заданный в члене AutoDepthStencilFormat. Допустимые значения для этого члена из перечисления DepthFormat показаны в таблице 4.1:
Таблица 4.1. Возможные форматы буфера глубины | |
Значение | Описание |
D16 | 16-разрядный Z-буфер для глубины |
D32 | 32-разрядный Z-буфер для глубины |
D16Lockable | 16-разрядный Z-буфер для глубины с возможностью блокировки |
D32FLockable | Блокируемый буфер глубины, в котором значения глубины представлены в виде стандартных чисел с плавающей точкой в формате IEEE |
D15S1 | 16-разрядный Z-буфер, в котором 15 бит используются для канала глубины, а последний бит — для канала трафарета (канал трафарета будет обсуждаться позже) |
D24S8 | 32-разрядный Z-буфер, в котором 24 бита используются для канала глубины, а оставшиеся 8 бит используются для канала трафарета |
D24X8 | 32-разрядный Z-буфер, в котором 24 бита используются для канала глубины, а оставшиеся 8 бит игнорируются |
D24X4S4 | 32-разрядный Z-буфер, в котором 24 бита используются для канала глубины, 4 бита используются для канала трафарета, а оставшиеся 4 бита игнорируются |
D24FS8 | Неблокируемый формат в котором 24 бита используются для хранения канала глубины (в формате с плавающей точкой), а оставшиеся 8 бит используются для канала трафарета |
Буферы глубины с большей разрядностью могут хранить больше данных о глубине за счет быстродействия. Если вы точно не знаете, что вам нужен большой буфер глубины, выбирайте меньшую разрядность. Большинство современных видеокарт поддерживают как минимум 16-разрядный буфер глубины, так что добавьте к инициализации структуры параметров показа следующие строки:
presentParams.EnableAutoDepthStencil = true; presentParams.AutoDepthStencilFormat = DepthFormat.D16;
Прекрасно, теперь у нашего устройства есть буфер глубины. Давайте взглянем, какие отличия появились в нашем приложении. Двигайтесь дальше и запустите программу.
Наверное, что-то сломано, поскольку мы видим не то, что ожидали. Что случилось с нашими кубами? Почему добавление буфера глубины к нашему устройству привело к внезапной поломке всей визуализации? Это произошло из-за того, что наш буфер глубины никогда не очищается, и поэтому находится в неправильном состоянии. Мы уже выполняем очистку устройства, и достаточно просто изменить ее так, чтобы одновременно очищался и буфер глубины. Модифицируйте вызов метода очистки следующим образом:
device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.CornflowerBlue, 1.0f, 0);
Теперь запуск приложения приводит к желаемому результату. Можете убедиться, что кубы разделены и буфер глубины функционирует нормально.
netlib.narod.ru | < Назад | Оглавление | Далее > |