AndroidAchieving special effects on water waves-Optimization
Luo chaohui (http://www.cnblogs.com/kesalin) This article follows the "signature-non-commercial use-consistency" creation public agreement
In the previous articleArticleWater Wave effects on Android"The amplitude of water waves is calculated for each pixel, with low efficiency, especially on mobile phones. We can use linear interpolation for optimization, so that we can reduce the calculation by half (MeshsizeIs2) Or decrease by 3/4 (MeshsizeIs4), The efficiency is greatly improved, even on the water machine can run more smoothly.
In the followingCodeIn order to fully use the shift operation to replace multiplication and division,MeshsizeMust be2Power,MeshshiftIs its power, indicating the number of shifted digits during calculation. Code download link:Http://www.cppblog.com/Files/kesalin/RippleDemo_opt.zip
The water wave diffusion code after linear interpolation optimization is as follows:
Static Final Int Meshsize = 2 ;
Static Final Int Meshshift = 1 ;
Int M_meshwidth;
Int M_meshheight;
M_meshwidth = m_width/meshsize + 1 ;
M_meshheight = m_height/meshsize + 1 ;;
Void Ripplespread ()
{
M_waveflag = False ;
Int I = 0 , Offset =0 ;
For ( Int Y = 1 ; Y <m_meshheight- 1 ; ++ Y ){
Offset = y * m_meshwidth;
For ( Int X = 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 ( Int Y = 1 ; Y <m_meshheight- 1 ; ++ Y ){
Offset = y * m_meshwidth;
For ( Int X = 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 );
}
}
}
//Exchange the wave energy data buffer
Short[] Temp = m_buf1;
M_buf1 = m_buf2;
M_buf2 = temp;
}
Since linear interpolation is used for amplitude calculation, the code for plotting may be changed accordingly:
Point P1, P2, P3, P4;
Point prowstart, prowend, P, rowstartinc, rowendinc, pinc;
Void Ripplerender ()
{
Int Px = 0 , Py = 0 , Dx =0 , Dy = 0 ;
Int Index = 0 , Offset = 0 ;
For ( Int J = 1 ; J <m_meshheight; ++ J ){
Offset = J * m_meshwidth;
For ( Int I = 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 ( Int Y = 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 ( Int X = 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;
}
}
}
}