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


Буферы - часть 2


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

ZeroMemory(@ddbltfx, SizeOf (ddbltfx) ) ; ddbltfx.dwSize := SizeOf (ddbltfx) ; ddbltfx. dwFillColor := 0;
while True do begin // Закрашиваем фон вторичной поверхности черным hRet := FDDSBack. Bit (nil, nil, nil, DDBLT COLORFILL or DDBLT WAIT, @ddbltfx) ;
// Внеэкранная поверхность также может быть потеряна
if hRet = DDERR^SURFACELOST then begin if Failed (RestoreAll) then Exit;
end
else Break; end;
// Помещаем растр на вспомогательную поверхность while True do begin
hRet := FDDSBack.BltFast (1ft, 112, FDDSImage, nil, DDBLTFAST_WAIT);
if hRet = DDERR_SURFACELOST then begin if Failed (RestoreAll) then Exit;
end
else Break; end;
// Вспомогательная поверхность заполнена, блиттинг производится //на первичную while True do begin
hRet := FDDSPrimary.BltFast (0, 0, FDDSBack, nil, DDBLTFAST_WAIT);
if hRet = DDERR_SURFACELOST then begin if Failed (RestoreAll) then Exit;
end
else Break;
end;

Функция восстановления поверхности использует вспомогательную функцию перезагрузки растра DDReLoadBitmap модуля DDUtil:

function TfrmDD.RestoreAll : HRESULT; begin
Result = DD_FALSE;
if Succeeded (FDDSPrimary._Restore) then begin if Failed (FDDSImage._Restore) then Exit;
// Рекомендуется перезагрузить растр после восстановления if Failed (DDReLoadBitmap(FDDSImage, szBitmap)) then Exit;
// Добавилось восстановление еще одной вспомогательной поверхности
if Failed (FDDSBack.^Restore) then Exit;
Result := DD_OK;
end;
end;

Протестируйте приложение: никаких полос не возникает, все выглядит прекрасно. DirectDraw предлагает автоматизированный механизм двойной буферизации, аналогичный проделанному нами вручную. Посмотрим на примере проекта каталога Ех1б, как это делается. При создании первичной поверхности указываем количество задних буферов. Вместо одной константы у нас появилась комбинация нескольких флагов. Создаваемая поверхность является комплексной, состоящей из двух поверхностей - первичной и присоединенной к ней вторичной поверхности заднего буфера. Чтобы оговорить то, что "перебрасывание" (flipping) содержимого заднего буфера на первичную поверхность будет осуществляться DirectDraw без нашего участия, необходимо добавить флаг DDSCAPS_FLIP:




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