Hi. Im having some trouble converting a sample from processing (www.processing.org) for creating the old school pixel fire effect.
My fire just doesnt travel up the screen more that 3 pixels. Ok 6 pixels it is.
The code looks correct to me, but the result is different.
Below:
My Bmax code and luis2048's FireCube (without the cube) and with a HSB to RGB function:
Edit: Updated my code. Thanks Merx!
My fire just doesnt travel up the screen more that 3 pixels. Ok 6 pixels it is.
The code looks correct to me, but the result is different.
Below:
My Bmax code and luis2048's FireCube (without the cube) and with a HSB to RGB function:
SuperStrict Framework BRL.GlMax2D Import BRL.Random AppTitle = "firefx, thanks to Merx for making it work ;)" 'converted from a processing example by luis2048. 'check www.processing.org Global resX:Int=320, resY:Int=240 SetGraphicsDriver GLMax2DDriver() Graphics resX,resY,0,0 Local frames:Int=0 Local fps:Int=0 Local sec:Long = MilliSecs() Local fireEffect:Fire = New Fire fireEffect.setup() Global pixmap:TPixmap = CreatePixmap(resX,resY,PF_RGB888) 'PF_RGBA8888 Global mx:Int = resX/2 Global my:Int = resY/2 Global fireIntensity:Int = 39 While(Not KeyHit(KEY_ESCAPE) And Not AppTerminate() ) If(MouseX() > 3 And MouseX() < resX-3) mx = MouseX() + Rand(3) EndIf If(MouseY() > 3 And MouseY() < resY-3) my = MouseY() + Rand(3) EndIf If KeyHit(KEY_UP) fireIntensity:+1 If KeyHit(KEY_DOWN) fireIntensity:-1 If fireIntensity < 35 fireIntensity = 35 If fireIntensity > 45 fireIntensity = 45 fireEffect.draw() DrawPixmap(pixmap,0,0) DrawText("fps: "+fps, 0,0) DrawText("fireIntensity: "+Int(fireIntensity),0,25) If(sec < MilliSecs() ) sec = MilliSecs() + 1000 fps = frames frames = 0 EndIf frames :+1 Flip Cls Wend End Type Fire Field fire:Int[,] Field paletteR:Int[] Field paletteG:Int[] Field paletteB:Int[] Field calc1:Int[] Field calc2:Int[] Field calc3:Int[] Field calc4:Int[] Field calc5:Int[] Method setup() calc1 = New Int[resX] calc3 = New Int[resX] calc4 = New Int[resX] calc2 = New Int[resY] calc5 = New Int[resY] fire = New Int[resX,resY] paletteR = New Int[255] paletteG = New Int[255] paletteB = New Int[255] 'generate palette Local i:Int For i=0 Until 255 Local h#= i/3.0 Local s#= 1.0 Local l#= i*2.0 Mod 255 Local rgb:Float[] = New Float[3] HSV2RGB( h, s, l, rgb ) paletteR[i] = rgb[0]*255.0 paletteG[i] = rgb[1]*255.0 paletteB[i] = rgb[2]*255.0 Next 'precalc wich pixel values to add during animation For Local x:Int=0 Until resX calc1[x] = x Mod resX calc3[x] = (x - 1 + resX) Mod resX calc4[x] = (x + 1) Mod resX Next For Local y:Int=0 Until resY calc2[y] = (y + 1) Mod resY calc5[y] = (y + 2) Mod resY Next End Method Method draw() 'randomize the bottom row of the fire buffer For Local x:Int = 0 Until resX fire[x,resY-1] = Rand(0,190) Next fire[mx,my] = 100 fire[mx+1,my] = 100 fire[mx-1,my] = 100 fire[mx+2,my] = 100 'get pointer to the first pixel Local pixel:Byte Ptr = PixmapPixelPtr(pixmap) 'RGBA 'Do the fire calc for every pixel For Local y:Int = 0 Until resY For Local x:Int = 0 Until resX fire[x,y] =((.. fire[ calc3[x], calc2[y] ].. + fire[ calc1[x], calc2[y] ].. + fire[ calc4[x], calc2[y] ].. + fire[ calc1[x], calc5[y] ] *32) / fireIntensity) 'change the last value here for more/less fire 'multiply by 32 or shl 5 ' Output everything to screen using our palette colors pixel[0] = paletteR[ fire[x,y] ] 'R pixel[1] = paletteG[ fire[x,y] ] 'G pixel[2] = paletteB[ fire[x,y] ] 'B 'pixel[3] = 1 'A pixel:+3 'next pixel Next Next End Method End Type ' Value ranges: ' hue [0,360] ' saturation [0.0,1.0] ' value [0.0, 1.0] ' rgb[] values to be set Function HSV2RGB(H:Float, S:Float, V:Float, rgb:Float[]) Local r:Float = 0 Local g:Float = 0 Local b:Float = 0 If V = 0 R = 0.0; G = 0.0; B = 0.0; Else If S = 0 R = V; G = V; B = V; Else Local hf:Float = H / 60.0; Local i:Int = Int( Floor(hf) ); Local f:Float = hf - i; Local pv:Float = V * ( 1 - S ) Local qv:Float = V * ( 1 - S * f ); Local tv:Float = V * ( 1 - S * ( 1 - f ) ); Select( i ) Case 0 R = V; G = tv; B = pv; Case 1 R = qv; G = V; B = pv; Case 2 R = pv; G = V; B = tv; Case 3 R = pv; G = qv; B = V; Case 4 R = tv; G = pv; B = V; Case 5 R = V; G = pv; B = qv; Case 6 R = V; G = tv; B = pv; Case -1 R = V; G = pv; B = qv; End Select EndIf rgb[0] = r; rgb[1] = g; rgb[2] = b; End Function
/** * Fire Cube demo effect * by luis2048. * * A rotating wireframe cube with flames rising up the screen. * The fire effect has been used quite often for oldskool demos. * First you create a palette of 256 colors ranging from red to * yellow (including black). For every frame, calculate each row * of pixels based on the two rows below it: The value of each pixel, * becomes the sum of the 3 pixels below it (one directly below, one * to the left, and one to the right), and one pixel directly two * rows below it. Then divide the sum so that the fire dies out as * it rises. */ // This will contain the pixels used to calculate the fire effect int[][] fire; // Flame colors color[] palette; int[] calc1,calc2,calc3,calc4,calc5; PGraphics pg; void setup(){ size(640, 360, P2D); // Create buffered image for 3d cube pg = createGraphics(width, height, P2D); calc1 = new int[width]; calc3 = new int[width]; calc4 = new int[width]; calc2 = new int[height]; calc5 = new int[height]; colorMode(RGB); fire = new int[width][height]; palette = new color[255]; // Generate the palette for(int x = 0; x < palette.length; x++) { //Hue goes from 0 to 85: red to yellow //Saturation is always the maximum: 255 //Lightness is 0..255 for x=0..128, and 255 for x=128..255 float myHue = x/3.0; float mySaturation = 1.0; float myLightness = x*2 % 255; float rgb[] = new float[3]; //HSL2RGB( myHue, mySaturation, myLightness, rgb); hsv_to_rgb( myHue, mySaturation, myLightness, rgb); palette[x] =color( rgb[0], rgb[1], rgb[2] ); } // Precalculate which pixel values to add during animation loop // this speeds up the effect by 10fps for (int x = 0; x < width; x++) { calc1[x] = x % width; calc3[x] = (x - 1 + width) % width; calc4[x] = (x + 1) % width; } for(int y = 0; y < height; y++) { calc2[y] = (y + 1) % height; calc5[y] = (y + 2) % height; } } void draw() { // Randomize the bottom row of the fire buffer for(int x = 0; x < width; x++) { fire[x][height-1] = int(random(30,190)) ; } loadPixels(); int counter = 0; // Do the fire calculations for every pixel, from top to bottom for (int y = 0; y < height; y++) { for(int x = 0; x < width; x++) { // Add pixel values around current pixel fire[x][y] = ((fire[calc3[x]][calc2[y]] + fire[calc1[x]][calc2[y]] + fire[calc4[x]][calc2[y]] + fire[calc1[x]][calc5[y]]) *32) / 129; // Output everything to screen using our palette colors pixels[counter] = palette[fire[x][y]]; counter++; } } updatePixels(); } // void hsv_to_rgb(float H, float S, float V,float rgb[]){ float R=0; float G=0; float B=0; if( V == 0 ) { R = 0; G = 0; B = 0; } else if( S == 0 ) { R = V; G = V; B = V; } else { float hf = H / 60.0f; int i = (int)floor( hf ); float f = hf - i; float pv = V * ( 1 - S ); float qv = V * ( 1 - S * f ); float tv = V * ( 1 - S * ( 1 - f ) ); switch( i ) { case 0: R = V; G = tv; B = pv; break; case 1: R = qv; G = V; B = pv; break; case 2: R = pv; G = V; B = tv; break; case 3: R = pv; G = qv; B = V; break; case 4: R = tv; G = pv; B = V; break; case 5: R = V; G = pv; B = qv; break; case 6: R = V; G = tv; B = pv; break; case -1: R = V; G = pv; B = qv; break; } } rgb[0] = R; rgb[1] = G; rgb[2] = B; }
Edit: Updated my code. Thanks Merx!