Blog. Just Blog

Эффект водной поверхности на Ассемблере

Версия для печати Добавить в Избранное Отправить на E-Mail | Категория: Образ мышления: Assembler | Автор: ManHunter
Эффект водной поверхности на Ассемблере
Эффект водной поверхности на Ассемблере

Бесконечно можно смотреть на три вещи: как горит огонь, как течет вода и как работают другие люди. К горящему огню мы вернемся как-нибудь в другой раз, а сегодня я предлагаю полюбоваться на эффект водной поверхности, реализованный на чистом Ассемблере. Я неоднократно встречал этот эффект в патчах и кейгенах разных крякерских команд и считаю его одним из лучших визуальных эффектов. Одно время даже была мысль рипнуть его из готовых exe-файлов, но потом мне попался оригинал исходника на MASM. Недолго думая, я портировал его на FASM и с огромным удовольствием буду использовать в своих релизах.

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

Подключается библиотека обычным include, структуры и константы описаны в комментариях к библиотеке и в прилагаемой тестовой программе. Запуск эффекта и его обработка выполняется по трем событиям родительского окна: WM_INITDIALOG, WM_PAINT и WM_CLOSE. Параметры вызова эффектов также смотрите в исходнике WaveObject.asm. По возможности я постарался прокомментировать основные моменты, но часть авторских комментариев так и осталась в оригинальном исходнике в виде непереводимых китайских иероглифов.
  1.         ...
  2.         cmp     [msg],WM_INITDIALOG
  3.         je      wminitdialog
  4.         cmp     [msg],WM_PAINT
  5.         je      wmpaint
  6.         cmp     [msg],WM_CLOSE
  7.         je      wmclose
  8.         ...
  9.  
  10. wminitdialog:
  11.         ; Загрузить битмап
  12.         invoke  LoadBitmap,[hInstance],1
  13.         mov     [hBitmap],eax
  14.         push    [hBitmap]
  15.         invoke  GetDlgItem,[hwnddlg],ID_IMG
  16.         ; Инициализация водной поверхности
  17.         stdcall _WaveInit,stWaveObj,eax,[hBitmap],30,0
  18.         pop     [hBitmap]
  19.         invoke  DeleteObject,[hBitmap]
  20.         ; Настроить эффекты
  21.         stdcall _WaveEffect,stWaveObj,1,5,4,250
  22.         ...
  23.  
  24. wmpaint:
  25.         ; В оригинальном исходнике в этом обработчике была допущена
  26.         ; серьезная ошибка, в моем варианте она исправлена
  27.         invoke  BeginPaint,[hwnddlg],stPs
  28.         invoke  GetDlgItem,[hwnddlg],ID_IMG
  29.         invoke  GetDC,eax
  30.         stdcall _WaveUpdateFrame,stWaveObj,eax,TRUE
  31.         invoke  EndPaint,[hwnddlg],stPs
  32.         ...
  33.  
  34. wmclose:
  35.         ; Освободить занятые ресурсы при закрытии диалогового окна
  36.         stdcall _WaveFree,stWaveObj
  37.         ...
А вот примеры обработчиков мышки, чтобы "водная поверхность" изображения реагировала на движение курсора и на клик левой кнопкой. В случае необходимости можно легко дописать по аналогии нужные обработчики.
  1.         ...
  2.         cmp     [msg],WM_LBUTTONDOWN
  3.         je      wmlbutton
  4.         cmp     [msg],WM_MOUSEMOVE
  5.         je      wmmouse
  6.         ...
  7.  
  8. wmlbutton:
  9.         ; Клик левой кнопкой мышки
  10.         mov     eax,[lparam]
  11.         movzx   ecx,ax          ; x
  12.         shr     eax,16          ; y
  13.         stdcall _WaveDropStone,stWaveObj,ecx,eax,2,256
  14.         ...
  15.  
  16. wmmouse:
  17.         ; Движение курсора мыши над изображением
  18.         mov     eax,[lparam]
  19.         movzx   ecx,ax          ; x
  20.         shr     eax,16          ; y
  21.         stdcall _WaveDropStone,stWaveObj,ecx,eax,2,256
  22.         ...
Не рекомендуется применять эффект водной поверхности на очень больших изображениях, будет заметно тормозить. Из-за особенностей внутреннего формата BMP-изображений, желательно, чтобы ширина картинки в пикселах была кратна 3. Больше явных ограничений нет, или я не смог их обнаружить.

В приложении пример программы с исходным текстом, демонстрирующей эффект дождя на водной поверхности и реагирующей на движение курсора мышки. Будьте осторожны, можно надолго залипнуть, наблюдая за кругами на воде :) Мои благодарности user за помощь в отладке.

Пример программы с исходным текстом (FASM)Пример программы с исходным текстом (FASM)

Water.Waves.Demo.zip (700,146 bytes)


Поделиться ссылкой ВКонтакте
Просмотров: 8814 | Комментариев: 19

