Опубликован: 08.07.2007 | Доступ: свободный | Студентов: 1363 / 142 | Оценка: 4.43 / 4.02 | Длительность: 13:47:00
Специальности: Программист
Лекция 6:

Трехмерная графика с использованием Direct3D

< Лекция 5 || Лекция 6: 123456 || Лекция 7 >

Буфер глубины

Если теперь мы попытаемся выводить объекты сцены, то они будут рисоваться в том порядке, в котором воспроизводятся. При этом нарисованные позже примитивы будут "лежать" поверх ранее выведенных. Для адекватной визуализации трехмерных объектов в графических библиотеках предусмотрен так называемый буфер глубины или z-буфер, который представляет собой двумерный массив, хранящий для каждого растеризуемого пикселя значение координаты z. Рассмотрим принцип работы буфера глубины на примере левосторонней системы координат. В начале в z-буфер заносятся (очищается) максимально возможные значения z, а буфер регенерации заполняется значениями пикселей, соответствующими фону. Затем каждая грань объекта преобразуется в растровую форму, причем порядок растеризации грани не играет особой роли. При разложении многоугольника в растр для каждой его точки выполняются следующие шаги:

  1. Вычисление глубины (z-координаты) в точке (x,y) ;
  2. Если z(x,y) меньше чем значение в z-буфере в позиции (x,y) то в z-буфер заносится значение z-координаты растеризуемой точки, а в буфер регенерации помещается обрабатываемый пиксель.

Если выполняется условие шага 2, это означает, что точка многоугольника расположена ближе к наблюдателю, чем точка, значение яркости которой находится в данный момент в позиции (x,y) буфера регенерации.


Единственный недостаток рассмотренного алгоритма – необходимость дополнительной памяти для хранения z-буфера, однако простая и эффективная реализация позволяет использовать этот алгоритм во многих приложениях. Для инициализации буфера глубины в библиотеке Direct3D достаточно заполнить два поля структуры D3DPRESENT_PARAMETERS:

C++
D3DPRESENT_PARAMETERS params;
…
ZeroMemory( &params, 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);

Чтобы отключить z-буфер, нужно установить данную константу D3DRS_ZENABLE в значение "ложь".

C++ device->SetRenderState (D3DRS_ZENABLE, D3DZB_FALSE);
Pascal device.SetRenderState(D3DRS_ZENABLE, 0);

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

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 );

Предпоследний параметр метода Clear задает значение, которым будем заполнен буфер глубины при очистке. Значение единица соответствует бесконечно удаленной точке трехмерного пространства; значение ноль – определяет самую близкую точку.

< Лекция 5 || Лекция 6: 123456 || Лекция 7 >
Олег Корсак
Олег Корсак
Латвия, Рига
Ренат Файзуллин
Ренат Файзуллин
Россия, Казань