摘要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 classSpriteBlur:publicCCSprite 04 { 05 public: 06 ~SpriteBlur(); 07 voidsetBlurSize(floatf); 08 boolinitWithTexture(CCTexture2D*texture,constCCRect&rect); 09 voiddraw(); 10 voidinitProgram(); 11 voidlistenBackToForeground(CCObject*obj); 12 13 staticSpriteBlur*create(constchar*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(constchar*pszFileName) 007 { 008 SpriteBlur*pRet=newSpriteBlur(); 009 if(pRet&&pRet->initWithFile(pszFileName)) 010 { 011 pRet->autorelease(); 012 } 013 else 014 { 015 CC_SAFE_DELETE(pRet); 016 } 017 018 returnpRet; 019 } 020 021 voidSpriteBlur::listenBackToForeground(CCObject*obj) 022 { 023 setShaderProgram(NULL); 024 initProgram(); 025 } 026 027 boolSpriteBlur::initWithTexture(CCTexture2D*texture,constCCRect&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 returntrue; 044 } 045 046 returnfalse; 047 } 048 049 voidSpriteBlur::initProgram() 050 { 051 GLchar*fragSource=(GLchar*)CCString::createWithContentsOfFile( 052 CCFileUtils::sharedFileUtils()->fullPathForFilename("Shaders/example_Blur.fsh").c_str())->getCString(); 053 CCGLProgram*pProgram=newCCGLProgram(); 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 voidSpriteBlur::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 longoffset=(long)&m_sQuad; 098 099 //vertex 100 intdiff=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 voidSpriteBlur::setBlurSize(floatf) 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 staticSpriteBlur*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=newSpriteBlur(); 09 if(pRet&&pRet->initWithTexture(pTexture,rect)) 10 { 11 pRet->autorelease(); 12 } 13 else 14 { 15 CC_SAFE_DELETE(pRet); 16 } 17 18 returnpRet; 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目录下