Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > разработка игр, графический дизайн и моделирование > Gamedev - cоздание игр: Unity, OpenGL, DirectX
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 14.01.2010, 21:47   #1
ZotaC
Форумчанин
 
Аватар для ZotaC
 
Регистрация: 25.06.2009
Сообщений: 163
По умолчанию BitBlt

Подскажите, пожалуйста, кто знает, как через функцию BitBlt рисовать прозрачность? У меня такой код:

BitBlt(BmpBuf.Canvas.Handle, X + j * 50 - 50, Y + i * 50 - 50, 50, 50, Textures[0].Canvas.Handle, 0, 0, SrcCopy);

И на той текстуре есть пиксели, закрашенные белым цветом, при выводе которые должны быть прозрачными. Рисовал через Canvas.Draw, и все было нормально, но через BitBlt пиксели рисуются белыми.
ZotaC вне форума Ответить с цитированием
Старый 15.01.2010, 14:37   #2
Вадим Буренков
Участник клуба
 
Аватар для Вадим Буренков
 
Регистрация: 06.03.2009
Сообщений: 1,346
По умолчанию

А зачем рисовать через bitbit если можно через canvas.draw, ведь сами говорите с ним нет проблем. BitBit полезно использовать с различными флагами а SrcCopy - простое копирование без учета цвета прозрачности. Вот остальные флаги:
Цитата:
• BLACKNESS заполняет прямоугольник адресата, используя цвет, связанный с индексом 0 в физической палитре (это черный цвет для заданной по умолчанию физической палитры );

• CAPTUREBLT включает в изображение также и окна, расположенные поверх указанного. По умолчанию изображение содержит только ваше окно ;

• DSTINVERT инвертирует цвета прямоугольника адресата ;

• MERGECOPY смешивает цвета исходного прямоугольника с указанным образцом , используя операцию AND;

• MERGEPAINT инвертирует цвета исходного прямоугольника, затем выполняет операцию OR с цветом адресата ;

• NOMIRRORBITMAP предотвращает зеркальное отражение изображения ;

• NOTSRCCOPY передает инвертированные цвета исходного прямоугольника адресату ;

• NOTSRCERASE - результирующий цвет образуется смешением цвета источника и адресата операцией OR с последующим инвертированием ;

• SRCAND смешивает цвета источника и адресата операцией AND;

• SRCCOPY непосредственно копирует цветовые данные источника в прямоугольник адресата ;

• SRCERASE смешивает инвертированные цвета прямоугольника адресата с цветами исходного прямоугольника операцией AND;

• SRCINVERT смешивает цвета источника и адресата операцией XOR;

• SRCPAINT смешивает цвета источника и адресата операцией OR;

• WHITENESS заполняет прямоугольник адресата , используя цвет , связанный с индексом 1 в физической палитре ( это бе* лый цвет для заданной по умолчанию физической палитры).
Вадим Буренков вне форума Ответить с цитированием
Старый 15.01.2010, 15:04   #3
Beermonza
Инженер ИС
Старожил
 
Аватар для Beermonza
 
Регистрация: 13.12.2006
Сообщений: 2,671
По умолчанию

ZotaC, для чего конкретно применяется BitBlt? ...судя по параметрам, в цикле выстраивается картинка из кусочков 50х50. Уточните.
Руководитель проекта MMO 2D RPG: Настоящее имя Денис Стрижак (10.05.1981-6.02.2019) Мир духу его
Beermonza вне форума Ответить с цитированием
Старый 15.01.2010, 21:17   #4
ZotaC
Форумчанин
 
Аватар для ZotaC
 
Регистрация: 25.06.2009
Сообщений: 163
По умолчанию

Когда я рисовал через Canvas.Draw, то игра занимала у меня 20-25% ЦП, а когда стал рисовать через BitBlt, она занимает 0-2%.
ZotaC вне форума Ответить с цитированием
Старый 15.01.2010, 21:33   #5
Beermonza
Инженер ИС
Старожил
 
Аватар для Beermonza
 
Регистрация: 13.12.2006
Сообщений: 2,671
По умолчанию

Естественно, флаг SrcCopy работает очень быстро, это банальный переброс без манипуляций. В Canvas.Draw с прозрачностью Transparent есть условия, это тормозит процесс.

