可以用来模拟那种刚睡醒然后睁开眼睛的场景效果。
实现方法很简单,就是几张坐标有点不一致的alpha图片慢慢靠在一起,并且同时让alpha恢复正常。虽说是静态图片的模糊,但这方法其实和
和运动模糊(motion blur)极其类似。
这里我使用BLEND_COLORMUL | BLEND_ALPHAADD | BLEND_NOZWRITE的混合模式,该模式下的纹理叠加在一起会显得亮,在这里,顺便复习一下BLEND几个参数的含义,以下内容转自互联网:
1)BLEND_COLORADD
表示顶点的颜色与纹理的纹元(texel)颜色相加,这使得纹理变亮,可见顶点颜色为 0x00000000,将不造成任何影响。
2)BLEND_COLORMUL
表示顶点的颜色与纹理的纹元颜色相乘,这使得纹理变暗,可见顶点颜色为 0xFFFFFFFF 将不造成任何影响。
3)BLEND_ALPHABLEND
渲染时,将对象的像素颜色(而非顶点的颜色)与当前屏幕的对应像素颜色进行 alpha 混合。
4)BLEND_ALPHAADD
渲染时,将对象的像素颜色与当前屏幕的对应像素颜色相加,结果是有了变亮的效果。
5)BLEND_ZWRITE
写像素的 Z-order 到 Z-buffer
6)BLEND_NOZWRITE
渲染时,不写像素的 Z-order 到 Z-buffer
以上1和2,3和4,5和6都是互斥的,并且必须选择一个的,默认情况下应该是2,3,6
话不多了,上代码吧,格式啊,取名什么的都比较挫,嘛,反正很短,当demo随便看看就好。如果要自己编译运行需要准备一张图片和设置好自己的图片路径哦(修改在Texture_Load处的参数)
/*
** motion blur demo
** based off of hge tutorial..
*/
#include "..\..\include\hge.h"
#include "..\..\include\hgesprite.h"
HGE *hge=0;
hgeSprite* spt1;
hgeSprite* spt2;
HTEXTURE tex;
float x=0.0f, y=0.0f;
float x2=0.0f, y2=0.0f;
float totaltime = 0;
float endtime = 0.5f;
int offset = 10;
bool FrameFunc()
{
float dt = hge->Timer_GetDelta();
totaltime += dt;
if(totaltime > 0.1f && offset != 0)
{
offset -=2;
totaltime = 0;
}
if(endtime > 0)
{
spt2->SetColor( ARGB( endtime/0.5f*((float)128), 255,255,255 ) );
endtime -= dt;
}
else
spt2->SetColor(ARGB(0,255,255,255));//alpha为0时,图片不显示,就看不到发光效果了,实际程序运用时,应该释放掉该精灵更好。
hge->Gfx_BeginScene();
hge->Gfx_Clear(0);
spt1->Render(x, y);
spt2->Render(x2-offset, y2);
spt2->Render(x2+offset, y2);
if(offset > 2)
{
spt2->Render(x2-(offset-2), y2);
spt2->Render(x2+(offset-2), y2);
}
hge->Gfx_EndScene();
return false;
}
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
hge = hgeCreate(HGE_VERSION);
hge->System_SetState(HGE_FRAMEFUNC, FrameFunc);
hge->System_SetState(HGE_TITLE, "HGE RealTime Blur Demo");
hge->System_SetState(HGE_FPS, 100);
hge->System_SetState(HGE_WINDOWED, true);
hge->System_SetState(HGE_SCREENWIDTH, 1024);
hge->System_SetState(HGE_SCREENHEIGHT, 768);
hge->System_SetState(HGE_SCREENBPP, 32);
if(hge->System_Initiate()) {
tex=hge->Texture_Load("alley_normal.jpg");
if(!tex)
{
MessageBox(NULL, "Can't load the picture file", "Error", MB_OK | MB_ICONERROR | MB_SYSTEMMODAL);
hge->System_Shutdown();
hge->Release();
return 0;
}
spt1=new hgeSprite(tex, 0, 0, 1024, 768);//这是最后会显示的精灵
spt2=new hgeSprite(tex, 0, 0, 1024, 768);
spt2->SetBlendMode(BLEND_COLORMUL | BLEND_ALPHAADD | BLEND_NOZWRITE);
spt2->SetColor(ARGB(128,255,255,255));
hge->System_Start();
// Delete created objects and free loaded resources
delete spt1;
delete spt2;
hge->Texture_Free(tex);
}
// Clean up and shutdown
hge->System_Shutdown();
hge->Release();
return 0;
}我的效果图: