November 30, 2020, 02:23:12 AM

Author Topic: [bb] Explosion Generator (non interactive) by Matty [ 1+ years ago ]  (Read 696 times)

Offline BlitzBot

  • Jr. Member
  • **
  • Posts: 1
Title : Explosion Generator (non interactive)
Author : Matty
Posted : 1+ years ago

Description : This program generates explosion animated images in the format of a 4096x4096 bitmap with 64 frames (8x8 512x512).

There are only two parameters the user needs to set (at the top of the program.)

These are:

1 - flag indicating whether to save/render the image to the hard drive (in subfolder erenders - make sure you have folder permissions!)

2 - the qty of renders you wish to save.

The program will exit after completing the final render or on pressing escape.

Of course using these images in a game will most likely require they be downsampled first......


Code :
Code: BlitzBasic
  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;Only two parameters you need!
  3. Const saverenders = False ;change this accordingly NOTE RENDERING IS SLOW!
  4. Global qty = 4 ;number of explosions to render as animated images change this accordingly
  5.  
  6. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  7. ;Matt Lloyd Explosion Generator (as used in my Space Battle Game for Android Devices)
  8. ;
  9. ;4-April-2015 ML
  10. ;       Note/Caveat - this code is not pretty - I fully admit that.  It is not intended to be.  It does its job and that's it.
  11. ;
  12. ;       This program will generate 2d renders of explosions using blitz3d at a resolution of 512x512.
  13. ;
  14. ;   No user interaction is required once the program starts......fire and forget.......
  15. ;      
  16. ;       If you wish to save these renders then you need to change the value of the const at the top of the program (set 'saverenders' to true)
  17. ;      
  18. ;       Renders are saved as 4096x4096 images (8x8 frames of 512x512 images) into a sub folder called 'erenders' with file naming convention
  19. ;       'explosion_currentdatetime_indexnumber.bmp'
  20. ;      
  21. ;       As far as I am aware 4096x4096 is the largest image that blitz can manage without internally resizing it - so why not go for the maximum resolution!
  22. ;
  23. ;      
  24. ;       Note 2 - It takes a few sequences to warm up before it attempts to render as it tries to make sure that
  25. ;       as much of the texture atlas is consumed.
  26. ;
  27. ;       Note 3  - It exports to bitmap. Yuck.  That can be changed pretty easily.
  28. ;
  29. ;       Note 4 - I imagine this may fail to render anything on certain PCs if they can't keep up with the frame rate.
  30. ;      
  31.  
  32. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  33. ;Technically no need to touch anything beyond this point!  All trespassers will be shot and so forth!
  34. HidePointer
  35. Global camera,ent,pivot,speciallist$
  36. Global explosiontexture
  37. Global cdate$ = Replace(CurrentDate$()," ","_")+"_"+Replace(CurrentTime$(),":","_")
  38. SeedRnd MilliSecs()
  39. main()
  40. End
  41.  
  42.  
  43. Function main()
  44.  
  45. ;miscellaneous vars - you don't need to touch these...
  46. Local box, render, e.explosion, time, time2, time3, frame, f0,f1,f2
  47. Local q, xx#,yy#,zz#,aab,aac,aae,x11,y11
  48.  
  49. init()
  50.  
  51. box = CreateCube()
  52. MoveEntity box,0,0,80
  53. EntityAlpha box,0
  54.  
  55. render = CreateImage(4096,4096); 512*8, 512*8
  56. e.explosion = First explosion
  57. time = MilliSecs()
  58. time2 = 10000
  59. time3 = 10000
  60.  
  61. Repeat
  62.         time11 = MilliSecs()
  63.         Cls
  64.         frame = frame + 1
  65.        
  66.         If(MilliSecs()>time And e=Null) Then
  67.                 f0 = f1
  68.                 f1 = frame
  69.                 f2 = f2+1
  70.                 time2 = f1 + (290/17)
  71.                 time3 = f1 + (130/17)
  72.                 For q = 0 To 2
  73.                         If(q>0) Then
  74.                                 xx# = Rnd(-10,10)
  75.                                 yy# = Rnd(-10,10)
  76.                                 zz# = Rnd(-8,2)
  77.                         EndIf
  78.                         aab = 1 - Sgn(Rand(0,20))
  79.                         aac = 1 - Sgn(Rand(0,2))
  80.                         aae = Sgn(Rand(0,20))
  81.        
  82.                         createexplosion(box,1,aae,aac,aab,Rnd(0.65,1.35),1,0,0,0,0,0,xx,yy,10+zz);
  83.                         If(q=2)
  84.                                 createexplosion(box,0,0,aac,1,Rnd(0.7,1.05),1,0,0,0,0,0,xx,yy,10+zz);
  85.                         EndIf
  86.                 Next   
  87.         EndIf
  88.  
  89.         If(frame>time3) Then
  90.                 For q = 0 To 2
  91.                         If(q<>-1) Then
  92.                                 xx# = Rnd(-20,20)
  93.                                 yy# = Rnd(-20,20)
  94.                                 zz# = Rnd(-1,1)
  95.                         EndIf
  96.                         aac = 1 - Sgn(Rand(0,10))
  97.                         createexplosion(box,3,1,aac,0,Rnd(0.8,1.35),   1,0,0,0,0,0,xx,yy,16+zz);
  98.                         If(q=0) Then
  99.                                 createexplosion(box,0,0,0,1,Rnd(0.6,1.0),1,0,0,0,0,0,xx,yy,16+zz);
  100.                         EndIf
  101.                 Next
  102.                 time3 = frame + 100000
  103.         EndIf
  104.  
  105.         If(frame>time2) Then
  106.                 For q = 0 To 1
  107.                         xx# = Rnd(-20,20)
  108.                         yy# = Rnd(-20,20)
  109.                         If(q=2) Then
  110.                                 xx=xx*1.5
  111.                                 yy=yy*1.5
  112.                         EndIf
  113.                         zz# = Rnd(-2,4)
  114.                         aab = 1- Sgn(Rand(0,1))
  115.                         createexplosion(box,1,aab,1-aab,0,Rnd(0.5,0.85),   1,0,0,0,0,0,xx,yy,8+zz);
  116.                         If(q=0) Then
  117.                                 aab = 1- Sgn(Rand(0,1))
  118.                                 createexplosion(box,0,0,1-aab,aab,Rnd(0.3,0.5),1,0,0,0,0,0,xx,yy,9+zz);
  119.                         EndIf
  120.                 Next   
  121.                 time2 = frame + 10000
  122.         EndIf
  123.  
  124.         updateexplosion()
  125.         RenderWorld
  126.         If(saverenders) Then
  127.                 x11 = (frame - f1) Mod 8
  128.                 y11 = ((frame - f1) - x11) / 8
  129.                 CopyRect 0,0,512,512,x11*512,y11*512,BackBuffer(),ImageBuffer(render)
  130.                 e.explosion = First explosion
  131.                 If(e.explosion = Null And (f1-f0)>55 And (f1-f0)<64) Then
  132.                         i11=i11+1
  133.                         If(i11>2) Then
  134.                                 xr = 3
  135.                                 yr = 3
  136.                                 CopyRect xr*512,yr*512,512,512,0,0,ImageBuffer(render),BackBuffer()
  137.                                 Text 0,0,(f1 - f0)+" Sequence Length"
  138.                                 Text 256,30,"......Please wait Saving LARGE image......",1,1
  139.                                 Flip
  140.                                 SaveImage render,"erendersexplosion_"+cdate$+"_"+i11+".bmp"
  141.                                 qty = qty - 1
  142.                                 Color 0,0,0
  143.                                 SetBuffer ImageBuffer(render)
  144.                                 Rect 0,0,ImageWidth(render),ImageHeight(render),1
  145.                                 SetBuffer BackBuffer()         
  146.                         EndIf
  147.                 EndIf
  148.         Else
  149.                 e.explosion = First explosion
  150.         EndIf
  151.         Color 255,255,255
  152.         Text 0,0,f1 - f0
  153.         If saverenders Then Text 0,15,qty+" renders to go!"
  154.         Flip
  155.         time22 = MilliSecs()-time11
  156.         If(time22<17) Then
  157.                 Delay 17 - time22
  158.         EndIf
  159. Until KeyHit(1) Or qty<=0
  160. End Function
  161.  
  162. Type explosion
  163.  
  164.         Field originalent
  165.         Field ent
  166.         Field typ$
  167.         Field vx#,vy#,vz#
  168.         Field sx#,sy#,sz#
  169.         Field r#,g#,b#,a#
  170.         Field dp#,dy#,dr#
  171.         Field time#
  172.         Field timestep#
  173.         Field trailcreated
  174.         Field special
  175.        
  176. End Type
  177.  
  178. Function updateexplosion()
  179.  
  180. defaulttimestep#=0.025
  181. For e.explosion = Each explosion
  182.         timestep# = e   imestep
  183.         TranslateEntity eent,evx*(timestep/defaulttimestep),evy*(timestep/defaulttimestep),evz*(timestep/defaulttimestep),True
  184.         ScaleEntity eent,esx,esy,esz
  185.         EntityColor eent,e
  186. ,eg,e
  187.         EntityAlpha eent,Float(ea)/255.0
  188.         TurnEntity eent,edp,edy,edr
  189.         e       ime=e   ime+timestep
  190.         updatefunction(e)
  191.         If(especial=1 And e     ime >= 0 And e  ime<e   imestep*5) Then
  192.                 createexplosion(ent,2,True,False,False,4,1,0,0,0,0,0)
  193.         EndIf
  194.         If(especial=1 And e     ime >= e        imestep*5) Then
  195.                 EntityAlpha ent,0
  196.         EndIf
  197.         If(especial>0 And e     ime>e   imestep*Rand(5,10)) Then
  198.                 createexplosion(eent,0,True,True,False,3,1,0,0,0,0,especial-1)
  199.                 especial = 0
  200.         EndIf
  201.         If(e    ime>=1.0 Or ea <= 0 Or esx<=0.001 Or esy<0.001 Or esz<0.001 Or (e
  202. <=0 And eg<=0 And e<=0))
  203.                 FreeEntity eent
  204.                 Delete e
  205.         EndIf
  206. Next
  207.  
  208. End Function
  209.  
  210. Function updatefunction(e.explosion)
  211.  
  212. If(e    yp="flames")
  213.  
  214.         If(e    ime<0.05) Then
  215.                 esx = esx * (1.0 + ((e  ime)/0.05)*0.0125)
  216.                 esy = esy * (1.0 + ((e  ime)/0.05)*0.0125)
  217.                 esz = esz * (1.0 + ((e  ime)/0.05)*0.0125)
  218.                 ea = ea * (1.0-e        imestep*15)
  219.                 MoveEntity eent,evx,evy,evz
  220.         Else
  221.                 If(e    ime<0.5) Then
  222.                         esx = esx * (1.05-e     imestep*55)
  223.                         esy = esy * (1.05-e     imestep*55)
  224.                         esz = esz * (1.05-e     imestep*55)
  225.                         ea = ea * (1.0-e        imestep*5)
  226.                 Else
  227.                         esx = esx * (1.05-e     imestep*5)
  228.                         esy = esy * (1.05-e     imestep*5)
  229.                         esz = esz * (1.05-e     imestep*5)
  230.                         ea = ea * (1.0-e        imestep*25)
  231.                 EndIf
  232.         EndIf
  233. EndIf
  234.  
  235.  
  236. If(e    yp="smoke") Then
  237.         If(e    ime<0.15) Then
  238.                 esx = esx *(1.0+(e      ime/0.15)*0.1)
  239.                 esy = esy *(1.0+(e      ime/0.15)*0.1)
  240.                 esz = esz *(1.0+(e      ime/0.15)*0.1)
  241.                 ea = ea - 0.5
  242.         Else
  243.         If(e    ime>0.5)
  244.                 esx = esx *(1.0-((e     ime-0.5)/0.5)*0.025)
  245.                 esy = esy *(1.0-((e     ime-0.5)/0.5)*0.025)
  246.                 esz = esz *(1.0-((e     ime-0.5)/0.5)*0.025)
  247.         EndIf
  248.         ea=ea-1.25
  249. EndIf
  250.  
  251. If(e    ime<0.3) Then
  252.         evx = evx * (1.0 - (e   ime/0.3)^2)
  253.         evy = evy * (1.0 - (e   ime/0.3)^2)
  254.         evz = evz * (1.0 - (e   ime/0.3)^2)
  255. EndIf
  256.  
  257. EndIf
  258.  
  259.  
  260. If(e    yp="sparks")
  261.  
  262.         ea = 255.0 - (Float(e   railcreated) /50.0) *128.0
  263.  
  264.         esx = esx * (1.0-e      imestep)*0.925
  265.         esx = esx * (1.0-e      imestep)*0.925
  266.         esx = esx * (1.0-e      imestep)*0.925
  267.  
  268.         MoveEntity eent,evx,evy,evz
  269.  
  270.  
  271.         If(e    railcreated<50 )
  272.  
  273.                 ;create a spark at our location with an increased time.....
  274.                 f.explosion = New explosion
  275.                 f       yp = "smoke"
  276.                 foriginalent = eent
  277.                 fent = CreateCube()
  278.                 EntityTexture fent,explosiontexture
  279.                 EntityFX fent,1+16+32
  280.                 fvx = evx*0.0125
  281.                 fvy = evy*0.0125
  282.                 fvz = evz*0.0125
  283.                 fsx = esx*1.5
  284.                 fsy = esy*1.5
  285.                 fsz = esz*1.5
  286.                 PositionEntity fent,EntityX(eent,True),EntityY(eent,True),EntityZ(eent,True)
  287.                 f       ime = 0
  288.                 f       imestep = 0.075
  289.                 f
  290.  = 128
  291.                 fg = 128
  292.                 f = 128
  293.                 fa = 40
  294.                 fdp=Rnd(-10,10)
  295.                 fdy=Rnd(-10,10)
  296.                 fdr=Rnd(-10,10)
  297.                 e       railcreated=e   railcreated+1
  298.         EndIf
  299. EndIf
  300.  
  301. If(esx<=0) Then esx=0.001
  302. If(esy<=0) Then esy=0.001
  303. If(esz<=0) Then esz=0.001
  304. If(ea>255) Then ea=255
  305. If(ea<0) Then ea=0
  306. If(ea>255) Then ea=255
  307. If(e
  308. >255) Then e
  309. =255
  310. If(eg>255) Then eg=255
  311. If(e>255) Then e=255
  312. If(e
  313. <0) Then e
  314. =0
  315. If(eg<0) Then eg=0
  316. If(e<0) Then e=0
  317.  
  318.  
  319. End Function
  320.  
  321.  
  322. Function createexplosion(ent,n,hasflames=True,hassparks=True,hassmoke=True,scale#=1.0,size#=1.0,offsetx#=0,offsety#=0,offsetz#=0,starttime#=0.0,special=0,posx#=0,posy#=0,posz#=0)
  323.  
  324. If(explosiontexture=0) Then
  325.         texsize = 256
  326.         explosiontexture = CreateTexture(texsize,texsize,1+4+2)
  327.         SetBuffer TextureBuffer(explosiontexture)
  328.  
  329.         pxx# = Float(texsize/2)-1
  330.         pyy# = Float(texsize/2)-1
  331.  
  332.         rr# = 0.1
  333.        
  334.         For px = 0 To texsize-1
  335.                 For py = 0 To texsize-1
  336.                         WritePixel px,py,0
  337.                 Next
  338.         Next
  339.        
  340.         aa = ((texsize/2)-4)*8
  341.         For jj = 0 To aa
  342.                 For angle = 0 To 3600
  343.                         myx# = pxx + rr*Cos(Float(angle)/10.0)
  344.                         myy# = pyy + rr*Sin(Float(angle)/10.0)
  345.                         col = Rand(250,255)
  346.                         alpha = (col - (rr*Float(0.16))^2)
  347.                         If(alpha<0) Then alpha = 0
  348.                         If(alpha>255) Then alpha = 255
  349.                         col = alpha
  350.                         WritePixel Int(myx),Int(myy),alpha Shl 24 Or col Shl 16 Or col Shl 8 Or col
  351.                 Next
  352.                 rr=rr+0.1
  353.         Next
  354.         SetBuffer BackBuffer()
  355. EndIf
  356.  
  357.  
  358. ;get bounding box....
  359. xw# = MeshWidth(ent)*size
  360. yw# = MeshHeight(ent)*size
  361. zw# = MeshDepth(ent)*size
  362.  
  363. TFormPoint -xw/2,-yw/2,-zw/2,ent,0
  364. x0# = TFormedX()
  365. y0# = TFormedY()
  366. z0# = TFormedZ()
  367.  
  368. TFormPoint +xw/2,+yw/2,+zw/2,ent,0
  369. x1# = TFormedX()
  370. y1# = TFormedY()
  371. z1# = TFormedZ()
  372.  
  373.  
  374. ;cube = CreateCube()
  375. If(x0<x1) Then xa# = x0 Else xa# = x1
  376. If(y0<y1) Then ya# = y0 Else ya# = y1
  377. If(z0<xz) Then za# = z0 Else za# = z1
  378.  
  379. xstep# = Abs(x1-x0) / 6.0
  380. ystep# = Abs(y1-y0) / 6.0
  381. zstep# = Abs(z1-z0) / 6.0
  382.  
  383. cx# = (offsetx)*(xw)+(x0+x1)/2.0
  384. cy# = (offsety)*(yw)+(y0+y1)/2.0
  385. cz# = (offsetz)*(zw)+(z0+z1)/2.0
  386.  
  387.  
  388. ;flames
  389. For nn = 1 To n+1
  390. If(hasflames)
  391. For i=-1 To 1
  392.         x# = cx+xstep*i*scale*0.5
  393.         For j=-1 To 1
  394.                 y# = cy+ystep*j*scale*0.5
  395.                 For k=-1 To 1
  396.                         If(i=0 And j=0 And k=0) Then
  397.                         Else
  398.  
  399.                         z#=cz+zstep*k*scale*0.5
  400.                         e.explosion = New explosion
  401.                         e       yp = "flames"
  402.                         eoriginalent = ent
  403.                         eent = CreateCube()
  404.                         RotateMesh eent,45,45,45
  405.                         aaa = CreateCube()
  406.                         AddMesh(aaa,eent)
  407.                         FreeEntity aaa
  408.                         EntityTexture eent,explosiontexture
  409.                         EntityFX eent,1+16+32
  410.  
  411.                         evx = scale*Rnd(-1.5,1.5)
  412.                         evy = scale*Rnd(-1.5,1.5)
  413.                         evz = scale*Rnd(-1.5,1.5)
  414.                         aad# = Rnd(0.975,1.01)
  415.                         esx = 7.0*scale*aad
  416.                         esy = 7.0*scale*aad
  417.                         esz = 7.0*scale*aad
  418.                         PositionEntity eent,x+posx,y+posy,z+posz
  419.  
  420.                         e
  421.  = 255
  422.                         eg = 110
  423.                         e = 64
  424.                         ea = 32
  425.                        
  426.                         edp=Rnd(-4,4)
  427.                         edy=Rnd(-4,4)
  428.                         edr=Rnd(-4,4)
  429.                         e       ime = starttime
  430.                         e       imestep = 0.005
  431.                         EntityBlend eent,3
  432.                         EndIf  
  433.                 Next
  434.         Next
  435. Next
  436. EndIf
  437. ;smoke
  438. If(hassmoke)
  439. bstep = Abs(xstep)
  440. If(Abs(ystep)>bstep) Then bstep = Abs(ystep)
  441. If(Abs(zstep)>bstep) Then bstep = Abs(zstep)
  442. For i=-1 To 1
  443.         x# = cx+xstep*i*scale
  444.         For j=-1 To 1
  445.                 y# = cy+ystep*j*scale
  446.                 For k=-1 To 1
  447.                         z#=cz+zstep*k*scale
  448.                         e.explosion = New explosion
  449.                         e       yp = "smoke"
  450.                         eoriginalent = ent
  451.                         eent = CreateCube()
  452.                         EntityTexture eent,explosiontexture
  453.                         EntityFX eent,16+1+32
  454.  
  455.                         sc#=Rand(0.7,1.2)
  456.                         esx = 5.0*scale*sc
  457.                         esy = 5.0*scale*sc
  458.                         esz = 5.0*scale*sc
  459.                
  460.                         rad# = scale * Rnd(0,2)
  461.                         angle1# = Rnd(360)
  462.                         angle2#= Rnd(360)
  463.  
  464.                         evx= 2.5*rad*Cos(angle1)
  465.                         evy= 2.5*rad*Sin(angle1)
  466.                         evz= 2.5*rad*Cos(angle2)
  467.  
  468.                         rad = rad*bstep*0.5
  469.                         PositionEntity eent,posx+cx+rad*Cos(angle1),posy+cy+rad*Sin(angle1),posz+cz+rad*Cos(angle2)
  470.                        
  471.                         e       ime = starttime
  472.                         e       imestep = 0.0075
  473.                         grey=Rand(-8,128)
  474.                         e
  475.  = 48+grey
  476.                         eg = 48+grey
  477.                         e = 48+grey
  478.  
  479.                         ea = 32
  480.  
  481.                         edp=Rnd(-2,2)
  482.                         edy=Rnd(-2,2)
  483.                         edr=Rnd(-2,2)
  484.        
  485.                 Next
  486.         Next
  487. Next
  488.  
  489. EndIf
  490. Next
  491. ;sparks
  492. If(hassparks)
  493. For i=-1 To 1
  494.         x# = cx+xstep*i*Rnd(12,20)*scale
  495.         For j=-1 To 1
  496.                 y# = cy+ystep*j*Rnd(12,20)*scale
  497.                 For k=-1 To 1
  498.                         If(i=0 And j=0 And k=0) Then
  499.                         Else
  500.                         z#=cz+zstep*k*Rnd(12,20)*scale
  501.                         e.explosion = New explosion
  502.                         e       yp = "sparks"
  503.                         eoriginalent = ent
  504.                         eent = CreateCube()
  505.                         EntityTexture eent,explosiontexture
  506.                         EntityFX eent,1+16+32
  507.                         EntityBlend eent,3
  508.                         rad# = scale * Rnd(0,2)
  509.                         angle1# = Rnd(360)
  510.                         angle2#= Rnd(360)
  511.  
  512.                         evx= 1.05*rad*Cos(angle1)
  513.                         evy= 1.05*rad*Sin(angle1)
  514.                         evz= 1.05*rad*Cos(angle2)
  515.                         aad# = Rnd(0.95,1.05)
  516.                         esx = scale*1.4*aad
  517.                         esy = scale*1.4*aad
  518.                         esz = scale*1.4*aad
  519.                         PositionEntity eent,x+posx,y+posy,z+posz
  520.                         e       ime = starttime+0.9975
  521.                         e       imestep = 0.000125
  522.                         e
  523.  = 255
  524.                         eg = 128
  525.                         e = 32
  526.                         ea = 255
  527.        
  528.                         edp=Rnd(-12,12)
  529.                         edy=Rnd(-1.5,1.5)
  530.                         edr=Rnd(-1,1)
  531.                         If(Rand(0,100)<70) Then
  532.                         especial = special
  533.                         If(especial>0) Then
  534.                                 speciallist=speciallist+" " +especial
  535.                         EndIf
  536.                         special = 0
  537.                         EndIf
  538.                         EndIf
  539.                 Next
  540.         Next
  541. Next
  542. EndIf
  543.  
  544. End Function
  545.  
  546. Function init()
  547. Graphics3D 512,512,0,6
  548. camera=CreateCamera()
  549. CameraClsColor camera,0,0,0
  550. AmbientLight(255,255,255)
  551. MoveEntity camera,0,0,00
  552. SetBuffer BackBuffer()
  553. End Function


Comments :


BlitzSupport(Posted 1+ years ago)

 Awesome!


Rick Nasher(Posted 1+ years ago)

 Very impressive explosions without any media! Didn't even know was possible like this. Amazing piece of code and not even that large or anything.


xlsior(Posted 1+ years ago)

 Very, very nice -- I don't suppose there's a way to save them with transparent backgrounds instead of black?


Matty(Posted 1+ years ago)

 Hi xlsior - most likely, but not using the standard 2d image saving routines that blitz comes with.  There is a tga code archives entry which could be applied easily enough.In my own project I didn't need transparency since I was going to be using additive blending .... but yep that would be a good idea.


*(Posted 1+ years ago)

 Might have a go at converting to max or monkey mainly as this would be a brilliant addition for all of us blitzers to use :)Might even make an appearance in Star Rogue :)


