该文主要是在百度搜索中,查找多人文档进行整理汇总:
在某些项目中可能会用到背景模糊效果。可能是显示一个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);