Метки: Assembler, окна
Внимание! Статья опубликована больше года назад, информация могла устареть!

Комментарии

Отзывы посетителей сайта о статье
brute (09.03.2015 в 15:22):
переписал на PB.
https://yadi.sk/d/_WK4xdBMf8FfU
С самими эффектами не разобрался - работают только некоторые из них. Имхо, если делать такие вещи для людей, то надо заворачивать в dll с описанием. Скомпилить библиотеку из fasm'a не получилось - компиль ругался на RtlZeroMemory, а что конкретно он хотел - я не понял.. Кстати, нашёл интересные ссылки для сторонников masm'a:
https://github.com/Xyl2k/Xylit...M32-snippets
http://www.xylibox.com/2010/12...yeahnet.html
https://github.com/Xyl2k
ManHunter (20.10.2014 в 16:18):
Мсье знает толк в извращениях :)
user (13.10.2014 в 00:58):
)Хех.. Попытался я приторочить эту библиотеку к заставке-скринсейверу.
Как скринсейвер в WinXP б/м работает только в режиме одиночных капель.
Если запускать как обычный экзек - б/м работает и в режиме ливня.
В общем, притормаживает алгоритм на высоком разрешении экрана.
Вот что получилсь, Q&D: http://rghost.ru/58492638
Isaev (12.10.2014 в 05:01):
Круги почему-то квадратные немного)) А в общем красиво
Одно время тоже рипнуть хотел, потом находил тутор по воде и огню
У меня есть рип на асме где по поверхности сферы по спирале текст произвольный пишется... так я его под винду и не смог перевести, т.к. там особенность шрифтов другая. а так хотелось
user (11.10.2014 в 11:06):
Ok. Спасибо, полезная примочка.
ManHunter (11.10.2014 в 09:52):
user, спасибо! Архив обновил.
NastyHo (11.10.2014 в 06:07):
user, так не тормозит.
user (11.10.2014 в 01:28):
Вот вроде как работает без глюков при любом размере картинки.
Пароль на архиве - "ManHunter"
http://rghost.ru/58457532
Заглушил там процедурку, в которой ошибки с обращением к памяти..
ManHunter (10.10.2014 в 20:52):
Ценное замечание! Надо будет поковыряться в отладчике, чего ему не нравится.
user (10.10.2014 в 20:48):
Глючение начинает проявляться сразу, как только размер картинки Width*Length превышает ~94200 пикселов вне зависимости от цветности.
user (10.10.2014 в 19:20):
С уменьшенной витмапкой работает нормально.
Вот что я заметил, если поставить брейк на .402718 в WATER.EXE последней версии архива (это стр.667 в WaveObj.asm),
и нажать в отладчике непрерывно F9 (Run), то между срабатываниями этого брейка проходит туча исключений по обращению к неверному адресу памяти где-то в системной библиотеке. Это если использовать старую большую битмапку. С новой маленькой - всё работает как часы без исключений.

Добавлю, и дело тут не в дополнительном определении контекста этого битмапа..
ManHunter (10.10.2014 в 09:14):
Уполовинил картинку, архив перезалил.
ManHunter (10.10.2014 в 07:04):
Значит картинка должна быть поменьше. В камментах я давал ссылку.
drs (10.10.2014 в 01:56):
Тормозит адово. W7Ult x64 Q8300
NastyHo (09.10.2014 в 21:44):
В tortoiseSVN аналогичный эффект не тормозит, Water.Waves.Demo же спустя секунду - надолго задумывается.
ЖК (09.10.2014 в 15:41):
Не знаю, товарищи, на Win7 x64 и i7 4770k демка работает без заметных проблем и тормозов.

Эффект симпатичный, так что спасибо за FASMовский порт.
Rustamer (09.10.2014 в 11:55):
Демка и на Win7 x86 также себя ведет - тормозит, а вот с картинкой поменьше действительно нормально. Кстати в релизах(в т.ч. в патче, выложенном на ргхосте) часто вижу, что из-за нестандартного размера шрифта окно увеличивается, надписи съезжают, кнопки выезжают за границы и тп. Эффект, конечно, стандартный, но в некоторых релизах все нормально. Так что тоже возьми на заметку имхо.
ManHunter (09.10.2014 в 11:25):
Картинки все-таки поменьше надо, типа такого: http://rghost.ru/58425564
СпанчГоп (09.10.2014 в 10:13):
На WinXP x86 не работает, после запуска появляются первые круги на 1 сек. и сразу "зависают".

Добавить комментарий

Заполните форму для добавления комментария
Имя*:
Текст комментария (не более 2000 символов)*:

*Все поля обязательны для заполнения.
Комментарии, содержащие рекламу, ненормативную лексику, оскорбления и т.п., а также флуд и сообщения не по теме, будут удаляться. Нарушителям может быть заблокирован доступ к сайту.
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2024
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.07 сек. / MySQL: 2 (0.0054 сек.) / Память: 4.5 Mb
Наверх