RippleWnd.cpp
资源名称:网络视频电话系统.rar [点击查看]
上传用户:oldpeter23
上传日期:2013-01-09
资源大小:1111k
文件大小:7k
源码类别:
IP电话/视频会议
开发平台:
Visual C++
- //NetTalk
- /*------------------------------------------------------------------------------*
- =============================
- 模块名称: RippleWnd.cpp
- =============================
- [版权]
- *------------------------------------------------------------------------------*/
- //借鉴来的水波特效,作者不详,在此谢过
- #include "WndX.h"
- #include "RippleWnd.h"
- #include <Stdio.h>
- #include <Windowsx.h>
- #pragma comment(lib,"ddraw")
- /*------------------------------------------------------------------------------*/
- CRippleWnd::CRippleWnd()
- {
- m_iCount=0;
- m_dwFps=0;
- }
- /*------------------------------------------------------------------------------*/
- CRippleWnd::~CRippleWnd()
- {
- }
- /*------------------------------------------------------------------------------*/
- BOOL CRippleWnd::Create(RECT &rc, HWND hParent,UINT uBmpID,int iWidth,int iHeight)
- {
- BOOL bRet=FALSE;
- m_iWidth=iWidth;
- m_iHeight=iHeight;
- if(!CWndX::Create(0,0,0,WS_CHILD|WS_VISIBLE,rc,hParent,0,0))
- goto RET;
- SetClassLong(m_hWnd,GCL_HBRBACKGROUND,0);
- if(!InitDDraw(uBmpID,iWidth,iHeight))
- goto RET;
- SetTimer(m_hWnd,1,30,0);
- m_dwTime=GetTickCount();
- bRet=TRUE;
- RET:
- return bRet;
- }
- /*------------------------------------------------------------------------------*/
- LRESULT CRippleWnd::WndProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
- {
- switch(uMsg)
- {
- case WM_DESTROY:
- KillTimer(m_hWnd,1);
- FreeObject();
- break;
- case WM_TIMER:
- {
- if(IsWindowVisible(m_hWnd))
- {
- UpdateFrame();
- }
- }
- break;
- case WM_LBUTTONDOWN:
- DropStone(LOWORD(lParam),HIWORD(lParam),3,128);
- break;
- case WM_MOUSEMOVE:
- if (wParam==MK_LBUTTON )
- {
- DropStone(LOWORD(lParam),HIWORD(lParam),3,128);
- }
- break;
- }
- return CWndX::WndProc(uMsg,wParam,lParam);
- }
- /*------------------------------------------------------------------------------*/
- BOOL CRippleWnd::InitDDraw(UINT uBmpID,int iWidth,int iHeight)
- {
- DDSURFACEDESC ddsd;
- HRESULT ddrval;
- //创建DirectDraw对象
- ddrval = DirectDrawCreate( NULL, &lpDD, NULL );
- if( ddrval != DD_OK )
- return FALSE;
- ddrval = lpDD->SetCooperativeLevel(NULL, DDSCL_NORMAL);
- if( ddrval != DD_OK )
- return FALSE;
- ddsd.dwSize = sizeof( ddsd );
- ddsd.dwFlags = DDSD_CAPS ;
- ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
- ddrval = lpDD->CreateSurface( &ddsd, &lpDDSPrimary, NULL );
- if( ddrval != DD_OK )
- return FALSE;
- ZeroMemory(&ddsd, sizeof(ddsd));
- ddsd.dwSize = sizeof(ddsd);
- ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT |DDSD_WIDTH;
- ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN |DDSCAPS_SYSTEMMEMORY ;
- ddsd.dwWidth = iWidth;
- ddsd.dwHeight = iHeight;
- if (lpDD->CreateSurface(&ddsd, &lpDDSPic1, NULL) != DD_OK)
- return FALSE;
- if (lpDD->CreateSurface(&ddsd, &lpDDSPic2, NULL) != DD_OK)
- return FALSE;
- lpDD->CreateClipper(0, &lpClipper, NULL);
- lpClipper->SetHWnd(0, m_hWnd);
- lpDDSPrimary->SetClipper(lpClipper);
- DDReLoadBitmap(lpDDSPic1, MAKEINTRESOURCE(uBmpID));
- buf1 = new short[iWidth*iHeight];
- buf2 = new short[iWidth*iHeight];
- ZeroMemory(buf1, iWidth*iHeight*sizeof(short));
- ZeroMemory(buf2, iWidth*iHeight*sizeof(short));
- return TRUE;
- }
- /*------------------------------------------------------------------------------*/
- void CRippleWnd::FreeObject()
- {
- if( lpDD != NULL )//释放DirectDraw对象
- {
- if( lpDDSPrimary != NULL )//释放主页面。
- {
- lpDDSPrimary->Release();
- lpDDSPrimary = NULL;
- }
- if( lpDDSPic1 != NULL )//释放离屏页面。
- {
- lpDDSPic1->Release();
- lpDDSPic1 = NULL;
- }
- if( lpDDSPic2 != NULL )
- {
- lpDDSPic2->Release();
- lpDDSPic2 = NULL;
- }
- if (lpClipper!=NULL)
- {
- lpClipper->Release();
- lpClipper=NULL;
- }
- lpDD->Release();
- lpDD = NULL;
- }
- if(buf1)
- delete buf1;
- if(buf2)
- delete buf2;
- }
- /*------------------------------------------------------------------------------*/
- void CRippleWnd::DropStone(int x,int y,int stonesize,int stoneweight)
- {
- //判断坐标是否在屏幕范围内
- if ((x+stonesize)>m_iWidth ||
- (y+stonesize)>m_iHeight||
- (x-stonesize)<0||
- (y-stonesize)<0)
- return;
- for (int posx=x-stonesize; posx<x+stonesize; posx++)
- for (int posy=y-stonesize; posy<y+stonesize; posy++)
- if ((posx-x)*(posx-x) + (posy-y)*(posy-y) < stonesize*stonesize)
- buf1[m_iWidth*posy+posx] = -stoneweight;
- }
- /*------------------------------------------------------------------------------*/
- void CRippleWnd::RenderRipple()
- {
- //锁定两个离屏页面
- DDSURFACEDESC ddsd1, ddsd2;
- ddsd1.dwSize = sizeof (DDSURFACEDESC);
- ddsd2.dwSize = sizeof(DDSURFACEDESC);
- lpDDSPic1->Lock(NULL, &ddsd1, DDLOCK_WAIT, NULL);
- lpDDSPic2->Lock(NULL, &ddsd2, DDLOCK_WAIT, NULL);
- //取得页面象素位深度,和页面内存指针
- int depth=ddsd1.ddpfPixelFormat.dwRGBBitCount/8;
- BYTE *Bitmap1 = (BYTE*)ddsd1.lpSurface;
- BYTE *Bitmap2 = (BYTE*)ddsd2.lpSurface;
- //下面进行页面渲染
- int xoff, yoff;
- int k = m_iWidth;
- for (int i=1; i<m_iHeight-1; i++)
- {
- for (int j=0; j<m_iWidth; j++)
- {
- //计算偏移量
- xoff = buf1[k-1]-buf1[k+1];
- yoff = buf1[k-m_iWidth]-buf1[k+m_iWidth];
- //判断坐标是否在窗口范围内
- if ((i+yoff )< 0 ) {k++; continue;}
- if ((i+yoff )> m_iHeight) {k++; continue;}
- if ((j+xoff )< 0 ) {k++; continue;}
- if ((j+xoff )> m_iWidth ) {k++; continue;}
- //计算出偏移象素和原始象素的内存地址偏移量
- int pos1, pos2;
- pos1=ddsd1.lPitch*(i+yoff)+ depth*(j+xoff);
- pos2=ddsd2.lPitch*i+ depth*j;
- //复制象素
- for (int d=0; d<depth; d++)
- Bitmap2[pos2++]=Bitmap1[pos1++];
- k++;
- }
- }
- //解锁页面
- lpDDSPic1->Unlock(&ddsd1);
- lpDDSPic2->Unlock(&ddsd2);
- HDC hdc;
- lpDDSPic2->GetDC(&hdc);
- char szFps[10];
- sprintf(szFps,"%dFPS",m_dwFps);
- SetBkMode(hdc,TRANSPARENT);
- SetTextColor(hdc,0x00ffaaaa);
- DrawText(hdc,szFps,strlen(szFps),&CRectX(200,5,280,20),DT_RIGHT);
- lpDDSPic2->ReleaseDC(hdc);
- }
- /*------------------------------------------------------------------------------*/
- void CRippleWnd::UpdateFrame()
- {
- m_iCount++;
- if(m_iCount>=20)
- {
- DropStone(
- (int)(m_iWidth*((short)rand()/32767.0)),
- (int)(m_iHeight*((short)rand()/32767.0)),
- 3,
- 128
- );
- DWORD temp=GetTickCount();
- m_dwFps=20000/(temp-m_dwTime);
- m_dwTime=temp;
- m_iCount=0;
- }
- RippleSpread();
- RenderRipple();//页面渲染
- //将离屏页面图象Blit到主页面
- RECT Window;
- POINT pt;
- GetClientRect(m_hWnd, &Window);
- pt.x=pt.y=0;
- ClientToScreen(m_hWnd, &pt);
- OffsetRect(&Window, pt.x, pt.y);
- lpDDSPrimary->Blt(&Window, lpDDSPic2, NULL, DDBLT_WAIT, NULL);
- }
- /*------------------------------------------------------------------------------*/
- void CRippleWnd::RippleSpread()
- {
- for (int i=m_iWidth; i<m_iWidth*m_iHeight-m_iWidth; i++)
- {
- //波能扩散
- buf2[i] = ((buf1[i-1]+
- buf1[i+1]+
- buf1[i-m_iWidth]+
- buf1[i+m_iWidth])
- >>1)
- - buf2[i];
- //波能衰减
- buf2[i] -= buf2[i]>>5;
- }
- //交换波能数据缓冲区
- short *ptmp =buf1;
- buf1 = buf2;
- buf2 = ptmp;
- }