CWaterRoutine.cpp
上传用户:sycq158
上传日期:2008-10-22
资源大小:15361k
文件大小:6k
源码类别:

游戏

开发平台:

Visual C++

  1. // WaterRoutine.cpp: implementation of the CWaterRoutine class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "stdafx.h"
  5. #include "CWaterRoutine.h"
  6. #include <math.h>
  7. #include "fstream.h"
  8. //////////////////////////////////////////////////////////////////////
  9. // Construction/Destruction
  10. //////////////////////////////////////////////////////////////////////
  11. #define random( min, max ) (( rand() % (int)((( max ) + 1 ) - ( min ))) + ( min ))
  12. #ifdef _DEBUG
  13. #define new DEBUG_NEW
  14. #undef THIS_FILE
  15. static char THIS_FILE[] = __FILE__;
  16. #endif
  17. CWaterRoutine::CWaterRoutine()
  18. {
  19. m_iHeightField1 = NULL;
  20. m_iHeightField2 = NULL;
  21. m_iWidth = 0;
  22. m_iHeight = 0;
  23. m_iHpage = 0;
  24. m_density = 5;
  25. //水波长短轴之比
  26. m_ABProportion=1;
  27. for(int i=0;i<1024;i++)
  28. for(int j=0;j<768;j++)
  29. {
  30. m_bBarArray[i][j]=FALSE;
  31. }
  32. }
  33. CWaterRoutine::~CWaterRoutine()
  34. {
  35. // Cleanup
  36. if(m_iHeightField1 != NULL)
  37. delete [] m_iHeightField1;
  38. if(m_iHeightField2 != NULL)
  39. delete [] m_iHeightField2;
  40. m_iHeightField1 = NULL;
  41. m_iHeightField2 = NULL;
  42. }
  43. void CWaterRoutine::Create(int iWidth,int iHeight)
  44. {
  45. if(m_iHeightField1 != NULL)
  46. delete [] m_iHeightField1;
  47. if(m_iHeightField2 != NULL)
  48. delete [] m_iHeightField2;
  49. // Create our height fields
  50. m_iHeightField1 = new int[(iWidth*iHeight)];
  51. m_iHeightField2 = new int[(iWidth*iHeight)];
  52. // Clear our height fields
  53. memset(m_iHeightField1,0,(iWidth*iHeight)*sizeof(int));
  54. memset(m_iHeightField2,0,(iWidth*iHeight)*sizeof(int));
  55. m_iWidth = iWidth;
  56. m_iHeight = iHeight;
  57. // Set our page to 0
  58. m_iHpage = 0;
  59. }
  60. void CWaterRoutine::FlattenWater()
  61. {
  62. // Clear our height fields
  63. memset(m_iHeightField1,0,(m_iWidth*m_iHeight)*sizeof(int));
  64. memset(m_iHeightField2,0,(m_iWidth*m_iHeight)*sizeof(int));
  65. }
  66. void CWaterRoutine::Render(DWORD* pSrcImage,DWORD* pTargetImage)
  67. {
  68. DrawWaterWithLight(m_iHpage,pSrcImage,pTargetImage);
  69. CalcWater(m_iHpage,m_density);
  70. m_iHpage ^= 1;
  71. }
  72. //这个density是一个阻尼系数
  73. void CWaterRoutine::CalcWater(int npage, int density)
  74. {
  75. int newh;
  76. int count = m_iWidth + 1;
  77. int *newptr;
  78. int *oldptr;
  79. if(npage == 0)
  80. {
  81. newptr = &m_iHeightField1[0];
  82. oldptr = &m_iHeightField2[0];
  83. }
  84. else
  85. {
  86. newptr = &m_iHeightField2[0];
  87. oldptr = &m_iHeightField1[0];
  88. }
  89. int x, y;
  90. for (y = (m_iHeight-1)*m_iWidth; count < y; count += 2)
  91. {
  92. for (x = count+m_iWidth-2; count < x; count++)
  93. {
  94. newh   = ((oldptr[count + m_iWidth]
  95.                       + oldptr[count - m_iWidth]
  96.                       + oldptr[count + 1]
  97.                       + oldptr[count - 1]
  98.                       + oldptr[count - m_iWidth - 1]
  99.                       + oldptr[count - m_iWidth + 1]
  100.                       + oldptr[count + m_iWidth - 1]
  101.                       + oldptr[count + m_iWidth + 1]
  102.                        ) >> 2 )
  103.                       - newptr[count];
  104. newptr[count] =  newh - (newh >> density);//衰减32
  105. }
  106. }
  107. }
  108. void CWaterRoutine::HeightBlob(int x, int y, int radius, int height, int page)
  109. {
  110. int rquad;
  111. int cx, cy, cyq;
  112. int left, top, right, bottom;
  113. int *newptr;
  114. int *oldptr;
  115. // Set up the pointers
  116. if(page == 0)
  117. {
  118. newptr = &m_iHeightField1[0];
  119. oldptr = &m_iHeightField2[0];
  120. }
  121. else
  122. {
  123. newptr = &m_iHeightField2[0];
  124. oldptr = &m_iHeightField1[0];
  125. }
  126. rquad = radius * radius;
  127. // Make a randomly-placed blob...
  128. if(x<0) 
  129. x = (int)(1+radius*m_ABProportion+ rand()%((int)(m_iWidth-2*radius*m_ABProportion-1)));
  130. if(y<0) 
  131. y = 1+radius+ rand()%(m_iHeight-2*radius-1);
  132. left=(int)(-radius*m_ABProportion); right =(int) (radius*m_ABProportion);
  133. top=-radius; bottom = radius;
  134. // Perform edge clipping...
  135. if(x - radius*m_ABProportion < 1) left -= int(x-radius*m_ABProportion-1);
  136. if(y - radius < 1) top  -= (y-radius-1);
  137. if(x + radius*m_ABProportion > m_iWidth-1) right -= int(x+radius*m_ABProportion-m_iWidth+1);
  138. if(y + radius > m_iHeight-1) bottom-= (y+radius-m_iHeight+1);
  139. double temp=(m_ABProportion*m_ABProportion);
  140. for(cy = top; cy < bottom; cy++)
  141. {
  142. cyq = cy*cy;
  143. for(cx = left; cx < right; cx++)
  144. {
  145. if((int)(cx*cx/temp + cyq) < rquad)
  146. {
  147. if(m_bBarArray[cx+x][cy+y]==FALSE)
  148. newptr[m_iWidth*(cy+y) + int(cx+x)] += height;
  149. }
  150. }
  151. }
  152. }
  153. void CWaterRoutine::DrawWaterWithLight(int page,DWORD* pSrcImage,DWORD* pTargetImage)
  154. {
  155. int dx, dy;
  156. int x, y;
  157. DWORD c;
  158. int offset=m_iWidth + 1;
  159. long lIndex;
  160. long lBreak = m_iWidth*m_iHeight;
  161. int *ptr = &m_iHeightField1[0];
  162. for (y = (m_iHeight-1)*m_iWidth; offset < y; offset += 2)
  163. {
  164. for (x = offset+m_iWidth-2; offset < x; offset++)
  165. {
  166. int t=offset/m_iWidth;
  167. int t1=offset%m_iWidth;
  168. if(m_bBarArray[t1][t]==TRUE)
  169. continue;
  170. dx = ptr[offset] - ptr[offset+1];
  171. dy = ptr[offset] - ptr[offset+m_iWidth];
  172. lIndex = offset + m_iWidth*(dy>>3) + (dx>>3);
  173. if(lIndex < lBreak && lIndex > 0)
  174. {
  175. c = pSrcImage[lIndex];// - (dx>>LightModifier);
  176. // Now we shift it by the dx component...
  177. // 
  178. c = GetShiftedColor(c,dx);
  179. pTargetImage[offset] = c;
  180. }
  181. offset++;
  182. dx = ptr[offset] - ptr[offset+1];
  183. dy = ptr[offset] - ptr[offset+m_iWidth];
  184. lIndex = offset + m_iWidth*(dy>>3) + (dx>>3);
  185. if(lIndex < lBreak && lIndex > 0)
  186. {
  187. c = pSrcImage[lIndex];// - (dx>>LightModifier);
  188. c = GetShiftedColor(c,dx);
  189. //temp[offset] = (c < 0) ? 0 : (c > 255) ? 255 : c;
  190. pTargetImage[offset] = c;
  191. }
  192. }
  193. }
  194. }
  195. COLORREF CWaterRoutine::GetShiftedColor(COLORREF color,int shift)
  196. {
  197. long R;
  198. long G;
  199. long B;
  200. int ir;
  201. int ig;
  202. int ib;
  203. R = GetRValue(color)-shift;
  204. G = GetGValue(color)-shift;
  205. B = GetBValue(color)-shift;
  206. ir = (R < 0) ? 0 : (R > 255) ? 255 : R;
  207. ig = (G < 0) ? 0 : (G > 255) ? 255 : G;
  208. ib = (B < 0) ? 0 : (B > 255) ? 255 : B;
  209. return RGB(ir,ig,ib);
  210. }
  211. void CWaterRoutine::LoadBarrierData()
  212. {
  213. fstream in("SolidData.txt",ios::in);
  214. if(in.fail())
  215. {
  216. AfxMessageBox("Cannot load the SolidData.txt");
  217. return;
  218. }
  219. int x,y;
  220. while(!in.eof())
  221. {
  222. in>>x>>y;
  223. m_bBarArray[x][y]=TRUE;
  224. }
  225. in.close();
  226. }