_PJ_(Posted 1+ years ago)

 This is very nice indeed, thanks Matty!Maybe setting the Graphics command to a resolution which is more native to the user's screen/gpu may allow for better framerate if they have problems.The viewport itself may be fixed to only render the 512x512 portion so the imagess are still valid, but some GPU perform at their best when at a "comfortable" resolution and/or fullscreen mode.___<div class="quote"> I don't suppose there's a way to save them with transparent backgrounds instead of black? </div>Not by default, you would either need to write a bmp file byte-by-byte* with the alpha flag set or use (as suggested) tga export function from code archives.* Something like:i) get readpixelfast valueii) set alpha flag on valueiii) poke value to bankiv) writebytes of bank to file as bmpThis will be slower than the savebuffer commands of course.


Matty(Posted 1+ years ago)

 Here are some sample explosions<a href="http://mattiesgames.com/articles/mygamepics.html" target="_blank">Link - see bottom of page - long page[/url]


Rick Nasher(Posted 1+ years ago)

 That game is looking just as awesome as the explosions!


Matty(Posted 1+ years ago)

 Edit - here is a version which outputs an image with transparency as a tga image (easy file format to write)
Code: [Select]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Only two parameters you need!
Global  saverenders = True ;change this accordingly NOTE RENDERING IS SLOW!
Global qty = 0 ;number of explosions to render as animated images change this accordingly


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Matt Lloyd Explosion Generator (as used in my Space Battle Game for Android Devices)
;
;4-April-2015 ML
; Note/Caveat - this code is not pretty - I fully admit that.  It is not intended to be.  It does its job and that's it.
;
; This program will generate 2d renders of explosions using blitz3d at a resolution of 512x512.
;
;   No user interaction is required once the program starts......fire and forget.......
;
; If you wish to save these renders then you need to change the value of the const at the top of the program (set 'saverenders' to true)
;
; Renders are saved as 4096x4096 images (8x8 frames of 512x512 images) into a sub folder called 'erenders' with file naming convention
; 'explosion_currentdatetime_indexnumber.tga' (new ! with alpha transparency)
;
; As far as I am aware 4096x4096 is the largest image that blitz can manage without internally resizing it - so why not go for the maximum resolution!
;
; Note 2 - It takes a few sequences to warm up before it attempts to render as it tries to make sure that
; as much of the texture atlas is consumed.
;
;
;
;
;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Technically no need to touch anything beyond this point!  All trespassers will be shot and so forth!
HidePointer
Global camera,ent,pivot,speciallist$
Global explosiontexture
Global cdate$ = Replace(CurrentDate$()," ","_")+"_"+Replace(CurrentTime$(),":","_")
Global rendertex