BitBlt эффективен при выводе готового кадра на форму, или куда вам нужно. Саму подложку лучше "собрать" один раз, и хранить как большой кусок экрана, ...загоняя его сначала в буфер, потом поверх динамические объекты. Как только обстановка в кадре меняется, снова выполняется сбор подложки, и она используется как задний фон.

Опишите вашу игру, как вы выполняете цикл отрисовки.
Руководитель проекта MMO 2D RPG: Настоящее имя Денис Стрижак (10.05.1981-6.02.2019) Мир духу его
Beermonza вне форума Ответить с цитированием
Старый 15.01.2010, 21:53   #6
ZotaC
Форумчанин
 
Аватар для ZotaC
 
Регистрация: 25.06.2009
Сообщений: 163
По умолчанию

Ну, во-первых, все рисуется в таймере (25 мс, так как если поставить 10, то загрузка будет еще больше). Первым идет цикл, который рисует текстуры (через case, проверяя по номерам текстур те, которые должны рисоваться в данных ячейках). Естесственно, рисуется только та часть, которая в данный момент находится на экране.

Далее рисуется игрок, потом идет цикл, который рисует врагов, потом определенные спецэффекты на карте (у меня массив карты типа TMap - запись, поэтому некоторые спецэффекты присваиваются определенным ячейкам массива, на что пришлось завести еще одно поле). Ну, далее - надписи (вывод статистики вверху экрана - сколько у игрока жизней, сколько врагов на карте и т.д.).

Сама игра разворачивается на весь экран, меняя разрешение на 800х600.
ZotaC вне форума Ответить с цитированием
Старый 15.01.2010, 22:10   #7
Вадим Буренков
Участник клуба
 
Аватар для Вадим Буренков
 
Регистрация: 06.03.2009
Сообщений: 1,346
По умолчанию

Это не первая и не последняя тема про скорость работы Canvas. Идеального результата не объешься, но можешь выводить сначала фон на буффер а потом фон+динамические объекты на другой буффер, а потом SRCCopy на форму как тебе Beermonza говорит. Он в своей игре добился нормальной скорости, но там оптимизизация . Если хочется без глюков учи DX/GL или бери двиг на них.
Вадим Буренков вне форума Ответить с цитированием
Старый 15.01.2010, 22:27   #8
ZotaC
Форумчанин
 
Аватар для ZotaC
 
Регистрация: 25.06.2009
Сообщений: 163
По умолчанию

Цитата:
Сообщение от Вадим Буренков Посмотреть сообщение
Это не первая и не последняя тема про скорость работы Canvas. Идеального результата не объешься, но можешь выводить сначала фон на буффер а потом фон+динамические объекты на другой буффер, а потом SRCCopy на форму как тебе Beermonza говорит. Он в своей игре добился нормальной скорости, но там оптимизизация . Если хочется без глюков учи DX/GL или бери двиг на них.
Beermonza дает хорошие советы, но его игр я не видел. Beermonza, можно попросить у вас ссылку на какой-нибудь ваш крупный проект (если такой есть)? Естесственно, не на исходники, а на сам проект. Это просто интерес, а, никоим образом, не подколка в вашу сторону.

А на DX/GL я еще перейду, всему ведь свое время, да? Вы только скажите мне, какая примерно загрузка ЦП считается нормальной для игр на canvas? Тут, конечно же, зависит от характеристик компьютера, но хоть примерно.
ZotaC вне форума Ответить с цитированием
Старый 16.01.2010, 00:50   #9
Beermonza
Инженер ИС
Старожил
 
Аватар для Beermonza
 
Регистрация: 13.12.2006
Сообщений: 2,671
По умолчанию Ускорение отрисовки графики

"Как вы относитесь к созданию игр на Delphi?" - тема в которой история "крупного проекта" с примерами и фишками оптимизации, с дельными советами, скринами и многим другим.

"Уроки по созданию игр для новичков" - там масса примеров игр на канве, аркадные тоже есть, разборка кодов, пояснения, ...почитайте, поможет.

Цитата:
Сообщение от ZotaC
Ну, во-первых, все рисуется в таймере (25 мс, так как если поставить 10, то загрузка будет еще больше).
Смело ставьте 31 мс - это самый предельный интервал при котором GDI работает на 25 кадров в секунду, не загружая особо CPU.

