CWaterRoutine.cpp
上传用户:sycq158
上传日期:2008-10-22
资源大小:15361k
文件大小:6k
- // WaterRoutine.cpp: implementation of the CWaterRoutine class.
- //
- //////////////////////////////////////////////////////////////////////
- #include "stdafx.h"
- #include "CWaterRoutine.h"
- #include <math.h>
- #include "fstream.h"
- //////////////////////////////////////////////////////////////////////
- // Construction/Destruction
- //////////////////////////////////////////////////////////////////////
- #define random( min, max ) (( rand() % (int)((( max ) + 1 ) - ( min ))) + ( min ))
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- CWaterRoutine::CWaterRoutine()
- {
- m_iHeightField1 = NULL;
- m_iHeightField2 = NULL;
- m_iWidth = 0;
- m_iHeight = 0;
- m_iHpage = 0;
- m_density = 5;
- //水波长短轴之比
- m_ABProportion=1;
- for(int i=0;i<1024;i++)
- for(int j=0;j<768;j++)
- {
- m_bBarArray[i][j]=FALSE;
- }
- }
- CWaterRoutine::~CWaterRoutine()
- {
- // Cleanup
- if(m_iHeightField1 != NULL)
- delete [] m_iHeightField1;
- if(m_iHeightField2 != NULL)
- delete [] m_iHeightField2;
- m_iHeightField1 = NULL;
- m_iHeightField2 = NULL;
- }
- void CWaterRoutine::Create(int iWidth,int iHeight)
- {
- if(m_iHeightField1 != NULL)
- delete [] m_iHeightField1;
- if(m_iHeightField2 != NULL)
- delete [] m_iHeightField2;
- // Create our height fields
- m_iHeightField1 = new int[(iWidth*iHeight)];
- m_iHeightField2 = new int[(iWidth*iHeight)];
- // Clear our height fields
- memset(m_iHeightField1,0,(iWidth*iHeight)*sizeof(int));
- memset(m_iHeightField2,0,(iWidth*iHeight)*sizeof(int));
- m_iWidth = iWidth;
- m_iHeight = iHeight;
- // Set our page to 0
- m_iHpage = 0;
- }
- void CWaterRoutine::FlattenWater()
- {
- // Clear our height fields
- memset(m_iHeightField1,0,(m_iWidth*m_iHeight)*sizeof(int));
- memset(m_iHeightField2,0,(m_iWidth*m_iHeight)*sizeof(int));
- }
- void CWaterRoutine::Render(DWORD* pSrcImage,DWORD* pTargetImage)
- {
- DrawWaterWithLight(m_iHpage,pSrcImage,pTargetImage);
- CalcWater(m_iHpage,m_density);
- m_iHpage ^= 1;
- }
- //这个density是一个阻尼系数
- void CWaterRoutine::CalcWater(int npage, int density)
- {
- int newh;
- int count = m_iWidth + 1;
- int *newptr;
- int *oldptr;
- if(npage == 0)
- {
- newptr = &m_iHeightField1[0];
- oldptr = &m_iHeightField2[0];
- }
- else
- {
- newptr = &m_iHeightField2[0];
- oldptr = &m_iHeightField1[0];
- }
- int x, y;
- for (y = (m_iHeight-1)*m_iWidth; count < y; count += 2)
- {
- for (x = count+m_iWidth-2; count < x; count++)
- {
- newh = ((oldptr[count + m_iWidth]
- + oldptr[count - m_iWidth]
- + oldptr[count + 1]
- + oldptr[count - 1]
- + oldptr[count - m_iWidth - 1]
- + oldptr[count - m_iWidth + 1]
- + oldptr[count + m_iWidth - 1]
- + oldptr[count + m_iWidth + 1]
- ) >> 2 )
- - newptr[count];
- newptr[count] = newh - (newh >> density);//衰减32
- }
- }
- }
- void CWaterRoutine::HeightBlob(int x, int y, int radius, int height, int page)
- {
- int rquad;
- int cx, cy, cyq;
- int left, top, right, bottom;
- int *newptr;
- int *oldptr;
- // Set up the pointers
- if(page == 0)
- {
- newptr = &m_iHeightField1[0];
- oldptr = &m_iHeightField2[0];
- }
- else
- {
- newptr = &m_iHeightField2[0];
- oldptr = &m_iHeightField1[0];
- }
- rquad = radius * radius;
- // Make a randomly-placed blob...
- if(x<0)
- x = (int)(1+radius*m_ABProportion+ rand()%((int)(m_iWidth-2*radius*m_ABProportion-1)));
- if(y<0)
- y = 1+radius+ rand()%(m_iHeight-2*radius-1);
- left=(int)(-radius*m_ABProportion); right =(int) (radius*m_ABProportion);
- top=-radius; bottom = radius;
- // Perform edge clipping...
- if(x - radius*m_ABProportion < 1) left -= int(x-radius*m_ABProportion-1);
- if(y - radius < 1) top -= (y-radius-1);
- if(x + radius*m_ABProportion > m_iWidth-1) right -= int(x+radius*m_ABProportion-m_iWidth+1);
- if(y + radius > m_iHeight-1) bottom-= (y+radius-m_iHeight+1);
- double temp=(m_ABProportion*m_ABProportion);
- for(cy = top; cy < bottom; cy++)
- {
- cyq = cy*cy;
- for(cx = left; cx < right; cx++)
- {
- if((int)(cx*cx/temp + cyq) < rquad)
- {
- if(m_bBarArray[cx+x][cy+y]==FALSE)
- newptr[m_iWidth*(cy+y) + int(cx+x)] += height;
- }
- }
- }
- }
- void CWaterRoutine::DrawWaterWithLight(int page,DWORD* pSrcImage,DWORD* pTargetImage)
- {
- int dx, dy;
- int x, y;
- DWORD c;
- int offset=m_iWidth + 1;
- long lIndex;
- long lBreak = m_iWidth*m_iHeight;
- int *ptr = &m_iHeightField1[0];
- for (y = (m_iHeight-1)*m_iWidth; offset < y; offset += 2)
- {
- for (x = offset+m_iWidth-2; offset < x; offset++)
- {
- int t=offset/m_iWidth;
- int t1=offset%m_iWidth;
- if(m_bBarArray[t1][t]==TRUE)
- continue;
- dx = ptr[offset] - ptr[offset+1];
- dy = ptr[offset] - ptr[offset+m_iWidth];
- lIndex = offset + m_iWidth*(dy>>3) + (dx>>3);
- if(lIndex < lBreak && lIndex > 0)
- {
- c = pSrcImage[lIndex];// - (dx>>LightModifier);
- // Now we shift it by the dx component...
- //
- c = GetShiftedColor(c,dx);
- pTargetImage[offset] = c;
- }
- offset++;
- dx = ptr[offset] - ptr[offset+1];
- dy = ptr[offset] - ptr[offset+m_iWidth];
- lIndex = offset + m_iWidth*(dy>>3) + (dx>>3);
- if(lIndex < lBreak && lIndex > 0)
- {
- c = pSrcImage[lIndex];// - (dx>>LightModifier);
- c = GetShiftedColor(c,dx);
- //temp[offset] = (c < 0) ? 0 : (c > 255) ? 255 : c;
- pTargetImage[offset] = c;
- }
- }
- }
- }
- COLORREF CWaterRoutine::GetShiftedColor(COLORREF color,int shift)
- {
- long R;
- long G;
- long B;
- int ir;
- int ig;
- int ib;
- R = GetRValue(color)-shift;
- G = GetGValue(color)-shift;
- B = GetBValue(color)-shift;
- ir = (R < 0) ? 0 : (R > 255) ? 255 : R;
- ig = (G < 0) ? 0 : (G > 255) ? 255 : G;
- ib = (B < 0) ? 0 : (B > 255) ? 255 : B;
- return RGB(ir,ig,ib);
- }
- void CWaterRoutine::LoadBarrierData()
- {
- fstream in("SolidData.txt",ios::in);
- if(in.fail())
- {
- AfxMessageBox("Cannot load the SolidData.txt");
- return;
- }
- int x,y;
- while(!in.eof())
- {
- in>>x>>y;
- m_bBarArray[x][y]=TRUE;
- }
- in.close();
- }