cocos 高斯模糊处理

该文主要是在百度搜索中,查找多人文档进行整理汇总:

在某些项目中可能会用到背景模糊效果。可能是显示一个UI并且把当前场景作为背景进行模糊化,

一:

首先我们可以采取截取当前场景:

 local screen = cc.RenderTexture:create(card:getContentSize().height, card:getContentSize().width);
  screen:begin()         
  card:visit()
  screen:endToLua()               
  screen:saveToFile("scene.png", cc.IMAGE_FORMAT_JPEG)

保存的路径:cc.FileUtils:getInstance():getWritablePath()

也可直接获取texture screen:getTexture()

二:

模糊处理类:

// 声明

class SpriteBlur : public CCSprite{


public:    ~SpriteBlur();    


void setBlurSize(float f);    


bool initWithTexture(CCTexture2D* texture, const CCRect&  rect);    


void draw();    


void initProgram();    


void listenBackToForeground(CCObject *obj);    


static SpriteBlur* create(const char *pszFileName);    


static SpriteBlur* createWithTexture(CCTexture2D *pTexture);


CCPoint blur_;   


GLfloat    sub_[4];    


GLuint    blurLocation;   


GLuint    subLocation;


};


//实现

SpriteBlur::~SpriteBlur()
{
    CCNotificationCenter::sharedNotificationCenter()->removeObserver(this, EVENT_COME_TO_FOREGROUND);
}


SpriteBlur* SpriteBlur::create(const char *pszFileName)
{
    SpriteBlur* pRet = new SpriteBlur();
    if (pRet && pRet->initWithFile(pszFileName))
    {
        pRet->autorelease();
    }
    else
    {
        CC_SAFE_DELETE(pRet);
    }
    
    return pRet;
}


void SpriteBlur::listenBackToForeground(CCObject *obj)
{
    setShaderProgram(NULL);
    initProgram();
}


bool SpriteBlur::initWithTexture(CCTexture2D* texture, const CCRect& rect)
{
    if( CCSprite::initWithTexture(texture, rect) ) 
    {
        CCNotificationCenter::sharedNotificationCenter()->addObserver(this,
                                                                      callfuncO_selector(SpriteBlur::listenBackToForeground),
                                                                      EVENT_COME_TO_FOREGROUND,
                                                                      NULL);
        
        CCSize s = getTexture()->getContentSizeInPixels();


        blur_ = ccp(1/s.width, 1/s.height);
        sub_[0] = sub_[1] = sub_[2] = sub_[3] = 0;


        this->initProgram();
        
        return true;
    }


    return false;
}


void SpriteBlur::initProgram()
{
    GLchar * fragSource = (GLchar*) CCString::createWithContentsOfFile(
                                CCFileUtils::sharedFileUtils()->fullPathForFilename("Shaders/example_Blur.fsh").c_str())->getCString();
    CCGLProgram* pProgram = new CCGLProgram();
    pProgram->initWithVertexShaderByteArray(ccPositionTextureColor_vert, fragSource);
    setShaderProgram(pProgram);
    pProgram->release();
    
    CHECK_GL_ERROR_DEBUG();
    
    getShaderProgram()->addAttribute(kCCAttributeNamePosition, kCCVertexAttrib_Position);
    getShaderProgram()->addAttribute(kCCAttributeNameColor, kCCVertexAttrib_Color);
    getShaderProgram()->addAttribute(kCCAttributeNameTexCoord, kCCVertexAttrib_TexCoords);
    
    CHECK_GL_ERROR_DEBUG();
    
    getShaderProgram()->link();
    
    CHECK_GL_ERROR_DEBUG();
    
    getShaderProgram()->updateUniforms();
    
    CHECK_GL_ERROR_DEBUG();
    
    subLocation = glGetUniformLocation( getShaderProgram()->getProgram(), "substract");
    blurLocation = glGetUniformLocation( getShaderProgram()->getProgram(), "blurSize");
    
    CHECK_GL_ERROR_DEBUG();
}