Цитата:
Сообщение от ZotaC
Первым идет цикл, который рисует текстуры (через case, проверяя по номерам текстур те, которые должны рисоваться в данных ячейках). Естесственно, рисуется только та часть, которая в данный момент находится на экране.
Если действие происходит на экране, на котором фон в некоторый момент статичен, например, как в аркадах, ...то нет смысла каждый раз по кусочкам собирать задний фон. Нужно создать процедуру, которая выполняется при условии, что флаг update = True, ...т.е. "требуется обновление", ...процедура берет буфер подложки, кладет на него в цикле текстуры через Canvas.Draw с прозрачностью или как-угодно, в общем - собирает уровень, или поверхность карты, может даже в несколько слоев, ...и переводит флаг update в False. В следующем цикле условие уже обнаружит флаг update = False, и пропустит сборку заднего фона, а просто следующая строка кода перебросит готовую подложку в буфер кадра через BitBlt.

Как только персонаж или что там у вас, шагнет за пределы экрана, флаг update станет True, кроме того изменится и диапазон сканирования массива карты, а процедура сбора подложки соберет новый задник и снова отправит его в кадр.

Таким образом один полный экран подложки выводится через BitBlt просто копированием, и в 100 раз быстрее чем аналогично, но каждый такт собирая задник по кускам.

Цитата:
Сообщение от ZotaC
Далее рисуется игрок, потом идет цикл, который рисует врагов, потом определенные спецэффекты на карте (у меня массив карты типа TMap - запись, поэтому некоторые спецэффекты присваиваются определенным ячейкам массива, на что пришлось завести еще одно поле). Ну, далее - надписи (вывод статистики вверху экрана - сколько у игрока жизней, сколько врагов на карте и т.д.).
Т.к. подложка уже будет собираться когда надо и перебрасываться в буфер кадра, то следующие цикли простой канвой с прозрачностью уже в буфер кадра рисуют все объекты и пр. слои. Тормозов не будет, т.к. объектов не много, по сравнению с тайлами заднего фона. Ориентир идет на 0% загрузки CPU.

Цитата:
Сообщение от ZotaC
Сама игра разворачивается на весь экран, меняя разрешение на 800х600.
У меня 1024х768 полный 24-битный альфа-канал на все текстуры, анимация объектов 24 кадра в секунду, 4 слоя, ...это РПГ, персонаж в центре экрана, карта уровней в изометрии ползет под ногами, ...внимание! загрузка CPU максимум 37%, проц - Core 2 Duo 1,8GHz. Добился только вставками на ассемблере, не без помощи форумчан, в теме "Как вы относитесь к созданию игр на Delphi?" эти вставки есть, их код. У меня операция BitBlt выполняется только один раз, при выводе готового кадра на форму (можно прям на рабочий стол).
Руководитель проекта MMO 2D RPG: Настоящее имя Денис Стрижак (10.05.1981-6.02.2019) Мир духу его
Beermonza вне форума Ответить с цитированием
Старый 16.01.2010, 01:32   #10
DomiNick
Студент, не
Старожил
 
Аватар для DomiNick
 
Регистрация: 29.01.2009
Сообщений: 2,067
По умолчанию

Цитата:
Подскажите, пожалуйста, кто знает, как через функцию BitBlt рисовать прозрачность?
Никак...

Вот основные WinAPI функции:

BitBlt - вывод изображения;
StretchBlt - вывод изображения с растягиванием;
PlgBlt - вывод изображения с параллельной проекцией (поворот);
TransparentBlt - вывод изображения с прозрачным фоном;
MaskBlt - вывод изображения по маске;
AlphaBlend - вывод изображения с полупрозрачностью;

Цитата:
Смело ставьте 31 мс - это самый предельный интервал при котором GDI работает на 25 кадров в секунду, не загружая особо CPU.
По моим тестам VCL'овский таймер бесполезно ставить меньше чем на 45-50...
I am the First of Cyber Evolution...
I am the First to Program your Future...
DomiNick вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
BitBlt на контекст DC и его альтернатива notHaker Мультимедиа в Delphi 7 03.12.2009 01:04