Графика DirectX в Delphi - [17]
Поверхностей вы можете создавать сколько угодно, но чем их меньше, тем быстрее будет осуществляться блиттинг. Поэтому лучше не плодить множество поверхностей, а, в идеальном случае, располагать все образы на одной большой поверхности.
В общем случае операция копирования блоков из системной памяти в видеопамять осуществляется медленнее, чем из видеопамяти в видеопамять. Поэтому образы, выводимые наиболее часто, старайтесь размешать в видеопамяти, а при ее нехватке те из образов, которые редко будут появляться, например заставки или меню, следует размещать в системной памяти.
Поддержка AGP если и стирает разницу в скоростях обмена, то незначительно. Если бы скорости работы с видеопамятью и системной памятью сосовпадали или были близки друг к другу, не было бы нужды производителям карт выпускать модели, различающиеся размером видеопамяти, а пользователям оставалось лишь наращивать размер системной памяти.
Для поверхности, создаваемой в видеопамяти, надо использовать комбинацию флагов DDSCAPS_OFFSCREENPLAIN or DDSCAPSJ/IDEOMEMORY. и наоборот, флаг DDSCAPS_SYSTEMMEMORY указывает, что поверхность должна располагаться в системной памяти.
Метод GetAvailablevidMem главного объекта DirectDraw позволяет выяснить, сколько видеопамяти осталось в распоряжении приложения.
При нехватке видеопамяти операция создания поверхности завершится провалом, код соответствующей ошибки - DDERR_OUTOFVIDEOMEMORY. В этом случае необходимо поменять флаг и заново попытаться создать поверхность.
Теперь обсудим вопросы масштабирования растров. Вспомогательная функция копирования растра поддерживает масштабирование. Задайте размер вторичной поверхности больше, чем размер используемого растра, например, так:
ddsd.dwWidth := wrkBitmap.Width * 2;
Теперь при воспроизведении мы увидим картинку, растянутую вдоль экрана, но не всю, а только ее половину. Для того чтобы вывести ее целиком, надо изменить значение поля Right структуры dstRect:
SetRect (dstRect, 100, 100, 100 + 256 * 2, 356);
Попробуем перемещать картинку по экрану (проект каталога Ех08). Переменная ift хранит текущее значение смещения картинки, на это значение опираемся при заполнении полей структуры dstRect:
SetRect (dstRect, 1ft, 100, 1ft + 256, 356);
Форма дополнилась обработчиком нажатия клавиши: демонстрационные программы, использующие DirectDraw, традиционно должны завершать работу при нажатии клавиши
case Key of
VK_ESCAPE, VK_F12 : begin // Традиция для DirectDraw
Close; Exit;
end;
VK_LEFT : begin // Клавиша "стрелка влево"
Dec (1ft, 1); // Уменьшаем 1ft
FormPaint (nil); // Перерисовываем экран end;
VK_RIGHT : begin // Клавиша "стрелка вправо"
Inc (1ft, 1); // Увеличиваем 1ft
FormPaint (nil); // Перерисовываем экран
end;
end;
Обратите внимание, что для перерисовки окна метод Refresh не годится, иначе сквозь экран будет проглядывать мелькнувшее окно приложения. Картинка движется с малым шагом с целю убедить вас, что если хоть один пиксел растра не помещается на первичную поверхность, не воспроизводится ничего.
Также наверняка вам бросится в глаза то, что картинка появляется медленно на экране, при ее воспроизведении вы можете увидеть мельтешение черных полос. Пока старайтесь не обращать на это внимания. В будущем мы устраним это - такого не должно быть в наших серьезных проектах.
Сейчас сделайте следующее. Запишите строку, задающую параметры области вывода так:
SetRect (dstRect, 1ft, 100, 1ft + 512, 356);
Картинка выводится растянутой, из чего делаем важный вывод: метод Bit поверхности поддерживает операцию масштабирования. Удобное для нас свойство, им можно пользоваться, чтобы задавать в качестве фона растровое изображение любого размера. Для этого измените ту же строку вот так:
SetRect (dstRect, 0, 0, ClientWidth, ClientHeight);
Теперь код, заполняющий первичную поверхность черным цветом, можно просто удалить. Он не нужен, его выполнение только отнимает драгоценное время.
Плохо в получающемся примере то, что размер растра используется в нем дважды: при задании размеров первичной поверхности и при задании области вывода. Здесь нас ждет хорошая новость: во втором случае можно ничего не указывать, по умолчанию будет использоваться вся поверхность, и строку блиттинга можно записать так:
hRet := FDDSPrimary.Blt (SdstRect, FDDSImage, nil, DDBLT_WAIT, nil);
To есть третий параметр равен nil. Обязательно проверьте это, все должно работать как следует.
С точки зрения оптимизации лучше явно задавать размер копируемой поверхности.
Протестируйте работу программы при переключении и восстановлении и, если картинка пейзажа теряется, скорректируйте код функции RestoreAli.
Я воспользуюсь случаем, чтобы посвятить вас в еще одну важную тему: в любой момент времени мы можем получить информацию обо всех свойствах поверхности, в том числе и о ее размерах. Для этого предназначен метод поверхности GetSurfaceDesc.
Иллюстрацией служит проект каталога Ех09. Код обработчика onPaint формы дополнился локальной переменной ddsd2 типа TDDSurfaceDesc2, перед блиттингом с ней производятся обычные действия (обнуление всех полей и задание размера), используется она с целью хранения информации о параметрах поверхности, для получения которых и вызывается изучаемый метод:
Разработчику часто требуется много сторонних инструментов, чтобы создавать и поддерживать проект. Система Git — один из таких инструментов и используется для контроля промежуточных версий вашего приложения, позволяя вам исправлять ошибки, откатывать к старой версии, разрабатывать проект в команде и сливать его потом. В книге вы узнаете об основах работы с Git: установка, ключевые команды, gitHub и многое другое.В книге рассматриваются следующие темы:основы Git;ветвление в Git;Git на сервере;распределённый Git;GitHub;инструменты Git;настройка Git;Git и другие системы контроля версий.
Рассмотрено все необходимое для разработки, компиляции, отладки и запуска приложений Java. Изложены практические приемы использования как традиционных, так и новейших конструкций объектно-ориентированного языка Java, графической библиотеки классов Swing, расширенной библиотеки Java 2D, работа со звуком, печать, способы русификации программ. Приведено полное описание нововведений Java SE 7: двоичная запись чисел, строковые варианты разветвлений, "ромбовидный оператор", NIO2, новые средства многопоточности и др.
В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.
В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.
В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.
Python - объектно-ориентированный язык сверхвысокого уровня. Python, в отличии от Java, не требует исключительно объектной ориентированности, но классы в Python так просто изучить и так удобно использовать, что даже новые и неискушенные пользователи быстро переходят на ОО-подход.