1. 程式人生 > >cocos2d-x 全面總結--字型描邊和製作陰影

cocos2d-x 全面總結--字型描邊和製作陰影

關於字型描邊的實現,不考慮效果和效率的話,是有三種方式:

  ① 利用CCLabelTTF製作文字描邊和陰影效果

  ② 利用CCRenderTexture渲染文理的方式生成帶有描邊效果的文字

  ③ 利用shader來實現,使用cocos2dx中CCGLProgram類與OpenGl繪圖機制中的著色器互動來實現

  第三種方式我沒試過,不過基於shader的強大特效功能,實現起來是沒問題的,後面我還會寫一篇關於shader來實現改變紋理顏色做特殊效果的文章。現在我們主要研究一下前兩種。前兩種方式從原理來說都是利用多個CCLabelTTF的重疊做的,只不過第二種方式是使用CCLabelTTF繪製了一個帶有描邊效果的文字圖片。

利用CCLabelTTF製作文字描邊和陰影效果

原理就是建立了4個描邊用的CCLabelTTF和一個正文主體CCLabelTTF,先畫描邊的label,顏色設定成要用的描邊色,分別在目標位置出做上下左右4個方向偏移,然後在蓋上我們的正文主體label即可。

/*string     文字 
 *fontName   文字字型型別 
 *fontSize   文字大小 
 *color3     文字顏色 
 *lineWidth  所描邊的寬度 
 */  
CCLabelTTF* HelloWorld::textAddStroke(const char* string, const char* fontName, float fontSize,const ccColor3B &color3,float lineWidth)  
{  
    /* 正文CCLabelTTF */
    CCLabelTTF* center = CCLabelTTF::create(string, fontName, fontSize);  
    center->setColor(color3);  
      
    /* 描邊CCLabelTTF 上 */
    CCLabelTTF* up = CCLabelTTF::create(string, fontName, fontSize);  
    up->setColor(ccBLACK);  
    up->setPosition(ccp(center->getContentSize().width*0.5, center->getContentSize().height*0.5+lineWidth));  
    center->addChild(up,-1);  
  
    /* 描邊CCLabelTTF 下 */
    CCLabelTTF* down = CCLabelTTF::create(string, fontName, fontSize);  
    down->setColor(ccBLACK);  
    down->setPosition(ccp(center->getContentSize().width*0.5, center->getContentSize().height*0.5-lineWidth));  
    center->addChild(down,-1);  
      
    /* 描邊CCLabelTTF 左 */ 
    CCLabelTTF* left = CCLabelTTF::create(string, fontName, fontSize);  
    left->setPosition(ccp(center->getContentSize().width*0.5-lineWidth, center->getContentSize().height*0.5));  
    left->setColor(ccBLACK);  
    center->addChild(left,-1);  
      
    /* 描邊CCLabelTTF 右 */
    CCLabelTTF* right = CCLabelTTF::create(string, fontName, fontSize);  
    right->setColor(ccBLACK);  
    right->setPosition(ccp(center->getContentSize().width*0.5+lineWidth,center->getContentSize().height*0.5));  
    center->addChild(right,-1);  
      
    return center;  
}  <span style="font-family: verdana, Arial, Helvetica, sans-serif;"> </span>

  陰影效果就更簡單了,只需要兩個label,一個陰影用的label和正文label,只需要設定陰影label:顏色、透明度和位置偏移即可。 

/*string         文字 
 *fontName       文字字型型別 
 *fontSize       文字大小 
 *color3         文字顏色 
 *shadowSize     陰影大小 
 *shadowOpacity  陰影透明度 
 */  
CCLabelTTF* HelloWorld::textAddShadow(const char* string, const char* fontName, float fontSize,const ccColor3B &color3,float shadowSize,float shadowOpacity)  
{  
    /* 陰影label */
    CCLabelTTF* shadow = CCLabelTTF::create(string, fontName, fontSize);  
    shadow->setColor(ccBLACK);  
    shadow->setOpacity(shadowOpacity);  
    
    /* 正文label */
    CCLabelTTF* center = CCLabelTTF::create(string, fontName, fontSize);  
    center->setColor(color3);  
    center->setPosition(ccp(shadow->getContentSize().width*0.5-shadowSize,shadow->getContentSize().height*0.5+shadowSize));  
    shadow->addChild(center);  
      
    return shadow;  
} <span style="font-family: verdana, Arial, Helvetica, sans-serif;"> </span>

  這裡提到一點,就是具體要建立幾個label是不一定的,建立的越多,效果是描邊越粗越亮但是效率越低,比如建立了40個描邊用的label,4個方向各10個,互相之間有微小的偏移不完全重疊,這樣的效果是label更加的粗且亮,陰影效果等同。

