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



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



Прямой доступ к графическим данным обеспечивает максимум быстродействия, и предоставляет разработчику возможность реализации любых, или почти любых, действий с изображением.
На время прямого доступа поверхность должна быть заблокирована, после работы поверхность необходимо разблокировать. Во время блокировки поверхности операционная система находится в особом режиме, поэтому блокировка должна применяться в течение максимально короткого промежутка времени.
Блокирование поверхности является одним из самых спорных моментов в DirectDraw. Фактически она означает исключительный доступ к разделу памяти, связанному с поверхностью. Если для работы с обычными переменными, например, при копировании одной строки в другую, нам не приходится блокировать память, ассоциированную с данными, то почему же при прямом доступе к памяти поверхности нам непременно следует блокировать эту память? Запирать поверхность необходимо, поскольку позиция поверхности в системной памяти может меняться, системный менеджер памяти по каким-то своим соображениям может перемещать блоки памяти.

Примечание
Работа с данными, размещаемыми в видеопамяти, в принципе отличается от привычной. Позже мы узнаем, как избавиться от блокирования поверхности, размещенной в системной памяти, если это необходимо.

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

function TfrmDD. Clear : HRESULT; var
desc : TDDSURFACEDESC2; // Вспомогательная структура
hRet : HRESULT; begin
Result := DD_FALSE;
ZeroMemory (@desc, SizeOf (desc) ) ; // Обычные действия с записью
desc.dwSize := SizeOf (desc) ;
// Запираем задний буфер
hRet := FDDSBack. Lock (nil, desc, DDLOCK_WAIT, 0) ;
if Failed (hRet) then begin
Result := hRet;
Exit;
end;
// Заполняем нулем блок памяти заднего буфера
FillChar (desc.lpSurfaceA, 307200, 0);
//В конце работы обязательно необходимо открыть запертую поверхность Result := FDDSBack.Unlock (nil);
end;




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