火焰傀偶的挣扎旅程

纯爷们的一生就是不停地燃烧,keep on burning soul!!
随笔 - 6, 文章 - 5, 评论 - 4, 引用 - 0
数据加载中……

在hge中实现对静态图片的动态模糊 (box blur版)


http://blog.csdn.net/jia20003/article/details/7201069

在该前辈的博客处找了段java的均值模糊(box blur)的代码,我把它换成hge的了,效率还可以,不过应该比不上前一篇的方法。但box blur是比较正统的模糊算法,不像前一篇的那般“邪道”,他直接处理像素,其思想方法类似高斯算法,实现上又比高斯算法要简单,虽然效果上比高斯差,但也值得了。

这里我简单讲一下均值模糊的步骤,当然各位也可以看那位前辈的博客:)

1.输入一个半径r,定义模糊的方向,r越大,则越模糊(虽然说是半径r,但是模糊的方向只取一条线,或两条线,例如横,竖,横与竖)。

2.根据1建立一个索引,其实就是空间换时间,提前算好了r范围内所有可能出现的颜色数值之和的均值,这是个固定的值,所以可以一开始就建)。

3.计算第一个r区域的各个像素值之和(r,g,b,a分别算)

4.开始遍历想要输出的纹理像素(注意原纹理矩阵依然保留),每行第一个像素,直接给他赋予2中的均值,往后每遍历一个像素,3计算的像素值之和都加上x+r +1和 x - r 之间的差(或者是y+r+1和y-r-1的差),然后再次赋予新的均值。

代码(使用横方向模糊,每摁一下L键开始模糊,半径为10):


/*
**
** motion blur demo
** based off of tutorial4..
*/
 
 
#include 
"..\..\include\hge.h"
#include 
"..\..\include\hgesprite.h"
 
 
HGE 
*hge=0;
 
 
hgeSprite
* spt1;

float x=0.0f, y=0.0f;


HTEXTURE boxblur( HTEXTURE 
inint radius ) ;

bool FrameFunc()
{
    
if(hge->Input_KeyDown(HGEK_L))
    {
        HTEXTURE dumptex 
= spt1->GetTexture();
        HTEXTURE tex2 
= boxblur(dumptex,10);
        spt1
->SetTexture(tex2);
        hge
->Texture_Free(dumptex);
    }

    hge
->Gfx_BeginScene();
    hge
->Gfx_Clear(0);
 
    spt1
->Render(x, y);

    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()) {
        
        HTEXTURE 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, 001024768);//这是最后会显示的精灵
               
        hge
->System_Start();

        hge
->Texture_Free(spt1->GetTexture());

        delete spt1;
    }
 
    
// Clean up and shutdown
    hge->System_Shutdown();
    hge
->Release();
    
return 0;
}

HTEXTURE boxblur( HTEXTURE 
inint radius ) 
{  
    
int width, height;
    width 
= hge->Texture_GetWidth(in);
    height 
= hge->Texture_GetHeight(in);
    HTEXTURE 
out = hge->Texture_Create(width, height);

    
int widthMinus1 = width-1;  
    
int tableSize = 2*radius+1;  
    unsigned 
int* divide = new unsigned int[256*tableSize];  

    
// the value scope will be 0 to 255, and number of 0 is table size  
    
// will get means from index not calculate result again since   
    
// color value must be  between 0 and 255.  
    for ( int i = 0; i < 256*tableSize; i++ )  
        divide[i] 
= i/tableSize;   

    
int inIndex = 0;  

    unsigned 
int* in_  = (unsigned int*)hge->Texture_Lock(in);
    unsigned 
int* out_ = (unsigned int*)hge->Texture_Lock(outfalse);

    
//   
    for ( int y = 0; y < height; y++ ) {  
        
int outIndex = y;  
        unsigned 
int ta = 0, tr = 0, tg = 0, tb = 0// ARGB -> prepare for the alpha, red, green, blue color value.  

        
for ( int i = -radius; i <= radius; i++ ) 
        {  
            
int clamp = (i < 0? 0 : (i > (width-1)) ? (width-1) : i;
            unsigned 
int rgb = in_[inIndex + clamp]; // read input pixel data here. table size data.  
            ta += (rgb >> 24& 0xff;  
            tr 
+= (rgb >> 16& 0xff;  
            tg 
+= (rgb >> 8& 0xff;  
            tb 
+= rgb & 0xff;  
        }  

        
for ( int x = 0; x < width; x++ ) 
        { 
// get output pixel data.  
            out_[ outIndex*width + x ] = (divide[ta] << 24| (divide[tr] << 16| (divide[tg] << 8| divide[tb]; // calculate the output data.  

            
int i1 = x+radius+1;  
            
if ( i1 > widthMinus1 )  
                i1 
= widthMinus1;  
            
int i2 = x-radius;  
            
if ( i2 < 0 )  
                i2 
= 0;  
            
int rgb1 = in_[inIndex+i1];  
            
int rgb2 = in_[inIndex+i2];  

            ta 
+= ((rgb1 >> 24& 0xff)-((rgb2 >> 24& 0xff);  
            tr 
+= ((rgb1 & 0xff0000)-(rgb2 & 0xff0000)) >> 16;  
            tg 
+= ((rgb1 & 0xff00)-(rgb2 & 0xff00)) >> 8;  
            tb 
+= (rgb1 & 0xff)-(rgb2 & 0xff);
        }  
        inIndex 
+= width; // next (i+ column number * n, n=1.n-1)  
    } 

    hge
->Texture_Unlock(in);
    hge
->Texture_Unlock(out);
    delete [] divide;
    
return out;
}



posted on 2012-12-13 16:24 WhiteDummy 阅读(1723) 评论(0)  编辑 收藏 引用 所属分类: HGE


只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理