利用CCRenderTexture渲染文理的方式生成帶有描邊效果的文字

  這種方式難點在於,很多人不瞭解OpenGl的繪圖著色機制,不過也不要緊,這裡只用到了一點著色知識,就是顏色的混合,這個大多數的人都知道,紅色和綠色混合會變成黃色,黑色和任何顏色混合還是黑色(0*任何數=0),任何顏色和白色的混合不改變顏色。

  繪圖時,OpenGL 會把源顏色和目標顏色各自取出,並乘以一個係數(源顏色乘以的係數稱為“源因子”,目標顏色乘以的係數稱為“目標因子”),然後做運算得到新的顏色值,並按照新的顏色來繪製。  

  比如,RGB格式,原來的顏色是(255,0,0)--紅色,目標顏色是(0,255,0)--綠色,加入係數為{1,0},運算方式為顏色的疊加,這意味著新的顏色(255,0,0)*1+(0,255,0)*0 = (255,0,0)--紅色,就是完全不用目標顏色的值,相當於沒變色, 係數中源因子為前者:1,目標因子為後者:0,這是{1,0}的混合機制。 

  好了,那麼我們來了解一下cocos2dx的渲染是怎麼做的。

  在cocos2dx中的可渲染的節點都是CCNode的子類,如精靈、場景、文字,CCNode有一個渲染混色的函式glBlendFunc()和setBlendFunc(),操作的是ccBlendFunc,ccBlendFunc有兩個調節變數,ccBlendFunc func = { GL_SRC_ALPHA, GL_ONE},這個調節變數就是前面說的係數:

GL_SRC_ALPHA:表示使用源顏色的alpha值來作為源因子。

GL_ONE: 表示使用1.0作為因子,實際上相當於完全的使用了這種顏色參與混合運算。

  這類引數有很多,自己可以跟蹤引擎程式碼內部去看。

再介紹一下,CCRenderTexture生成描邊字型的原理,CCRenderTexture可以理解為一張紋理畫布,我們可以再這張畫布上塗鴉,當我們收工的時候,這張畫就算畫好了,即生成一張紋理。因此,我們是在畫布上,用一個label在不同的位置不斷的去畫,類似第一種方式,我們在畫布上繪製label的時候,在目標位置處的360個方向畫多個label,重疊,最後通過畫布就生成帶有描邊文字的一張紋理圖,然後用這張紋理圖生成一個精靈放到場景裡,完畢。

下面先把程式碼貼上來: 

