Dark Bit Factory & Gravity

PROGRAMMING => Freebasic => Topic started by: rdc on January 31, 2007

Title: Fire Effect
Post by: rdc on January 31, 2007
A little fire effect I coded. Exe and source.

Title: Re: Fire Effect
Post by: benny! on January 31, 2007
Looks cool in its own way. Although I think it would be more realistically if the fire
would fade more away the higher it rises. Nevertheless, nice fx. Well done !!!
Title: Re: Fire Effect
Post by: Shockwave on January 31, 2007
Have some Karma for that Rick :)

Looking through the source there are a couple of things that I'd suggest.. I noticed that you seem to be splittting colour components during the running of the program, there is no need to do this, if you set up a palette for your fire in the beginning and have a flame buffer where values are written that determine the heat of a pixel, 0 is cold and 0 in the palette would be &H000000 and say 500 is hot and &HFFFF77 in your fire palette is will save you the trouble of chopping up all those colour values like you are doing at the moment.

You can then simply add the four surrounding pixels together at it's simplest and perform a shr 2 on them to determine the middle pixel.

It's a great attempt, you need to be using tinyptc for pixel pushing stuff though I think.

Here's some source for you..

Code: [Select]


'           FreeBasic Fire Technique Coded By Shockwave^DBF June 2006.
'           ==========================================================
'                                 Using Tinyptc
'                           UNFINISHED... PREVIEW ONLY.
'%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

        OPTION STATIC
        OPTION EXPLICIT

'%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
' INCLUDES;
'%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
        #define fbcopy1 FLAME_BUFFER2(X+Y)=FLAME_BUFFER(X+Y-SV)
        #define fbcopy2 FLAME_BUFFER(X+(LOL))=FLAME_BUFFER2((X+SV)+(LOL)) 
        '#define ptc_win
        #Include Once "tinyptc.bi"
   
'%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
' SET UP SCREEN;
'%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

        If( ptc_open( "FIRE BY SHOCKWAVE^DBF", 640, 480 ) = 0 ) Then
        End -1
        End If

'%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
' DEFINE ALL VARIABLES;
'%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
       
    dim shared BUFFER (640 * 480) As uInteger :'               Screen buffer.
    dim shared FLAME_BUFFER (640 * 480) As Integer :'         Flame buffer.   
    dim shared COLOURS(640) as integer:       '               Colour Palette.
    dim shared COOL_MAP (640 * 480) As Integer :'             Cool Map.
    DIM SHARED LOOPY AS INTEGER
    dim shared as integer xx,yy
    dim shared COOL_SCROLL AS INTEGER
    COOL_SCROLL=0
'%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
' DEFINE ALL SUBS;
'%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   
    declare sub GENERATE_COLOURS()
    DECLARE SUB COPY_BUFFER()
    DECLARE SUB MAKE_COOL_MAP()
    DECLARE SUB SCROLL_AA()
    declare SUB Millisecs()
'%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
' INITIALISE;
'%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

    GENERATE_COLOURS()
    MAKE_COOL_MAP()
'%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
' MAIN LOOP;
'%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

DIM SHARED Y AS INTEGER
DIM SHARED V AS INTEGER
DIM SHARED GADD AS INTEGER





DIM SHARED AS DOUBLE M ,oldtime,newtime
dim shared tst as string
    dim shared ticks,t as integer
    ticks=0
    oldtime=timer
do
    GADD=GADD+3
    V=50+39*COS(GADD/143)
   
   
    SCROLL_AA()           
   
    COPY_BUFFER()
       
   
    M=120
   

    for loopy =0 to 2000
            xx=320+((M+v)*sin((loopy+gadd) * 3.1415926535897932 / 180 ))
            yy=240+((M+v)*cos((loopy+gadd) * 3.1415926535897932 / 180 ))
            FLAME_BUFFER(xx+(yy*640))=640
           
            M=M-.07
   
    next
                   
    MILLISECS()
    ptc_update@BUFFER(0)   
    ticks=ticks+1
    loop until inkey$<>""
'%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
' SHUT DOWN;
'%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

    Ptc_close
    END


SUB Millisecs()
    t=timer

if  t-oldtime >=1 then
    newtime = ticks
    ticks=0
    oldtime=timer
    TST = str( (newtime) )
    TST = "FPS "+TST
    print tst
end if
                     
end sub

'%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
' ANTI ALIAS AND SCROLL ETC..
'%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SUB SCROLL_AA()
    dim AS UINTEGER A,B,C,D
    D=640*478

    COOL_SCROLL=COOL_SCROLL+3
    IF COOL_SCROLL>480 THEN COOL_SCROLL=COOL_SCROLL-480
    C=COOL_SCROLL*640
   

    FOR A=640 TO (640*478)     
        FLAME_BUFFER(A)=FLAME_BUFFER(A+1280)-COOL_MAP(C+1280)       
        IF FLAME_BUFFER(A)<0 then FLAME_BUFFER(A)=0       
        C=C+1
        IF C>D THEN C=640
       
    NEXT
   
    FOR A=640 TO (640*478)
         B=(FLAME_BUFFER(A-640)+FLAME_BUFFER(A+640)+FLAME_BUFFER(A-1)+FLAME_BUFFER(A+1)) SHR 2
                 
        FLAME_BUFFER(A)=B
    NEXT
   

