我正在制作一个动态壁纸,在触摸屏幕时会融入一些水波纹效果,但我有点卡住了。
创建多个图像并循环创建一个波纹动画会不会更好?或者在将它放在画布上之前将位图扭曲一点会更好吗?
This是一个通过OpenGL完成的非常好的连锁效果的视频。
我对OpenGL没有任何经验,并想知道是否仍然可以在动态壁纸上创建2D水效果?
答案 0 :(得分:17)
我也希望在Android中实现逼真的连锁效果,所以我将分享我的经验:
作为参考实现,我使用了谢尔盖的Chiluyonok JavaScript端口Neil Wallis Java算法。这是一个可以试验原始JS代码的游乐场:http://jsfiddle.net/esteewhy/5Ht3b/6/
首先,我将JS代码移植到Java只是为了意识到我的华为U8100硬件无法超过1 fps。 (在网上有几个类似的尝试,唯一的结论是:它们的速度非常慢)。
顺便说一下,这个SO答案非常有用,可以基本了解如何在Android中编写交互式图形代码:https://stackoverflow.com/a/4946893/35438。我从那里借了fps counter。然后我决定尝试Android NDK重新实现纯C中的原始算法(我10年来第一次遇到它!)。尽管NDK的文档有些令人困惑(特别是在需求和先决条件方面),但这一切都像魅力一样,所以我能够达到高达30 fps - 它可能不会太令人印象深刻,但仍然是对Java代码的彻底改进
最后,我把我的所有工作都放到了网上:https://github.com/esteewhy/whater,所以请随意玩。它包含:
(项目不是“干净”,即:所有二进制文件都在那里,因此即使没有NDK也可以“按原样”运行它。)
答案 1 :(得分:6)
您可以在此处找到触控效果效果的示例:
https://github.com/MasDennis/RajawaliExamples
它利用了rajawali OpenGL ES框架/库。您可以从市场下载rajawali示例应用程序,看看它的外观。浏览“src”文件夹,您将看到TouchRippleEffect活动和渲染器。希望有所帮助。
答案 2 :(得分:4)
我不是这方面的专家,但我相信在OpenGL中进行水效果的典型方法是使用片段着色器。使用静态图像作为纹理,着色器可以改变用于对图像进行采样的纹理坐标,从而以任意方式扭曲它。
计算像素的方向和距圆心的距离,并根据距离的正弦函数调整纹理坐标朝向或远离圆的中心,你应该得到一个很好的连锁效果。
根据您关联的YouTube视频的描述来判断,通过使用三角形网格并仅在顶点处调整纹理坐标来完成此操作。这应该也可以,但除非你使用相当精细的网格,否则看起来不会那么好。使用片段着色器按像素执行此操作是理想的,但我不知道这是否会导致手机GPU出现性能问题。