Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Drawing Text with an outline  (Read 13311 times)

0 Members and 1 Guest are viewing this topic.

Megatron

  • Newbie
  • *
  • Posts: 22
    • View Profile
Drawing Text with an outline
« on: November 03, 2010, 07:28:33 am »
I was wondering if it's possible to draw a text object so that the font has an outline?

for instance, if I have a white font, I may want to put a thin black border around it to accentuate it. I'd assume it'd be possible via shaders, but I was wondering if there was a way that doesnt rely on shaders.

I'm using the .net bindings for SFML so that may be a possible limitation.

If anyone has an idea how to do this that they could share, that'd be great.

Thanks

inlinevoid

  • Newbie
  • *
  • Posts: 49
    • MSN Messenger - inlinevoidmain@gmail.com
    • AOL Instant Messenger - inlinevoid
    • View Profile
    • Email
Drawing Text with an outline
« Reply #1 on: November 03, 2010, 07:35:27 am »
Well, you could try wrapping two strings inside your own string class.

Make one string slightly larger then the other, and place it behind the smaller one to give an 'outline' effect.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Drawing Text with an outline
« Reply #2 on: November 03, 2010, 08:06:11 am »
No, this is not possible at all sorry.

Quote
Make one string slightly larger then the other, and place it behind the smaller one to give an 'outline' effect.

This will not produce the desired effect ;)
Laurent Gomila - SFML developer

Spodi

  • Full Member
  • ***
  • Posts: 150
    • View Profile
    • http://www.netgore.com/
Drawing Text with an outline
« Reply #3 on: November 03, 2010, 08:22:05 am »
I personally do this right now by drawing the text 5 times. Draw the background using the offsets of (0,1),(1,0),(0,-1),(-1,0) (up,down,left,right) and then the normal text. Inefficient? You betcha! But it gets the job done.

I have looked into doing this with shaders, but I couldn't find any decent way of doing it without some of the features of newer version of GLSL (namely the ability to look up the size of the texture so you could actually use a pixel scale).

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Drawing Text with an outline
« Reply #4 on: November 03, 2010, 08:48:38 am »
Quote
namely the ability to look up the size of the texture so you could actually use a pixel scale

If that's the only thing you need, you can send it manually to the shader through a variable.
Laurent Gomila - SFML developer

Spodi

  • Full Member
  • ***
  • Posts: 150
    • View Profile
    • http://www.netgore.com/
Drawing Text with an outline
« Reply #5 on: November 03, 2010, 09:00:43 am »
Quote from: "Laurent"
Quote
namely the ability to look up the size of the texture so you could actually use a pixel scale

If that's the only thing you need, you can send it manually to the shader through a variable.


That was what I had in mind at first, too, but didn't realize at the time that Font had a GetImage method (clearly I didn't look very hard). Maybe I'll play around with it again and see if I can whip up something.

bastien

  • Full Member
  • ***
  • Posts: 231
    • View Profile
    • http://bastien-leonard.alwaysdata.net
Drawing Text with an outline
« Reply #6 on: November 03, 2010, 09:02:47 am »
Wouldn't a font like that work? http://www.dafont.com/bower-shadow.font
Check out pysfml-cython, an up to date Python 2/3 binding for SFML 2: https://github.com/bastienleonard/pysfml-cython

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Drawing Text with an outline
« Reply #7 on: November 03, 2010, 09:14:05 am »
It works as long as you don't want to control the outline width or color.
Laurent Gomila - SFML developer

Spodi

  • Full Member
  • ***
  • Posts: 150
    • View Profile
    • http://www.netgore.com/
Drawing Text with an outline
« Reply #8 on: November 03, 2010, 07:36:42 pm »
The problem with doing it inside of a font file directly, or applying it to a font using SetPixel, is that you are increasing the amount of memory used to store your fonts. With using a font with outlines built-in, it also introduces a lot more hassle.

Ideally, you want to be able to just say "use outline", and it draws with outlines with no reduction to performance and takes up no extra memory. With shaders, this is likely possible since not many of us are going to be bottlenecked on the fragment processing (unless you are already using some heavy shaders).

Spodi

  • Full Member
  • ***
  • Posts: 150
    • View Profile
    • http://www.netgore.com/
Drawing Text with an outline
« Reply #9 on: November 03, 2010, 10:09:18 pm »
Well, after a few hours, I managed to come up with something that works decently. Took quite some time to come up with the right algorithm to preserve the alpha values properly.

Code: [Select]
uniform sampler2D tex;
uniform vec2 texSize;
uniform vec4 outlineColor;
void main(void)
{
vec2 off = 1.0 / texSize;
vec2 tc = gl_TexCoord[0].st;

vec4 c = texture2D(tex, tc);
vec4 n = texture2D(tex, vec2(tc.x, tc.y - off.y));
vec4 e = texture2D(tex, vec2(tc.x + off.x, tc.y));
vec4 s = texture2D(tex, vec2(tc.x, tc.y + off.y));
vec4 w = texture2D(tex, vec2(tc.x - off.x, tc.y));

vec4 origColor = c * gl_Color;

float ua = 0.0;
ua = mix(ua, 1.0, c.a);
ua = mix(ua, 1.0, n.a);
ua = mix(ua, 1.0, e.a);
ua = mix(ua, 1.0, s.a);
ua = mix(ua, 1.0, w.a);

vec4 underColor = outlineColor * vec4(ua);

gl_FragColor = underColor;
gl_FragColor = mix(gl_FragColor, origColor, origColor.a);

if (gl_FragColor.a > 0.0)
gl_FragColor.a = 1.0;
}


There is a little issue with the display of the first character. It seems SFML adds a little white block to the top-left corner of a font bitmap, so that ends up making a little artifact display for the first character. In theory, it'll also show artifacts if there are any font characters without padding between them in the font texture. Could get rid of this by just clamping the texture coordinates, but don't know of any way of finding the specified coordinates for the draw call without passing them as a parameter (which would require modifying SFML to update that parameter before each character is drawn).

Edit: Updated the shader. Kinda disappointed in myself for not realizing to take this approach initially. Was too stuck on the idea of recognizing when the edge has been reached.

Megatron

  • Newbie
  • *
  • Posts: 22
    • View Profile
Drawing Text with an outline
« Reply #10 on: November 07, 2010, 06:36:08 am »
Thanks spodi, the way you mentioned before worked, Ill give the shader a try later

 

anything