Author Topic: Fire Particle System  (Read 9128 times)

0 Members and 1 Guest are viewing this topic.

Offline rdc

  • Pentium
  • *****
  • Posts: 1495
  • Karma: 140
  • Yes, it is me.
    • View Profile
    • Clark Productions
Fire Particle System
« on: February 02, 2007 »
I thought I would try my hand a fire particle system. I think it turned out pretty well considering this was a first pass at it. One thing I did in this was to generate 5 different cooling maps, and then periodically select a random map when rendering. It gives the fire a much more realistic feel I think. If you look at the source you will see that this thing is pushing 50,000 particles, so the speed isn't bad considering, but I am open to suggestions on improvement. Exe and source included.


Offline benny!

  • Senior Member
  • DBF Aficionado
  • ********
  • Posts: 4384
  • Karma: 228
  • in this place forever!
    • View Profile
    • bennyschuetz.com - mycroBlog
Re: Fire Particle System
« Reply #1 on: February 02, 2007 »
Thats excellent, mate.

Karma boost for you.
[ mycroBLOG - POUET :: whatever keeps us longing - for another breath of air - is getting rare ]

Challenge Trophies Won:

Online Shockwave

  • good/evil
  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 17414
  • Karma: 498
  • evil/good
    • View Profile
    • My Homepage
Re: Fire Particle System
« Reply #2 on: February 02, 2007 »
Now that is much better looking, it looks great! Much better than the first go. Have some K :)
Shockwave ^ Codigos
Challenge Trophies Won:

Offline rdc

  • Pentium
  • *****
  • Posts: 1495
  • Karma: 140
  • Yes, it is me.
    • View Profile
    • Clark Productions
Re: Fire Particle System
« Reply #3 on: February 02, 2007 »
Thanks guys. I had the idea last night as I was going to sleep to use Wu particles in this. It might look better and would require less pixels as well. I am going to give that a shot today.

Offline Clyde

  • A Little Fuzzy Wuzzy
  • DBF Aficionado
  • ******
  • Posts: 7271
  • Karma: 71
    • View Profile
Re: Fire Particle System
« Reply #4 on: February 02, 2007 »
Welldone with the particles RDC.
Still Putting The IT Into Gravy
If Only I Knew Then What I Know Now.

Challenge Trophies Won:

Offline rdc

  • Pentium
  • *****
  • Posts: 1495
  • Karma: 140
  • Yes, it is me.
    • View Profile
    • Clark Productions
Re: Fire Particle System
« Reply #5 on: February 02, 2007 »
Thanks man.

Offline ninogenio

  • Pentium
  • *****
  • Posts: 1668
  • Karma: 133
    • View Profile
Re: Fire Particle System
« Reply #6 on: February 02, 2007 »
VERY VERY cool mate!

this is probably some of the coolest stuff ive seen you do!

karma for that surely.

anyway hows about doing something like this to it just to make it that little bit more authentic it uses relsofts smooth function which loops through every pixel on screen adds the four sourunding color values to that pixel then divides the overall value by 4.

Code: [Select]
'Fire Particle System
'Thanks to Shockwave for code help.
'*****************************************'
option explicit

#include "tinyptc.bi"
#define sw 400
#define sh 300
#define maxage 255
#define maxpts 50000
#define numcoolmaps 5

'Color type to extract rgb color information
'Posted by Jofers on FB forum
Type Pixel_Color
    B As Ubyte
    G As Ubyte
    R As Ubyte
    A As Ubyte
End Type

Union Pixel
    Channel As Pixel_Color
    Value   As Uinteger
End Union

type particle
    x as integer
    y as integer
    age as integer
end type

const cx = sw / 2


declare sub smoothS( buffer())
dim shared buffer(sw * sh) as integer
dim shared fire as particle ptr
dim shared coolmap(0 to numcoolmaps, 0 to sw -1, 0 to sh - 1) as integer
dim shared pal(0 to maxage) as uinteger
dim shared currcoolmap as integer
dim as double t

function AlphaBlend(alpha as integer, fcolor as uinteger, bcolor as uinteger) as uinteger
    dim as integer invalpha, r, g, b
    dim as Pixel fc, bc
   
    invalpha = 255 - alpha
    fc.value = fcolor
    bc.value = bcolor
    r = ((fc.channel.r * alpha) + (bc.channel.r * invalpha)) shr 8
    g = ((fc.channel.g * alpha) + (bc.channel.g * invalpha)) shr 8
    b = ((fc.channel.b * alpha) + (bc.channel.b * invalpha)) shr 8
   
    return RGB(r, g, b)   