END SUB

'%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
' GENERATE A BUFFER FOR A COOLING MAP, THIS WILL COOL THE FIRE PARTICLES.
'%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


SUB MAKE_COOL_MAP()
    DIM AS INTEGER A,B,C
    FOR A=1 TO 4000
        COOL_MAP((RND*(639*477))+640)=RND*640
    NEXT
    FOR C=1 TO 10
    FOR A=640 TO 640*478
        B=(COOL_MAP(A-640)+COOL_MAP(A+640)+COOL_MAP(A-1)+COOL_MAP(A+1)+COOL_MAP(A)) *.2
        IF B<0 THEN B = 0
        IF B>500 THEN B=500
        COOL_MAP(A)=INT(B)
    NEXT
    NEXT
END SUB

'%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
' COPY FLAME BUFFER INTO SCREEN BUFFER USING COLOURS ARRAY;
'%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SUB COPY_BUFFER()   
    dim as integer A
   
    for A=0 to 640*479           
        BUFFER(A)=COLOURS(FLAME_BUFFER(A))               
    next
   
END SUB

'%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
' GENERATE A NICE PALETTE;
'%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SUB GENERATE_COLOURS()
   
    dim as integer A,RD,GR,BL

    RD=0
    GR=0
    BL=0
   
    FOR A=1 TO 640
       
        if RD<254 then RD=RD+1
        if A>100 AND GR<255 then GR=GR+1
        if A>255 and BL<255 then BL=BL+1
       
        COLOURS(A) = RGB (RD,GR,BL)
    NEXT

END SUB
Title: Re: Fire Effect
Post by: rdc on January 31, 2007
Thanks for the comments. Thanks for the code example too.
Title: Re: Fire Effect
Post by: Shockwave on January 31, 2007
You're welcome :) Fire is something that needs to be worked on over time, yours will get cooler!
Title: Re: Fire Effect
Post by: rdc on January 31, 2007
Heh. Yeah, it is more of a smoke effect really. Changing the palette to gray it looks like smoke. Your idea of a cooling table is something I hadn't thought of; I am going to try that. Thanks again. I Karma'ed you for that. :)
Title: Fire to Cloud
Post by: rdc on February 01, 2007
This is one of those program where it starts off as one thing and ends up another. :) Flipping this on its side, and generating a cooling map as Shockwave suggested, it produces a decent looking cloud bank. I have a timer in this to randomize the cool map every few seconds. Changing the palette produces some interesting patterns as well. I think I will be able to use this at some point. It might be interesting to  use this technique in the tunnel code. Exe and new source attached.
Title: Re: Fire Effect
Post by: Shockwave on February 01, 2007
That really does look like clouds Rick, very nice indeed, however still runs slow because of unnecessary calculations.

As a cloud texture generator though it really does generate some very nice looking clouds! Nice to see you taking the fire off in a different direction, will be watching to see what else you can make it do :) Thank's for the Karma!

Btw, you need to blur your cool map if you are going to use this in fire to create those lovely tongues of flame. I suggest that you plot a few hundred points on your map in a high colour (!!!!!use a precalculated palette this is why your program is slow!!!!) and do about 20 anti alias passes on the cool map to blur it. Also the cool map should scroll at the same rate as the flames to create even cooling of each flame particle, however, don't physically scroll the cool map, use some offset instead to save on speed. When you're doing pixel intensive stuff like this you need to keep the calculations as simple as you can and you will notice a big boost in speed :)

Oh and have some Karma back for that lovely cloud sim :)
Title: Re: Fire Effect
Post by: rdc on February 01, 2007
Thanks man. Yeah, I didn't optimize anything in this since I was trying to get a handle on the algo. It will need to be reworked if I use it in a prod. I did smooth the cool map in the first pass on this, but took it out to increase the granularity of the output.

I appreciate you taking the time to critique this. It all helps. :)
Title: Re: Fire Effect
Post by: Shockwave on February 01, 2007
Cool. :) It's just that I fell into a lot of the same traps myself!  :cheers:
Title: Re: Fire Effect
Post by: Clyde on February 01, 2007
Thats really cool RDC.

Do you know what else it reminds me of when it's filled the screen. Is if it had some sinus and used a Blue pallete, it would make for a rather neat water reflection.

Cheers and all the best,
Clyde.
Title: Re: Fire Effect
Post by: rdc on February 02, 2007
Yeah, good idea Clyde. Might be worth a shot.