Буфер глубины
Если теперь мы попытаемся выводить объекты сцены, то они будут рисоваться в том порядке, в котором воспроизводятся. При этом нарисованные позже примитивы будут "лежать" поверх ранее выведенных. Для адекватной визуализации трехмерных объектов в графических библиотеках предусмотрен так называемый буфер глубины или z-буфер, который представляет собой двумерный массив, хранящий для каждого растеризуемого пикселя значение координаты z. Рассмотрим принцип работы буфера глубины на примере левосторонней системы координат. В начале в z-буфер заносятся (очищается) максимально возможные значения z, а буфер регенерации заполняется значениями пикселей, соответствующими фону. Затем каждая грань объекта преобразуется в растровую форму, причем порядок растеризации грани не играет особой роли. При разложении многоугольника в растр для каждой его точки выполняются следующие шаги:
- Вычисление глубины (z-координаты) в точке (x,y);
- Если z(x,y) меньше чем значение в z-буфере в позиции (x,y) то в z-буфер заносится значение z-координаты растеризуемой точки, а в буфер регенерации помещается обрабатываемый пиксель.
Если выполняется условие шага 2, это означает, что точка многоугольника расположена ближе к наблюдателю, чем точка, значение яркости которой находится в данный момент в позиции (x,y) буфера регенерации.
Единственный недостаток рассмотренного алгоритма – необходимость дополнительной памяти для хранения z-буфера, однако простая и эффективная реализация позволяет использовать этот алгоритм во многих приложениях. Для инициализации буфера глубины в библиотеке Direct3D достаточно заполнить два поля структуры D3DPRESENT_PARAMETERS:
C++ | D3DPRESENT_PARAMETERS params; … ZeroMemory( ¶ms, sizeof(params) ); … params.EnableAutoDepthStencil = true; params.AutoDepthStencilFormat = D3DFMT_D16; … | |
Pascal |
var params: TD3DPresentParameters; … ZeroMemory( @params, SizeOf(params) ); … params.EnableAutoDepthStencil := true; params.AutoDepthStencilFormat := D3DFMT_D16; … |
Программист может не беспокоиться о линейных размерах буфера глубины, т.к.
система автоматически определяет размеры. Для работы с буфером глубины необходимо также установить константу режима D3DRS_ZENABLE в значение "истина".
C++ | device->SetRenderState (D3DRS_ZENABLE, D3DZB_TRUE); |
Pascal | device.SetRenderState(D3DRS_ZENABLE, 1); |
C++ | device->SetRenderState (D3DRS_ZENABLE, D3DZB_FALSE); |
Pascal | device.SetRenderState(D3DRS_ZENABLE, 0); |
C++ | device->Clear( 0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(255,255,255), 1.0f, 0 ); |
Pascal | device.Clear( 0, nil, D3DCLEAR_TARGET or D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(255,255,255), 1.0, 0 ); |