end function

function GetRandom(lowerbound as integer, upperbound as integer) as integer
   return Int((upperbound - lowerbound + 1) * Rnd + lowerbound)
end function

'Interpolation code by Rattrapmax6
Sub CreatePalette(cpal() as Integer, sr as integer, sg as integer, sb as integer, er as integer, eg as integer, eb as integer)
    Dim As Integer i
    Dim iStart(3) As Integer
    Dim iEnd(3) As Integer
    Dim iShow(3) As Integer
    Dim Rend(3) As Double
    Dim InterPol(3) As Double
   
    InterPol(0) = Ubound(cpal)
    iStart(1) = sr
    iStart(2) = sg
    iStart(3) = sb
    iEnd(1) = er
    iEnd(2) = eg
    iEnd(3) = eb
    InterPol(1) = (iStart(1) - iEnd(1)) / InterPol(0)
    InterPol(2) = (iStart(2) - iEnd(2)) / InterPol(0)
    InterPol(3) = (iStart(3) - iEnd(3)) / InterPol(0)       
    Rend(1) = iStart(1)
    Rend(2) = iStart(2)
    Rend(3) = iStart(3)   
   
    For i = 0 To Ubound(cpal)
        iShow(1) = Rend(1)
        iShow(2) = Rend(2)
        iShow(3) = Rend(3)

        cpal(i) = Rgb(iShow(1),iShow(2),iShow(3))

        Rend(1) -= InterPol(1)
        Rend(2) -= InterPol(2)
        Rend(3) -= InterPol(3)
    Next
   
End Sub

function Smooth( arr() as integer, imap as integer, x as integer, y as integer) as integer
    dim as integer xx, yy, cnt, v
   
    cnt = 0
   
    v = arr(imap, x, y)
    cnt += 1

    if x < sw - 1 then
        xx = x + 1
        yy = y
        v += arr(imap, xx, yy)
        cnt += 1
    end if

    if x > 0 then
        xx = x - 1
        yy = y
        v += arr(imap, xx, yy)
        cnt += 1
    end if
               
    if y < sh - 1 then
        xx = x
        yy = (y + 1)
        v += arr(imap, x, y + 1)
        cnt += 1
    end if
   
    if y > 0 then
        xx = x
        yy = (y - 1)
        v += arr(imap, x, y - 1)
        cnt += 1
    end if
   
    v = v / cnt
       
    return v
end function

sub CreateCoolMap
    dim as integer i, j, x, y
   
    for i = 0 to numcoolmaps
        for x = 0 to sw - 1
            for y = 0 to sh - 1
                coolmap(i, x, y) = GetRandom(-20, 20)
            next
        next
   
        for j = 1 to 10
            for x = 0 to sw - 1
                for y = 0 to sh - 1
                    coolmap(i, x, y) = Smooth(coolmap(), i, x, y)
                next
            next
        next
    next   
end sub



'-----------------------------
'relsofts smooth function
'-----------------------------
private sub smoothS( buffer())
    dim maxpixel as integer
    dim offset as integer
    dim pixel as integer
    dim r as integer
    dim g as integer
    dim b as integer
    dim nr as integer
    dim ng as integer
    dim nb as integer



    maxpixel = ubound(buffer)
    for offset = SW to maxpixel-SW
        pixel = buffer(offset-1)
        r = pixel shr 16
        g = pixel shr 8 and 255
        b = pixel and 255
        nr = r shr 2
        ng = g shr 2
        nb = b shr 2
        pixel = buffer(offset+1)
        r = pixel shr 16
        g = pixel shr 8 and 255
        b = pixel and 255
        nr = nr + ( r shr 2 )
        ng = ng + ( g shr 2 )
        nb = nb + ( b shr 2 )
        pixel = buffer(offset+SW)
        r = pixel shr 16
        g = pixel shr 8 and 255
        b = pixel and 255
        nr = nr + ( r shr 2 )
        ng = ng + ( g shr 2 )
        nb = nb + ( b shr 2 )
        pixel = buffer(offset-SW)
        r = pixel shr 16
        g = pixel shr 8 and 255
        b = pixel and 255
        nr = nr + ( r shr 2 )
        ng = ng + ( g shr 2 )
        nb = nb + ( b shr 2 )
        buffer(offset) = nr shl 16 or ng shl 8 or nb
    next i

