GLBasic forum

Main forum => Beta Tests => Topic started by: Corax on 2009-Aug-08

Title: TextWave-function too slow
Post by: Corax on 2009-Aug-08
This program takes a string and transforms it into a colored, waved graphic.
In the final version it should also read information out of a *.txt file and
let it scroll right to left over the screen.

Obviously, it is far too slow with the grabsprite-solution (FPS on my computer: 10/30).
Can anyone think up a faster approach ?

TextWave.zip - 0.46MB (http://www.zshare.net/download/63807592dae82737/)
Title: Re: TextWave-function too slow
Post by: Moru on 2009-Aug-08
The bitmapfonts library on my homepage has some limited text-scrolling options if you want to see it. Full source included ofcourse :-)
Title: Re: TextWave-function too slow
Post by: MrTAToad on 2009-Aug-08
The way to go would be to somehow use Polyvectors.  Unfortunately, I wouldn't know how to start...
Title: Re: TextWave-function too slow
Post by: Hemlos on 2009-Aug-11
I love this effect, but the code really needs to be simplified.

Grabsprite is your speed issue....
I put in my own FPS function, and pumped the limitfps up.
By removing grabsprite from the routines, the FPS jumps up to 600+ fps.

TIP: turn this function into an isolated event, with a text input, and positioning.
ie FUNCTION fnFontWaver: text$, Xpos, Ypos, WaveHeight
Add a wave height too, for more dynamic control of the output.

Also try something like this:
1. get rid of the grabsprites in a loop.
2. grab the image of your string one time.(or each time the input is different into your function...use static to remember the input, to test if changed.) This is tricky adding to most programs, because you will need to clear your backbuffer at some point during the main loops...without interupt the program which is using this function. Use a hidden screen to swap the current backbuffer with a new one, then back again.
3. Make the output dynamic using drawanim.

Title: Re: TextWave-function too slow
Post by: Kitty Hello on 2009-Aug-11
Code (glbasic) Select

// --------------------------------- //
// Project: TextWave
// --------------------------------- //

//_____________________________________________________________________________ DECLARATIONS
   //............................................................................. "CONs"
   // values for fnHC()
   GLOBAL NumHC = 100; GLOBAL HCy = 178; GLOBAL HCyy = 64

   //............................................................................... DIMs
   // DIMs for fnHC()
   DIM dHCl[NumHC][4]
   DIM dHCr[NumHC][4]

   // DIM for fnFontWaver()
   DIM dWaver[640]

   //............................................................................... VARs
   // values for fnFontWaver()
   GLOBAL Angle, Speed = 50, Dir

   // counter
   GLOBAL cnt

//______________________________________________________________________________________ INI
   // limit frames per second
   LIMITFPS -1

   // set resolution / fullscreen true/false
//   SETSCREEN 640, 480, 1 // GF: GAAAAAHHHHH, my eyes


   // load fonts
   SETTRANSPARENCY RGB(255,255,255)
   LOADFONT "Font.png", 0
   SETTRANSPARENCY RGB(255,0,128)
   LOADFONT "smalfont.png", 1

   // set font index
   SETFONT 0

   // initialize color-stream
   FOR cnt = 0 TO NumHC-1
      dHCl[cnt][0] = RND(639)
      dHCl[cnt][1] = RND(HCyy) + HCy
      dHCl[cnt][2] = RND(2) + 2
      dHCl[cnt][3] = RND(2)
      dHCr[cnt][0] = RND(810) - 171
      dHCr[cnt][1] = RND(HCyy) + HCy
      dHCr[cnt][2] = RND(2) + 2
      dHCr[cnt][3] = RND(2)
   NEXT

   // initialize Wave
   FOR cnt = 0 TO 639
      IF Dir = 0
         Speed = Speed + 0.1
         IF Speed > 70; Speed = 70; Dir = 1; ENDIF
      ELSE
         Speed = Speed - 0.1
         IF Speed < 30; Speed = 30; Dir = 0; ENDIF
      ENDIF
      INC Angle, 1
      dWaver[cnt] = Speed * SIN(Angle) + 240
   NEXT

   //.................................................. LOAD GFX
   LOADSPRITE "", 0 // for temporary GFX
   LOADSPRITE "BG.png", 1 // background
   LOADANIM "HypnoCircles.png", 2, 181, 61 // for color-stream

