ProjectPhysX / FluidX3D

The fastest and most memory efficient lattice Boltzmann CFD software, running on all GPUs via OpenCL. Free for non-commercial use.
https://youtube.com/@ProjectPhysX
Other
3.48k stars 281 forks source link

Including the scale, frame-info, and copyright notice inside the output PNG files ? #190

Open gitcnd opened 1 month ago

gitcnd commented 1 month ago

I had a try at doing this myself, but it only works for about 5% of the frames... is there a trick to know how to draw those things, or how to wait for them to be drawn, before calling lbm.graphics.write_frame() ?

(By "scale", I mean the coloured bar on the right) pic_2024-06-03_13 11 25_614

ProjectPhysX commented 2 weeks ago

Hi @gitcnd,

a little hack is needed to make this work. Modify the LBM::Graphics::write_frame() function as follows

void LBM::Graphics::write_frame(const uint x1, const uint y1, const uint x2, const uint y2, const string& path, const string& name, const string& extension, bool print_preview) { // save a cropped current frame with two corner points (x1,y1) and (x2,y2)
    info.allow_rendering = false; // temporarily disable interactive rendering
    int* image_data = draw_frame(); // make sure the frame is fully rendered

+   draw_bitmap(image_data); // swap image_data and camera.bitmap
+   key_H = true; // enable color scale
+   info.allow_rendering = true; // to enable main_label() function
+   main_label(1.0/60.0); // draw label on camera.bitmap

    const string filename = default_filename(path, name, extension, lbm->get_t());
    const uint xa=max(min(x1, x2), 0u), xb=min(max(x1, x2), camera.width ); // sort coordinates if necessary
    const uint ya=max(min(y1, y2), 0u), yb=min(max(y1, y2), camera.height);
    Image* image = new Image(xb-xa, yb-ya); // create local copy of frame buffer
    for(uint y=0u; y<image->height(); y++) for(uint x=0u; x<image->width(); x++) image->set_color(x, y, image_data[camera.width*(ya+y)+(xa+x)]);
#ifndef INTERACTIVE_GRAPHICS_ASCII
    if(print_preview) {
        println();
        print_image(image);
        print_info("Image \""+filename+"\" saved.");
    }
#endif // INTERACTIVE_GRAPHICS_ASCII
    running_encoders++;
    thread encoder(encode_image, image, filename, extension, &running_encoders); // the main bottleneck in rendering images to the hard disk is .png encoding, so encode image in new thread
    encoder.detach(); // detatch thread so it can run concurrently
    info.allow_rendering = true;
}

With color scale enabled, to draw only the color scale and not the rendering settings in the top left corner, add a return; at the end of this line.

Kind regards, Moritz