end sub



sub MoveParticles
    dim as integer i, xx, yy, r, clr
   
    smoothS buffer()
    do while i < maxpts
        fire[i].age = fire[i].age + coolmap(currcoolmap, fire[i].x, fire[i].y) + 2
        if fire[i].age < 0 then fire[i].age = 0
        if fire[i].age < maxage then
            r = GetRandom(-1, 1)
            xx = fire[i].x + r
            yy = fire[i].y - 1
            if xx < 0 or xx > sw - 1 or yy < 0 or yy > sw - 1 then
                fire[i].age = maxage
            else
                fire[i].x = xx
                fire[i].y = yy
                if buffer(fire[i].x + fire[i].y * sw) > 0 then
                    clr = AlphaBlend(fire[i].age, buffer(fire[i].x + fire[i].y * sw), pal(fire[i].age))
                else
                    clr = pal(fire[i].age)
                end if
                buffer(fire[i].x + fire[i].y * sw) = clr
            end if
        end if
        i += 1
    loop
end sub

sub AddParticles
    dim as integer i

    do while i < maxpts
        if fire[i].age >= maxage then
            fire[i].x = GetRandom(cx - 20, cx + 20)
            fire[i].y = GetRandom(sh - 1, sh - 3)
            fire[i].age = GetRandom(0, maxage / 10)     
        end if
        i += 1
    loop
   
end sub

sub DoFire
    MoveParticles
    AddParticles
    ptc_update @buffer(0)
end sub

Randomize timer

CreatePalette pal(), 255, 255, 0, 255, 0, 0
print "Generating cooling maps. Please wait..."
CreateCoolMap
'Allocate the fire array
fire = Callocate(maxpts * len(particle))
if fire = 0 then
    end -1
end if
AddParticles

if ptc_open("Fire Particles", sw, sh) = 0 then
    end -1
end if

t = timer
do
    if timer > (t + .5) then
        currcoolmap = GetRandom(0, numcoolmaps)
        t = timer
    end if
    DoFire
    sleep .1
loop until inkey<>""
deallocate fire
ptc_close
Challenge Trophies Won:

Offline rdc

  • Pentium
  • *****
  • Posts: 1495
  • Karma: 140
  • Yes, it is me.
    • View Profile
    • Clark Productions
Re: Fire Particle System
« Reply #7 on: February 02, 2007 »
Thanks man. I did try a smoothed version but didn't really like the result. Instead I am using an alpha value for each particle based on both the age of the particle (not in this version) and if the particle overlaps another particle. I think the result is a little cleaner this way.

Thanks for the suggestion though.

Offline ninogenio

  • Pentium
  • *****
  • Posts: 1668
  • Karma: 133
    • View Profile
Re: Fire Particle System
« Reply #8 on: February 02, 2007 »
cool that should work great cant wait to see where it goes it should definitly be faithfull  to real fire then good stuff.
Challenge Trophies Won:

Offline rdc

  • Pentium
  • *****
  • Posts: 1495
  • Karma: 140
  • Yes, it is me.
    • View Profile
    • Clark Productions
Re: Fire Particle System
« Reply #9 on: February 02, 2007 »
Here is the smoothed version, in case you want to look at it. I am only smoothing the fire area (I keep track of the fire boundaries in the move particle routine) so it doesn't have to do the whole screen, but it still impacts the performance a bit. I could manipulate the palette indexes instead, but you lose too much detail that way.

This probably does look more realistic, but I think there would be problems with this technique if this were on top of a background. I would have to keep track of neighboring pixels rather than just looking at the buffer, which would complicate things quite a bit.

Online Shockwave

  • good/evil
  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 17414
  • Karma: 498
  • evil/good
    • View Profile
    • My Homepage
Re: Fire Particle System
« Reply #10 on: February 03, 2007 »
The smoothed version looks to me to be better than the other version.

You've developed this into quite something else indeed, it's a different looking fire technique to most I have seen and it has it's own merits.

Using alpha is not wrong, hell, if it works then fine, but although what you have is very nice, it is really expensive. I like it because it's different. If you wanted to develop a more realistic looking fire effect where you don't have to keep track of particles and you can literally set fire to anything in much higher resolution then I can explain it to you in a lot of detail of you like. I say this partly because I know how tenacious you are and I'd love to see what you would do with the effect once you had the technique down.
Shockwave ^ Codigos
Challenge Trophies Won:

