[cocos2d-x]对CCSprite进行高斯模糊
摘要cocos2d-x 2.2.1 中没有直接用于模糊精灵的类,但是在TestCpp里面的ShaderTest实现了高斯模糊。于是直接搬过来用就行了。 cocos2d-x高斯模糊精灵blur
你可以从下面的目录找到示例的源代码:
cocos2d-x-2.2.1\samples\Cpp\TestCpp\Classes\ShaderTest
SpriteBlur类用于实现高斯模糊,但并没有定义在ShaderTest.h中,打开ShaderTest.cpp,大概在488行有这个类的定义和实现:
01
//ShaderBlur
02
03
class
SpriteBlur:
public
CCSprite
04
{
05
public
:
06
~SpriteBlur();
07
void
setBlurSize(
float
f);
08
bool
initWithTexture(CCTexture2D*texture,
const
CCRect&rect);
09
void
draw();
10
void
initProgram();
11
void
listenBackToForeground(CCObject*obj);
12
13
static
SpriteBlur*create(
const
char
*pszFileName);
14
15
CCPointblur_;
16
GLfloatsub_[4];
17
18
GLuintblurLocation;
19
GLuintsubLocation;
20
};
实现:
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
CCSizes=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
ccBlendFuncblend=getBlendFunc();
084
ccGLBlendFunc(blend.src,blend.dst);
085
086
getShaderProgram()->use();
087
getShaderProgram()->setUniformsForBuiltins();
088
getShaderProgram()->setUniformLocationWith3f(blurLocation,blur_.x,blur_.y);
089
getShaderProgram()->setUniformLocationWith5fv(subLocation,sub_,1);
090
091
ccGLBindTexture2D(getTexture()->getName());
092
093
//
094
//Attributes
095
//
096
#definekQuadSizesizeof(m_sQuad.bl)
097
long
offset=(
long
)&m_sQuad;
098
099
//vertex
100
int
diff=offsetof(ccV3F_C4B_T2F,vertices);
101
glVertexAttribPointer(kCCVertexAttrib_Position,3,GL_FLOAT,GL_FALSE,kQuadSize,(
void
*)(offset+diff));
102
103
//texCoods
104
diff=offsetof(ccV3F_C4B_T2F,texCoords);
105
glVertexAttribPointer(kCCVertexAttrib_TexCoords,2,GL_FLOAT,GL_FALSE,kQuadSize,(
void
*)(offset+diff));
106
107
//color
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
CCSizes=getTexture()->getContentSizeInPixels();
120
121
blur_=ccp(1/s.width,1/s.height);
122
blur_=ccpMult(blur_,f);
123
}
好了,直接copy到你的program里面,不过有一点需要注意,就是他这个只能用一个文件(图片)create,如果需要用一个Texture初始化(因为有时候需要模糊即时的sprite),可以稍微改装一下,加一个函数:
1
static
SpriteBlur*createWithTexture(CCTexture2D*pTexture);
实现:
01
SpriteBlur*SpriteBlur::createWithTexture(CCTexture2D*pTexture)
02
{
03
CCAssert(pTexture!=NULL,
"Invalidtextureforsprite"
);
04
05
CCRectrect=CCRectZero;
06
rect.size=pTexture->getContentSize();
07
08
SpriteBlur*pRet=
new
SpriteBlur();
09
if
(pRet&&pRet->initWithTexture(pTexture,rect))
10
{
11
pRet->autorelease();
12
}
13
else
14
{
15
CC_SAFE_DELETE(pRet);
16
}
17
18
return
pRet;
19
}
用法:
1
SpriteBlur*bluredSpr=SpriteBlur::createWithTexture(tex);
2
bluredSpr->setPosition(ccp(sz.width/2,sz.height/2));
3
bluredSpr->setBlurSize(0.9f);
//这里稍微设小一点
4
addChild(bluredSpr);
效果:
注意:
他需要一个fsh文件(具体看它的实现),似乎是叠texture用的,找到example_Blur.fsh放到你的Resources\Shaders目录下
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。