I myself have actually been doing a lot of thorough research on this
topic for my project OpenRPGMaker and I’ve found that a quick and
dirty method of doing it would be to use TTF_RenderText_Solid() then
make a new SDL_Surface of the same width and height (bpp can be
whatever you want) and then go through each RGB pixel values and
compare them with the text’s RGB color. If they are the same then
place the color value of the current x and y coordinate on you
gradient (using the modulus operator on the coordinate to allow
tiling of the gradient) onto the newly created surface, otherwise if
they are not the same then simply place a pre-chosen color to place
instead and then use
SDL_SetColorKey(newsurface, SDL_SRCCOLORKEY,
(Uint32)chosen_transparent_color) on the surface after it’s finished
rendering. The original surface can then be freed and the new one can
be used in its place.
Interesting. Is there a way to create an alpha-only surface? (No
color information, only an alpha channel.) I could render the font
onto that and then do a bit of creative blitting…
I would do it like this:
- Create the gradient surface. (this could be tiled or )
- Create the text with SDL_ttf with alpha channel.
- Replace every pixels RGB values of the SDL_ttf created surface with
the gradients corresponding RGB value leaving the alpha value as is.
This has the added benefit of creating the gradient only once.
I would make my custom gradient text blitter, because it would be
faster.
pseudo:
Get and set functions are left as an exercise.
Getting only Red, Green or Blue component is not very sensible, but I
used that to make things clearer.
This uses way too much functions, but it makes things clearer. (Again)
int
gradient_text_blitter( SDL_Surface* text_a,
SDL_Surface* gradient_rgb,
SDL_Surface* dst, int x, int y ) {
for(int i=0; i<text_a->w; i++)
for(int j=0; i<text_a->h; i++) {
Uint32 a = getA( text_a, i, j );
if( a > 0 ) {
Uint32 r = getR( gradient_rgb, i, j );
Uint32 g = getG( gradient_rgb, i, j );
Uint32 b = getB( gradient_rgb, i, j );
alphaBlendPixelTo( dst, x+i, y+j, r, g, b, a );
}
}
}
void
alphaBlendPixelTo( SDL_Surface* dst, int x, int y,
Uint32 r, Uint32 g, Uint32 b, Uint32 a ) {
if( x >= dst->w || y>= dst->h )
return;
Uint32 rgb = ((getR( dst, x, y )(255-a)+ra)/255;
rgb = rgb<<8 + ((getG( dst, x, y )(255-a)+ga)/255;
rgb = rgb<<8 + ((getB( dst, x, y )(255-a)+ba)/255;
setPixelTo( dst, x, y, rgb );
}On Thursday 17 April 2008, Justin Davis wrote:
On Sat, 2008-04-05 at 15:02 -0700, Mason Wheeler wrote:
----- Original Message ----
From: David Olsen
To: A list for developers using the SDL library. (includes
SDL-announce) Sent: Saturday, April 5, 2008
2:36:51 PM
Subject: Re: [SDL] Font color gradients
I would think that using the output from SDL_TTF(Blended - the one
that gives you a per-pixel alpha image), you could blit the text
onto a predefined surface which contains a color gradient, and you
should get a resulting image of the sort you want. (Oh, first you
must have SRCALPHA turned on in both surfaces, or it won’t act as a
mask. Look at the documentation of the SDL_SetAlpha function) I
might have the surface order reversed… you might need to blit the
colored gradient surface onto the rendered text surface. But a
little experimentation along those lines should get you set up.
-Dave
----- Original Message -----
From: “Mason Wheeler”
To:
Sent: Saturday, April 05, 2008 7:12 AM
Subject: [SDL] Font color gradients
I’ve been looking through SDL_TTF, and it looks like the only
option available is to render a font in a single, solid color.
How would I do gradients and other custom colorations? The ideal
way would be to use the glyph shapes as “cutouts” in an existing
graphic from an SDL_Surface, which would allow custom colors to
be defined beforehand. If this isn’t feasible, I’d like to be
able to define multiple foreground colors and create a gradient
from them.
How would I go about doing something like this?