Читаем Графика DirectX в Delphi полностью

Вспомним, что нам системой предоставлены два экрана, передний и задний буферы, причем второй экран скрыт от зрителя до тех пор, пока не вызывается метод Present объекта устройства. Поэтому данным экраном мы можем воспользоваться для наших целей, осуществляя в него построения по нужной схеме, и не выкладывать его содержимое на передний экран. Система предоставляет нам доступ к содержимому заднего буфера, с помощью метода GetBackBuffer объекта устройства, результат помещается в объект типа IDirect3DSurface8.

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

Переходим к иллюстрации - проекту из каталога Ех04, где рисуется знакомая тестовая сцена, при щелчке кнопки мыши сообщается, какой объект находится под курсором (рис. 10.4).

Первым делом обращаю ваше внимание на то, что при инициализации графической системы необходимо указать возможность запирания поверхности заднего буфера, для чего в поле Flags структуры ТD3DРRЕSЕNТ_РАРАМЕТЕRS не обходимо занести соответствующую константу:

ZeroMemory(@d3dpp, SizeOf(d3dpp));

with d3dpp do begin

Windowed := True;

SwapEffect := D3DSWAPEFFECT_DISCARD;

// Разрешаем запирание поверхности заднего буфера

Flags := D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;

BackBufferFormat := d3ddm.Format;

EnableAutoDepthStencil := True;

AutoDepthStencilFormat := D3DFMT_D16;

end;

Это очень важный момент, не упустите его.

Формат вершин включает в себя координаты, нормаль и цветовую составляющую:

D3DFVF_CUSTOMVERTEX = D3DFVF_XYZ or D3DFVF_NORMAL or D3DFVF_DIFFUSE;

При заполнении буфера вершин цветовая составляющая заполняется только для треугольников сферы и конуса. Для треугольников, образующих комнату, значение диффузной составляющей вершин остается нулевым. Вы можете оптимизировать подобные моменты и использовать отдельные форматы вершин.

Материалы для стен, конуса и сферы инициализируются точно так же, как в первоначальном примере, но при обычном воспроизведении необходимо обязательно указать, что окрашивание треугольников производится с учетом текущего установленного материала, а не значения диффузной составляющей их вершин:

with FDSDDevice do begin

SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);

SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);

SetRenderState(D3DRS_AMBIENT, $00202020);

SetRenderState(D3DRS_LIGHTING, Dword (True));

SetRenderState(D3DRS_NORMALIZENORMALS, DWORD (True));

// Явно указываем использование материала

SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);

SetRenderState(D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL);

SetRenderState(D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_MATERIAL);

end;

При движении курсора мыши по поверхности окна отслеживаются его координаты:

var

OX, OY : DWORD;

procedure TfrmD3D.FormMouseMove(Sender: TObject; Shift: TShiftState;

X, Y: Integer);

begin

OX := X;

OY := Y; end;

Вы можете оптимизировать часть кода, связанную с определением позиции, ведь для получения положение курсора в любой момент времени можно использовать функцию GetCursorPos.

Помимо функции Render, я ввел функцию укороченного воспроизведения, которая отображает сцену с измененными установками и не заканчивается переключением буферов:

function TfrmD3D.Draw : HRESULT;

var

hRet : HRESULT;

begin

if FD3DDevice = nil then begin

Result := E_FAIL;

Exit;

end;

// Очищаем только Z-буфер

hRet := FD3DDevice.Clear(0, nil, D3DCLEAR_ZBUFFER, 0, 1.0, 0);

if FAILED(hRet) then begin

Result := hRet;

Exit;

end;

hRet := FD3DDevice.BeginScene;

if FAILED(hRet) then begin

Result := hRet;

Exit;

end;

with FD3DDevice do begin

SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);

SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);

// Работа с освещением запрещена

SetRenderState(D3DRS_LIGHTING, Dword (False));

end;

DrawScene; // Рисуем комнату

Result := FD3DDevice.EndScene;

end;

При отключенном освещении стены комнаты будут выглядеть черными. Поэтому нам незачем тратить время для очистки цветового буфера. Здесь I также можно оптимизировать код, воспроизводить только те объекты, между (которыми будет осуществляться выбор, и не тратить время на воспроизведение объектов фона. В таком случае потребуется, конечно, очищать цветовой буфер.

Чтобы увидеть, каким остается содержимое заднего буфера после работы этой функции, можете дополнить ее строкой переключения буферов. После щелчка кнопки мыши вы увидите такую же картинку, как на рис. 10.5.

При щелчке кнопки мыши получаем доступ к заднему буферу, запираем полученную поверхность и анализируем содержимое нужного пиксела:

procedure TfrmD3D.FormClick(Sender: TObject);

var

Back : IDirect3DSurface8; // Поверхность заднего буфера

d3dlr : TD3DLOCKED_RECT;

dwDstPitch : DWORD;

hRet : HRESULT;

DWColor : DWORD;

R, G, В : Byte;

begin

R := 0; // Инициализация для предотвращения предупреждений компилятора

G := 0;

В := 0;

FActive := False; // Перерисовку кадра временно отменяем

Back := nil;

Перейти на страницу:

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных