Вход/Регистрация
Графика DirectX в Delphi
вернуться

Краснов Михаил

Шрифт:

ddsCaps.dwCaps := DDSCAPS_OFFSCREENPLAIN; // Внеэкранная поверхность

dwWidth := wrkBitmap.Width; // Ширина поверхности равна ширине растра

dwHeight := wrkBitmap.Height; // Задаем высоту поверхности end; // with

// Собственно создание вспомогательной поверхности

hRet := FDD.CreateSurfасе(ddsd, FDDSImage, nil);

if hRet <> DD_OK then begin // Анализируем на предмет успешности

ErrorOut(hRet, 'Create Image Surface');

Exit;

end;

// Копирование растра из wrkBitmap во вспомогательную поверхность

hRet := DDCopyBitmap (FDDSImage, wrkBitmap.Handle, 0, 0, wrkBitmap.Width,

wrkBitmap.Height);

if hRet <> DD_OK then begin // Обязательно анализируем результат

ErrorOut(hRet, 'DDCopyBitmap');

Exit;

end;

// Удаление вспомогательного объекта wrkBitmap.Free;

Вспомогательная, внеэкранная поверхность Foosimage создается с описанием DDSCAPSJDFFSCREENPLAIN. Здесь есть некоторые нюансы, но пока рассматривать их не будем.

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

не забываем дописать имя модуля после uses. В тонкости того, как осуществляется копирование, можете не вникать или разберитесь позднее самостоятельно. Код данной функции основан на функциях API. Ключевым является вызов StretchBlt.

Вспомогательная поверхность создана и заполнена растром размером 256x256 пикселов. Среди аргументов операции блиттинга присутствуют структуры типа TRECT, задающие местоположение в принимающей поверхности и копируемую область. Поэтому код обработчика перерисовки окна дополнился переменными dstRect и srcRect типа TRECT. Заполняем их поля с помощью API-функции setRect:

SetRect (dstRect, 100, 100, 356, 356); // Для принимающей поверхности

SetRect (srcRect, 0, 0, 256, 256); // Для источника

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

Канву для вывода растра не используем, делаем теперь все традиционным для DirectDraw способом:

while True do begin // Возможно, придется производить неоднократно

hRet := FDDSPrimary.Blt (SdstRect, FDDSImage, @srcRect, DDBLT_WAIT,

nil); // Собственно блиттинг

if hRet = DDERR_SURFACELOST then begin // Поверхность потеряна

if Failed (RestoreAll) then Exit; // Пытаемся восстановить

end else Break; // Или все прошло успешно, или неустранимая ошибка

end;

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

function TfrmDD.RestoreAll : HRESULT; begin

Result := DD_FALSE; // Определяемся с результатом // Пытаемся восстановить первичную поверхность

if Succeeded (FDDSPrimary._Restore) then begin

// Пытаемся восстановить вторичную поверхность

if Failed (FDDSImage._Restore) then Exit;

Result := DD_OK; // Все прошло успешно

end;

end;

Нажав комбинацию клавиш <Alt>+<Tab>, переключитесь с этого приложения, а затем верните ему фокус. Если восстановление поверхностей прошло успешно, вы увидите картинку с пейзажем. Но если это получилось с вашей картой, совсем не обязательно, что это произойдет и с другими. На иных компьютерах пользователи в такой ситуации могут получить бессмысленный узор. Согласно рекомендациям разработчиков, поверхности, содержащие растр, при восстановлении должны заново заполняться.

Если это окно из рассматриваемого примера у вас восстанавливается без потерь, можете двигаться дальше. Если же у вас картинка при восстановлении портится, функцию восстановления исправьте следующим образом:

function TfrmDD.RestoreAll : HRESULT; var

hRet : HRESULT; begin

hRet := FDDSPrimary._Restore;

if Succeeded (hRet) then begin hRet := FDDSImage._Restore;

if Failed (hRet} then begin Result := hRet;

Exit;

end;

// Перезагружаем на поверхность содержимое растра Result := DDReLoadBitmap(FDDSImage, imageBMP);

  • Читать дальше
  • 1
  • ...
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: