摘要 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
|
CCPoint blur_;
|
16
|
GLfloat sub_[4];
|
17
|
18
|
GLuint blurLocation;
|
19
|
GLuint subLocation;
|
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
|
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
|
// Attributes
|
095
|
//
|
096
|
#define kQuadSize sizeof(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
|
CCSize s = 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, "Invalid texture for sprite" );
|
04
|
05
|
CCRect rect = 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目录下
时间: 2024-09-20 10:33:09