DirectX Графика в проектах Delphi



Источник света и свойства материала - часть 7


Вы можете оптимизировать часть кода, связанную с определением позиции, ведь для получения положение курсора в любой момент времени можно использовать функцию 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.

Рис. 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;
hRet := Draw; // Рисуем упрощенный вариант сцены, в задний буфер
if Failed (hret) then ErrorOut ('Draw', hRet); // Получаем доступ к заднему буферу
hRet := FDSDDevice.GetBackBuf fer (0, D3DBACKBUFFER_TYPE_MONO, Back) ;
if Failed (hret) then ErrorOut ( 'GetBackBuf fer ' , hRet); // Обнуляем поля вспомогательной структуры
ZeroMemory (@d3dlr, SizeOf (d3dlr) ) ; // Поверхность заднего буфера запирается
hRet := Back.LockRect (d3dlr, nil, D3DLOCK__READONLY) ;
if Failed (hret) then ErrorOut {'LockRect', hRet); // Значение смещения при выравнивании поверхности
dwDstPitch := dSdlr. Pitch;
case d3ddm. Format of // Текущий формат рабочего стола
D3DFMT_X8R8G8B8 : begin // 32-битный RGB
// Пиксел, соответствующий позиции курсора
DWColor := PDWORD (DWORD (d3dlr .pBits) + OY *
dwDstPitch + OX * 4)A; // Цветовые веса пиксела
R := (DWColor shr 23) and $lf;
G := (DWColor shr 7) and $lf;
В := DWColor and $lf;
end;
D3DFMT_R5G6B5 : begin // 16-битный 5-6-5
DWColor := PDWORD (DWORD (d3dlr .pBits) + OY *
dwDstPitch + OX * 2)^;
R := (DWColor shr 11) and $lf;
G := (DWColor shr 5) and $3f;
В := DWColor and $lf;
end;
end;
Back.UnLockRect; // Возможное исключение не обрабатывается
if Assigned (Back) then begin // Удаляем поверхность
Back._Release;
Back := nil;
end;
// Интерпретация результата
if В о 0 then ShowMessage ('Выбран конус') else
if R <> 0 then ShowMessage ('Выбрана сфера') else
if G <> 0 then ShowMessage ('Выбран объект зеленого цвета')
else
ShowMessage ('Ничего не выбрано');
Factive := True;
end;




Содержание  Назад  Вперед