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



Механизм трехмерной игры - часть 9


Для упрощения вычислений я позволяю человечкам проходить сквозь препятствия и друг через друга. Код предотвращения этих ситуаций очень прост, и вы можете самостоятельно дополнить его отслеживанием таких ситуаций.
Для вывода значения FPS треугольники символов цифр и точки объединены мною в один файл numbers.txt. Процедура piaceLetter определяет в потоке положение и количество треугольников для нужного символа:

procedure TfrmD3D.DrawLetters;
var
i : Integer; nS, nW : Integer;
begin
with FDSDDevice do begin
// Некоторые треугольники построены против часовой
SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
//Не тратить время на освещение
SetRenderState(D3DRS_LIGHTING, DWORD (False));
// Направляем поток на буфер символов
SetStreamSource(0, FD3DVBLetter, SizeOf(TNormVertex));
SetVertexShader(D3DFVF_NORMVERTEX);
end;
// Цикл вывода в пространстве символов FPS for i := 1 to Length(FpsOut) do begin
// Получаем положение треугольников символа
PiaceLetter (FpsOut[i], nS, nW);
// Сдвигаемся в пространстве для вывода очередного символа
LetTrans._41 := i * 0.1;
FD3DDevice.SetTransform(D3DTS_WORLD, LetTrans);
FD3DDevice.DrawPrimitive(D3DPTJTRIANGLELIST, nS, nW);
end;
// Возвращаем обычные установки with FD3DDevice do begin
SetRenderState(D3DRS_COLLMODE, D3DCULL_CCW);
SetRenderState(D3DRS_LIGHTING, DWORD (True) ) ;
end;
end;

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

function TfrmD3D.BukupTexture (var FDSTextBMP : IDIRECT3DTEXTURE8;
const FileName : String) : HRESULT;
var
hRet : HRESULT;
d3dlr : TD3DLOCKED__RECT;
dwDstPitch : DWORD;
X, Y : DWORD;
Bmp : TBitmap;
R, G, В : Byte;
begin
Bmp := TBitmap.Create;
try
Bmp.LoadFromfile (FileName);
except
raise EAbort.Create ('Can''t open file: ' + FileName);
Result := S_FALSE;
Exit;
end;
hRet := FD3DDevice.CreateTexture (Bmp.Width, Bmp.Height, 0, 0,
D3DFMT_A8R8G8B8, D3DPOOL MANAGED, FD3TextBMP);
if FAILED(hRet) then begin
Result := hRet;
Exit;
end;
hRet := FD3TextBMP.LockRect(0, d3dlr, nil, 0) ;
if FAILED(hRet) then begin
Result := hRet;
Exit;
end;
dwDstPitch := d3dlr.Pitch;
for Y := 0' to Bmp.Height - 1 do
for X := 0 to Bmp.Width - 1 do begin
R := GetRValue (Bmp.Canvas.Pixels [X,
DWORD (Bmp.Height -1) - Y] ) ;
G := GetGValue (Bmp.Canvas.Pixels [X,
DWORD (Bmp.Height -I) - Y] ) ;
В := GetBValue (Bmp.Canvas.Pixels [X,
DWORD (Bmp.Height -I) - Y] ) ;
PDWORD(DWORD(d3dlr.pBits)+Y*dwDstPitch+X*4)л :=
D3DCOLOR_XRGB(R, G, B);
end;
// Резервируем место для копии первоначального растра
GetMem (TexPointer, 4 * Bmp.Width * Bmp.Height); // Запоминаем первоначальньй растр
CopyMemory (TexPointer, d3dlr.pBits, 4 * Bmp.Width * Bmp.Height)
wrkTexWidth := Bmp.Width; wrkTexHeight := Bmp.Height; Bmp.Free;
Result := FDSTextBMP.UnlockRect(0);
end;
// Покрытие снегом текстуры
function TfrmDSD.SnowTexture (var FD3TextBMP : IDIRECT3DTEXTURE8)
HRESULT;
var
hRet : HRESULT;
d3dlr : TD3DLOCKED_RECT;
i : Integer;
dwDstPitch : DWORD;
begin
// Запираем прямоугольник текстуры
hRet := FDSTextBMP.LockRect(0, d3dlr, nil, 0);
if FAILED(hRet) then begin
Result := hRet;
Exit;
end;
// Копируем в него первоначальный растр
CopyMemory (d3dlr.pBits, TexPointer, 4 * wrkTexWidth * wrkTexHeight);
dwDstPitch := d3dlr.Pitch;
// Произвольные точки текстуры закрашиваем черным
for i := 1 to 10000 do
PDWORD (DWORD(d3dlr.pBits) + DWORD(random(wrkTexHeight)) * dwDstPitch +
DWORD(random(wrkTexWidth)) * 4)Л := 0; Result := FD3TextBMP.OnlockRect(0);
end;




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