大佬教程收集整理的这篇文章主要介绍了在Cocos2d-x v3.x 中实现带颜色滤镜的Sprite,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
一、目的@H_675_13@
Cocos2d-x做项目时经常会碰到要对图片进行变色的需求,最常用的就是变灰了,就要让按钮变灰来表示当前的状态是不可点的。 但是Cocos2d-x的Sprite中是没有这个变灰支持的。那么,就要我们自己动手来扩展实现一个。我们让这个带变色功能的Sprite叫做FilterSprite。这个FilterSprite扩展了Sprite的功能:可以方便地变换颜色。
二、原理@H_675_13@
对图片进行颜色变换,就是对图片上的每个像素进行变换。要实现这个,要新创建一个fragmentShader,这个fragmentShader 比sprite的那个fragmentShader多了一个颜色变换矩阵。shader会让图片上每个像素与颜色变换矩阵进行相乘,输出新的像素值。
这个shader是这样的:
从shader上我们看到,“filterMat” 就是所谓的颜色变换矩阵,仅仅在原来像素输出前用它处理了一下:与待输出像素相乘。 这个shader是opengl层级的,要应用到coco2dx引擎中,我们要着手实现cocos2dx的FilterSprite类了。
三、实现@H_675_13@
实现这个FilterSprite注意几个要点:
引擎中一个shader对应一个GLProgram,所以这个带颜色滤镜的shader(称为filterShader)对应一个GLProgram(称为filterProgram)对象,在实际使用时,是用对GLProgram进行了封装的GLProgramState(称为filterProgramState)对象,FilterSprite对象的_glProgramState要设置成filterProgramState对象,在源码中FilterSprite的initWithTexture进行这个filterShader和filterProgram的关联。
在渲染时要将滤镜传递给shader程序,在源码中就是在onDraw回调时调用:
四、使用@H_675_13@
使用起来非常简单,只需要设置一个颜色矩阵,例如,如果要变灰就设置一个灰度矩阵,如果要恢复原貌就设置一个单位矩阵。
五、源码@H_675_13@
FilterSprite.h:@H_675_13@
#ifndef__FilterSpirte_h
#define__FilterSpirte_h
#include
"cocos2d.h"
USING_NS_Cc;
:
FilterSprite();
FilterSprite*createWithTexture(Texture2D*pTexturE);
FilterSprite*createWithTexture(Texture2D*pTexture,monospace!important; font-size:1em!important; min-height:inherit!important; BACkground:none!important">Rect&rect,
bool
@H_616_69@rotated=
false
@H_616_69@);
FilterSprite*createWithSpriteFrame(SpriteFrame*pSpriteFramE);
initWithTexture(Texture2D*pTexture,monospace!important; font-size:1em!important; min-height:inherit!important; BACkground:none!important">Rect&tRect);
virtual
draw(Renderer*renderer,monospace!important; font-size:1em!important; min-height:inherit!important; BACkground:none!important">Mat4&transform,uint32_tflags)override;
onDraw(
:1.1em!important; margin:0px!important; outline:0px!important; overflow:visible!important; padding:0px!important; position:static!important; right:auto!important; top:auto!important; vertical-align:baseline!important; width:auto!important; font-family:Consolas,uint32_tflags);
setFilterMat(cocos2d::Mat4matrixArray);
//to-do提供一个设置滤镜的方法
protected
@H_616_69@:
private
@H_616_69@:
cocos2d::Mat4m_uSpriteFilter;
};
#endif
|
@H_675_13@
FilterSprite.cpp:@H_675_13@
"FilterSprite.h"
FilterSprite::FilterSprite(
)
@H_353_109@m_uSpriteFilter=Mat4::IDENTITY;
}
FilterSprite::~FilterSprite()
}
FilterSprite*FilterSprite::create()
if
@H_616_69@(sprite&&sprite->init())
sprite->autorelease();
return
@H_616_69@sprite;
}
nullptr;
}
)FilterSprite();
(sprite&&sprite->initWithFile(fileName))
sprite->autorelease();
sprite;
}
nullptr;
}
Rect&rect)
)FilterSprite();
(sprite&&sprite->initWithFile(filename,rect))
sprite->autorelease();
sprite;
}
nullptr;
}
FilterSprite*FilterSprite::createWithTexture(Texture2D*pTexturE)
)FilterSprite();
Rectrect=Rect::ZERO;
rect.size=pTexture->getContentSize();
(sprite&&sprite->initWithTexture(pTexture,rect))
sprite->autorelease();
sprite;
}
nullptr;
}
FilterSprite*FilterSprite::createWithTexture(Texture2D*texture,monospace!important; font-size:1em!important; min-height:inherit!important; BACkground:none!important">rotated)
)FilterSprite();
(sprite&&sprite->initWithTexture(texture,rect))
sprite->autorelease();
sprite;
}
nullptr;
}
FilterSprite*FilterSprite::createWithSpriteFrame(SpriteFrame*spriteFramE)
)FilterSprite();
(sprite&&spriteFrame&&sprite->initWithSpriteFrame(spriteFramE))
sprite->autorelease();
sprite;
}
nullptr;
}
{
#
COCOS2D_DEBUG>0
sprintf
@H_616_69@(msg,
"InvalidspriteFramename:%s"
:1.1em!important; margin:0px!important; outline:0px!important; overflow:visible!important; padding:0px!important; position:static!important; right:auto!important; top:auto!important; vertical-align:baseline!important; width:auto!important; font-family:Consolas,spriteFramename.c_str());
#endif
createWithSpriteFrame(framE);
}
FilterSprite::initWithTexture(Texture2D*pTexture,monospace!important; font-size:1em!important; min-height:inherit!important; BACkground:none!important">Rect&tRect){
CC_BREAK_IF(!Sprite::initWithTexture(pTexture,tRect));
GLchar*pszFragsource=
"#ifdefGL_ES\n\
;\n\
#endif\n\
uniformsampler2Du_texture;\n\
varyingvec2v_texCoord;\n\
varyingvec4v_fragmentColor;\n\
uniformmat4fiterMat;\n\
)\n\
{\n\
:1.1em!important; margin:0px!important; outline:0px!important; overflow:visible!important; padding:0px!important; position:static!important; right:auto!important; top:auto!important; vertical-align:baseline!important; width:auto!important; font-family:Consolas,v_texCoord);\n\
gl_FragColor=fiterMat*value;\n\
}";
autoglprogramstate=GLProgramState::getOrCreateWithGLProgram(glprogram);
setGLProgramState(glprogramstatE);
;
}
FilterSprite::setFilterMat(cocos2d::Mat4matrixArray)
@H_353_109@m_uSpriteFilter=matrixArray;
}
FilterSprite::draw(Renderer*renderer,uint32_tflags)
_customcatommand.func=CC_CALLBACK_0(FilterSprite::onDraw,153)!important; BACkground:none!important">this
:1.1em!important; margin:0px!important; outline:0px!important; overflow:visible!important; padding:0px!important; position:static!important; right:auto!important; top:auto!important; vertical-align:baseline!important; width:auto!important; font-family:Consolas,transform,flags);
}
FilterSprite::onDraw(
:1.1em!important; margin:0px!important; outline:0px!important; overflow:visible!important; padding:0px!important; position:static!important; right:auto!important; top:auto!important; vertical-align:baseline!important; width:auto!important; font-family:Consolas,uint32_tflags)
autoglProgramState=getGLProgramState();
:1.1em!important; margin:0px!important; outline:0px!important; overflow:visible!important; padding:0px!important; position:static!important; right:auto!important; top:auto!important; vertical-align:baseline!important; width:auto!important; font-family:Consolas,m_uSpriteFilter);
glProgramState->apply(transform);
GL::blendFunc(_blendFunc.src,_blendFunc.dst);
GL::bindTexture2D(_texture->getName());
GL::enableVertexAttribs(GL::VERTEX_ATTRIB_FLAG_POS_COLOR_TEX);
//vertex
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION,3,GL_FLOAT,GL_falSE,kQuadSize,(
*)(offset+diff));
//texCoods
:1.1em!important; margin:0px!important; outline:0px!important; overflow:visible!important; padding:0px!important; position:static!important; right:auto!important; top:auto!important; vertical-align:baseline!important; width:auto!important; font-family:Consolas,texCoords);
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_TEX_COORD,2,monospace!important; font-size:1em!important; min-height:inherit!important; BACkground:none!important">*)(offset+diff));
//color
:1.1em!important; margin:0px!important; outline:0px!important; overflow:visible!important; padding:0px!important; position:static!important; right:auto!important; top:auto!important; vertical-align:baseline!important; width:auto!important; font-family:Consolas,colors);
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_COLOR,4,GL_UNSIGNED_BYTE,GL_TRUE,monospace!important; font-size:1em!important; min-height:inherit!important; BACkground:none!important">*)(offset+diff));
CC_INCREMENT_GL_DRAWN_BATCHES_AND_VERTICES(1,4);
}
|
以上是大佬教程为你收集整理的在Cocos2d-x v3.x 中实现带颜色滤镜的Sprite全部内容,希望文章能够帮你解决在Cocos2d-x v3.x 中实现带颜色滤镜的Sprite所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。
文章评论 (3)