SeedRnd MilliSecs()
main()
End
Function main()

;miscellaneous vars - you don't need to touch these...
Local box, render, e.explosion, time, time2, time3, frame, f0,f1,f2
Local q, xx#,yy#,zz#,aab,aac,aae,x11,y11

init()
qty2$ = Input("Qty To Save (erenders/)? (enter -1 to view only)")
qty = Int(qty2$)
If(qty<0) Then qty = -1
If(qty>999) Then qty = 999




box = CreateCube()
MoveEntity box,0,0,80
EntityAlpha box,0

render = CreateImage(4096,4096); 512*8, 512*8
rendertex = CreateTexture(4096,4096,1+2)
clearrendertex()
e.explosion = First explosion
time = MilliSecs()
time2 = 10000
time3 = 10000
Repeat
time11 = MilliSecs()
Cls
frame = frame + 1

If(MilliSecs()>time And e=Null) Then
f0 = f1
f1 = frame
f2 = f2+1
time2 = f1 + (290/17)
time3 = f1 + (130/17)
For q = 0 To 2
If(q>0) Then
xx# = Rnd(-10,10)
yy# = Rnd(-10,10)
zz# = Rnd(-8,2)
EndIf
aab = 1 - Sgn(Rand(0,20))
aac = 1 - Sgn(Rand(0,2))
aae = Sgn(Rand(0,20))