void SpriteBlur::draw()
{
    ccGLEnableVertexAttribs(kCCVertexAttribFlag_PosColorTex );
    ccBlendFunc blend = getBlendFunc();
    ccGLBlendFunc(blend.src, blend.dst);


    getShaderProgram()->use();
    getShaderProgram()->setUniformsForBuiltins();
    getShaderProgram()->setUniformLocationWith2f(blurLocation, blur_.x, blur_.y);
    getShaderProgram()->setUniformLocationWith4fv(subLocation, sub_, 1);


    ccGLBindTexture2D( getTexture()->getName());


    //
    // Attributes
    //
#define kQuadSize sizeof(m_sQuad.bl)
    long offset = (long)&m_sQuad;


    // vertex
    int diff = offsetof( ccV3F_C4B_T2F, vertices);
    glVertexAttribPointer(kCCVertexAttrib_Position, 3, GL_FLOAT, GL_FALSE, kQuadSize, (void*) (offset + diff));


    // texCoods
    diff = offsetof( ccV3F_C4B_T2F, texCoords);
    glVertexAttribPointer(kCCVertexAttrib_TexCoords, 2, GL_FLOAT, GL_FALSE, kQuadSize, (void*)(offset + diff));


    // color
    diff = offsetof( ccV3F_C4B_T2F, colors);
    glVertexAttribPointer(kCCVertexAttrib_Color, 4, GL_UNSIGNED_BYTE, GL_TRUE, kQuadSize, (void*)(offset + diff));




    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);


    CC_INCREMENT_GL_DRAWS(1);
}


void SpriteBlur::setBlurSize(float f)
{
    CCSize s = getTexture()->getContentSizeInPixels();


    blur_ = ccp(1/s.width, 1/s.height);
    blur_ = ccpMult(blur_,f);
}


SpriteBlur* SpriteBlur::createWithTexture(CCTexture2D *pTexture)
{
    CCAssert(pTexture != NULL, "Invalid texture for sprite");


    CCRect rect = CCRectZero;
    rect.size = pTexture->getContentSize();


    SpriteBlur* pRet = new SpriteBlur();
    if (pRet && pRet->initWithTexture(pTexture,rect))
    {
        pRet->autorelease();
    }
    else
    {
        CC_SAFE_DELETE(pRet);
    }
    
    return pRet;
}


三、

example_Blur.fsh

#ifdef GL_ES
precision mediump float;
#endif


varying vec4 v_fragmentColor;
varying vec2 v_texCoord;


uniform float blurRadius;
uniform float sampleNum;
uniform float test;
uniform vec2 resolution;


vec4 blur(vec2);


void main(void)
{
    vec4 col = blur(v_texCoord); //* v_fragmentColor.rgb;
    gl_FragColor = vec4(col) * v_fragmentColor;
}


vec4 blur(vec2 p)
{
    //sampleNum = 2.0;
    //blurRadius = 3.5;
    if (blurRadius > 0.0 && sampleNum > 1.0)
    {
        vec4 col = vec4(0);
        vec4 colaphale = vec4(0);
        vec2 unit = 1.0 / resolution.xy;
        
        float r = blurRadius;
        float sampleStep = r / sampleNum;
        
        float count = 0.0;
        
        for(float x = -r; x < r; x += sampleStep)
        {
            for(float y = -r; y < r; y += sampleStep)
            {
                float weight = (r - abs(x)) * (r - abs(y));
                col += texture2D(CC_Texture0, p + vec2(x * unit.x, y * unit.y)) * weight;
                count += weight;
                #ifdef  USE_ETC
                    colaphale += texture2D(CC_Texture1, p + vec2(x * unit.x, y * unit.y)) * weight;
                #endif
            }
        }
        #ifdef  USE_ETC
            col.a = colaphale.r;
        #endif
        return col / count;
    }
    vec4 texColor = texture2D(CC_Texture0, p);
    #ifdef  USE_ETC
        texColor = FormatEtc(texColor);
    #endif
    return texColor;
}

四、调用

SpriteBlur *bluredSpr = SpriteBlur::create(path);

bluredSpr->setPosition(ccp(sz.width/2,sz.height/2));

this->addChild(bluredSpr);


猜你喜欢

转载自blog.csdn.net/erweimac/article/details/79259732