• Welcome to Dark Bit Factory & Gravity.
 

Fast Fire [BB2D]

Started by mike_g, August 09, 2007

Previous topic - Next topic

0 Members and 0 Guests are viewing this topic.

mike_g

Heres an old school fire effect I found here and converted to Blitz. I am trying to get it to run as fast as possible. So far I have managed to get the fps up from 16 to 60 on my computer, which I am quite chuffed with, but theres one thing I cant figure out.

I would like to be able to get the Y position at the top of the fire (where its no longer black), then start drawing from that position. It would be much better when drawing on higher resolutions. I figured maybe some of you guys have done this stuff before and know how this could be done.

Anyway, heres the code:
Const GRAPHICS_WIDTH = 400
Const GRAPHICS_HEIGHT = 300

Graphics GRAPHICS_WIDTH, GRAPHICS_HEIGHT, 32, 2
SetBuffer BackBuffer()
SeedRnd MilliSecs()

Dim fire(GRAPHICS_WIDTH, GRAPHICS_HEIGHT)
Dim screen_buffer(GRAPHICS_WIDTH, GRAPHICS_HEIGHT)
Dim palette(256)

;LOAD COLOUR PALETTE
For i = 0 To 255
If r > 255 Then r = 255
If g > 255 Then g = 255
If b > 255 Then b = 255
palette(i)=(r Shl 16)+(g Shl 8)+b
r=r+5: g=g+3: b=b+2
Next

;DEMO LOOP
old_time=MilliSecs()
While Not KeyHit(1)
Cls
If MilliSecs() > old_time+1000
old_time=MilliSecs()
fps=frame_count
frame_count=0
EndIf

DrawFire()

Color 255, 255, 255
Text 2, 2, fps
frame_count=frame_count+1
Flip
Wend


Function DrawFire()
Local w=GRAPHICS_WIDTH-1
Local h=GRAPHICS_HEIGHT-1

;CREATE A RANDOM BASE FOR THE FIRE
For x=0 To w
    fire(x, h) = Rand(0, 255)
Next

;DO FIRE
For y=50 To h-1 ;how do i get the top of the fire?
upper_y = y+1
If y < h-1
lower_y = y+2
Else
lower_y = upper_y
EndIf
left_pix = fire( 0, upper_y )
mid_pix =  fire( 0, upper_y )
right_pix =fire( 1, upper_y)
base_pix = fire( 0, lower_y)

For x=0 To w
left_pix = mid_pix
mid_pix = right_pix

If x < w
right_pix= fire( x+1, upper_y )
Else
right_pix= fire( x, upper_y )
EndIf

base_pix = fire( x, lower_y )
fire(x, y)=((left_pix+mid_pix+right_pix+base_pix)Shl 5) /129

;DRAW FIRE TO SCREEN BUFFER
screen_buffer(x, y)=palette( fire(x, y) )
Next
Next

;DRAW TO SCREEN
LockBuffer BackBuffer()
For y=50 To h
For x=0 To w
    WritePixelFast(x, y, screen_buffer(x, y))
Next
Next
UnlockBuffer BackBuffer()
End Function


Shockwave

Works well, actually it is amazingly compact for a fire routine :)

31 fps here p4 3.0 Ghz, Ati X1650
Shockwave ^ Codigos
Challenge Trophies Won:

mike_g

Hmm, thats strange. Maybe your debugger was on? My specs are: Athlon 1.47ghz + 16mb mobilty U1 graphics + winXP. and I get 60fps. Then again we did some speed tests on Blitz 2d drawing on Socoder a while back and the results were very bizzare, some of the slowest computers came out top. Thanx for testing it :)

Shockwave

Doh! I am sorry mate. I did have debug on and it runs at 61 fps now (without debug).
Shockwave ^ Codigos
Challenge Trophies Won:

a

~120 fps ("Flip 0") - athlon64 3200+; x600 se

Tetra

I was about to post flip false ;D :whack: after making a bank conversion to compare, but the bank conversion ran at the same speed.

Ran at 51fps here with flip false ( 2001 computer :P )
Challenge Trophies Won:

mike_g

Ooooooh... If i put 0 after flip I get 78fps. I was wondering why blitz famerates never went higher than 61 on my PC, guess flip limits them by default. Cool :)

Jim

Flip tries to synchronise the update of the window with the refresh rate of your monitor.  This avoids tearing, where the frame is updated when the raster is halfway down the screen, giving you two halves of two different renders.  Your monitor is likely set to 60Hz - if you can, I'd adjust that to at least 75Hz to avoid eyestrain.  Flip 0 tells it not to sync, so there's no waiting going on and it runs flat out.

Jim
Challenge Trophies Won: