1
votes

I posted a question about drawing text onto a pixmap to generate dynamic textures at runtime, and that problem was resolved here

Is there an easy way that I can tint the font that I copy to a new pixmap, or do I need to do it manually pixel by pixel? I can't find anything obvious in the libgdx library or on Google.

My current process is:

  1. create a new pixmap
  2. draw a character onto that pixmap
  3. convert the pixmap into a texture for rendering.

At some point in that process I'm like to be able to tint the font at runtime.

Code updated to test Jyro117's answer. (Not working, see image below)

    // Set up the base image
    Pixmap newPixmap = new Pixmap(backImage.getWidth(),
            backImage.getHeight(), Format.RGBA8888);
    newPixmap.drawPixmap(backImage, 0, 0);

    // Copy out the letter from our fontsheet
    // and draw the char to a new pixmap
    Glyph glyph = fontData.getGlyph(getLetterToDraw().charAt(0));
    Pixmap charPixmap = new Pixmap(glyph.width, glyph.height,
            Format.RGBA8888);
    charPixmap.drawPixmap(fontPixmap, 0, 0, glyph.srcX, glyph.srcY,
            glyph.width, glyph.height);

    // try to tint it?!
    charPixmap.setColor(1, 0, 0, 100);
    charPixmap.fillRectangle(0, 0, newPixmap.getWidth(),
            newPixmap.getHeight());

    // copy the character to our new bitmap
    newPixmap.drawPixmap(charPixmap, (BLOCK_SIZE - glyph.width) / 2,
            (BLOCK_SIZE - glyph.height) / 2);

    texture = new Texture(newPixmap);

    newPixmap.dispose();
    charPixmap.dispose();

example

1
Maybe ask the question of the whole Process in the Badlogicforum. From Bitmapfont to pixermap on runtime... It seems to have problems with the alpha of the pixmap. It should work with the overlay but the alpha blending isnt right. Maybe its not possible what you are going for. There is no other way to tint a pixmap. Else you need to tint the Font befor you create a pixmap but i think its not possible like that.BennX
You could use 2 Fonts: One with default color, one with the tinted color and switch between them. Or did i missunderstand something?Springrbua
@Springrbua Yes, that's an option, bun then I need to create and store a sheet for every colour I want to use.Will Calderwood
Isn't it possible to tint only the font? BitMapFont.setColor(Color)?Springrbua
I'm not using a BitmapFont object for the drawing, otherwise yes, that would work.Will Calderwood

1 Answers

2
votes

Pixmap has all the functions you need to tint it.

  • Get a pixmap of the font (in your case fontPixmap)
  • Make sure alpha blending is enabled.
  • Set the color, (setting alpha to the desired level)
  • Draw rectangle over entire font image (0,0,width,height)
  • Now the pixmap of your font has the desired tinting

Hopefully that clears it up for you.

Edit:

Alright, so I see what exactly you mean, it would appear there is no way by default to change the 'type' of blending for Pixmap. At least without me looking into the native code under the covers. BitmapFont gets around this by using vertex data for the glyph and renders each one as a shape instead of image. So in order to do this you will have to do it with two passes:

  • First we fill the pixmap with the desired color and alpha (note: the values for this are between 0f and 1f, so your alpha should be something like 0.3f not 100)
  • Next you iterate over all pixels of the image and are looking for pixels which have their alpha value below a certain threshold (should be around 0.3f). Then you could either set the alpha of those pixels below the threshold to 0, or maybe do something fancier like Math.pow(alpha, 3), etc. Basically the alpha you just added to the image (using source over blending) you want to reduce/remove, but only for pixels which are supposed to be transparent. You may have to play around with different values or reduction techniques to get it looking correctly.

Note: You can iterate over the pixel data by calling getPixel() or get the Bytebuffer with getPixels() and the 4th byte will be the pixel's alpha value between 0 and 255.

Edit 2:

I just thought of an alternative way to do this is to use a Frame Buffer.

  • Render your font texture onto the frame buffer.
  • Draw a colored rectangle with alpha over the entire frame buffer using the proper alpha blending function (Not sure which one off the top of my head but you want one which only applies if dst has an alpha greater than 0).
  • Grab the texture from the frame buffer and use that as your tinted font.