Offline rdc

  • Pentium
  • *****
  • Posts: 1495
  • Karma: 140
  • Yes, it is me.
    • View Profile
    • Clark Productions
Re: Fire Particle System
« Reply #11 on: February 03, 2007 »
Any info would be appreciated man. I am still studying your code and it is quite educational. I appreciate you sharing it.

I agree with you on how expensive this is. Unless you have a really powerful machine, this technique wouldn't work very well except for small particle systems. Still, it is something I hadn't tried before and your fire example got me thinking about fire and about particles in general, so I wanted to give it go and see what turned up. :)

Online Shockwave

  • good/evil
  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 17414
  • Karma: 498
  • evil/good
    • View Profile
    • My Homepage
Re: Fire Particle System
« Reply #12 on: February 03, 2007 »
Ok, cool. Well, in the source I gave you earlier is everything you need probably but it's not too well commented at the moment. So what I'll do is I'll explain the technique here.

The simplest part of the technique (and the most important) is to get the colours done. the best way of doing this is to have an array, you can afford to have quite a big one so you can have a really nice even spread of colours with some interesting variations.

Define say an array of 2000 elements.

Make a sub to fill your array,never mind interpolating colour values, this creates a linear and ugly palette, you need to ditch that. It's more effective to do something like this;

Code: [Select]
SUB MAKE_PALETTE()
DIM AS INTEGER L
DIM AS DOUBLE R,G,B

   R=0
   G=0
   B=0

FOR L=0 TO 999
R=R+.3
G=G+.02
B=B+.01
IF L>50 THEN
R=R+1.3
G=G+.8
B=B+.3
END IF
IF L>500 THEN
R=R+2.3
G=G+1.02
B=B+1.01
END IF

   PALETTE(L) = RGB (R,G,B)
NEXT
END SUB

Now that code is mighty bastardised and may contain mistakes, but you get the idea, you can tweak this palette very easily and can make some nice realistic flame looking colours, the best advantage to it is the overhead it will save you later.

You need a screen buffer for your tinyptc screen, as well as this you need two other buffers, one for a cool map and one for a flame buffer.

The system works by having fire particles that scroll upwards, and on top of that you have a cooling map that also does the same, cooling each part of the flame buffer it is covering progressivley each frame.

So...

Lets forget the cool map for a moment, and we just have our flame buffer.
You will know how to write a number between 0 and 999 into any part of that buffer? That's how this will work.

You could say;

X=200
Y=100
HEAT=999

FLAME_BUFFER (X + (Y * XRES)) = HEAT

Which would set that point of the screen on fire at the hottest temperature. This will be how you write flames into your flame buffer.

We need to scroll the buffer...

Decide a speed for your fire particles to scroll upwards, say 2 or 3 pixels is good.
DO NOT PHYSICALLY SCROLL IT!! This is slow.

All you need to do is have an offset variable.

SCROLLSTART = (SCROLLOFFSET*XRES)

And when you copy the colours into your screen buffer;

FOR A=0 TO (XRES*(YRES-3))
 screen_buffer(SCROLLSTART) = FLAME_BUFFER(SCROLLSTART)
 SCROLLSTART=SCROLLSTART+1
 IF SCROLLSTART>(XRES*YRES) THEN SCROLLSTART=0
NEXT
SCROLLOFFSET=SCROLLOFFSET+3
IF SCROLLOFFSET>YRES THEN SCROLLOFFSET=0

Probably bugged but you get the idea..

The cool map should be a blurry map you can create by plotting a few thousand dots with a value of 999 and then anti aliasing it about 20 - 50 times.

You can use the same offset method as I described above to scroll your cool map.

The anti alias to be as fast as possible should be the addition of the four pixels surrounding the one you are on (NOT INCLUDING IT!) and then perform a shr 2 on the result.

I will comment the earlier source I gave you fully to explain this all better tomorrow :)


 
« Last Edit: February 03, 2007 by Shockwave »
Shockwave ^ Codigos
Challenge Trophies Won:

Online Shockwave

  • good/evil
  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 17414
  • Karma: 498
  • evil/good
    • View Profile
    • My Homepage