//________________________________________________________________________________ MAIN LOOP
WHILE TRUE

   // this function draws a colored background
   fnHC()

   // print text over background
   PRINT "FARTOOSLOW", 0, 208

   // add transparent color
   DRAWRECT 0,0,640, 208, RGB(255,0,128)
   DRAWRECT 0,272,640,208, RGB(255,0,128)

   // change y-coordinates of text portions
   fnFontWaver()

   // draw background
   DRAWSPRITE 1, 0, 0

   // draw text
   ALPHAMODE 0.5; DRAWSPRITE 77, 0, 10; ALPHAMODE 0
   DRAWSPRITE 77, 0, 0

   // speedwatch
   DEBUG_FPS_Time = GETTIMERALL()
   DEBUG_FPS_Counter = DEBUG_FPS_Counter + 1
   IF ( DEBUG_FPS_Time - DEBUG_FPS_temp ) >= 1000.0
      DEBUG_FPS_temp = DEBUG_FPS_Time
      DEBUG_s_FPS = DEBUG_FPS_Counter
      DEBUG_FPS_Counter = 0
   ENDIF
   DEBUG_InfoFrames$ = "FPS: " + DEBUG_s_FPS + "/30"
   SETFONT 1
   PRINT DEBUG_InfoFrames$, 0, 0
   SETFONT 0

   // draw buffer on screen
   SHOWSCREEN

WEND

//________________________________________________________________________________ FUNCTIONs
// ------------------------------------------------------------- //
// ---  FNHC  ---
// .............................................................
// draws colored background
// ------------------------------------------------------------- //
FUNCTION fnHC:

   LOCAL lcnt

   ALPHAMODE 0.32

   FOR lcnt = 0 TO NumHC-1
      IF dHCl[lcnt][0] < -170
         dHCl[lcnt][0] = 639
         dHCl[lcnt][1] = RND(HCyy) + HCy
         dHCl[lcnt][2] = RND(2) + 2
         dHCl[lcnt][3] = RND(2)
      ELSE
         DRAWANIM 2, dHCl[lcnt][3], dHCl[lcnt][0], dHCl[lcnt][1]
         DEC dHCl[lcnt][0], dHCl[lcnt][2]
      ENDIF
      IF dHCr[lcnt][0] > 638
         dHCr[lcnt][0] = -170
         dHCr[lcnt][1] = RND(HCyy) + HCy
         dHCr[lcnt][2] = RND(2) + 2
         dHCr[lcnt][3] = RND(2)
      ELSE
         DRAWANIM 2, dHCr[lcnt][3], dHCr[lcnt][0], dHCr[lcnt][1]
         INC dHCr[lcnt][0], dHCl[lcnt][2]
      ENDIF
   NEXT

   ALPHAMODE 0

ENDFUNCTION // FNHC

// ------------------------------------------------------------- //
// ---  FNFONTWAVER  ---
// .............................................................
// repositions pixel columns
// ------------------------------------------------------------- //
FUNCTION fnFontWaver:

   LOCAL lcnt

   // delete first entry
   DIMDEL dWaver[], 0
   // add last entry
   REDIM dWaver[640]

   // compute last entry?s y-coordinate
   IF Dir = 0
      Speed = Speed + 0.1
      IF Speed > 70; Speed = 70; Dir = 1; ENDIF
   ELSE
      Speed = Speed - 0.1
      IF Speed < 30; Speed = 30; Dir = 0; ENDIF
   ENDIF
   INC Angle, 1
   dWaver[639] = Speed * SIN(Angle) + 240

IF TRUE
// draw waved GFX
SMOOTHSHADING FALSE
GRABSPRITE 0, 0, 208, 640, 128

DRAWRECT 0, 208, 640, 64, RGB(255, 0, 128)

// top left to right
LOCAL block% = 8
FOR lcnt = 0 TO 639-block STEP block%
STARTPOLY 0
POLYVECTOR lcnt,          dWaver[lcnt],       lcnt,       0,  0xffffff
POLYVECTOR lcnt,       64+dWaver[lcnt],       lcnt,       64, 0xffffff
POLYVECTOR lcnt+block, 64+dWaver[lcnt+block], lcnt+block, 64, 0xffffff
POLYVECTOR lcnt+block,    dWaver[lcnt+block], lcnt+block, 0,  0xffffff
ENDPOLY
NEXT
ELSE
// draw waved GFX
FOR lcnt = 0 TO 639
GRABSPRITE 0, lcnt, 208, 1, 64
DRAWRECT lcnt, 208, 1, 64, RGB(255, 0, 128)
DRAWSPRITE 0, lcnt, dWaver[lcnt]
NEXT

ENDIF

   // copy screen - GF: DONT! Use CREATESCREEN instead!
   GRABSPRITE 77, 0, 32, 640, 448

ENDFUNCTION // FNFONTWAVER


FUNCTION poo:

   // copy screen
   GRABSPRITE 0, 0, 32, 640, 448
ENDFUNCTION


That's about 80 FPS on my machine now. Try this:
- Don't re-use the same sprite with GRABSPRITE if the dimensions between the calls change -> use 2 sprites for that
- Use CREATESCREEN instead of GRABSPRITE
- Use POLYVECTOR instead of 1 pixel slice GRABSPRITE.

If you use CREATESCREEN instead of GRABSPRITE (everywhere), you can easily get > 200 FPS.




Title: Re: TextWave-function too slow
Post by: Corax on 2009-Aug-18
Thanks for the help !