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



Непосредственный доступ к пикселам оверхности - часть 3


function TfrmDD. PutPixel (const X, Y : Integer;
const Value : Byte) : HRESULT; var
desc : TDDSURFACEDESC2 ;
hRet : HRESULT; begin
ZeroMemory (Odesc, SizeOf (desc) );
desc.dwSize := SizeOf (desc) ;
// Всегда, всегда анализируйте результат
hRet := FDDSBack.Lock (nil, desc, DDLOCK_WAIT, 0) ;
if Failed (hRet) then begin Result := hRet;
Exit;
end;
// Находим адрес нужного пиксела и устанавливаем его значение
PByte (Integer (desc. IpSurf асе) + Y * desc.lPitch + X) Л := Value;
Result := FDDSBack. Unlock (nil) ; end;

Поле lPitch записи TDDSURFACEDESC2 содержит расстояние до начала следующей строки. Для 8-битного режима это будет, конечно, 640 (ширина по-iepxHOCTH умножить на размер одной ячейки). Но мы подготавливаем уни"рсальный код, для других режимов есть существенное отличие.
Сод перерисовки кадра совсем прост, ставим очередную точку:

Result := PutPixel (random (ScreenWidth) ,
random (ScreenHeight) , random (255));

Для того чтобы нарисованные точки не пропадали, экран очищать необходимо только один раз. У нас это делается сразу после подготовки поверхностей. Обратите внимание, как все происходит:

Failed (Clear) then Close; // Очищаем задний буфер
Failed (FlipPages) then Close; // Переставляем буферы
// Очищаем то, что раньше находилось в переднем буфере Failed (Clear) then Close;

Нельзя забывать и о ситуации восстановления окна, после восстановления поверхностей опять следует очистить оба буфера:

unction TfrmDD. RestoreAll : HRESULT;
var
hRet : HRESULT;
begin
hRet := FDDSPrimary._Restore;
if Succeeded (hRet) then begin // Только при успехе этого дейсвия
if Failed (Clear) then Close;
if Failed (FlipPages) then Close; // Здесь неудача уже непоправима
if Failed (Clear) then Close; Result := DD_OK end else
Result := hRet;
end;

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

procedure TfrmDD.ApplicationEventslIdle(Sender: TObject;
var Done: Boolean); begin
if FActive then begin
if Succeeded (UpdateFrame)
then FlipPages else RestoreAll end;
Done := False; end;




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