Re: Fire Particle System
« Reply #13 on: February 03, 2007 »
Have now commented the main bits here 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 640:' THIS BIT DRAWS THE FIRE ON THE SCREEN
     flame_buffer(LOOPY+(300*640))=640
    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:' SCREEN BOUNDS

    COOL_SCROLL=COOL_SCROLL+3: ' MOVE OFFSET!
    IF COOL_SCROLL>480 THEN COOL_SCROLL=COOL_SCROLL-480: ' RESET OFFSET IF OFF SCREEN
    C=COOL_SCROLL*640 : ' CONVERT OFFSET INTO VALUE COMPATIBLE WITH OUR 1 DIMENSIONAL ARRAYS.
   

    FOR A=640 TO (640*478)     
        FLAME_BUFFER(A)=FLAME_BUFFER(A+1280)-COOL_MAP(C+1280) :' 1280 IS XRES * 2 SO WE SCROLL THE FLAME BUFFER UP 2 LINES AND DARKEN AT SAME TIME TO SAVE SPEED.     
        IF FLAME_BUFFER(A)<0 then FLAME_BUFFER(A)=0 :' STOP ILLEGAL COLOUR PALETTE REFERENCES.
        C=C+1:' MOVE ONLE LINE DOWN.
        IF C>D THEN C=640:' IF C OFF SCREEN THEN PUT C BACK AT END OF IST SCAN LINE.
       
    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:' CHEAP ANTI ALIAS OF FLAME BUFFER                 
         FLAME_BUFFER(A)=B:' NB, THIS LOOP COULD PROBABLY BE COMBINED WITH ABOVE LOOP TO INCREASE SPEED MORE.
    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:' WE'LL PLOT 4000 POINTS IN THE MAP.
        COOL_MAP((RND*(639*477))+640)=RND*640 :' RANDOM POINT IN COOL MAP = RANDOM VALUE UP TO 640
    NEXT
    FOR C=1 TO 10: ' THE NUMBER OF AA PASSES, MORE PASSES = BRIGHTER FLAMES.
    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 :' ACTUALLY DARKENS THE CENTRAL PIXEL SLIGHTLY, IS DESIRABLE..
        IF B<0 THEN B = 0: ' MAKE IT IN BOUNDS AND BULLET PROOF
        IF B>500 THEN B=500:'MAKE IT IN BOUNDS AND BULLET PROOF
        COOL_MAP(A)=INT(B) :' MAKE SURE IT'S AN INTEGER.
    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

To give you an idea of how fast this could be, I can see improvements now that could be made to my code. If the loops were all changed to pointer arithmetic, it would be significantly faster again. And it's not slow now. Full screen fire in 800*600 would be no problem at all.

Anyway, hope this helps Rick, please do post questions, I'm expecting a few!
Shockwave ^ Codigos
Challenge Trophies Won:

Offline rdc

  • Pentium
  • *****
  • Posts: 1495
  • Karma: 140
  • Yes, it is me.
    • View Profile
    • Clark Productions
Re: Fire Particle System
« Reply #14 on: February 03, 2007 »
Thanks a bunch. I'll look at it.

Offline ninogenio

  • Pentium
  • *****
  • Posts: 1668
  • Karma: 133
    • View Profile
Re: Fire Particle System
« Reply #15 on: February 03, 2007 »
really top notch tut shockwave very handy!

cheers.
Challenge Trophies Won:

Offline rdc

  • Pentium
  • *****
  • Posts: 1495
  • Karma: 140
  • Yes, it is me.
    • View Profile
    • Clark Productions
Re: Fire Particle System
« Reply #16 on: February 03, 2007 »
A little something I did for my peeps over at Ascii World.


Offline taj

  • Bytes hurt
  • DBF Aficionado
  • ******
  • Posts: 4810
  • Karma: 189
  • Scene there, done that.
    • View Profile
Re: Fire Particle System
« Reply #17 on: February 03, 2007 »
rdc,

I have to join the gang and offer you karma here for one of the best uses of particles Ive seen in a long time. Wrath of Khan was better but they had a slightly bigger budget than you ;-)
Challenge Trophies Won:

Online Shockwave

  • good/evil
  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 17414
  • Karma: 498
  • evil/good
    • View Profile
    • My Homepage
Re: Fire Particle System
« Reply #18 on: February 03, 2007 »
That's some wicked Ascii fire! :) Nice one.
Shockwave ^ Codigos
Challenge Trophies Won:

Offline rdc

  • Pentium
  • *****
  • Posts: 1495
  • Karma: 140
  • Yes, it is me.
    • View Profile
    • Clark Productions
Re: Fire Particle System
« Reply #19 on: February 03, 2007 »
Taj: lol. If only I had the budget. :)

Shock: Thanks. I think I got the gist of the algo from your most excellent tutorial/code example. Stay tuned... :)