BASIC

Author Topic: TextWave-function too slow  (Read 3151 times)

Offline Corax

  • Mr. Drawsprite
  • **
  • Posts: 57
    • View Profile
TextWave-function too slow
« 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

Offline Moru

  • Administrator
  • Prof. Inline
  • *******
  • Posts: 1779
    • View Profile
    • Homepage
Re: TextWave-function too slow
« Reply #1 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 :-)

MrTAToad

  • Guest
Re: TextWave-function too slow
« Reply #2 on: 2009-Aug-08 »
The way to go would be to somehow use Polyvectors.  Unfortunately, I wouldn't know how to start...

Offline Hemlos

  • To boldy go where no pixel has gone before!
  • Global Moderator
  • Prof. Inline
  • *******
  • Posts: 1635
  • Particle Hawk
    • View Profile
Re: TextWave-function too slow
« Reply #3 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.

Volume_of_Earth(km^3) = 4/3*3.14*POW(6371.392896,3)

Offline Kitty Hello

  • code monkey
  • Administrator
  • Prof. Inline
  • *******
  • Posts: 10715
  • here on my island the sea says 'hello'
    • View Profile
    • http://www.glbasic.com
Re: TextWave-function too slow
« Reply #4 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.





Offline Corax

  • Mr. Drawsprite
  • **
  • Posts: 57
    • View Profile
Re: TextWave-function too slow
« Reply #5 on: 2009-Aug-18 »
Thanks for the help !