createexplosion(box,1,aae,aac,aab,Rnd(0.65,1.35),1,0,0,0,0,0,xx,yy,10+zz);
If(q=2)
createexplosion(box,0,0,aac,1,Rnd(0.7,1.05),1,0,0,0,0,0,xx,yy,10+zz);
EndIf
Next
EndIf

If(frame>time3) Then
For q = 0 To 2
If(q<>-1) Then
xx# = Rnd(-20,20)
yy# = Rnd(-20,20)
zz# = Rnd(-1,1)
EndIf
aac = 1 - Sgn(Rand(0,10))
createexplosion(box,3,1,aac,0,Rnd(0.8,1.35),   1,0,0,0,0,0,xx,yy,16+zz);
If(q=0) Then
createexplosion(box,0,0,0,1,Rnd(0.6,1.0),1,0,0,0,0,0,xx,yy,16+zz);
EndIf
Next
time3 = frame + 100000
EndIf

If(frame>time2) Then
For q = 0 To 1
xx# = Rnd(-20,20)
yy# = Rnd(-20,20)
If(q=2) Then
xx=xx*1.5
yy=yy*1.5
EndIf
zz# = Rnd(-2,4)
aab = 1- Sgn(Rand(0,1))
createexplosion(box,1,aab,1-aab,0,Rnd(0.5,0.85),   1,0,0,0,0,0,xx,yy,8+zz);
If(q=0) Then
aab = 1- Sgn(Rand(0,1))
createexplosion(box,0,0,1-aab,aab,Rnd(0.3,0.5),1,0,0,0,0,0,xx,yy,9+zz);
EndIf
Next
time2 = frame + 10000
EndIf

