Эффект водной поверхности на Ассемблере
Эффект водной поверхности на Ассемблере
Бесконечно можно смотреть на три вещи: как горит огонь, как течет вода и как работают другие люди. К горящему огню мы вернемся как-нибудь в другой раз, а сегодня я предлагаю полюбоваться на эффект водной поверхности, реализованный на чистом Ассемблере. Я неоднократно встречал этот эффект в патчах и кейгенах разных крякерских команд и считаю его одним из лучших визуальных эффектов. Одно время даже была мысль рипнуть его из готовых exe-файлов, но потом мне попался оригинал исходника на MASM. Недолго думая, я портировал его на FASM и с огромным удовольствием буду использовать в своих релизах.
Эффект заключается в том, что изображение на форме как бы помещается на дно водоема с прозрачной водой, а по поверхности воды расходятся круги от падающих капель (в оригинальном исходнике - от брошенных камней). Комбинируя координаты и силу падения капель, можно добиться таких эффектов, как имитация дождя или скольжение по воде невидимого глайдера. Если сюда добавить обработчик движения мыши, то будет еще красивее, например, курсор будет оставлять след на поверхности воды, а клик кнопкой мышки будет как бросок булыжника в водоем. Конечно, до абсолютно точной физической модели тут далеко, не учитывается интерференция, отражение волн и другие волновые процессы, но выглядит все равно очень классно.
Подключается библиотека обычным include, структуры и константы описаны в комментариях к библиотеке и в прилагаемой тестовой программе. Запуск эффекта и его обработка выполняется по трем событиям родительского окна: WM_INITDIALOG, WM_PAINT и WM_CLOSE. Параметры вызова эффектов также смотрите в исходнике WaveObject.asm. По возможности я постарался прокомментировать основные моменты, но часть авторских комментариев так и осталась в оригинальном исходнике в виде непереводимых китайских иероглифов.
Code (Assembler) : Убрать нумерацию
- ...
- cmp [msg],WM_INITDIALOG
- je wminitdialog
- cmp [msg],WM_PAINT
- je wmpaint
- cmp [msg],WM_CLOSE
- je wmclose
- ...
- wminitdialog:
- ; Загрузить битмап
- invoke LoadBitmap,[hInstance],1
- mov [hBitmap],eax
- push [hBitmap]
- invoke GetDlgItem,[hwnddlg],ID_IMG
- ; Инициализация водной поверхности
- stdcall _WaveInit,stWaveObj,eax,[hBitmap],30,0
- pop [hBitmap]
- invoke DeleteObject,[hBitmap]
- ; Настроить эффекты
- stdcall _WaveEffect,stWaveObj,1,5,4,250
- ...
- wmpaint:
- ; В оригинальном исходнике в этом обработчике была допущена
- ; серьезная ошибка, в моем варианте она исправлена
- invoke BeginPaint,[hwnddlg],stPs
- invoke GetDlgItem,[hwnddlg],ID_IMG
- invoke GetDC,eax
- stdcall _WaveUpdateFrame,stWaveObj,eax,TRUE
- invoke EndPaint,[hwnddlg],stPs
- ...
- wmclose:
- ; Освободить занятые ресурсы при закрытии диалогового окна
- stdcall _WaveFree,stWaveObj
- ...
Code (Assembler) : Убрать нумерацию
- ...
- cmp [msg],WM_LBUTTONDOWN
- je wmlbutton
- cmp [msg],WM_MOUSEMOVE
- je wmmouse
- ...
- wmlbutton:
- ; Клик левой кнопкой мышки
- mov eax,[lparam]
- movzx ecx,ax ; x
- shr eax,16 ; y
- stdcall _WaveDropStone,stWaveObj,ecx,eax,2,256
- ...
- wmmouse:
- ; Движение курсора мыши над изображением
- mov eax,[lparam]
- movzx ecx,ax ; x
- shr eax,16 ; y
- stdcall _WaveDropStone,stWaveObj,ecx,eax,2,256
- ...
В приложении пример программы с исходным текстом, демонстрирующей эффект дождя на водной поверхности и реагирующей на движение курсора мышки. Будьте осторожны, можно надолго залипнуть, наблюдая за кругами на воде :) Мои благодарности user за помощь в отладке.
Просмотров: 8814 | Комментариев: 19
Внимание! Статья опубликована больше года назад, информация могла устареть!
Комментарии
Отзывы посетителей сайта о статье
ManHunter
(20.10.2014 в 16:18):
Мсье знает толк в извращениях :)
user
(13.10.2014 в 00:58):
)Хех.. Попытался я приторочить эту библиотеку к заставке-скринсейверу.
Как скринсейвер в WinXP б/м работает только в режиме одиночных капель.
Если запускать как обычный экзек - б/м работает и в режиме ливня.
В общем, притормаживает алгоритм на высоком разрешении экрана.
Вот что получилсь, Q&D: http://rghost.ru/58492638
Как скринсейвер в 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"
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), то между срабатываниями этого брейка проходит туча исключений по обращению к неверному адресу памяти где-то в системной библиотеке. Это если использовать старую большую битмапку. С новой маленькой - всё работает как часы без исключений.
Добавлю, и дело тут не в дополнительном определении контекста этого битмапа..
Вот что я заметил, если поставить брейк на .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овский порт.
Эффект симпатичный, так что спасибо за 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 сек. и сразу "зависают".
Добавить комментарий
Заполните форму для добавления комментария
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