cocos2d-x 2.x版本文字描边研究01_使用shader描边
来源:互联网 发布:如何投诉广电网络 编辑:程序博客网 时间:2024/06/06 17:59
由于Cocos2d-x 2.x版本对描边支持的不好,3.X的基于Freetype的字库的描边效果还是不错的,但项目用的是旧版本引擎,又需要用到描边字,最近也研究了几种描边的方法,想分享一下。
在网上找了很多种描边的方式,各有优劣,有的描边效果很不错,而有的效果稍差但绘制效率更高。这篇文章讲解其中一种基于Shader的描边方法。
“云风”大哥的ejoy2d引擎中提供了一种效率很高的描边算法,使用ejoy2d进行描边时,有不错的效果,但是我集成到了cocos2dx中,描边效果不太明显,可能是与生成的纹理有关系,如果对描边的效果要求不高,可以考虑用一下这个描边效果。
描边的原理参考云风的博客,http://blog.codingnow.com/2013/09/edge_font.html
参考的ejoy2d的描边shader,可以去github上查看源码,https://github.com/ejoy/ejoy2d
描边shader如下:
/* * LICENSE ??? */#ifdef GL_ESprecision highp float;#endifuniform sampler2D u_texture;varying vec2 v_texCoord;varying vec4 v_fragmentColor;uniform vec4 u_effectColor;void main() { float c = texture2D(u_texture, v_texCoord).w; float alpha = clamp(c, 0.0, 0.5) * 2.0; float color = (clamp(c, 0.5, 1.0) - 0.5) * 2.0; gl_FragColor.xyz = (v_fragmentColor.xyz + u_effectColor.xyz) * color; gl_FragColor.w = alpha; gl_FragColor *= v_fragmentColor.w; gl_FragColor *= v_fragmentColor.w; }
我封装了一个StrokeLabel类来对cocos2dx的CCLabelTTF进行了绘制的修改,增加了使用自有的shader进行着色的逻辑。
//// StrokeLabel.h// StrokeLabel_01//// Created by cc on 15/1/27.////#ifndef __StrokeLabel_01__StrokeLabel__#define __StrokeLabel_01__StrokeLabel__#include "CCLabelTTFLoader.h"USING_NS_CC;class StrokeLabel : public CCLabelTTF { private: //描边宽度 float m_strokeSize; //描边效果颜色 ccColor4B m_effectColor; ccColor4F m_effectColorF; //文本颜色 ccColor4F m_textColorF; ccColor4B m_textColor; //描边颜色值,传入shader的全局变量 GLuint m_uniformEffectColor; public: #pragma mark <构造 && 析构> StrokeLabel(); ~StrokeLabel(); #pragma mark <创建 && 初始化> /** * 创建描边字 * * @param content 文本内容 * @param fontName 字体 * @param fontSize 字号 * @param textColor 文本颜色 * @param strokeColor 描边颜色 * @param strokeSize 描边宽度 * * @return 描边字 */ static StrokeLabel* createWithAttribute(const std::string& content, const std::string& fontName, float fontSize, const ccColor3B& textColor, const ccColor3B& strokeColor, float strokeSize); /** * 初始化描边字 * * @param content 文本内容 * @param fontName 字体 * @param fontSize 字号 * @param textColor 文本颜色 * @param strokeColor 描边颜色 * @param strokeSize 描边宽度 * * @return true: 初始化成功 false: 初始化失败 */ bool initWithAttribute(const std::string& content, const std::string& fontName, float fontSize, const ccColor3B& textColor, const ccColor3B& strokeColor, float strokeSize); /** * 更新Shader程序 */ void updateShaderProgram(); /** * 绘制 */ virtual void draw();};#endif /* defined(__StrokeLabel_01__StrokeLabel__) */
//// StrokeLabel.cpp// StrokeLabel_01//// Created by cc on 15/1/27.////#include "StrokeLabel.h"StrokeLabel::StrokeLabel(): m_strokeSize(0), m_uniformEffectColor(0) { }StrokeLabel::~StrokeLabel() { }long long int getNowTime() { struct timeval tv; gettimeofday(&tv, NULL); long long int nowTime = ((long long int)tv.tv_sec) * 1000 + tv.tv_usec / 1000; return nowTime;}/** * 创建描边字 * * @param content 文本内容 * @param fontName 字体 * @param fontSize 字号 * @param textColor 文本颜色 * @param strokeColor 描边颜色 * @param strokeSize 描边宽度 * * @return 描边字 */StrokeLabel* StrokeLabel::createWithAttribute(const std::string& content, const std::string& fontName, float fontSize, const ccColor3B& textColor, const ccColor3B& strokeColor, float strokeSize) { StrokeLabel *pRet = new StrokeLabel(); if (pRet && pRet->initWithAttribute(content, fontName, fontSize, textColor, strokeColor, strokeSize)) { pRet->autorelease(); return pRet; } CC_SAFE_DELETE(pRet); return NULL;}/** * 初始化描边字 * * @param content 文本内容 * @param fontName 字体 * @param fontSize 字号 * @param textColor 文本颜色 * @param strokeColor 描边颜色 * @param strokeSize 描边宽度 * * @return true: 初始化成功 false: 初始化失败 */bool StrokeLabel::initWithAttribute(const std::string& content, const std::string& fontName, float fontSize, const ccColor3B& textColor, const ccColor3B& strokeColor, float strokeSize) { if (!CCLabelTTF::initWithString(content.c_str(), fontName.c_str(), fontSize)) { return false; } m_textColor = ccc4(textColor.r, textColor.g, textColor.b, 255); m_textColorF.r = m_textColor.r / 255.0f; m_textColorF.g = m_textColor.g / 255.0f; m_textColorF.b = m_textColor.b / 255.0f; m_textColorF.a = m_textColor.a / 255.0f; m_effectColor = ccc4(strokeColor.r, strokeColor.g, strokeColor.b, 255);; m_effectColorF.r = m_effectColor.r / 255.0f; m_effectColorF.g = m_effectColor.g / 255.0f; m_effectColorF.b = m_effectColor.b / 255.0f; m_effectColorF.a = m_effectColor.a / 255.0f; this->setColor(textColor); this->updateShaderProgram(); return true;}/** * 更新Shader程序 */void StrokeLabel::updateShaderProgram() { const GLchar* fragmentSource = (GLchar*)CCString::createWithContentsOfFile(CCFileUtils::sharedFileUtils()->fullPathForFilename("Label_outline1.frag").c_str())->getCString(); CCGLProgram* pProgram = new CCGLProgram(); pProgram->initWithVertexShaderByteArray(ccPositionTextureColor_vert, fragmentSource); setShaderProgram(pProgram); pProgram->release(); CHECK_GL_ERROR_DEBUG(); getShaderProgram()->addAttribute(kCCAttributeNamePosition, kCCVertexAttrib_Position); getShaderProgram()->addAttribute(kCCAttributeNameColor, kCCVertexAttrib_Color); getShaderProgram()->addAttribute(kCCAttributeNameTexCoord, kCCVertexAttrib_TexCoords); CHECK_GL_ERROR_DEBUG(); getShaderProgram()->link(); CHECK_GL_ERROR_DEBUG(); getShaderProgram()->updateUniforms(); m_uniformEffectColor = glGetUniformLocation(getShaderProgram()->getProgram(), "u_effectColor"); }void StrokeLabel::draw() { long long int startTime = getNowTime(); CC_PROFILER_START_CATEGORY(kCCProfilerCategorySprite, "CCSprite - draw"); CCAssert(!m_pobBatchNode, "If CCSprite is being rendered by CCSpriteBatchNode, CCSprite#draw SHOULD NOT be called"); CC_NODE_DRAW_SETUP(); ccGLBlendFunc( m_sBlendFunc.src, m_sBlendFunc.dst ); getShaderProgram()->use(); getShaderProgram()->setUniformLocationWith4f(m_uniformEffectColor, m_effectColorF.r, m_effectColorF.g, m_effectColorF.b,m_effectColorF.a); getShaderProgram()->setUniformsForBuiltins(); ccGLBindTexture2D( m_pobTexture->getName() ); ccGLEnableVertexAttribs( kCCVertexAttribFlag_PosColorTex ); #define kQuadSize sizeof(m_sQuad.bl)#ifdef EMSCRIPTEN long offset = 0; setGLBufferData(&m_sQuad, 4 * kQuadSize, 0);#else long offset = (long)&m_sQuad;#endif // EMSCRIPTEN // vertex int diff = offsetof( ccV3F_C4B_T2F, vertices); glVertexAttribPointer(kCCVertexAttrib_Position, 3, GL_FLOAT, GL_FALSE, kQuadSize, (void*) (offset + diff)); // texCoods diff = offsetof( ccV3F_C4B_T2F, texCoords); glVertexAttribPointer(kCCVertexAttrib_TexCoords, 2, GL_FLOAT, GL_FALSE, kQuadSize, (void*)(offset + diff)); // color diff = offsetof( ccV3F_C4B_T2F, colors); glVertexAttribPointer(kCCVertexAttrib_Color, 4, GL_UNSIGNED_BYTE, GL_TRUE, kQuadSize, (void*)(offset + diff)); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); CHECK_GL_ERROR_DEBUG(); #if CC_SPRITE_DEBUG_DRAW == 1 // draw bounding box CCPoint vertices[4]={ ccp(m_sQuad.tl.vertices.x,m_sQuad.tl.vertices.y), ccp(m_sQuad.bl.vertices.x,m_sQuad.bl.vertices.y), ccp(m_sQuad.br.vertices.x,m_sQuad.br.vertices.y), ccp(m_sQuad.tr.vertices.x,m_sQuad.tr.vertices.y), }; ccDrawPoly(vertices, 4, true);#elif CC_SPRITE_DEBUG_DRAW == 2 // draw texture box CCSize s = this->getTextureRect().size; CCPoint offsetPix = this->getOffsetPosition(); CCPoint vertices[4] = { ccp(offsetPix.x,offsetPix.y), ccp(offsetPix.x+s.width,offsetPix.y), ccp(offsetPix.x+s.width,offsetPix.y+s.height), ccp(offsetPix.x,offsetPix.y+s.height) }; ccDrawPoly(vertices, 4, true);#endif // CC_SPRITE_DEBUG_DRAW CC_INCREMENT_GL_DRAWS(1); CC_PROFILER_STOP_CATEGORY(kCCProfilerCategorySprite, "CCSprite - draw"); long long int endTime = getNowTime(); long long int druation = endTime - startTime; CCLOG("drawTime %lld", druation); }
我在每一次绘制都打印了一下绘制消耗的时间,单位是毫秒,基本都近似于0~1毫秒,所以绘制效率还是很高的。
用这个shader描边描出来的效果在2dx上的表现一般,描的很浅,下面是普通白字和白字描红边的对比效果图。
这是在Ios上描边效果,Android的效果也差不多。
描边的代码在这里下载:http://download.csdn.net/download/oktears/8403783
本文由CC原创总结,如需转载请注明出处:http://blog.csdn.net/oktears/article/details/43200757
1 0
- cocos2d-x 2.x版本文字描边研究01_使用shader描边
- cocos2d-x 文字描边
- cocos2d-x 文字描边
- Cocos2d-x lua shader使用
- Cocos2d-x-------------------------------------------Label数字文字描边
- cocos2d-x中shader的使用
- cocos2d-x中shader的使用
- cocos2d-x shader(1)-基本概念与使用
- cocos2d-x中shader的使用
- cocos2d-x shader
- Cocos2d-X的shader
- 【cocos2d-x 2.x 学习与应用总结】10: cocos2d-x自带的shader及其使用
- cocos2d-x之字体描边效果shader实现
- Cocos2d-x pgeRippleSprite OpenGL ES2.0 Shader版本
- cocos2d-x 使用图片作为文字
- cocos2d-x 2.x CCScale9Sprite shader渲染变灰方法
- cocos2d-x文字移动
- Cocos2d-x 文字标签
- easyui datagrid 导出excel
- 图结构(八)- Prim算法
- filter用法
- 枕叶癫痫治疗 01iycpu0
- Unity3D Shader官方教程翻译Unity3D 的渲染管道
- cocos2d-x 2.x版本文字描边研究01_使用shader描边
- 啊哈C——学习2.7练习
- [3D理论] Unity3D技术之为 Android 构建插件
- unity3d 学习之EZGUI简易教程
- 做一个操作系统——2实模式切换到保护模式
- Easyui接收后台json数据处理的小结(二)
- 邗江区汊河街道 01j2pcky
- 安装Django
- [图文教程] 【原创内容】unity2d-第一课:2D开发工具介绍