CCTexture2D* FlyBloodLabel::createStrokeTexture(const char* value,float strokeValue,ccColor3B color)
{
    // float fontSize = m_fontSize - 2 * strokeSize;
    /* 建立一個CCLabelTTF,含有期望字型樣式,作為畫筆 */
    CCLabelTTF *label = CCLabelTTF::create(value,"Arial",EFFECT_LABEL_FONT_SIZE);
    
    /* 通過label的大小來設定最終生成的紋理圖片的大小,strokeValue為描邊字型的偏移量,影響粗細 */
    CCSize textureSize = label->getContentSize();
    textureSize.width += 2 * strokeValue;
    textureSize.height += 2 * strokeValue;
    
    /* 監測OpenGl的錯誤狀態 */
    glGetError();
    
    /* 建立一張紋理畫布 */
    CCRenderTexture *rt = CCRenderTexture::create(textureSize.width, textureSize.height);
    if(!rt)
    {
        CCLog("create render texture failed !!!!");
        addChild(label);
        return 0;
    }
    
    /* 設定描邊的顏色 */
    label->setColor(color);
    
    /* 
     *拿到源文字的混色機制,儲存以備恢復,並設定新的目標混色機制
     *混色機制設為:源顏色透明度(影響亮度)和目標顏色(影響顏色)
     */
    ccBlendFunc originalBlend = label->getBlendFunc();
    ccBlendFunc func = { GL_SRC_ALPHA, GL_ONE};
    label->setBlendFunc(func);
    
    /* 這是自定義的一些調整,傾斜了一點 */
    label->setAnchorPoint(ccp(0.5, 0.5));
    label->setRotationX(15);
    
    /* 張開畫布,開始繪畫 */
    rt->begin();
    for(int i = 0; i < 360; i += 5)//每變化5度繪製一張
    {
        float r = CC_DEGREES_TO_RADIANS(i); //度數格式的轉換
        label->setPosition(ccp(textureSize.width * 0.5f + sin(r) * strokeValue,textureSize.height * 0.5f + cos(r) * strokeValue));

        /* CCRenderTexture的用法,在begin和end之間visit的紋理,都會畫在CCRenderTexture裡面 */
        label->visit();//畫了一次該label
    }

    /* 恢復原始的label並繪製在最上層 */
    label->setColor(ccWHITE);
    label->setBlendFunc(originalBlend);
    label->setPosition(ccp(textureSize.width * 0.5f, textureSize.height * 0.5f));
    label->visit();

    /* 在畫布上繪製結束,此時會生成一張紋理 */
    rt->end();
    
    /* 取出生成的紋理,新增抗鋸齒打磨,並返回 */
    CCTexture2D *texture = rt->getSprite()->getTexture();
    texture->setAntiAliasTexParameters();// setAliasTexParameters();
    
    return texture;
}

  除此之外,還有一種方式就是Shader,這個還在研究,不過它的特效功能著實強大,以後逐步學習。

相關推薦

cocos2d-x 全面總結--字型製作陰影

關於字型描邊的實現,不考慮效果和效率的話,是有三種方式:   ① 利用CCLabelTTF製作文字描邊和陰影效果   ② 利用CCRenderTexture渲染文理的方式生成帶有描邊效果的文字   ③ 利用shader來實現,使用cocos2dx中CCGLProgr

卡通渲染Cocos2d-x中的實現(與對物體表面顏色的色階化)

卡通渲染Cocos2d-x中的實現 在一些型別的遊戲中,使用卡通渲染能夠將原有模型的一些細節剝離,使原本比較寫實的模型變得卡通化。在這裡,我向大家介紹簡單介紹一下如何在Cocos2d-x中實現卡通渲染。 事實上,卡通渲染具體來說,可以分為兩個部分:描邊與對物體表面顏色的

cocos2d實現CCLabelTTF真正字型效果

在開發遊戲中,我們需要在需要在遊戲中顯示一個字型輪廓比較清晰的效果,我們就需要給字型的周圍進行描邊,讓字型顯示比較更加突出,我重寫了cclabelttf類,使它具有描邊的特效,和描邊的大小以及顏色。。。 開發人員:Jason's.Alex   QQ:531401335 cs

cocos2d-x win8下的環境配置建立項目

cts ear bat article VS2010 移植 reat 還得 cocos cocos2dx 跨平臺。可是看網上說開發最合適還是在vs2010中,基本是編完後再移植到安卓。 1.去官網下載源代碼2.2.3版本號的。 2.然後運行根文件夾下的build

Android TextView 字型效果程式碼

 類繼承TextView,重寫ondraw函式。無需額外的textview做背景。以下為修改的diff檔案。 Index: ***Activity.java ============================================================

關於 NSMutableAttributedString 的詳解 比如 字型 字型陰影

