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


Частичное обновление экрана



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

if FDDSBack.BltFast (0, 0, FDDSBackGround, nil, DDBLTFAST_WAIT) = DDERR__SURFACELOST then Close;
if FDDSPrimary.BltFast (0, 0, FDDSBackGround, nil, DDBLTFAST_WAIT) = DDERR_SURFACELOST then Close;

Обновление кадра объединяет собственно воспроизведение и переключение страниц. Хоть функция перерисовки кадра и вызывается все также беспрерывно, но при каждом вызове на экране только выводится текущее значение FPS, а изменения в картинку вносятся через некоторые промежутки времени, при перемещении образа:

function TfrmDD.UpdateFrame : HRESULT;
var
DC : HOC; wrkRect : TRECT;
begin
Result := DD_FALSE;
ThisTickCount := GetTickCount;
Inc (Frames) ;
if ThisTickCount - LastTickCount > 60 then begin
// Прямоугольник, соответствующий старому положению образа SetRect (wrkRect, 288 + trunc (cos (Angle) * 150),
208 + trunc (sin (Angle) * 150),
352 + trunc (cos (Angle) * 150),
272 + trunc (sin (Angle) * 150));
Angle := Angle + 0.05;
if Angle > 2 * Pi then Angle := Angle -2 * Pi;
//На задней поверхности выводим образ в новом месте if FDDSBack.BltFast (288 + trunc (cos(Angle) * 150),
208 + trunc (sin(Angle) * 150),
FDDSImage, nil,
DDBLTFAST_WAIT or DDBLTFAST_SRCCOLORKEY) = DDERR_SURFACELOST then if Failed (RestoreAll) then Exit;
FPS := PChar ('FPS = ' + Format('%6.2f ,
[Frames * 1000 / (ThisTickCount - LastTickCount)]));
Frames := 0;
LastTickCount := GetTickCount;
// Переключаем страницы, на переднем буфере образ в новом месте if FDDSPrimary.Flip(nil, DDFLIP_WAIT) = DDERR_SURFACELOST
then if Failed (RestoreAll) then Exit;
// Стираем образ на заднем буфере
if FDDSBack.Blt (SwrkRect, FDDSBackGround, @wrkRect, DDBLT_WAIT, nil) = DDERR_SURFACELOST then if Failed (RestoreAll) then Exit;
end;
if Succeeded (FDDSPrimary.GetDC (DC)) then begin
TextOut (DC, 20, 20, fps, 12);
FDDSPrimary.ReleaseDC (DC);
end;
Result := DD_OK;
end;




Начало  Назад  Вперед