cocos中label无法使用shader

主要原因是cocos中没有原本支持多重滤镜,在label的实现中,

默认使用了label_normal的shader

setGLProgramState(GLProgramState::getOrCreateWithGLProgramName(GLProgram::SHADER_NAME_LABEL_NORMAL));

Cocos2d-x 中的 shader 支持位于几个类中,它们是:

  • shaders/CCGLProgram
  • shaders/CCShaderCache
  • shaders/ccShaders
  • shaders/ccGLStateCache

其中, CCGLPrgram 负责 shader 的生成、编译、缓存、attribute 的 bind、uniform 设置等等工作,是非常重要的一个类。在这个类中, m_uVertShader 和 m_uFragShader 这两个用来指定 shader 位置索引值的变量值定为 0,且没有地方进行修改。

这也就是说,如果不对 CCGLProgram 进行 hack ,是无法实现多重shader的。

那么,能不能使用多个 CCGLProgram 实例实现多重 shader 呢?

从 CCNode 的源码来看,每个 CCNode 实例都持有一个 m_pShaderProgram 成员变量,所有的渲染操作都是基于这一个变量来实现。那么也就是说,在不对 CCNode 进行 hack 的前提下,也无法实现多重渲染。

使用 CCRenderTexture (参考自某网上文章)

CCRenderTexture 可以用来渲染屏幕外的内容。我们一般使用它将纹理渲染到一块屏幕之外的区域中,然后对纹理进行进一步操作。在需要的时候,再将其渲染到屏幕上。

我们可以利用 CCRenderTexture 来实现多重滤镜支持。

在下面的代码中,CCHBlurFilter 和 CCVBlurFilter 分别负责实现横向模糊和纵向模糊。而CCFilteredSprite 则负责根据 Filter 进行渲染。

//建立横向和纵向模糊滤镜
CCHBlurFilter* __hblurFilter = CCHBlurFilter::create(0.02f);
CCBlurBaseFilter* __vblurFilter = CCVBlurFilter::create(0.02f);
//对helloworld.pn使用横向模糊滤镜
CCSprite* __hs = CCFilteredSprite::create("helloworld.png", __hblurFilter);
__hs->setAnchorPoint(ccp(0,0));
CCSize __size = __hs->getContentSize();
//将进行过横向模糊的纹理渲染到CCRenderTexture中
CCRenderTexture* __canva = CCRenderTexture::create(__size.width, __size.height);
__canva->begin();
__hs->visit();
__canva->end();
//根据CCRenderTexture中的纹理创建新的纹理
CCTexture2D* __tex2 = new CCTexture2D();
__tex2->initWithImage(__canva->newCCImage(true));
__tex2->autorelease();
//根据新的纹理创建最终的CCFilteredSprite,应用纵向模糊滤镜
CCSprite* __final = CCFilteredSprite::createWithTexture(__tex2, __vblurFilter);
__final->setAnchorPoint(ccp(0,0));
__final->setPosition(ccp(0,0));
//显示最终效果
this->addChild(__final);

如果把渲染的功能集成到 CCFilteredSprite 中,就可以简化调用,例如:

CCSprite* __final = CCFilteredSprite::create("helloworld.png", 
    CCArray::create(__hblurFilter, __vblurFilter, NULL));
this->addChild(__final);

猜你喜欢

转载自blog.csdn.net/wanziqin/article/details/85710335