001
SpriteBlur::~SpriteBlur()
002
{
003
CCNotificationCenter::sharedNotificationCenter()->removeObserver(
this
, EVENT_COME_TO_FOREGROUND);
004
}
005
006
SpriteBlur* SpriteBlur::create(
const
char
*pszFileName)
007
{
008
SpriteBlur* pRet =
new
SpriteBlur();
009
if
(pRet && pRet->initWithFile(pszFileName))
010
{
011
pRet->autorelease();
012
}
013
else
014
{
015
CC_SAFE_DELETE(pRet);
016
}
017
018
return
pRet;
019
}
020
021
void
SpriteBlur::listenBackToForeground(CCObject *obj)
022
{
023
setShaderProgram(NULL);
024
initProgram();
025
}
026
027
bool
SpriteBlur::initWithTexture(CCTexture2D* texture,
const
CCRect& rect)
028
{
029
if
( CCSprite::initWithTexture(texture, rect) )
030
{
031
CCNotificationCenter::sharedNotificationCenter()->addObserver(
this
,
032
callfuncO_selector(SpriteBlur::listenBackToForeground),
033
EVENT_COME_TO_FOREGROUND,
034
NULL);
035
036
CCSize s = getTexture()->getContentSizeInPixels();
037
038
blur_ = ccp(1/s.width, 1/s.height);
039
sub_[0] = sub_[1] = sub_[2] = sub_[3] = 0;
040
041
this
->initProgram();
042
043
return
true
;
044
}
045
046
return
false
;
047
}
048
049
void
SpriteBlur::initProgram()
050
{
051
GLchar * fragSource = (GLchar*) CCString::createWithContentsOfFile(
052
CCFileUtils::sharedFileUtils()->fullPathForFilename(
"Shaders/example_Blur.fsh"
).c_str())->getCString();
053
CCGLProgram* pProgram =
new
CCGLProgram();
054
pProgram->initWithVertexShaderByteArray(ccPositionTextureColor_vert, fragSource);
055
setShaderProgram(pProgram);
056
pProgram->release();
057
058
CHECK_GL_ERROR_DEBUG();
059
060
getShaderProgram()->addAttribute(kCCAttributeNamePosition, kCCVertexAttrib_Position);
061
getShaderProgram()->addAttribute(kCCAttributeNameColor, kCCVertexAttrib_Color);
062
getShaderProgram()->addAttribute(kCCAttributeNameTexCoord, kCCVertexAttrib_TexCoords);
063
064
CHECK_GL_ERROR_DEBUG();
065
066
getShaderProgram()->link();
067
068
CHECK_GL_ERROR_DEBUG();
069
070
getShaderProgram()->updateUniforms();
071
072
CHECK_GL_ERROR_DEBUG();
073
074
subLocation = glGetUniformLocation( getShaderProgram()->getProgram(),
"substract"
);
075
blurLocation = glGetUniformLocation( getShaderProgram()->getProgram(),
"blurSize"
);
076
077
CHECK_GL_ERROR_DEBUG();
078
}
079
080
void
SpriteBlur::draw()
081
{
082
ccGLEnableVertexAttribs(kCCVertexAttribFlag_PosColorTex );
083
ccBlendFunc blend = getBlendFunc();
084
ccGLBlendFunc(blend.src, blend.dst);
085
086
getShaderProgram()->use();
087
getShaderProgram()->setUniformsForBuiltins();
088
getShaderProgram()->setUniformLocationWith2f(blurLocation, blur_.x, blur_.y);
089
getShaderProgram()->setUniformLocationWith4fv(subLocation, sub_, 1);
090
091
ccGLBindTexture2D( getTexture()->getName());
092
093
094
095
096
#define kQuadSize sizeof(m_sQuad.bl)
097
long
offset = (
long
)&m_sQuad;
098
099
100
int
diff = offsetof( ccV3F_C4B_T2F, vertices);
101
glVertexAttribPointer(kCCVertexAttrib_Position, 3, GL_FLOAT, GL_FALSE, kQuadSize, (
void
*) (offset + diff));
102
103
104
diff = offsetof( ccV3F_C4B_T2F, texCoords);
105
glVertexAttribPointer(kCCVertexAttrib_TexCoords, 2, GL_FLOAT, GL_FALSE, kQuadSize, (
void
*)(offset + diff));
106
107
108
diff = offsetof( ccV3F_C4B_T2F, colors);
109
glVertexAttribPointer(kCCVertexAttrib_Color, 4, GL_UNSIGNED_BYTE, GL_TRUE, kQuadSize, (
void
*)(offset + diff));
110
111
112
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
113
114
CC_INCREMENT_GL_DRAWS(1);
115
}
116
117
void
SpriteBlur::setBlurSize(
float
f)
118
{
119
CCSize s = getTexture()->getContentSizeInPixels();
120
121
blur_ = ccp(1/s.width, 1/s.height);
122
blur_ = ccpMult(blur_,f);
123
}