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. 在Android中用纯Java代码布局
  2. 使用Android Studio调试Android Framework代码
  3. Linux手机打电话代码分析
  4. Android软件广告屏蔽方法及代码
  5. Android studio使用技巧(二:国际化以及代码重构)
  6. Android的反编译和代码混淆
  7. 在Android上实现HttpServer的示例代码

随机推荐

  1. 2010.12.29(2)——— android GridView
  2. windowSoftInputMode属性设置值
  3. EditText阻止自动弹出虚拟键盘
  4. windowSoftInputMode属性设置值
  5. android布局属性详解
  6. Android(安卓)平铺背景图片
  7. Android(安卓)进程和线程
  8. Android(安卓)SDCard操作(文件读写,容量
  9. android 摄像头图像数据YUV转Bitmap, 再转
  10. 初次在Android上使用OpenCV