利用CCSpriteBatchNode来批量渲染CCSprite的时候无法设置shader的问题
2014-05-28 18:44
344 查看
之前按着网上的设置,已经可以将CCSprite设置成灰色(不知道怎么设置的同学可以随便在X度搜索一下,以下给出随便一个链接http://my.oschina.net/u/1430085/blog/191673,有兴趣的同学可以再看一下),
但是项目中有一个类继承了CCSprite,相当于一个九宫格图片,这些图片的生成是通过CCSpriteBatchNode来批量渲染的,对于这些节点,无法设置shader。代码已经调用,可是不起作用,通过查看CCSpriteBatchNode的代码,看到了原因
bool CCSpriteBatchNode::initWithTexture(CCTexture2D *tex,unsignedint capacity)
{
m_blendFunc.src =CC_BLEND_SRC;
m_blendFunc.dst =CC_BLEND_DST;
m_pobTextureAtlas =
new CCTextureAtlas();
if (0 == capacity)
{
capacity = kDefaultSpriteBatchCapacity;
}
m_pobTextureAtlas->initWithTexture(tex, capacity);
updateBlendFunc();
// no lazy alloc in this node
m_pChildren = newCCArray();
m_pChildren->initWithCapacity(capacity);
m_pobDescendants =
new CCArray();
m_pobDescendants->initWithCapacity(capacity);
setShaderProgram(CCShaderCache::sharedShaderCache()->programForKey(kCCShader_PositionTextureColor));
return true;
}
通过上面的代码,我们可以看到在CCSpriteBatchNode中,已经对shader进行了设置,那么通过这个节点所渲染的CCSprite,再怎么设置也没有用。
我就做了一个实验,将kCCShader_PositionTextureColor换成了ccPositionTextureGray_frag(根据你自己写得不同shader不同不同,这个是引用上面的链接的,我自己项目里写的是kCCShader_PositionTextureGray),然后所有通过CCSpriteBatchNode生成的CCSprite都会变成灰色。那么下面的问题就在于如何让CCSprite设置shader的时候让它的CCSpriteBatchNode也改变,其实就是改变CCSpriteBatchNode的shader。
继续阅读CCSpriteBatchNode的代码:
// draw
void CCSpriteBatchNode::draw(void)
{
CC_PROFILER_START("CCSpriteBatchNode - draw");
// Optimization: Fast Dispatch
if(m_pobTextureAtlas->getTotalQuads() ==0 )
{
return;
}
CC_NODE_DRAW_SETUP();
arrayMakeObjectsPerformSelector(m_pChildren,updateTransform,CCSprite*);
ccGLBlendFunc(
m_blendFunc.src, m_blendFunc.dst );
m_pobTextureAtlas->drawQuads();
CC_PROFILER_STOP("CCSpriteBatchNode - draw");
}
在这个函数中我看到CCSpriteBatchNode会调用CCSprite的updateTransform,方法,再进入到CCSprite的updateTransform方法中:
void CCSprite::updateTransform(void)
{
CCAssert(m_pobBatchNode,"updateTransform is only valid when CCSprite is being rendered using an CCSpriteBatchNode");
噢~原来是这样,只有CCSpriteBatchNode会调用这个方法,那么下一个问题就是如何在这个方法中设置CCSpriteBatchNode的shader。
在利用CCSpriteBatchNode生成CCSprite的时候,CCSpriteBatchNode会对CCSprite设置CCSpriteBatchNode:
void CCSpriteBatchNode::insertChild(CCSprite *pSprite,unsignedint uIndex)
{
pSprite->setBatchNode(this);
pSprite->setAtlasIndex(uIndex);
pSprite->setDirty(true);
if(m_pobTextureAtlas->getTotalQuads() ==m_pobTextureAtlas->getCapacity())
{
increaseAtlasCapacity();
}
ccV3F_C4B_T2F_Quad quad = pSprite->getQuad();
m_pobTextureAtlas->insertQuad(&quad, uIndex);
ccArray *descendantsData =
m_pobDescendants->data;
ccArrayInsertObjectAtIndex(descendantsData, pSprite, uIndex);
// update indices
unsigned int i = uIndex+1;
CCSprite* pChild = NULL;
for(; i<descendantsData->num; i++){
pChild = (CCSprite*)descendantsData->arr[i];
pChild->setAtlasIndex(pChild->getAtlasIndex() +1);
}
// add children recursively
CCObject* pObj = NULL;
CCARRAY_FOREACH(pSprite->getChildren(), pObj)
{
pChild = (CCSprite*)pObj;
unsigned int idx =atlasIndexForChild(pChild, pChild->getZOrder());
insertChild(pChild, idx);
}
}
这样就可以在CCSprite中获取到生成自己的CCSpriteBatchNode了
最后,在setGray(isGray) (这个函数需要你自己写,上面的例子也会提到)中对CCSpriteBatchNode进行设置就好了
getBatchNode()->setShaderProgram(CCShaderCache::sharedShaderCache()->programForKey(kCCShader_PositionTextureGray));
大功告成~
但是项目中有一个类继承了CCSprite,相当于一个九宫格图片,这些图片的生成是通过CCSpriteBatchNode来批量渲染的,对于这些节点,无法设置shader。代码已经调用,可是不起作用,通过查看CCSpriteBatchNode的代码,看到了原因
bool CCSpriteBatchNode::initWithTexture(CCTexture2D *tex,unsignedint capacity)
{
m_blendFunc.src =CC_BLEND_SRC;
m_blendFunc.dst =CC_BLEND_DST;
m_pobTextureAtlas =
new CCTextureAtlas();
if (0 == capacity)
{
capacity = kDefaultSpriteBatchCapacity;
}
m_pobTextureAtlas->initWithTexture(tex, capacity);
updateBlendFunc();
// no lazy alloc in this node
m_pChildren = newCCArray();
m_pChildren->initWithCapacity(capacity);
m_pobDescendants =
new CCArray();
m_pobDescendants->initWithCapacity(capacity);
setShaderProgram(CCShaderCache::sharedShaderCache()->programForKey(kCCShader_PositionTextureColor));
return true;
}
通过上面的代码,我们可以看到在CCSpriteBatchNode中,已经对shader进行了设置,那么通过这个节点所渲染的CCSprite,再怎么设置也没有用。
我就做了一个实验,将kCCShader_PositionTextureColor换成了ccPositionTextureGray_frag(根据你自己写得不同shader不同不同,这个是引用上面的链接的,我自己项目里写的是kCCShader_PositionTextureGray),然后所有通过CCSpriteBatchNode生成的CCSprite都会变成灰色。那么下面的问题就在于如何让CCSprite设置shader的时候让它的CCSpriteBatchNode也改变,其实就是改变CCSpriteBatchNode的shader。
继续阅读CCSpriteBatchNode的代码:
// draw
void CCSpriteBatchNode::draw(void)
{
CC_PROFILER_START("CCSpriteBatchNode - draw");
// Optimization: Fast Dispatch
if(m_pobTextureAtlas->getTotalQuads() ==0 )
{
return;
}
CC_NODE_DRAW_SETUP();
arrayMakeObjectsPerformSelector(m_pChildren,updateTransform,CCSprite*);
ccGLBlendFunc(
m_blendFunc.src, m_blendFunc.dst );
m_pobTextureAtlas->drawQuads();
CC_PROFILER_STOP("CCSpriteBatchNode - draw");
}
在这个函数中我看到CCSpriteBatchNode会调用CCSprite的updateTransform,方法,再进入到CCSprite的updateTransform方法中:
void CCSprite::updateTransform(void)
{
CCAssert(m_pobBatchNode,"updateTransform is only valid when CCSprite is being rendered using an CCSpriteBatchNode");
噢~原来是这样,只有CCSpriteBatchNode会调用这个方法,那么下一个问题就是如何在这个方法中设置CCSpriteBatchNode的shader。
在利用CCSpriteBatchNode生成CCSprite的时候,CCSpriteBatchNode会对CCSprite设置CCSpriteBatchNode:
void CCSpriteBatchNode::insertChild(CCSprite *pSprite,unsignedint uIndex)
{
pSprite->setBatchNode(this);
pSprite->setAtlasIndex(uIndex);
pSprite->setDirty(true);
if(m_pobTextureAtlas->getTotalQuads() ==m_pobTextureAtlas->getCapacity())
{
increaseAtlasCapacity();
}
ccV3F_C4B_T2F_Quad quad = pSprite->getQuad();
m_pobTextureAtlas->insertQuad(&quad, uIndex);
ccArray *descendantsData =
m_pobDescendants->data;
ccArrayInsertObjectAtIndex(descendantsData, pSprite, uIndex);
// update indices
unsigned int i = uIndex+1;
CCSprite* pChild = NULL;
for(; i<descendantsData->num; i++){
pChild = (CCSprite*)descendantsData->arr[i];
pChild->setAtlasIndex(pChild->getAtlasIndex() +1);
}
// add children recursively
CCObject* pObj = NULL;
CCARRAY_FOREACH(pSprite->getChildren(), pObj)
{
pChild = (CCSprite*)pObj;
unsigned int idx =atlasIndexForChild(pChild, pChild->getZOrder());
insertChild(pChild, idx);
}
}
这样就可以在CCSprite中获取到生成自己的CCSpriteBatchNode了
最后,在setGray(isGray) (这个函数需要你自己写,上面的例子也会提到)中对CCSpriteBatchNode进行设置就好了
getBatchNode()->setShaderProgram(CCShaderCache::sharedShaderCache()->programForKey(kCCShader_PositionTextureGray));
大功告成~
相关文章推荐
- Cocos2d-x 2.x CCSprite 灰白图的生成(利用shader设置)
- 【转】Cocos2d-x 2.x CCSprite 灰白图的生成(利用shader设置)——2013-08-27 21
- android webview设置缩放按钮时候无法显示问题
- Cocos2d-x 2.x CCSprite 灰白图的生成(利用shader设置)
- SQLServer 数据库变成单个用户后无法访问问题的解决方法[在手动还原该数据库的时候,设置为单用户模式,然后其他用户访问的时候就。。。。]
- thinkphp使用view的时候无法利用phpexcel导出数据问题的解决
- SGA设置错误导致数据库无法连接问题
- 解决windows2000中无法设置默认输入法的问题
- 关于利用模板生成静态页面的时候出现乱码的问题
- MIME设置问题导致网站上某些类型文件无法下载(以ISO为例)
- java -jar参数运行打包好的jar应用程序的时候发现应用程序无法找到classpath下设置好的第三方类库?
- 刚发现了一个问题,关于vs2005 datagridview的,我发现在设计行标头的HeaderCell.Value的时候要是设置RowTemplate.Height 的值>= 17则行标头的那个黑三角就显示出来了,要是小于17就不能显示了,想问问大家,是怎么回事?
- 今天使用vs2005时候,发现了这个问题“无法附加。绑定句柄无效”。参考下面的图片
- VC6路径设置错误引发的无法调试的奇怪问题
- 解决在查看里无法设置“显示所有文件和文件夹”及“隐藏受保护的操作系统文件”的问题
- 维度用法设置不当导致的数据无法正确聚合的问题及解决
- FLASH项目上传服务器无法播放FLV-MIME设置问题解决
- 关于在Word中无法设置中文效果问题
- asp.net 2.0在使用了mater page的情况下Form defaultbutton无法设置的问题
- 开机的时候如果出现提示$home/.dmrc无法写入 问题解决方法