-
Уважаемые участники форума! Просьба знающих OpenGL API помочь|подсказать как переделать найденный мной на форуме vingrad пример симуляции воды на битмапе, при движении курсора мыши в пределах его TRect-а. Сложность заключается в том, что алгоритм данного примера хоть и очень красиво и быстро благодаря OpenGL-у рисует воду, мне несовсем подходит ввиду реализации самого примера, а именно: 1. Картинка загружается процедурой procedure LoadBitmap(Filename: String; out Width, Height: Cardinal; out pData: Pointer); взятой из GlScene правильно (судя по выходящих ширине и высоте), но в итоге отображается только часть картинки, при этом сильно увеличенная 2. В пределах формы имеется чёрный фон Изображение: http://imageshack.us/photo/my-images/541/87793500.png/В общем хотелось бы что-то вроде http://imageshack.us/photo/my-images/32/17306035.png/Данный пример взят с http://www.delphisources.ru/pages/sources/graph/2006_year/water_effect.htmlОн не менее хорош, но очень сильно нагружает ЦПУ. Я убрал обаработку алгоритма воды в поток с низким приоритетом синхронизацией, чтоб не вешать приложение, но нагрузка на процессор никуда не делась и оставить её, я не могу тк считаю дурным тоном нагружать процессор будущего пользователя, зная что с использованием OpenGL можно возложить задачу на ГПУ. У меня к вам 2 просьбы. Либо помочь доработать пример с OpenGL (мне он больше нравится :) ) либо указать мне на возможности оптимизации второго примера, не в ущерб качеству симулируемой воды к сожалению чтение MSDN для понимания OpenGL процедур используемых в 1-м примере и изучение GlScene мне не помогло продвинуться дальше :( вот исходники 1-го и 2-го примера в одном архиве.7z: http://sendfile.su/793038Буду очень признателен за вашу помощь и наставления! :) Прошу прощения у администрации, если открыл данную тему не в том разделе.
-
Может это подойдет: http://rouse.drkb.ru/tmp/wave.zipЭто небольшая переделка одного из примеров небезызвестного Яна Хорна. Загрузка процессора в районе 2-3 процентов.
-
хм, пардон, судя по первой картинке это мой пример и есть :)
-
Rouse_ спасибо, у меня в архиве выше тот же самый который я взял из Вашего сообщения на форуме http://forum.vingrad.ru/forum/topic-95403.htmlКстати, там же я спрашивал о том же. Пример очень красивый, но мне не хватает знаний довести его до вида примера номер 2 :(
-
К сожалению доработать не смогу, уж очень давно не работал в данном направлении, но у нас на форуме есть несколько спецов, к примеру "antonn" которым это сделать, что раз плюнуть :) Так что кастуй его в ветку :)
-
Rouse_ Ок, спасибо :)
=========================================
Уважаемая Администрация. Просьба перенести данную тему в раздел пользователя "antonn", в раздел "Игры", если я не ошибаюсь!
-
Да-да, перенесите в мой раздел! =) Я только с GDI имел дело, и когда пытался сделать себе "эффект падающей капли" то мучал как раз пример water_effect.zip из ссылок выше. По части производительности ничего особо не изменилось, и не смог победить "отражение от стенок", из-за чего забросил свое желание. Съедает в примере он одно ядро из-за того что расчет и прорисовка находятся в TMainForm.idle(). Можно использовать таймер для ограничения fps (поставить ему интервал 33, например), загружать процессор будет меньше, но и плавность анимации может потеряться. Для пущей оптимизации можно останавливать перерисовку если все волны "улеглись", и запускать ее когда запускается новая волна.
-
> antonn © (11.04.13 21:47) [6]
Хм, я что думал что ты как раз с OpenGL работаешь, значит запамятовал. Eraser, что-ли? :) Короче не помню - кто-то точно был, кто хорошо в теме :)
-
-
Как раз в OGL я довольно плохо разбираюсь... но раз уж сказали "может": Приблизить - уменьшить первое число в gluPerspective (угол камеры) Масштаб текстуры (после LoadTexture): glMatrixMode(GL_TEXTURE); glScalef(4,4,1); // подобрать первые два числа glMatrixMode(GL_MODELVIEW);
Сотфвер можно ещё прилично разогнать, многопоточность хорошо помогает: https://docs.google.com/file/d/0B_vHqwd58bsUX1RJcUQ1ejRiNnc/edit?usp=sharing но всё равно, чтобы более-менее шевелилось в 1920*1080 - нужен наверное i5-i7 с полной загрузкой. (кстати, кто-нибудь знает, как в гугл-диске дать просто ссылку на скачивание файла, без просмотра содержимого архива?)
-
На fps WaterEffect наибольшее влияние оказывает процедура render - если ее содержимое закомментировать, у меня fps растёт от 35 до 113, однако процессор загружен полностью - для его разгрузки надо пересматривать организацию программы. Не исключено, что render можно оптимизировать, ускорив в 2-4 раза
-
тогда может кто подскажет как загасить "отражение от стенок" в софтварном варианте? :)
-
-
Sapersky с такой связкой удалось в какой-то мере избавиться от сильного увеличения, но изображений теперь 2 :) glEnable(GL_TEXTURE_2D); LoadTexture('picture.bmp', WaterTexture); glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); glMatrixMode(GL_TEXTURE); glScalef(10,5,1); // подобрать первые два числа glMatrixMode(GL_MODELVIEW); Viscosity := 0.96; и настроил немного gluPerspective(40.0, Width/Height, 1.0, 100.0); (с 45.0 на 40.0) в процедуре. В итоге получилось: http://imageshack.us/photo/my-images/213/29667086.png/но уже лучше, спасибо antonn, MBo похоже на скорость 2 примера, а точнее на ресурсоёмкость влияет метод image.Picture.Bitmap.ScanLine в строке 332 согласно второму ответу на http://stackoverflow.com/questions/13583451/how-to-use-scanline-property-for-24-bit-bitmaps
-
> похоже на скорость 2 примера, а точнее на ресурсоёмкость > влияет метод image.Picture.Bitmap.ScanLine в строке 332 > согласно второму ответу наhttp://stackoverflow.com/questions/13583451/how- > to-use-scanline-property-for-24-bit-bitmaps
Не надо гадать на кофейной гуще из соседнего отдела. Берём профаллер и смотрим что тормазит. Видим что тормозит render причем равномерно на строчках с 515 по 546. более всего тормозит 516 строчка 17% остальные примерно по ~6%.
-
но всё равно, чтобы более-менее шевелилось в 1920*1080 - нужен наверное i5-i7 с полной загрузкой. Указателе плюс убирание медленных операций даст выигрыш в 10 раз. И параллельность а именно: потоковая(ядра) и SIMD (SSE) даст прирост ещё 8 раз. У меня проц G620 выдаёт 150 fps на 323х323(по умолчанию) пикселей (500 fps без render).
-
в таких разрешениях софтварно и вывод битмапа на экран без тормозов уже не получится сделать
-
Небольшая модификация render (битмапы сделаны 32-битными!) у меня поднимает fps с 33 до 53
procedure AddLight(Src, Dst: Pointer; light: Integer);
asm
movd xmm0, [Src]
pxor xmm6, xmm6
movd xmm1, light
pshufd xmm1, xmm1, 0
punpcklbw xmm0, xmm6
punpcklwd xmm0, xmm6
paddd xmm0, xmm1
packssdw xmm0, xmm0
packuswb xmm0, xmm0
movd [Dst], xmm0
end;
begin
bgbw := backgroundBitmap.width;
bgbh := backgroundBitmap.Height;
for Y := 0 to bitmapHeight - 1 do begin
for X := 0 to bitmapWidth - 1 do begin
dx := waves[X + 1, Y].Height - waves[X, Y].Height;
dy := waves[X, Y + 1].Height - waves[X, Y].Height;
r := waves[X, Y].Height + depth;
xMap := X + round(dx * r);
yMap := Y + round(dy * r);
light := round((dx + dy) * lightIntensity);
if xMap < 0 then
xMap := - xMap;
if xMap >= bgbw then
xMap := xMap mod bgbw;
if yMap < 0 then
yMap := - yMap;
if yMap >= bgbh then
yMap := yMap mod bgbh;
AddLight(@backgroundLines[yMap][xMap * 4], @bitmapLines[Y][X * 4], light);
end;
-
Ну да, у меня тоже наложение освещения (только 8->32) сделано через MMX. Потом выложу исходники, когда более-менее причешу. Хотя это не самое узкое место, просто в оригинале сделано криво - 6 вызовов функции на пиксель.
Вообще сотверный пример вполне можно портировать на шейдеры... ранее мне попадался другой вариант алгоритма, с чтением из результирующего буфера, что в шейдерах делать нельзя.
тогда может кто подскажет как загасить "отражение от стенок" в софтварном варианте? :)
Может, после каждой итерации присваивать крайним пикселям значения [крайних-1]? Отражение, как я понимаю, получается из-за того, что с краю всегда 0.
-
с такой связкой удалось в какой-то мере избавиться от сильного увеличения, но изображений теперь 2 :)
glTranslatef(0.5,0.5,0) к текстурной трансформации, или 0.5,0,0
-
да, кстати...
> но нагрузка на процессор никуда не делась и оставить её, > я не могу тк считаю дурным тоном нагружать процессор будущего > пользователя, зная что с использованием OpenGL можно возложить > задачу на ГПУ.
имхо реализация на CPU и небольшая (ну или большая, как получится) загрузка его с лихвой перекроют собственные мучения с рендером и его вкрячиванием в программу, и возможными проблемами у пользователя потом (драйвера, другой мешающийся софт, железо (например на ноуте включение дискретной видеокарты может быть нежелательным для юзера))
-
Sapersky
> glTranslatef(0.5,0.5,0) к текстурной трансформации, или > 0.5,0,0
с (0.5,0.5,0) очень сильное увеличение, а с (0.5,0,0) картинка получается однотонно серой :)
antonn
> имхо реализация на CPU и небольшая (ну или большая, как > получится) загрузка его с лихвой перекроют собственные мучения > с рендером и его вкрячиванием в программу, и возможными > проблемами у пользователя потом (драйвера, другой мешающийся > софт, железо (например на ноуте включение дискретной видеокарты > может быть нежелательным для юзера))
исходил из того что OpenGL по умолчанию вместе с виндой идёт и процессор не грузит почти и видеокарту, ну или грузит последнюю, но несильно. Ну и он всё ж немного красивее Но в целом согласен и с радостью использую ЦПУ-шную реализацию! :) Надеюсь у Sapersky получится оптимизировать второй пример, а потом можно как Вы предложили фиксировать fps таймером скажем на 90, чтоб и загрузки процессора практически не было и анимация быстрая :
-
> Wladimir1987 © (11.04.13 16:19)
См. примеры шейдеров.
-
Может, после каждой итерации присваивать крайним пикселям значения [крайних-1]?
Хотя нет, в TMainForm.simulEdges() это и делается - но на отражения никак не влияет.
с (0.5,0.5,0) очень сильное увеличение, а с (0.5,0,0) картинка получается однотонно серой :)
Точно к текстурной трансформации добавляешь? Т.е. между glMatrixMode(GL_TEXTURE); и glMatrixMode(GL_MODELVIEW); если да - выложи свою текстуру.
Надеюсь у Sapersky получится оптимизировать второй пример, а потом можно как Вы предложили фиксировать fps таймером скажем на 90, чтоб и загрузки процессора практически не было и анимация быстрая
Совсем без нагрузки не получится, разве что в маленьком окне. Проверил ради интереса пример из [9] на 1920*1080 - как раз 90 FPS с полной загрузкой i5. Но не ко всякому 1920*1080 прилагается i5.
-
> Точно к текстурной трансформации добавляешь? Т.е. между
да, между, те код как и на пред. странице в сообщении нр. 13, только цифры менял. Текстура 256x256. Кстати, а можно сделать текстуру больше размером. Оригинальная картинка размером 337 на 590, но когда я загружаю её, то она тераяет цвета, а та что 256x256 растягивается и получается нечёткой вот текстура + оригинал http://sendfile.su/uploaded.php?ok=794400&err=0 > Совсем без нагрузки не получится, разве что в маленьком > окне. > Проверил ради интереса пример из [9] на 1920*1080 - как > раз 90 FPS с полной загрузкой i5. Но не ко всякому 1920*1080 > прилагается i5.
Ну нагрузка будет это ни страшно, но скорость в 90 FPS при разрешении (внимание!) 1920*1080 и думаю это очень быстро! :) У меня i7 в ноуте и скорость при картинке 337 на 590 максимум 120+-10 fps
-
"Выцветание" - это глюк загрузки картинки "некруглой" ширины. Если обрезать до 332, скажем - нормально загружается. Можно поправить функцию загрузки, но проще наверное найти нормальную загрузку OGL-текстуры в сети. За исключением этого размеры в принципе любые.
Как бороться с раздвоенностью картинки при выводе в пропорциональном масштабе я не знаю. Теоретически должно помогать такое: glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); // или GL_CLAMP_TO_EDGE glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP ); но не помогает.
-
Sapersky Ничего страшного, если пример с OGL трудно "оседлать" ;) то ну его! Можно узнать насчёт реализации на ЦПУ? На ЦПУ тоже очень классный пример! на прошлой странице Вы писали о
> Хотя это не самое узкое место, просто в оригинале сделано > криво - 6 вызовов функции на пиксель.
апдейт MBo пробовал, скорость обработки действительно возросла и хотел бы узнать насчет вашей оптимизации. Я был бы рад снижению нагрузки на цпу не в ущерб качеству, но в педелах разумного, те оптимизации алгоритма, настолько, насколько возможно!
-
|