updateexplosion()
CameraClsMode camera,True,True
RenderWorld
If(saverenders And qty>0) Then
x11 = (frame - f1) Mod 8
y11 = ((frame - f1) - x11) / 8
If(i11>1) Then savetorendertex(x11,y11)

;CopyRect 0,0,512,512,x11*512,y11*512,BackBuffer(),ImageBuffer(render)
e.explosion = First explosion
If(e.explosion = Null And (f1-f0)>55 And (f1-f0)<64) Then
i11=i11+1
If(i11>2) Then
xr = 3
yr = 3
;CopyRect xr*512,yr*512,512,512,0,0,ImageBuffer(render),BackBuffer()
Color 0,0,0
Text 0,0,(f1 - f0)+" Sequence Length"
Text 256,30,"......Please wait Saving LARGE image......",1,1
Flip
If(FileType("erenders")=2) Then
;SaveImage render,"erendersexplosion_"+cdate$+"_"+i11+".bmp"
saverendertex("erendersexplosion_"+cdate$+"_"+i11+".tga")
Else
If(FileType("erenders")=0) Then
CreateDir("erenders")
If(FileType("erenders")=2) Then
;SaveImage render,"erendersexplosion_"+cdate$+"_"+i11+".bmp"
saverendertex("erendersexplosion_"+cdate$+"_"+i11+".tga")
EndIf
EndIf
EndIf
qty = qty - 1
Color 0,0,0
SetBuffer ImageBuffer(render)
Rect 0,0,ImageWidth(render),ImageHeight(render),1
SetBuffer BackBuffer()
EndIf
EndIf



