摘要 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行有这个类的定义和实现: 03 | class SpriteBlur : public CCSprite | 07 | void setBlurSize( float f); | 08 | bool initWithTexture(CCTexture2D* texture, const CCRect& rect); | 11 | void listenBackToForeground(CCObject *obj); | 13 | static SpriteBlur* create( const char *pszFileName); | 实现: 001 | SpriteBlur::~SpriteBlur() | 003 | CCNotificationCenter::sharedNotificationCenter()->removeObserver( this , EVENT_COME_TO_FOREGROUND); | 006 | SpriteBlur* SpriteBlur::create( const char *pszFileName) | 008 | SpriteBlur* pRet = new SpriteBlur(); | 009 | if (pRet && pRet->initWithFile(pszFileName)) | 015 | CC_SAFE_DELETE(pRet); | 021 | void SpriteBlur::listenBackToForeground(CCObject *obj) | 023 | setShaderProgram(NULL); | 027 | bool SpriteBlur::initWithTexture(CCTexture2D* texture, const CCRect& rect) | 029 | if ( CCSprite::initWithTexture(texture, rect) ) | 031 | CCNotificationCenter::sharedNotificationCenter()->addObserver( this , | 032 | callfuncO_selector(SpriteBlur::listenBackToForeground), | 033 | EVENT_COME_TO_FOREGROUND, | 036 | CCSize s = getTexture()->getContentSizeInPixels(); | 038 | blur_ = ccp(1/s.width, 1/s.height); | 039 | sub_[0] = sub_[1] = sub_[2] = sub_[3] = 0; | 049 | void SpriteBlur::initProgram() | 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); | 058 | CHECK_GL_ERROR_DEBUG(); | 060 | getShaderProgram()->addAttribute(kCCAttributeNamePosition, kCCVertexAttrib_Position); | 061 | getShaderProgram()->addAttribute(kCCAttributeNameColor, kCCVertexAttrib_Color); | 062 | getShaderProgram()->addAttribute(kCCAttributeNameTexCoord, kCCVertexAttrib_TexCoords); | 064 | CHECK_GL_ERROR_DEBUG(); | 066 | getShaderProgram()->link(); | 068 | CHECK_GL_ERROR_DEBUG(); | 070 | getShaderProgram()->updateUniforms(); | 072 | CHECK_GL_ERROR_DEBUG(); | 074 | subLocation = glGetUniformLocation( getShaderProgram()->getProgram(), "substract" ); | 075 | blurLocation = glGetUniformLocation( getShaderProgram()->getProgram(), "blurSize" ); | 077 | CHECK_GL_ERROR_DEBUG(); | 080 | void SpriteBlur::draw() | 082 | ccGLEnableVertexAttribs(kCCVertexAttribFlag_PosColorTex ); | 083 | ccBlendFunc blend = getBlendFunc(); | 084 | ccGLBlendFunc(blend.src, blend.dst); | 086 | getShaderProgram()->use(); | 087 | getShaderProgram()->setUniformsForBuiltins(); | 088 | getShaderProgram()->setUniformLocationWith3f(blurLocation, blur_.x, blur_.y); | 089 | getShaderProgram()->setUniformLocationWith5fv(subLocation, sub_, 1); | 091 | ccGLBindTexture2D( getTexture()->getName()); | 096 | #define kQuadSize sizeof(m_sQuad.bl) | 097 | long offset = ( long )&m_sQuad; | 100 | int diff = offsetof( ccV3F_C4B_T2F, vertices); | 101 | glVertexAttribPointer(kCCVertexAttrib_Position, 3, GL_FLOAT, GL_FALSE, kQuadSize, ( void *) (offset + diff)); | 104 | diff = offsetof( ccV3F_C4B_T2F, texCoords); | 105 | glVertexAttribPointer(kCCVertexAttrib_TexCoords, 2, GL_FLOAT, GL_FALSE, kQuadSize, ( void *)(offset + diff)); | 108 | diff = offsetof( ccV3F_C4B_T2F, colors); | 109 | glVertexAttribPointer(kCCVertexAttrib_Color, 4, GL_UNSIGNED_BYTE, GL_TRUE, kQuadSize, ( void *)(offset + diff)); | 112 | glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); | 114 | CC_INCREMENT_GL_DRAWS(1); | 117 | void SpriteBlur::setBlurSize( float f) | 119 | CCSize s = getTexture()->getContentSizeInPixels(); | 121 | blur_ = ccp(1/s.width, 1/s.height); | 122 | blur_ = ccpMult(blur_,f); | 好了,直接copy到你的program里面,不过有一点需要注意,就是他这个只能用一个文件(图片)create,如果需要用一个Texture初始化(因为有时候需要模糊即时的sprite),可以稍微改装一下,加一个函数: 1 | static SpriteBlur* createWithTexture(CCTexture2D *pTexture); | 实现: 01 | SpriteBlur* SpriteBlur::createWithTexture(CCTexture2D *pTexture) | 03 | CCAssert(pTexture != NULL, "Invalid texture for sprite" ); | 05 | CCRect rect = CCRectZero; | 06 | rect.size = pTexture->getContentSize(); | 08 | SpriteBlur* pRet = new SpriteBlur(); | 09 | if (pRet && pRet->initWithTexture(pTexture,rect)) | 用法: 1 | SpriteBlur *bluredSpr = SpriteBlur::createWithTexture(tex); | 2 | bluredSpr->setPosition(ccp(sz.width/2,sz.height/2)); | 3 | bluredSpr->setBlurSize(0.9f); | 效果: 注意: 他需要一个fsh文件(具体看它的实现),似乎是叠texture用的,找到example_Blur.fsh放到你的Resources\Shaders目录下
|