Best way to do Bitmap Fonts

Blitz3D Forums/Blitz3D Programming/Best way to do Bitmap Fonts

Fry Crayola(Posted 2004) [#1]
I tried creating a bitmap font that works in a single surface system. Like any other image I would display, I take the uv coords of the letter on the texture and create a quad, then texture it with these coords.

Easily done - but even though the font appears on screen the same size as it would using Text (one unit in the surface/mesh = one pixel), the font is slightly blurred. Mipmapping is off on the texture.

Is there any way of solving this? There are of course two alternatives.

I could just use straight DrawImage commands, but I don't like mixing 2D and 3D. I hear it's not a smart idea.

Or I could write a routine that drew the pixels directly to the backbuffer. Kind of like a custom drawimage. Might be exactly the same though in terms of how it's treated (i.e. as a 2D command).

Both of this will give me a pixel perfect font... but I'm concerned they will throw up problems and I can't carry out transparency effects or zoom the whole screen (for snazzy effects, really).

Any way to fix the original problem, should I stick with it as it is, or go for one of the other systems?


Rob Farley(Posted 2004) [#2]
clear the texture filters.


Fry Crayola(Posted 2004) [#3]
Already had. I've then set the alpha, colour and clamping flags for other uses.

So Mipmapping is definitely off.

But thanks anyhoo.


TeaVirus(Posted 2004) [#4]
You need to shift your entity my .5 pixels as in this example by skidracer:

http://www.blitzbasic.com/codearcs/codearcs.php?code=773

This is what does the trick: PositionEntity magic,-.5,-.5,0


Fry Crayola(Posted 2004) [#5]
Ok, I'll give that a bigger try. I didn't pay much attention the first time because other things were working out. But ta. Hopefully something will happen on that front.

What's the reasoning behind shifting the entity?


TeaVirus(Posted 2004) [#6]
My understanding is this aligns the screen pixels and texels so that there is no interpolation. Basically, the pixel is centered on the texel so that 1 texel = 1 pixel.


Fry Crayola(Posted 2004) [#7]
I'm sorry, I cannot work out what's going on in Skidracer's code. Maybe I'm useless, but it's too confusing for me.

I've tried positioning my mesh -0.5, -0.5, 0 from where I had it, and that's not working out at all. I get the same blur.


Stevie G(Posted 2004) [#8]
I've studied this quite a bit ...

He scales a pivot first, which is attached to the camera based on the screen resolution , aspect etc... He then attaches this second pivot to the first and offsets by -.5,-.5. Which equates to .5 of a pixel in local coords due to the parent pivots scaling.

Hmmm not sure if that made sense but maybe you get the jist?!


Fry Crayola(Posted 2004) [#9]
Hmm. I'm going to study it more when I get the chance (which is tomorrow), but I did run his program and it runs fine so I know I should be able to replicate it with no problems.


Jeremy Alessi(Posted 2004) [#10]
Eh, no reason not to mix 2D with 3D. It was a bad batch of drivers that caused that problem! Get Seth's Font Lib off BlitzCoder. It does 2D and 3D bitmapped fonts and it rules!


Fry Crayola(Posted 2004) [#11]
Well, I'll do both and run a speed test, picking the best from that. The advantage of using quads would be that I can treat the screen as one big entity and carry out whatever operations I like on it.

I don't like using other code. If I use my own I learn a lot more, and it's easier to debug.


Fry Crayola(Posted 2004) [#12]
Ok, I'm still not any closer to having my pixel perfect text.

I have noticed however that if I create a quad the size of my texture, it is pixel perfect. It's only when I create the smaller quads for each letter that this stops being the case.

I'm not wanting to use individual sprites at the moment - I want to stick to my single surface.


Gabriel(Posted 2004) [#13]
Eh, no reason not to mix 2D with 3D. It was a bad batch of drivers that caused that problem! Get Seth's Font Lib off BlitzCoder. It does 2D and 3D bitmapped fonts and it rules!


Well that bad batch of drivers seems to cover both Nvidia and ATI and has been running for well over a year now, so I'd consider that a reason. Judging by all the ATI owners with various driver versions who found that Particle Candy editor that used BCF incredibly slow, it's still a current problem ( though it didn't affect me so badly, but it was still significantly slower than the same thing in 3d. )


Fry Crayola(Posted 2004) [#14]
Back to the quads - it's definitely a texture problem, not distance. But moving my mesh -.5, -.5 doesn't do anything, nor does moving the quads by that amount.


Stevie G(Posted 2004) [#15]
Not sure if this helps but your quads have to be scaled in screen coords, i.e. if you wanted a quad of 32 x 32 you scale by 32 * Graphicswidth/2.0 on both x & y axis.


Fry Crayola(Posted 2004) [#16]
Sorry, I don't understand.

That says I scale it by 32 * 800/2.0, or scale it by 32*400.0
That's a big scale, which is confusing. And why scale the quad? That would make the image bigger on screen.

The mesh I place the quad on is positioned at -400, -300, 400, so the visible area is 800 units wide, and 600 units tall. Screen coordinates, really. So if I want to place 32*32 image, I create a 32*32 quad. Scaling?


jfk EO-11110(Posted 2004) [#17]
Imagine, with a default camerazoom, the FOV is 90 degs. that means, a mesh of a physical width of 640 blitzunits needs to be 640 units away from the cam to be fully onscreen. So the texelsize in 3D is distance/screenwidth. if you use an other distance, you also need to use other offsets than -.5,-.5.


Fry Crayola(Posted 2004) [#18]
I understood that a mesh with a physical width of 640 units needs to be 320 units away. At least, with the default camerazoom that's the case in my program.


jfk EO-11110(Posted 2004) [#19]
oops, yes,of course, 320.


Fry Crayola(Posted 2004) [#20]
So let me see if I understand this. I have a mesh that is 800x600 (the screen size) and thus it is positioned 400 units away.

On screen, the texel size is distance/screenwidth, or 400/800, which is 0.5.

What does this mean? When I offset the mesh by -.5, -.5 I saw no difference. Maybe I did it wrong - I'm not sure.


jfk EO-11110(Posted 2004) [#21]
well, in theory :) this would offset the texels to fit the pixels. But right now I am not sure anymore if this is all true :/ because: When you have an even number of texels, you wouldn't need to offset the position of the mesh since the center would be exactly between 319 and 320. I guess you'd see the diffrence best if you are using a TFT flat screen, and not a tube monitor, because there the LCD Pixels are truely seperated. IF a Texel is stretched across 2 pixels, you'd see the diffrence clearly.

Of course, you need to make sure that every texels UV Coords are positioned on a integer "pixel-coordinate"


Fry Crayola(Posted 2004) [#22]
It's a laptop screen. Which is probably TFT. And it's all confusing. I still believe it's set up properly so that one texel = one pixel or thereabouts because larger quads are pixel perfect. It's these smaller ones that I create for the text that show problems.


jfk EO-11110(Posted 2004) [#23]
Sou you scale quads to individual sized? Then it's no surprise.


Fry Crayola(Posted 2004) [#24]
Eh? The quads don't get scaled at all - the main mesh is just positioned far enough away from the camera so that it's all shown on screen. I create a quad depending on the image in question. The bigger the image, the bigger the quad. Is that wrong? That's how I assumed single surface systems work.


jfk EO-11110(Posted 2004) [#25]
Maybe you need to use an offset for both, the mesh position as well as the UV Coords. only the UV Coords need to be 0.5 texels set off, that means eg. U#-(0.5/texturewidth#) Since you are useing quads, the quads must be aligned pixelperfect. If they are, you need to make sure that the UV's are pixelerfect as well.


Fry Crayola(Posted 2004) [#26]
Ok, I'll see what I can conjure up on Monday. Thanks.


ronbravo(Posted 2004) [#27]
I've been trying to figure out what skidracer's code means but I can't figure out why he does what he does with the code. Could someone contact him and ask him to explain it. I would but my email isn't working.