Else
e.explosion = First explosion
EndIf
Color 255,255,255
Text 0,0,f1 - f0
If saverenders Then Text 0,15,qty+" renders to go!"
Text 400,0,"ESC to Exit"
Flip
time22 = MilliSecs()-time11
If(time22<17) Then
Delay 17 - time22
EndIf
Until KeyHit(1) Or qty=0
End Function

Type explosion

Field originalent
Field ent
Field typ$
Field vx#,vy#,vz#
Field sx#,sy#,sz#
Field r#,g#,b#,a#
Field dp#,dy#,dr#
Field time#
Field timestep#
Field trailcreated
Field special

End Type

Function updateexplosion()

defaulttimestep#=0.025
For e.explosion = Each explosion
timestep# = e imestep
TranslateEntity eent,evx*(timestep/defaulttimestep),evy*(timestep/defaulttimestep),evz*(timestep/defaulttimestep),True
ScaleEntity eent,esx,esy,esz
EntityColor eent,e,eg,e
EntityAlpha eent,Float(ea)/255.0
TurnEntity eent,edp,edy,edr
e ime=e ime+timestep
updatefunction(e)
If(especial=1 And e ime >= 0 And e ime<e imestep*5) Then
createexplosion(ent,2,True,False,False,4,1,0,0,0,0,0)
EndIf
If(especial=1 And e ime >= e imestep*5) Then
EntityAlpha ent,0
EndIf
If(especial>0 And e ime>e imestep*Rand(5,10)) Then
createexplosion(eent,0,True,True,False,3,1,0,0,0,0,especial-1)
especial = 0
EndIf
If(e ime>=1.0 Or ea <= 0 Or esx<=0.001 Or esy<0.001 Or esz<0.001 Or (e<=0 And eg<=0 And e<=0))
FreeEntity eent
Delete e
EndIf
Next

End Function

Function updatefunction(e.explosion)

If(e yp="flames")

If(e ime<0.05) Then
esx = esx * (1.0 + ((e ime)/0.05)*0.0125)
esy = esy * (1.0 + ((e ime)/0.05)*0.0125)
esz = esz * (1.0 + ((e ime)/0.05)*0.0125)
ea = ea * (1.0-e imestep*15)
MoveEntity eent,evx,evy,evz
Else
If(e ime<0.5) Then
esx = esx * (1.05-e imestep*55)
esy = esy * (1.05-e imestep*55)
esz = esz * (1.05-e imestep*55)
ea = ea * (1.0-e imestep*5)
Else
esx = esx * (1.05-e imestep*5)
esy = esy * (1.05-e imestep*5)
esz = esz * (1.05-e imestep*5)
ea = ea * (1.0-e imestep*25)
EndIf
EndIf
EndIf


If(e yp="smoke") Then
If(e ime<0.15) Then
esx = esx *(1.0+(e ime/0.15)*0.1)
esy = esy *(1.0+(e ime/0.15)*0.1)
esz = esz *(1.0+(e ime/0.15)*0.1)
ea = ea - 0.5
Else
If(e ime>0.5)
esx = esx *(1.0-((e ime-0.5)/0.5)*0.025)
esy = esy *(1.0-((e ime-0.5)/0.5)*0.025)
esz = esz *(1.0-((e ime-0.5)/0.5)*0.025)
EndIf
ea=ea-1.25
EndIf

If(e ime<0.3) Then
evx = evx * (1.0 - (e ime/0.3)^2)
evy = evy * (1.0 - (e ime/0.3)^2)
evz = evz * (1.0 - (e ime/0.3)^2)
EndIf

EndIf


If(e yp="sparks")

ea = 255.0 - (Float(e railcreated) /50.0) *128.0

esx = esx * (1.0-e imestep)*0.925
esx = esx * (1.0-e imestep)*0.925
esx = esx * (1.0-e imestep)*0.925

MoveEntity eent,evx,evy,evz


If(e railcreated<50 )

