📄 ripple.cpp
字号:
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 = BACKWIDTH;
ddsd.dwHeight = BACKHEIGHT;
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, ChooseWnd());
lpDDSPrimary->SetClipper(lpClipper);
if( !InitSurfaces() )
return FALSE;
return TRUE;
}
//******************************************************************
//函数:WinMain()
//功能:应用程序入口
//******************************************************************
int PASCAL WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
hInst=hInstance;
ShowAbout();
//初始化主窗口
if ( !InitWindow( hInstance, nCmdShow ) )
return FALSE;
//初始化DirectDraw环境
if ( !InitDDraw())
{
MessageBox(fullscreen ? hwndwin:hwndful, "初始化DirectDraw过程中出错!", "Error", MB_OK );
FreeObjects();
return FALSE;
}
//进入消息循环
while(1)
{
if(PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
{
if(!GetMessage(&msg, NULL, 0, 0 )) return msg.wParam;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else if(bActive)
{
UpdateFrame();
}
else WaitMessage();
}
return msg.wParam;
}
//******************************************************************
//函数:InitSurfaces()
//功能:初始化页面图象
//******************************************************************
BOOL InitSurfaces( void )
{
DDReLoadBitmap(lpDDSPic1, "back.bmp");
buf1 = new short[BACKWIDTH*BACKHEIGHT];
buf2 = new short[BACKWIDTH*BACKHEIGHT];
ZeroMemory(buf1, BACKWIDTH*BACKHEIGHT*sizeof(short));
ZeroMemory(buf2, BACKWIDTH*BACKHEIGHT*sizeof(short));
for (int i=0; i<10; i++)
DropStone(BACKWIDTH*i/10, BACKHEIGHT/2, 3, 128);
return TRUE;
}
//*******************************************************
//计算波能数据缓冲区
//*******************************************************
void RippleSpread()
{
for (int i=BACKWIDTH; i<BACKWIDTH*BACKHEIGHT-BACKWIDTH; i++)
{
//波能扩散
buf2[i] = ((buf1[i-1]+
buf1[i+1]+
buf1[i-BACKWIDTH]+
buf1[i+BACKWIDTH])
>>1)
- buf2[i];
//波能衰减
buf2[i] -= buf2[i]>>5;
}
//交换波能数据缓冲区
short *ptmp =buf1;
buf1 = buf2;
buf2 = ptmp;
}
//*******************************************************
//根据波能数据缓冲区对离屏页面进行渲染
//*******************************************************
void 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 = BACKWIDTH;
for (int i=1; i<BACKHEIGHT-1; i++)
{
for (int j=0; j<BACKWIDTH; j++)
{
//计算偏移量
xoff = buf1[k-1]-buf1[k+1];
yoff = buf1[k-BACKWIDTH]-buf1[k+BACKWIDTH];
//判断坐标是否在窗口范围内
if ((i+yoff )< 0 ) {k++; continue;}
if ((i+yoff )> BACKHEIGHT) {k++; continue;}
if ((j+xoff )< 0 ) {k++; continue;}
if ((j+xoff )> BACKWIDTH ) {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);
}
//********************************************************
//更新屏幕
//********************************************************
void UpdateFrame( void )
{
//随机增加波源
if (rain==TRUE)
DropStone(
(int)(BACKWIDTH*((short)rand()/32767.0)),
(int)(BACKHEIGHT*((short)rand()/32767.0)),
3,
128
);
if (downripper==TRUE)
DropStone(
(int)(BACKWIDTH*((short)rand()/32767.0)),
BACKHEIGHT-3,
3,
128
);
if (upripper==TRUE)
DropStone(
(int)(BACKWIDTH*((short)rand()/32767.0)),
3,
3,
128
);
RippleSpread();//计算波能数据缓冲区
RenderRipple();//页面渲染
//将离屏页面图象Blit到主页面
RECT Window;
POINT pt;
GetClientRect(ChooseWnd(), &Window);
pt.x=pt.y=0;
ClientToScreen(ChooseWnd(), &pt);
OffsetRect(&Window, pt.x, pt.y);
lpDDSPrimary->Blt(&Window, lpDDSPic2, NULL, DDBLT_WAIT, NULL);
}
void MakeRect(RECT *rect, short left, short top, short width, short height)
{
rect->left=left;
rect->top=top;
rect->right=left+width;
rect->bottom=top+height;
}
//*****************************************************
//增加波源
//*****************************************************
void DropStone(int x,//x坐标
int y,//y坐标
int stonesize,//波源半径
int stoneweight)//波源能量
{
//判断坐标是否在屏幕范围内
if ((x+stonesize)>BACKWIDTH ||
(y+stonesize)>BACKHEIGHT||
(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[BACKWIDTH*posy+posx] = -stoneweight;
}
void ShowAbout(void)
{
char temp[]="\n"
"===============水波特效================"
"\n\n"
" 天恒工作室 唐洁 \n"
"\n\n"
" Email : tj@ahpost.com.cn或flyingtjf@sina.com.cn\n"
"\n\n"
" 2004年12月9日\n\n"
"=======================================\n\n"
;
MessageBox(ChooseWnd(), temp, TITLE, MB_OK);
}
HWND ChooseWnd()
{
return fullscreen ? hwndful:hwndwin;
}
//调整窗口大小
void AdjustWindowSize(HWND hwnd)
{
RECT rect;
MakeRect(&rect, 0, 0, BACKWIDTH, BACKHEIGHT );
AdjustWindowRectEx( &rect,
GetWindowStyle(hwnd),
GetMenu(hwnd)!=NULL,
GetWindowExStyle(hwnd));
MoveWindow( hwnd,
(GetSystemMetrics(SM_CXFULLSCREEN)-(rect.right-rect.left))/2,
(GetSystemMetrics(SM_CYFULLSCREEN)-(rect.bottom-rect.top))/2,
rect.right-rect.left,
rect.bottom-rect.top,
TRUE);
}
//初始化预览窗口
BOOL InitPreviewWindow( HINSTANCE hInstance, int nCmdShow )
{
WNDCLASS wc3; //窗口类结构
//填充窗口类结构
wc3.style = 0;
wc3.lpfnWndProc = WinProc;
wc3.cbClsExtra = 0;
wc3.cbWndExtra = 0;
wc3.hInstance = hInstance;
wc3.hIcon = LoadIcon( hInstance, MAKEINTRESOURCE(ID_APP));
wc3.hCursor = LoadCursor( NULL, IDC_ARROW);
wc3.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wc3.lpszMenuName = MAKEINTRESOURCE(IDR_MENU1);
wc3.lpszClassName = "preview";
//注册窗口类
RegisterClass( &wc3 );
//创建窗口
HWND tmp=CreateWindowEx(
0,
"preview",
"水波预览", //窗口的标题名
WS_OVERLAPPEDWINDOW,
0,0,
10,10,
NULL,
NULL,
hInstance,
NULL );
if (!tmp) return FALSE;
ShowWindow(tmp, SW_HIDE);
UpdateWindow(tmp);
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -