FireCube - screen pixel vs. PGraphic pixel relationship - SOLVED
in
Programming Questions
•
1 year ago
---Solved--- Turns out it was easier than I thought. Anyway I learned a lot by not letting it defeat me.
- /**
- * 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.
- */
- /*
- * Modification by bassnharp to use a class for the cube
- * to allow multiple cubes at the same time
- */
- // This will contain the pixels used to calculate the fire effect
- int[][] fire;
- // Flame colors
- color[] palette;
- color[] palette2;
- float angle;
- int[] calc1,calc2,calc3,calc4,calc5;
- //PGraphics pg;
- int firecubeCount = 5;
- FireCube[] fcubes = new FireCube[firecubeCount];
- void setup(){
- size(500, 360, P2D);
- // Create buffered images for 3d cube
- for (int i = 0; i < firecubeCount; i++) {
- fcubes[i] = new FireCube(100, 100); //
- }
- calc1 = new int[width];
- calc3 = new int[width];
- calc4 = new int[width];
- calc2 = new int[height];
- calc5 = new int[height];
- colorMode(HSB);
- fire = new int[width][height];
- palette = new color[255];
- palette2 = 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
- palette[x] = color(x/3, 255, constrain(x*3, 0, 255));
- }
- // Generate the palette
- for(int x = 100; x < palette2.length + 100; 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
- palette2[x-100] = color(x/3, 255, constrain((x-100)*3, 0, 255));
- }
- // 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() {
- angle = angle + 0.05;
- // Rotating wireframe cube
- for (int i = 0; i < firecubeCount; i++) {
- //fcubes[i].setTranslate(120 +(i*100), height >> 1);
- //fcubes[i].setTranslate(50 + (i*100), 100); // I see something here
- fcubes[i].setPosition((i*100), 50 + (i*50));
- fcubes[i].setAngle(angle);
- fcubes[i].paintCube();
- angle = angle + 0.01;
- }
- // Randomize the bottom row of the fire buffer
- for(int x = 0; x < width; x++)
- {
- fire[x][height-1] = int(random(0,190)) ;
- }
- loadPixels();
- // testing
- //if (false) {
- 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]]) << 5) / 129;
- // Output everything to screen using our palette colors
- if (x < (width/2)) {
- pixels[counter] = palette[fire[x][y]];
- }
- else {
- pixels[counter] = palette2[fire[x][y]];
- }
- counter++;
- }
- }
- // loop through the width and height of the PGraphic array
- // Extract the red value using right shift and bit mask
- // equivalent of red(pg.pixels[x+y*w])
- for (int i = 0; i < firecubeCount; i++) {
- counter = 0;
- for (int y = 0; y < fcubes[i].pg.height; y++) {
- for(int x = 0; x < fcubes[i].pg.width; x++) {
- if ((fcubes[i].pg.pixels[counter++] >> 16 & 0xFF) == 128) {
- fire[fcubes[i].screenPosX + x][fcubes[i].screenPosY + y] = 128;
- }
- } // x - width
- } // y - height
- } // for firecubeCount
- updatePixels();
- }
- class FireCube {
- // Properties
- PGraphics pg;
- float ang = 0;
- int transX, transY;
- int screenPosX, screenPosY;
- // Constructors
- FireCube(){
- this(0, 0);
- }
- FireCube(int widthX, int heightY){
- // Create buffered image for 3d cube
- pg = createGraphics(widthX, heightY, P3D);
- }
- void setPosition(int screenPosX, int screenPosY) {
- this.screenPosX = screenPosX;
- this.screenPosY = screenPosY;
- }
- void setAngle(float ang) {
- this.ang = ang;
- }
- void paintCube() {
- pg.beginDraw();
- pg.translate(pg.width >> 1, pg.height >> 1);
- pg.rotateX(sin(ang/2));
- pg.rotateY(cos(ang/2));
- pg.background(0);
- pg.stroke(128);
- pg.scale(15);
- pg.noFill();
- pg.box(2);
- pg.endDraw();
- }
- }
1