Text with Bitmaps?

Blitz3D Forums/Blitz3D Beginners Area/Text with Bitmaps?

gellyware(Posted 2003) [#1]
Hi, Ive read some posts on blitz about making text appear with bitmaps instead of the SLOOOOWWwwwww text command. Can anyone give me a demonstration code and fully document it so I can understand whats going on? I am basically trying to substitute the TEXT command with imported bitmap fonts. How does this work? Thank you!


Bremer(Posted 2003) [#2]
Create a bitmap with the letters drawn and load it as an animated image, where each frame is a letter. Then read the string and deduct 65 (I think) which gives you a number from zero and up that can be used as a frame pointer for the anim image and then use drawimage for each letter. I don't have any code right here, but I'm sure there are some in the code section or check at blitzcoder.com


skn3(Posted 2003) [#3]
Quick example I just made.
Graphics 640,480,32,2

Global Font      = LoadFont("Arial",20,False,False,False)
Global ImageFont = ConvertFont2Image(Font,255,255,255)
Global FontCharacterGap = 8

SetBuffer BackBuffer()

Repeat
	Cls
	DrawText(ImageFont,MouseX()+40,MouseY(),"x="+MouseX()+", y="+MouseY())
	DrawText(ImageFont,MouseX()+40,MouseY()+15,"Hello there how are you!")
	Flip
Until KeyDown(1)

FreeImage(ImageFont)
FreeFont(Font)

Function ConvertFont2Image(Font,Red,Green,Blue,TransparentR=255,TransparentG=0,TransparentB=255)
	SetFont(Font)
	Color Red,Green,Blue
	
	Width  = FontWidth()
	Height = FontHeight()
	
	Image  = CreateImage(Width,Height,256)
	MaskImage Image,TransparentR,TransparentG,TransparentB
	
	For Ascii=0 To 255
		SetBuffer ImageBuffer(Image,Ascii)
		Text 0,0,Chr$(Ascii)
	Next
	Return Image
End Function

Function DrawText(Font,x,y,TextString$)
	For i=1 To Len(TextString$)
		DrawImage Font,x,y,Asc(Mid$(TextString$,i,1))
		x=x+FontCharacterGap
	Next
End Function



gellyware(Posted 2003) [#4]
nice example! skn3[ac], would you mind explaining it if theres not to much to ask?


gellyware(Posted 2003) [#5]
Also, I did some tests on your code and it doesnt seem like its much faster than the good old text command? If you do this:

DrawText(ImageFont,MouseX()+40,MouseY()+15,"Hello there how are you!")

DrawText(ImageFont,MouseX()+40,MouseY()+15,"Hello there how are you!")

DrawText(ImageFont,MouseX()+40,MouseY()+15,"Hello there how are you!")

DrawText(ImageFont,MouseX()+40,MouseY()+15,"Hello there how are you!")

DrawText(ImageFont,MouseX()+40,MouseY()+15,"Hello there how are you!")

DrawText(ImageFont,MouseX()+40,MouseY()+15,"Hello there how are you!")

DrawText(ImageFont,MouseX()+40,MouseY()+15,"Hello there how are you!")

DrawText(ImageFont,MouseX()+40,MouseY()+15,"Hello there how are you!")



you will notice a great decrease in speed. The reason I need a function like this to be very fast is because I am working on an interface with a particle engine and I will need at least 10-20 dynamic texts appearing on the screen, and I do not want the screen fps to drop because a) it will give me a false impression of how many particles are/could be generated and b) I would just like it to run at optimal speed without the the interface being the slowdown. Any other suggestions?


skn3(Posted 2003) [#6]
It really shouldn't be slower.
I just tried this on my computer
DrawText(ImageFont,MouseX()+40,MouseY(),"x="+MouseX()+", y="+MouseY()) 
DrawText(ImageFont,MouseX()+40,MouseY()+15,"Hello there how are you!")
DrawText(ImageFont,MouseX()+40,MouseY(),"x="+MouseX()+", y="+MouseY()) 
DrawText(ImageFont,MouseX()+40,MouseY()+15,"Hello there how are you!")
DrawText(ImageFont,MouseX()+40,MouseY(),"x="+MouseX()+", y="+MouseY()) 
DrawText(ImageFont,MouseX()+40,MouseY()+15,"Hello there how are you!")
DrawText(ImageFont,MouseX()+40,MouseY(),"x="+MouseX()+", y="+MouseY()) 
DrawText(ImageFont,MouseX()+40,MouseY()+15,"Hello there how are you!")
DrawText(ImageFont,MouseX()+40,MouseY(),"x="+MouseX()+", y="+MouseY()) 
DrawText(ImageFont,MouseX()+40,MouseY()+15,"Hello there how are you!")
DrawText(ImageFont,MouseX()+40,MouseY(),"x="+MouseX()+", y="+MouseY()) 
DrawText(ImageFont,MouseX()+40,MouseY()+15,"Hello there how are you!")
DrawText(ImageFont,MouseX()+40,MouseY(),"x="+MouseX()+", y="+MouseY()) 
DrawText(ImageFont,MouseX()+40,MouseY()+15,"Hello there how are you!")
DrawText(ImageFont,MouseX()+40,MouseY(),"x="+MouseX()+", y="+MouseY()) 
DrawText(ImageFont,MouseX()+40,MouseY()+15,"Hello there how are you!")
DrawText(ImageFont,MouseX()+40,MouseY(),"x="+MouseX()+", y="+MouseY()) 
DrawText(ImageFont,MouseX()+40,MouseY()+15,"Hello there how are you!")
DrawText(ImageFont,MouseX()+40,MouseY(),"x="+MouseX()+", y="+MouseY()) 
DrawText(ImageFont,MouseX()+40,MouseY()+15,"Hello there how are you!")


And it ran perfectly. Also 4 times that amount of text ran perfectly :)


gellyware(Posted 2003) [#7]
what type of video card do you have? I have just a stock 3d card that came with the comp. I wonder if any text will be a problem with it :( I really like your code though, would you mind explaining it? I dont quite understand what is going on. Thanks skn3[ac]


skn3(Posted 2003) [#8]
My graphics card is Radeon 9700 pro.
If you are using a bog standard stock card. Then that will not reflect the end user. The average card in computers is the geforce 2 or tnt cards. They will handle this sort of thing perfectly.

Ok no problem, Here goes.
At the start, you Open your font,.. get the width/height of the largest character in that font with fontwidth and fontheight.

There are 256 characters available to ascii (because each character is 1 byte. 1 byte has 256 combinations)

So you create either an array of indervidual images...
Width=fontwidth()
Height=fontheight()
dim MyFont(255)
for i=0 to 255
   MyFont(i)=createimage(Width,Height)
next

Or simply create an animstrip like so...
Width=fontwidth()
Height=fontheight()
MyFont=createimage(Width,Height,255)


Then you cycle through each ascii value from 0 to 255, and draw the letter to the indervidual image, or correct frame.
Example
Width=fontwidth()
Height=fontheight()
MyFont=createimage(Width,Height,256)
for i=0 to 255
   setbuffer imagebuffer(MyFont,i)
   text 0,0,chr$(i)
next


Now about ascii: To turn a letter into a usable number, you can use the Asc function.
If you did print asc(" ") (thats a space), it would print 32 to screen. That is because the ascii for space is 32.

To reverse the number to a letter you use Chr$(). So print chr$(32) would print a space to the screen.

Now that you know the ascii code, you will also know the frame, or array slot.

To then draw a character you could do it like so.
Width=fontwidth()
Height=fontheight()
MyFont=createimage(Width,Height,256)
for i=0 to 255
   setbuffer imagebuffer(MyFont,i)
   text 0,0,chr$(i)
next

x=5
y=5
drawimage MyFont,x,y,asc("a")


Hope that makes sense.


gellyware(Posted 2003) [#9]
Yes it does, thank you so much. So the average gamer has a pretty high end graphics card and not the one that comes with their comp? What do you do for users who do not purchase another video card and use the one that came with their computer? It could be my drivers too, I know I have had a problem playing jokers space game, my computer renders it at about 1 fps. However I am working on a particle engine and got about 200 particles on the screen at one time without it slowing down. This confuses me greatly :)


Al Mackey(Posted 2003) [#10]
I think the slow text issue is related to drivers. A program I wrote was running very slow on my brother's computer, which beats mine in all its stats. I started disabling features, and when text was disabled, it started going fast on his. Later, I had made text something that could be turned on and off, and when he upgraded his drivers (he has one of the high-end GeForce 3 cards, I think) text slowdown stopped being an issue.

Unfortunately, you can't expect anyone out there to keep their drivers up to date, especially when they don't think anything is wrong with them, so it's best to find workarounds like the one above.


gellyware(Posted 2003) [#11]
Just updated the drivers and you text function works wonderfully! Thanks skn3[ac]