-
Уважаемые участники форума! Просьба знающих 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
|