There are three ways to implement font strokes without regard to effectiveness and efficiency:
① using Cclabelttf to make text strokes and shadow effects
② using Ccrendertexture to render text with a stroke effect
③ is implemented using shader, which is implemented by interacting with shaders in the Ccglprogram class in COCOS2DX and in the OpenGL drawing mechanism.
The third way I haven't tried, but based on the powerful effect of shader, the implementation is no problem, I will also write an article about shader to achieve change texture color to do special effects. Now we'll focus on the first two types. The first two approaches are based on the principle of overlapping multiple cclabelttf, but the second way is to use Cclabelttf to draw a text picture with a stroke effect.
use Cclabelttf to create text strokes and shadow effects
Online a lot of blogs have spoken this way, written very well, here to a link: http://blog.csdn.net/song_hui_xiang/article/details/17375279
The principle is to create 4 strokes with the Cclabelttf and a body Cclabelttf, first draw the label of the stroke, color set to use the stroke color, respectively, in the target position out of the left and right 4 direction offset, and then cover our body label can be.
/*string text *fontname text font type *fontsize text size *color3 text color *linewidth the width of the stroke */cclabelttf* Hellowo
Rld::textaddstroke (const char* string, const char* fontname, float fontsize,const cccolor3b &color3,float lineWidth)
{/* Body CCLABELTTF */cclabelttf* Center = cclabelttf::create (String, FontName, fontSize);
Center->setcolor (COLOR3);
/* Stroke 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);
/* Stroke 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);
/* Stroke Cclabelttf Left */ 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);
/* Stroke Cclabelttf Right */cclabelttf* R = 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>
The shadow effect is much simpler, requiring only two labels, a label for the shadow and the body label, and just setting the shadow label: color, transparency, and position offset.
/*string text *fontname text font type *fontsize text size *color3 text color *shadowsize Shadow size *shadowopacity Shadow transparency */cclabelttf* Helloworld::textaddshadow (const char* string, const char* FontName, FL Oat fontsize,const cccolor3b &color3,float shadowsize,float shadowopacity) {/* Shadow label */cclabelttf* Sha
Dow = Cclabelttf::create (string, FontName, fontSize);
Shadow->setcolor (Ccblack);
Shadow->setopacity (shadowopacity);
/* Body 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>
Here is a point, is specifically to create a few labels is not necessarily, the more you create, the effect is that the thicker the stroke is brighter but less efficient, such as the creation of 40 strokes with the label,4 direction of each of the 10, there is a slight offset between each other does not completely overlap, the effect is the label more coarse and bright, The shadow effect is equal.
Create text with stroke effect by ccrendertexture rendering arts and Sciences
The difficulty in this way is that many people do not understand OpenGL's drawing coloring mechanism, but it does not matter, here only a little coloring knowledge, is the color of the mix, this most people know that the red and green mix will turn yellow, black and any color mixed or black (0* any number of =0), Any color and white blend does not change color.
When plotting, OpenGL takes the source and target colors out and multiplies them by a factor (the source color is multiplied by the factor called the "source factor", the target color is multiplied by the factor called the "target Factor"), then the operation is given a new color value and is drawn according to the new color.
For example, the RGB format, the original color is (255,0,0)-red, the target color is (0,255,0)-green, the added factor is {1,0}, the operation is a color overlay, which means that the new color is (255,0,0) *1+ (0,255,0) *0 = (255,0, 0)--red, is completely without the target color value, equivalent to No color change, the coefficient of the source factor is the former: 1, the target factor is the latter: 0, this is {1,0} of the mixing mechanism.
Well, then let's see how Cocos2dx's rendering is done.
The COCOS2DX nodes are ccnode subclasses, such as sprites, scenes, text, Ccnode have a function to render the process color Glblendfunc () and Setblendfunc (), the operation is Ccblendfunc, Ccblendfunc has two adjustment variables, ccblendfunc func = {gl_src_alpha, gl_one}, which is the coefficient of the preceding argument:
Gl_src_alpha: Indicates that the source color's ALPHA value is used as the source factor.
Gl_one: The use of 1.0 as a factor is actually equivalent to fully using this color to participate in the blending operation.
There are many such parameters that can be traced inside the engine code.
Again, Ccrendertexture generated the principle of the stroke font, ccrendertexture can be understood as a texture canvas, we can draw on this canvas, when we are done, this painting, even if the picture, that is, to create a texture. So, we are on the canvas, with a label in different places to draw constantly, similar to the first way, we draw a label on the canvas, in the target position in the 360 directions to draw a number of labels, overlap, and finally through the canvas to generate a texture with stroke text, Then use this texture to create a sprite and put it in the scene, complete.
Here's the code first:
cctexture2d* flybloodlabel::createstroketexture (const char* value,float strokevalue,cccolor3b color) {//float fontSi
Ze = m_fontsize-2 * strokesize;
/* Create a CCLABELTTF that contains the desired font style, as a brush */Cclabelttf *label = cclabelttf::create (value, "Arial", effect_label_font_size);
/* Sets the size of the resulting texture picture by the size of the label, Strokevalue the offset of the stroke font, affecting the weight/ccsize texturesize = Label->getcontentsize ();
Texturesize.width + = 2 * strokevalue;
Texturesize.height + = 2 * strokevalue;
/* Monitor error status of OpenGL */Glgeterror ();
/* Create a texture canvas */ccrendertexture *RT = Ccrendertexture::create (Texturesize.width, texturesize.height);
if (!rt) {Cclog ("Create render texture failed!!!!");
AddChild (label);
return 0;
}/* Sets the color of the stroke */label->setcolor (color); /* * Get the color blending mechanism of the source text, store it for recovery, and set a new target blending mechanism * The process color mechanism is set to: source color transparency (affect brightness) and target color (affect color) */ccblendfunc originalblend = Label
->getblendfunc (); Ccblendfunc func = {gl_src_ALPHA, Gl_one};
Label->setblendfunc (func);
/* This is a customization of some tweaks, tilted a bit */Label->setanchorpoint (CCP (0.5, 0.5));
Label->setrotationx (15);
/* Open canvas, start painting */Rt->begin (); for (int i = 0; i <; i + = 5)//5 degrees per change draw a {float R = Cc_degrees_to_radians (i);//conversion of degree format LABEL-&G
T;setposition (CCP (texturesize.width * 0.5f + sin (r) * strokevalue,texturesize.height * 0.5f + cos (r) * strokevalue));
/* Ccrendertexture's usage, visit texture between begin and end, will be drawn in Ccrendertexture */label->visit ();//Draw the label once}
/* Restore the original label and draw it on the top */Label->setcolor (ccwhite);
Label->setblendfunc (Originalblend);
Label->setposition (CCP (Texturesize.width * 0.5f, Texturesize.height * 0.5f));
Label->visit ();
/* Draws the end on the canvas, creating a texture */rt->end ();
/* Remove the resulting texture, add antialiasing grinding, and return */cctexture2d *texture = Rt->getsprite ()->gettexture (); Texture->setantialiastexparameters ();//Setaliastexparameters ();
return texture; }
In addition, there is another way is shader, this is still in the study, but its special effects are really powerful, and gradually learn.