zoukankan      html  css  js  c++  java
  • [zz]字体、图片描边

    参考:


    CCRenderTexture这个类平时没怎么用过,想不到用TA来创建描边效果轻松并且效果也还不错。

    上面2个帖子的实现,抛开一个c++,一个oc语言来看,我发现思路其实是一样的,这里我翻译了成quick的lua版本,并在代码中相应做了些注释,朋友们可以看下。

    -- @param:node 欲描边的显示对象
    -- @param:strokeWidth 描边宽度
    -- @param:color 描边颜色
    -- @param:opacity 描边透明度
    function createStroke(node, strokeWidth, color, opacity)
        local w = node:getTexture():getContentSize().width + strokeWidth * 2
        local h = node:getTexture():getContentSize().height + strokeWidth * 2
        local rt = CCRenderTexture:create(w, h)
    
        -- 记录原始位置
        local originX, originY = node:getPosition()
        -- 记录原始颜色RGB信息
        local originColorR = node:getColor().r
        local originColorG = node:getColor().g
        local originColorB = node:getColor().b
        -- 记录原始透明度信息
        local originOpacity = node:getOpacity()
        -- 记录原始是否显示
        local originVisibility = node:isVisible()
        -- 记录原始混合模式
        local originBlend = node:getBlendFunc()
    
        -- 设置颜色、透明度、显示
        node:setColor(color)
        node:setOpacity(opacity)
        node:setVisible(true)
        -- 设置新的混合模式
        local blendFuc = ccBlendFunc:new()
        blendFuc.src = GL_SRC_ALPHA
        blendFuc.dst = GL_ONE
        -- blendFuc.dst = GL_ONE_MINUS_SRC_COLOR
        node:setBlendFunc(blendFuc)
    
        -- 这里考虑到锚点的位置,如果锚点刚好在中心处,代码可能会更好理解点
        local bottomLeftX = node:getTexture():getContentSize().width * node:getAnchorPoint().x + strokeWidth 
        local bottomLeftY = node:getTexture():getContentSize().height * node:getAnchorPoint().y + strokeWidth
    
        local positionOffsetX = node:getTexture():getContentSize().width * node:getAnchorPoint().x - node:getTexture():getContentSize().width / 2
        local positionOffsetY = node:getTexture():getContentSize().height * node:getAnchorPoint().y - node:getTexture():getContentSize().height / 2
    
        local rtPosition = ccp(originX - positionOffsetX, originY - positionOffsetY)
    
        rt:begin()
        -- 步进值这里为10,不同的步进值描边的精细度也不同
        for i = 0, 360, 10 do
            -- 这里解释了为什么要保存原来的初始信息
            node:setPosition(ccp(bottomLeftX + math.sin(degrees2radians(i)) * strokeWidth, bottomLeftY + math.cos(degrees2radians(i)) * strokeWidth))
            node:visit()
        end
        rt:endToLua()
    
        -- 恢复原状
        node:setPosition(originX, originY)
        node:setColor(ccc3(originColorR, originColorG, originColorB))
        node:setBlendFunc(originBlend)
        node:setVisible(originVisibility)
        node:setOpacity(originOpacity)
    
        rt:setPosition(rtPosition)
    
        return rt
    end

    举个例子

    -- 文本、图片一样,这里用文本举个例子
    local quickLabel = ui.newTTFLabel({
            text = "QuickCocos2dX-createStroke",
            color = display.COLOR_RED,
            size = 60,
            align = ui.TEXT_ALIGN_CENTER,
            x = display.cx,
            y = display.cy + 150
        }):addTo(self, 1)
    
    local  renderTexture = createStroke(quickLabel, 4, ccc3(0xca, 0xa5, 0x5f), 100)
    -- 设置反锯齿
    renderTexture:getSprite():getTexture():setAntiAliasTexParameters()
    self:addChild(renderTexture, quickLabel:getZOrder()-1)

    这样下来,会drawcall2次。

    群里有朋友提到,如果文本改变,那下方的描边如何做?

    那对应的描边renderTexture也需要改变,我想是得先remove掉然后重新创建纹理,那各位可以简单封装下,当文本重新setString的时候,相应去创建下方的描边纹理就可以了。

     


    Stroke example for CCLabelTTF and CCSprite.

    By Alexandr Gerasimov Posted  10 months ago Comments 11

    Alexandr Gerasimov

     Posts: 8

    Hey guys! Several days ago i found a cocs2d-iphone examples "stroke effect for CCLabelTTF objects". Here is the link to the cocos2d-iphone forum: http://www.cocos2d-iphone.org/forum/topic/12126

    I made little modifications in this example and rewrote it for c++. Here is my code:

    1CCRenderTexture* createStroke(CCSprite* label, int size, ccColor3B color, GLubyte opacity)

     2 {

     3

     4    CCRenderTexture* rt = CCRenderTexture::renderTextureWithWidthAndHeight(

     5        label->getTexture()->getContentSize().width + size * 2,

     6        label->getTexture()->getContentSize().height+size * 2

     7        );

     8

     9    CCPoint originalPos = label->getPosition();

    10

    11    ccColor3B originalColor = label->getColor();

    12

    13    GLubyte originalOpacity = label->getOpacity();

    14

    15    bool originalVisibility = label->getIsVisible();

    16

    17    label->setColor(color);

    18

    19    label->setOpacity(opacity);

    20

    21    label->setIsVisible(true);

    22

    23    ccBlendFunc originalBlend = label->getBlendFunc();

    24

    25    ccBlendFunc bf = {GL_SRC_ALPHA, GL_ONE};

    26

    27    label->setBlendFunc(bf);

    28

    29    CCPoint bottomLeft = ccp(

    30        label->getTexture()->getContentSize().width * label->getAnchorPoint().x + size, 

    31        label->getTexture()->getContentSize().height * label->getAnchorPoint().y + size);

    32

    33    CCPoint positionOffset= ccp(

    34        - label->getTexture()->getContentSize().width / 2,

    35        - label->getTexture()->getContentSize().height / 2);

    36

    37    CCPoint position = ccpSub(originalPos, positionOffset);

    38

    39    rt->begin();

    40

    41    for (int i=0; i<360; i+= 15) // you should optimize that for your needs

    42    {

    43        label->setPosition(

    44            ccp(bottomLeft.x + sin(CC_DEGREES_TO_RADIANS(i))*size, bottomLeft.y + cos(CC_DEGREES_TO_RADIANS(i))*size)

    45            );

    46        label->visit();

    47    }

    48    rt->end();

    49

    50    label->setPosition(originalPos);

    51    label->setColor(originalColor);

    52    label->setBlendFunc(originalBlend);

    53    label->setIsVisible(originalVisibility);

    54    label->setOpacity(originalOpacity);

    55

    56    rt->setPosition(position);

    57

    58    return rt;

    59}

     


    I added "opacity" property and possibility to add Stroke for all CCSprite nodes.

    Example of usage:

    1    CCSprite* sprite = CCSprite::spriteWithFile("some_sprite.png");

    2

    3    addChild(sprite);

    4

    5    CCRenderTexture* tex = createStroke(sprite, 2 /*size*/, ccc3(0, 255, 0)/*color*/, 50 /*opacity*/);

    6

    7    addChild(tex, sprite->getZOrder() - 1);

     

     

    stroke.png (47.6 kB)

    Alexander Belchenko

     Posts: 35

    RE: Stroke example for CCLabelTTF and CCSprite. 10 months ago

    I suspect the latest line should be read as

    addChild(tex, sprite->getZOrder() - 1);

    Thanks for sharing this.

    Alexandr Gerasimov

     Posts: 8

    RE: Stroke example for CCLabelTTF and CCSprite. 10 months ago

    Alexander Belchenko wrote:

    I suspect the latest line should be read as

    addChild(tex, sprite->getZOrder() - 1);

    Thanks for sharing this.

    Exactly! Thx and welcome!

    xavi pinol

     Posts: 9

    RE: Stroke example for CCLabelTTF and CCSprite. 9 months ago

    It actually works on iOS, but I'm having some problems on Android.

    I know is sounds weird, but have a look at the screenshots

    Android:

    iOS:

    Is there any solution for this?

    xavi pinol

     Posts: 9

    RE: Stroke example for CCLabelTTF and CCSprite. 9 months ago

    Solved with:

    rt->getSprite()->getTexture()->setAntiAliasTexParameters();

    xavi pinol wrote:

    It actually works on iOS, but I'm having some problems on Android.

    I know is sounds weird, but have a look at the screenshots
    ...

    Alexandr Gerasimov

     Posts: 8

    RE: Stroke example for CCLabelTTF and CCSprite. 9 months ago

    Right, thx for solving! I use setAntiAliasTexParameters by default for all my textures 

    xavi pinol wrote:

    Solved with:

    rt->getSprite()->getTexture()->setAntiAliasTexParameters();

    xavi pinol wrote:

    It actually works on iOS, but I'm having some problems on Android.

    I know is sounds weird, but have a look at the screenshots
    ...

    Lance Gray

     Posts: 468

     Location: Coffee World

    RE: Stroke example for CCLabelTTF and CCSprite. 9 months ago

    Thanks for sharing!

    Check out my blog: sudo make_me_a_game

    GVBox Production

     Posts: 19

    RE: Stroke example for CCLabelTTF and CCSprite. 6 months ago

    Thanks for sharing !

    juyoung kim

     Posts: 8

    RE: Stroke example for CCLabelTTF and CCSprite. 5 months ago

    Thanks for sharing!

    Austin K

     Posts: 3

    RE: Stroke example for CCLabelTTF and CCSprite. 5 months ago

    Thank you for sharing this! Has anyone created HTML5 support? I could really use it.

    Thanks.

    Simon Pan

     Posts: 66

     Location: Taiwan

    RE: Stroke example for CCLabelTTF and CCSprite. 4 months ago

    Alexandr Gerasimov wrote:

    Hey guys! Several days ago i found a cocs2d-iphone examples "stroke effect for CCLabelTTF objects". Here is the link to the cocos2d-iphone forum: http://www.cocos2d-iphone.org/forum/topic/12126

    I made little modifications in this example and rewrote it for c++. Here is my code:

    [...]
    I added "opacity" property and possibility to add Stroke for all CCSprite nodes.

    Example of usage:
    [...]

     

    Add the check while CCSprite is using setAnchorPoint as below:

    static CCRenderTexture* createStroke(CCSprite* label, int size, ccColor3B color, GLubyte opacity){

            CCRenderTexture* rt = CCRenderTexture::create(label->getTexture()->getContentSize().width + size * 2,

                                                          label->getTexture()->getContentSize().height+size * 2);

            CCPoint originalPos = label->getPosition();

            ccColor3B originalColor = label->getColor();

            GLubyte originalOpacity = label->getOpacity();

            label->setColor(color);

            label->setOpacity(opacity);

            bool originalVisibility = label->isVisible();

            ccBlendFunc originalBlend = label->getBlendFunc();

            ccBlendFunc bf = {GL_SRC_ALPHA, GL_ONE};

            label->setBlendFunc(bf);

            CCPoint bottomLeft = ccp(

                                     label->getTexture()->getContentSize().width * label->getAnchorPoint().x + size,

                                     label->getTexture()->getContentSize().height * label->getAnchorPoint().y + size);

            //原來沒有判斷AnchorPoint的寫法

            //  CCPoint positionOffset= ccp(   - label->getTexture()->getContentSize().width / 2,

            //                                  - label->getTexture()->getContentSize().height / 2);

            //SetAnchorPoint會影響到positionOffset,所以要做判斷

            CCPoint positionOffset = CCPointZero;

            if(label->getAnchorPoint().x == 0.5f){

                positionOffset.x = 0;

            }else if(label->getAnchorPoint().x == 0.0f){

                positionOffset.x =- label->getTexture()->getContentSize().width / 2;

            }else{

                positionOffset.x = label->getTexture()->getContentSize().width/2;

            }

            if(label->getAnchorPoint().y == 0.5f){

                positionOffset.y = 0;

            }else if(label->getAnchorPoint().y == 0.0f){

                positionOffset.y =- label->getTexture()->getContentSize().height / 2;

            }else{

                positionOffset.y =  label->getTexture()->getContentSize().height/2;

            }

            CCPoint position = ccpSub(originalPos, positionOffset);

            rt->begin();

            for (int i=0; i<360 data-blogger-escaped-for="" data-blogger-escaped-i="" data-blogger-escaped-label-="" data-blogger-escaped-needs="" data-blogger-escaped-optimize="" data-blogger-escaped-should="" data-blogger-escaped-that="" data-blogger-escaped-you="" data-blogger-escaped-your="">setPosition(

                                   ccp(bottomLeft.x + sin(CC_DEGREES_TO_RADIANS(i))*size, bottomLeft.y + cos(CC_DEGREES_TO_RADIANS(i))*size)

                                   );

                label->visit();

            }

            rt->end();

            label->setPosition(originalPos);

            label->setColor(originalColor);

            label->setBlendFunc(originalBlend);

            label->setVisible(originalVisibility);

            label->setOpacity(originalOpacity);

            rt->setPosition(position);

            //反踞齒

            rt->getSprite()->getTexture()->setAntiAliasTexParameters();

            return rt;

        }

     

    Dony Karlos

     Posts: 13

     Location: FBoooW

    RE: Stroke example for CCLabelTTF and CCSprite. 16 days ago

    is there lua code of this?

     :::::::::::::::::::::::

    From: http://www.cocos2d-x.org/forums/6/topics/22335

  • 相关阅读:
    PHP userAgent解析 PHP
    VB 2 C# 语法对比图
    HTML特殊字符数据库读写处理
    备份数据库
    Rose建模初步 [来自:UMLChina]
    ASP下的二级联动(XML方式)
    VSS使用手册
    管理项目的好助手——VSS入门
    【转】VB.NET的阳历与农历转换的算法
    GIF, JPEG和PNG
  • 原文地址:https://www.cnblogs.com/wishing/p/3450104.html
Copyright © 2011-2022 走看看