-(void)test { UITextView *textView; NSMutableAttributedString * attString = [[NSMutableAttributedString alloc]initWithStri

【小松教你手遊開發】【unity實用技能】NGUI字型

NGUI的UILabel中實現字型的描邊是通過以方形的方式對字型網格頂點偏移一定位置後作為其描邊網格。以這種方式描邊在邊角處會生硬,描邊不均勻問題,特別是在比較大的字型描邊時偏移越大這種生硬,不均勻程度越明顯。處理這種描邊一可以通過改進shader的方式來做調整,這裡我介紹林一種新的方式:以圓形方式對字型網

cocos2dx中CCLabelTTF的陰影

遊戲中經常會用到文字描邊和陰影,當cocos2dx中並沒有給我們提供,下面是我參考:點選開啟連結(http://blog.csdn.net/song_hui_xiang/article/details/17375279)和點選開啟連結(http://fengmm521.bl

cocos2d-x 3.0開發筆記---用progressTimer製作血槽

血條經常會用到,沒必要重複編寫浪費時間,這裡用最新版的API寫個,方便以後呼叫。 以下程式碼使用的引擎版本是cocos2d-x 3.0rc0 1.RADIAL Sprite *bgSprite = Sprite::create("red.png"); addChil

Cocos2d-X引擎+Lua語言俄羅斯方塊的製作及基本邏輯編寫(上)

一、遊戲區域準備 ①首先解決格子到最終螢幕位置的轉換問題。 開啟src->app目錄下新建一個Common.lua檔案。用notepad++開啟,編碼格式轉為UTF-8無編碼格式。下面為Common.lua具體程式碼 cGridSize

cocos2d-x 利用CCLabelTTF製作文字陰影效果的實現方法

感謝點評與關注,歡迎轉載與分享。勤奮努力,持之以恆! 方法一: cocos2d-x 已經為我們封裝好了,方法就在類CCLabelTTF裡面。 /** enable or disable shadow for the label */ void enableS

cocos2d-x 精靈新增效果

學習cocos2d-x 以來一直對裡面的shader部分感興趣,今天正好花了點時間來研究一下精靈的描邊效果。 主要參考了子龍山人大神的TestCpp裡面例子並結合自己的理解,實現相對比較簡單。主要是根據引擎內部自帶的shader相關程式碼來實現的。 好了廢話不多說看程式碼:

Cocos2d-x】圖片的一種比較好的shader實現方法

轉載: http://blog.csdn.net/u011281572/article/details/44999609 圖片描邊需求如下: 1. 可指定描邊寬度2. 可指定描邊顏色3. 可用於字型 圖片描邊我所知道的方式有以下幾種: 1. Cocos2d-x 3.x中,

cocos2d-x Label問題以及解決辦法

這裡以quick_cocos2dx_3.3為例說明一下cocos2dx的Label描邊問題以及個人想到的一個不是很完美的解決辦法。 先上一段程式:     local label = display

cocos2d-x 2.x版本文字研究01_使用shader

由於Cocos2d-x 2.x版本對描邊支援的不好,3.X的基於Freetype的字型檔的描邊效果還是不錯的,但專案用的是舊版本引擎,又需要用到描邊字,最近也研究了幾種描邊的方法,想分享一下。 在網上找了很多種描邊的方式,各有優劣,有的描邊效果很不錯,而有的效果稍差但繪製效

關於cocos2d-x 安卓之間的相互調用

using with font android bject deb 交流 sta log 近期在研究cocos2d遊戲移植安卓須要調用非常多方法。所以在研究之中寫下它們之間相互調用 首先,cocos2d調用安卓 在一個.h文件裏加入頭文件 #include &l

cocos2d-x CCScrollViewCCTableView的使用

滾動視圖 ddl position 手勢滑動 mar efi rgb process soft 在遊戲和應用中常常要實現左右滑動展示遊戲幫助、以列表顯示內容的UI效果,就像android中的Gallery和ListView。本文通過CCScrollView和CCTab

cocos2d-x-3.3rc2-003 cocos中的引用計數自己主動釋放池

all post clas popu https -o git 打開鏈接 自己 點擊打開鏈接 cocos2d-x-3.3rc2-003 cocos中的引用計數和自己主動釋放池

cocos2d-x 關於旋轉移動的一點小技巧

小白 get posit seq sso 解釋 pre create ron 你犯困嗎,恩。給你講個笑話提提神~ 一對情侶去從林遊玩。被食人族捉住。食人族首領心情非常好。說你們假設想活命,就吃掉對方的大便。在他們回來的路上。女人終於忍不住停下。坐到石頭上哭起來。男人

Cocos2d-x】坐標系圖層

pac 多說 pan art world 地圖 分辨 play instance 在Cocos2D-X中,存在四種坐標系: 1、OpenGL坐標系:該坐標系原點在屏幕左下角。x軸向右,y軸向上。這也就是cocos2dx中用到的坐標系所以沒啥好說的。 2、屏幕坐標系(UI