Android(安卓)上实现水波特效二--优化
Android上实现水波特效二--优化
罗朝辉(http://blog.csdn.com/kesalin)
转载请注明出处
在上一篇文章《Android 上实现水波特效》中对水波波幅的计算是针对每一个像素的,效率比较低,尤其是在手机上运行,相当缓慢。我们可以利用线性插值进行优化,这样可以将计算减少一半(MeshSize为2)或减少四分之三(MeshSize为4),效率得以大大提升,即使是在水机上也能较为流畅地运行。
在下面的代码中,为了充分使用移位运算替代乘除法,MeshSize必须为2的整次幂,MeshShift就是其幂数,表示计算时的移位位数。代码下载链接:http://www.cppblog.com/Files/kesalin/RippleDemo_opt.zip
线性插值优化之后的水波扩散代码如下:
staticfinalintMeshSize= 2; staticfinalintMeshShift= 1; intm_meshWidth; intm_meshHeight; m_meshWidth=m_width/MeshSize+ 1; m_meshHeight=m_height/MeshSize+ 1;;
voidrippleSpread() { m_waveFlag=false;
inti = 0, offset = 0; for(inty = 1; y <m_meshHeight- 1; ++y) { offset = y *m_meshWidth; for(intx = 1; x <m_meshWidth- 1; ++x) { i = offset + x; m_buf2[i] = (short)(((m_buf1[i - 1] +m_buf1[i + 1] +m_buf1[i -m_meshWidth] +m_buf1[i +m_meshWidth]) >> 1)-m_buf2[i]);
m_buf2[i] -= (m_buf2[i] >> 5); m_waveFlag|= (m_buf2[i] != 0); } }
if(m_waveFlag){ m_waveFlag=false;
for(inty = 1; y <m_meshHeight- 1; ++y) { offset = y *m_meshWidth; for(intx = 1; x <m_meshWidth- 1; ++x) { i = offset + x; m_bufDiffX[i] = (short)((m_buf2[i + 1] -m_buf2[i - 1]) >> 3); m_bufDiffY[i] = (short)((m_buf2[i +m_meshWidth] -m_buf2[i -m_meshWidth]) >> 3);
m_waveFlag|= (m_bufDiffX[i] != 0 ||m_bufDiffY[i] != 0); } } }
//交换波能数据缓冲区 short[] temp =m_buf1; m_buf1=m_buf2; m_buf2= temp; } |
既然波幅计算使用了线性插值,描绘时的代码也许相应进行更改:
Pointp1,p2,p3,p4; PointpRowStart,pRowEnd,p,rowStartInc,rowEndInc,pInc;
voidrippleRender() { intpx = 0, py = 0, dx = 0, dy = 0; intindex = 0, offset = 0;
for(intj = 1; j <m_meshHeight; ++j) { offset = j *m_meshWidth; for(inti = 1; i <m_meshWidth; ++i) { index = offset + i; p1.x=m_bufDiffX[index -m_meshWidth- 1]; p1.y=m_bufDiffY[index -m_meshWidth- 1]; p2.x=m_bufDiffX[index -m_meshWidth]; p2.y=m_bufDiffY[index -m_meshWidth]; p3.x=m_bufDiffX[index - 1]; p3.y=m_bufDiffY[index - 1]; p4.x=m_bufDiffX[index]; p4.y=m_bufDiffY[index];
pRowStart.x=p1.x<<MeshShift; pRowStart.y=p1.y<<MeshShift; rowStartInc.x=p3.x-p1.x; rowStartInc.y=p3.y-p1.y;
pRowEnd.x=p2.x<<MeshShift; pRowEnd.y=p2.y<<MeshShift; rowEndInc.x=p4.x-p2.x; rowEndInc.y=p4.y-p2.y;
py = (j - 1) <<MeshShift; for(inty = 0; y <MeshSize; ++y) { p.x=pRowStart.x; p.y=pRowStart.y;
// scaled by MeshSize times pInc.x= (pRowEnd.x-pRowStart.x) >>MeshShift; pInc.y= (pRowEnd.y-pRowStart.y) >>MeshShift;
px = (i - 1) <<MeshShift; for(intx = 0; x <MeshSize; ++x) { dx = px +p.x>>MeshShift; dy = py +p.y>>MeshShift;
if((dx >= 0) && (dy >= 0) && (dx <m_width) && (dy <m_height) ) { m_bitmap2[py *m_width+ px] =m_bitmap1[dy *m_width+ dx]; } else{ m_bitmap2[py *m_width+ px] =m_bitmap1[py *m_width+ px]; }
p.x+=pInc.x; p.y+=pInc.y; ++px; }
pRowStart.x+=rowStartInc.x; pRowStart.y+=rowStartInc.y; pRowEnd.x+=rowEndInc.x; pRowEnd.y+=rowEndInc.y; ++py; } } } } |
更多相关文章
- 使用Kotlin:让Android与JS交互的详解
- 在Android中用纯Java代码布局
- 【Android(安卓)开发】: Android(安卓)消息处理机制之三: Handle
- Android(安卓)Studio中创建Kotlin For Android项目
- 编写高效的Android代码
- Androidの自定义进度条ProgressBar实现
- Antrus – 我搞的一个Android下的MVC开源框架
- 浅谈J2me游戏如何快速移植到Android
- Android(安卓)NDK开发(一)——ndk-build编译生成so库文件并使用