;create a spark at our location with an increased time.....
f.explosion = New explosion
f yp = "smoke"
foriginalent = eent
fent = CreateCube()
EntityTexture fent,explosiontexture
EntityFX fent,1+16+32
fvx = evx*0.0125
fvy = evy*0.0125
fvz = evz*0.0125
fsx = esx*1.5
fsy = esy*1.5
fsz = esz*1.5
PositionEntity fent,EntityX(eent,True),EntityY(eent,True),EntityZ(eent,True)
f ime = 0
f imestep = 0.075
f = 128
fg = 128
f = 128
fa = 40
fdp=Rnd(-10,10)
fdy=Rnd(-10,10)
fdr=Rnd(-10,10)
e railcreated=e railcreated+1
EndIf
EndIf

If(esx<=0) Then esx=0.001
If(esy<=0) Then esy=0.001
If(esz<=0) Then esz=0.001
If(ea>255) Then ea=255
If(ea<0) Then ea=0
If(ea>255) Then ea=255
If(e>255) Then e=255
If(eg>255) Then eg=255
If(e>255) Then e=255
If(e<0) Then e=0
If(eg<0) Then eg=0
If(e<0) Then e=0


End Function


Function createexplosion(ent,n,hasflames=True,hassparks=True,hassmoke=True,scale#=1.0,size#=1.0,offsetx#=0,offsety#=0,offsetz#=0,starttime#=0.0,special=0,posx#=0,posy#=0,posz#=0)

If(explosiontexture=0) Then
texsize = 256
explosiontexture = CreateTexture(texsize,texsize,1+4+2)
SetBuffer TextureBuffer(explosiontexture)

pxx# = Float(texsize/2)-1
pyy# = Float(texsize/2)-1

rr# = 0.1

For px = 0 To texsize-1
For py = 0 To texsize-1
WritePixel px,py,0
Next
Next

aa = ((texsize/2)-4)*8
For jj = 0 To aa
For angle = 0 To 3600
myx# = pxx + rr*Cos(Float(angle)/10.0)
myy# = pyy + rr*Sin(Float(angle)/10.0)
col = Rand(250,255)
alpha = (col - (rr*Float(0.16))^2)
If(alpha<0) Then alpha = 0
If(alpha>255) Then alpha = 255
col = alpha
WritePixel Int(myx),Int(myy),alpha Shl 24 Or col Shl 16 Or col Shl 8 Or col
Next
rr=rr+0.1
Next
SetBuffer BackBuffer()
EndIf


;get bounding box....
xw# = MeshWidth(ent)*size
yw# = MeshHeight(ent)*size
zw# = MeshDepth(ent)*size

TFormPoint -xw/2,-yw/2,-zw/2,ent,0
x0# = TFormedX()
y0# = TFormedY()
z0# = TFormedZ()

TFormPoint +xw/2,+yw/2,+zw/2,ent,0
x1# = TFormedX()
y1# = TFormedY()
z1# = TFormedZ()


;cube = CreateCube()
If(x0<x1) Then xa# = x0 Else xa# = x1
If(y0<y1) Then ya# = y0 Else ya# = y1
If(z0<xz) Then za# = z0 Else za# = z1

xstep# = Abs(x1-x0) / 6.0
ystep# = Abs(y1-y0) / 6.0
zstep# = Abs(z1-z0) / 6.0

cx# = (offsetx)*(xw)+(x0+x1)/2.0
cy# = (offsety)*(yw)+(y0+y1)/2.0
cz# = (offsetz)*(zw)+(z0+z1)/2.0


;flames
For nn = 1 To n+1
If(hasflames)
For i=-1 To 1
x# = cx+xstep*i*scale*0.5
For j=-1 To 1
y# = cy+ystep*j*scale*0.5
For k=-1 To 1
If(i=0 And j=0 And k=0) Then
Else

z#=cz+zstep*k*scale*0.5
e.explosion = New explosion
e yp = "flames"
eoriginalent = ent
eent = CreateCube()
RotateMesh eent,45,45,45
aaa = CreateCube()
AddMesh(aaa,eent)
FreeEntity aaa
EntityTexture eent,explosiontexture
EntityFX eent,1+16+32

evx = scale*Rnd(-1.5,1.5)
evy = scale*Rnd(-1.5,1.5)
evz = scale*Rnd(-1.5,1.5)
aad# = Rnd(0.975,1.01)
esx = 7.0*scale*aad
esy = 7.0*scale*aad
esz = 7.0*scale*aad
PositionEntity eent,x+posx,y+posy,z+posz

e = 255
eg = 110
e = 64
ea = 32

edp=Rnd(-4,4)
edy=Rnd(-4,4)
edr=Rnd(-4,4)
e ime = starttime
e imestep = 0.005
EntityBlend eent,3
EndIf
Next
Next
Next
EndIf
;smoke
If(hassmoke)
bstep = Abs(xstep)
If(Abs(ystep)>bstep) Then bstep = Abs(ystep)
If(Abs(zstep)>bstep) Then bstep = Abs(zstep)
For i=-1 To 1
x# = cx+xstep*i*scale
For j=-1 To 1
y# = cy+ystep*j*scale
For k=-1 To 1
z#=cz+zstep*k*scale
e.explosion = New explosion
e yp = "smoke"
eoriginalent = ent
eent = CreateCube()
EntityTexture eent,explosiontexture
EntityFX eent,16+1+32

sc#=Rand(0.7,1.2)
esx = 5.0*scale*sc
esy = 5.0*scale*sc
esz = 5.0*scale*sc

rad# = scale * Rnd(0,2)
angle1# = Rnd(360)
angle2#= Rnd(360)

evx= 2.5*rad*Cos(angle1)
evy= 2.5*rad*Sin(angle1)
evz= 2.5*rad*Cos(angle2)

rad = rad*bstep*0.5
PositionEntity eent,posx+cx+rad*Cos(angle1),posy+cy+rad*Sin(angle1),posz+cz+rad*Cos(angle2)

e ime = starttime
e imestep = 0.0075
grey=Rand(-8,128)
e = 48+grey
eg = 48+grey
e = 48+grey

ea = 32

edp=Rnd(-2,2)
edy=Rnd(-2,2)
edr=Rnd(-2,2)

Next
Next
Next

EndIf
Next
;sparks
If(hassparks)
For i=-1 To 1
x# = cx+xstep*i*Rnd(12,20)*scale
For j=-1 To 1
y# = cy+ystep*j*Rnd(12,20)*scale
For k=-1 To 1
If(i=0 And j=0 And k=0) Then
Else
z#=cz+zstep*k*Rnd(12,20)*scale
e.explosion = New explosion
e yp = "sparks"
eoriginalent = ent
eent = CreateCube()
EntityTexture eent,explosiontexture
EntityFX eent,1+16+32
EntityBlend eent,3
rad# = scale * Rnd(0,2)
angle1# = Rnd(360)
angle2#= Rnd(360)

evx= 1.05*rad*Cos(angle1)
evy= 1.05*rad*Sin(angle1)
evz= 1.05*rad*Cos(angle2)
aad# = Rnd(0.95,1.05)
esx = scale*1.4*aad
esy = scale*1.4*aad
esz = scale*1.4*aad
PositionEntity eent,x+posx,y+posy,z+posz
e ime = starttime+0.9975
e imestep = 0.000125
e = 255
eg = 128
e = 32
ea = 255

edp=Rnd(-12,12)
edy=Rnd(-1.5,1.5)
edr=Rnd(-1,1)
If(Rand(0,100)<70) Then
especial = special
If(especial>0) Then
speciallist=speciallist+" " +especial
EndIf
special = 0
EndIf
EndIf
Next
Next
Next
EndIf

End Function

Function init()
Graphics3D 512,512,0,6
camera=CreateCamera()
CameraClsColor camera,0,0,0
AmbientLight(255,255,255)
MoveEntity camera,0,0,00
SetBuffer BackBuffer()
End Function
Function clearrendertex()
SetBuffer TextureBuffer(rendertex)
LockBuffer TextureBuffer(rendertex)
For x = 0 To 4095
For y = 0 To 4095
WritePixelFast x,y,0
Next
Next
UnlockBuffer TextureBuffer(rendertex)
SetBuffer BackBuffer()
End Function
Function savetorendertex(x11,y11)
;save as a texture.......with alpha...by rendering over black and white respectively......
CameraClsColor camera,0,0,0
RenderWorld
CopyRect 0,0,512,512,x11*512,y11*512,BackBuffer(),TextureBuffer(rendertex)
CameraClsColor camera,255,255,255
RenderWorld
CameraClsColor camera,0,0,0
LockBuffer BackBuffer()
LockBuffer TextureBuffer(rendertex)
For x=0 To 511
For y = 0 To 511
ix11 = x11*512 + x
iy11 = y11*512 + y
rgbblack = ReadPixelFast(ix11,iy11,TextureBuffer(rendertex))
rgbwhite = ReadPixelFast(x,y,BackBuffer())
;all the pixels that are black 0,0,0 and white 255,255,255 are transparent....
rb = (rgbblack Shr 16) And 255
gb = (rgbblack Shr 8) And 255
bb = rgbblack And 255

rw = (rgbwhite Shr 16) And 255
gw = (rgbwhite Shr 8) And 255
bw = rgbwhite And 255

alpha = 255
If(rb=0 And gb=0 And bb=0 And rw=255 And gw=255 And bw=255) Then
;completely transparent....
alpha = 0
EndIf
sb = (rb + gb + bb)/3
sw = (rw + gw + bw)/3
awb = 255 - (sw - sb)
If(awb<0) Then awb = 0
If(awb>255) Then awb = 255
alpha = awb

WritePixelFast(ix11,iy11,rb Shl 16 Or gb Shl 8 Or bb Or alpha Shl 24,TextureBuffer(rendertex))
Next
Next
UnlockBuffer TextureBuffer(rendertex)
UnlockBuffer BackBuffer()
End Function
Function saverendertex(filename$)
outbank = CreateBank(18+4096*4096*4)
PokeByte outbank,0,0
PokeByte outbank,1,0
PokeByte outbank,2,2
For i = 1 To 9
PokeByte outbank,2+i,0
Next
PokeShort outbank,12,4096
PokeShort outbank,14,4096
PokeByte outbank,16,32
PokeByte outbank,17,0
offset = 18
LockBuffer TextureBuffer(rendertex)
For iy = 4095 To 0 Step -1
For ix = 0 To 4095
argb = ReadPixelFast(ix,iy,TextureBuffer(rendertex))
PokeByte outbank,offset,argb And 255
PokeByte outbank,offset+1,(argb Shr 8) And 255
PokeByte outbank,offset+2,(argb Shr 16) And 255
PokeByte outbank,offset+3,(argb Shr 24) And 255
offset = offset + 4
Next
Next
UnlockBuffer TextureBuffer(rendertex)

outfile = WriteFile(filename)
WriteBytes outbank,outfile,0,BankSize(outbank)
CloseFile outfile
FreeBank outbank
End Function



xlsior(Posted 1+ years ago)

 Nice of you to revisit this!When I run it, it shows a slow explosion being rendered with a white background, it says to wait while saving a large image, but the resulting image loads in Photoshop with a black background, not transparent... Do I need to tweak anything else, or is this Photoshop misunderstanding the transparancy?


Matty(Posted 1+ years ago)

 Id say it is photoshop.  It opens paint.net with correct alpha.


Matty(Posted 1+ years ago)

 Additional : its slower because it has to render each frame twice. Once with a black and once with a white background to calculate the alpha channel pixel by pixel.


xlsior(Posted 1+ years ago)

 Yup, you're right -- the alpha does show properly in paint.netAgain, fantastic job!


Bobysait(Posted 1+ years ago)

 It's quite good !But ... Save yourself some headackes and use the tabulation key :)There is no way programming can be fun while debugging such unindented code.ps : just a tip for the alpha without the tga extension :You could use 2 bitmaps for output- one with the color- one with the alpha on the red channel (or blue channel, it should be faster as there is no shift to perform)Then it is easy to convert on any software or on blitzmax (where you can save in png with alpha and compression using SavePixmapPNG) [/i]

 

SimplePortal 2.3.6 © 2008-2014, SimplePortal