Android上实现水波特效二--优化

罗朝辉(http://blog.csdn.com/kesalin

转载请注明出处


在上一篇文章《Android 上实现水波特效中对水波波幅的计算是针对每一个像素的,效率比较低,尤其是在手机上运行,相当缓慢。我们可以利用线性插值进行优化,这样可以将计算减少一半(MeshSize2)或减少四分之三(MeshSize4),效率得以大大提升,即使是在水机上也能较为流畅地运行。

在下面的代码中,为了充分使用移位运算替代乘除法,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;

}

}

}

}

更多相关文章

  1. 使用Kotlin:让Android与JS交互的详解
  2. 在Android中用纯Java代码布局
  3. 【Android(安卓)开发】: Android(安卓)消息处理机制之三: Handle
  4. Android(安卓)Studio中创建Kotlin For Android项目
  5. 编写高效的Android代码
  6. Androidの自定义进度条ProgressBar实现
  7. Antrus – 我搞的一个Android下的MVC开源框架
  8. 浅谈J2me游戏如何快速移植到Android
  9. Android(安卓)NDK开发(一)——ndk-build编译生成so库文件并使用

随机推荐

  1. android in linux 笔记
  2. Android(安卓)MVC模式
  3. Android禁止横屏和竖屏切换
  4. Android短视频开发
  5. Android(安卓)RadioButton背景图片和文字
  6. 头条Android(安卓)屏幕适配
  7. Android获取keystore文件的信息
  8. Android(安卓)AsyncTask
  9. Android中RelativeLayout各个属性的含义
  10. 【Android】联通性 -- USB从属模式