Slow Drawtext?

BlitzMax Forums/BlitzMax Beginners Area/Slow Drawtext?

Pierrou(Posted 2012) [#1]
Hi!

I thought I was done with my new project, which is a French reading game for children... until I tested it on some PCs, not necessarily old machines (the MacOS version seems OK). On most computers, character animations, text scrolling and everything runs >>>60 fps without any slowdown... The game runs in windowed mode, the size of the window being more or less the size of the desktop. On some computers (especially a netbook and a recent desktop computer with a cheap graphics chip on the motherboard, both running XP) unfortunately it's not that smooth...

After a close examination of all animations, I went to the conclusion that the game went a bit slow only when a certain amount of text was displayed, using a ttf font and the drawtext command (either about 25 homemade buttons with some text inside, or a few lines of text). No complicated calculations were needed during those animations, just drawing a few things at fixed coordinates. The interface loop is also very minimalistic during animations. When I cut the framerate to 30 fps using a frame skipping routine, which is still good for such a game, it's OK again, but I'd like the game to run flawlessy on any not-too-old PC.

Is there any explanation and/or any remedy?

Thank you in advance for your help!!


xlsior(Posted 2012) [#2]
Try using an image font instead, writing text by drawing the individual letters to the screen instead of using DrawText.

There should be some code in the code archives for that kind of thing -- drawtext can be pretty slow on low-end computers.

Last edited 2012


ima747(Posted 2012) [#3]
Are you using directx or open gl on windows systems?


Midimaster(Posted 2012) [#4]
Hi I am Peter from Midimaster Education Software. I know the problem, because often our customers have the same small computers. It is caused by the graphic cards. They cannot work as fast as new data are coming in.

So we always try to do this: If you have fixed areas, where nearly nothing happens during the animation. f.e. areas with buttons etc... try to paint them not as often as the center of your screen. Do not use CLS, but a backgound picture which already contains all fix background elements.

You could also render this background "on the fly" with "GrabImage" at the beginning of the game (..which needs once 200msec ).

Also an idea is to use 30Hz instead of 60Hz. Often the consumption of performance decrease from 100% to 10% with the half Frequency. You could combine 60Hz timer with a 30Hz paint refreshing and will not loose any speed in the game:

symbolic code:
Graphics 800,600
Timer:TTimer = CreateTimer(60)
Local FlipFlag%, UseFlip%, 
Repeat
     If FlipFlag=0
           DrawImage BackGround,0,0
                DrawAllScreenElements()
           Flip 0
     Endif
 
    ' here all action stuff
          ScrollX = ScrollX+1
          CollisionCheck()
          ' Mouse and Keychecks
          If KeyHit(1) Then PlayerX = PlayerX+1

     If UseFlip=1
            FlipFlag = 1-FlipFlag
     Else
           FlipFlag = 0
           If CheckRealFPS()<50 Then UseFlip = 1
     Endif
     WaitTimer Timer
Until KeyHit(KEY_ESCAPE)

Function RealFPS%()
     Local Result%
     Global TenSeconds%, FPS%
     If TenSeconds=0
          TenSeconds=Millisecs()+10*1000
          Result=999
          FPS=1
     Else If TenSeconds<Millisecs()
          TenSeconds=Millisecs()+10*1000
          Result=FPS/10
          FPS=1
     Else
          FPS=FPS+1
          Result=999
     Endif
     Return Result         
End Function

You could do this in case of performance problems only, by counting the real FPS and the decide to use the FlipFlag%


SLotman(Posted 2012) [#5]
Are you sure the texts are to blame? I've run bmax games on a 700mhz machine, onboard crappy video (a SiS one), using a lot of text on screen, without any problems whatsoever...!

I really find it hard to believe any machine built in the last 5 years or so would have any difficulty to run a 2D game made in bmax...


Derron(Posted 2012) [#6]
I can assure that printing a lot of text slows down the application enormously.

Blitzmax uses an imageframe for each glyph (character) instead of using it as an image atlas (one image but draw only a portion of it).

As standard ogl/dx implementation does not combine multiple calls to one texture you have to do what Midimaster suggested with "grabimage".

To speed up things do something like:

type tbutton
  field x:int,y:int,w:int,h:int
  field dirty:int =0
  field image:Timage
  field text:string="Mytext"

  method draw()
    if not dirty
      drawimage(self.image,x,y)
    else
      drawmybutton
      drawText(text,x,y)
      self.image = grabimage(x,y,w,h)      
      self.dirty = false
    endif
  end method
end Type


above code was not tested... just written within seconds.

The idea is to store the "generated" output. Using this you can style up the text with underlying ones (emboss, shadow...).

Use the same technique for Tooltip/Hover-Boxes... but this will slightly increase memory usage as the cache are "timages".


What you could also do - to make it even more useable:
Write your BitmapFont-Engine (which loads TTFs, renders them on a texture), write a "paste char to image/pixmap"-function and generate images which hold your text (with alpha, shadows, ...).

That way you can also write hiscore-text on the screen or you could have animated button-backgrounds.

But at the end you would write a generic "image cache"-system which could be used for much more than just texts (here you benefit from your own bitmapfont-class - as then images and fonts are the same - only missing thing is lines/rects/ovals).

The last mentioned thing is only preferable if you have no option to do something like buffered drawing or render-to-texture. In that case you would have to implement a kind of texture atlas to cached images too (store eg. 20 text-cacheimages on one texture to speed it up even more)


bye Ron

oh edit: as old SiS-cards were mentioned.... I've done first tests with Blitzmax years ago - also with a sis 741 on one test pc. At that time you had problems with image size (>512x512 cut fps on my SiS) and text display. That time I hoped to get something like dirty-rects - would improve performance even more.

Last edited 2012


Pierrou(Posted 2012) [#7]
I can't try what's above or even really think about it for the moment, I will in the next few days, but thanks to everyone of you for your kind answers. In my very first project (which sold quite well and no one complained about) I did what Midimaster suggested, ie drawing only parts of the screen instead of everything, not in order to be fast, but just because I was an absolute beginner and it seemed right to me to do so. When I started this new project, I was suggested to redraw everything everytime to avoid issues, which especially occured on Mac but also on a few PCs... And now there's that drawtext issue :(
(the game is using directX by the way)
The problem is I have to draw text since it is a reading game :)
I will try to follow your advice...
Thanks again,


Pierrou(Posted 2012) [#8]
Hi again,
I just used Grabimage/Drawimage in a few places more instead of writing everything again and again, and it's much better this way. If it still gets slow on small computers I will try what Derron suggested, but it seems to be OK this way.

Thanks to everyone here for being once again so nice and efficient... Blitzmax is great, but the community makes it even better.