#include #include //the GLUT graphics library #include //the numerical simulation FFTW library #include "fluids.h" #include "palette.h" #include "colormap.h" #define FALSE 0 #define TRUE !FALSE void do_one_simulation_step(void) { if (!frozen) { calculate_one_simulation_step(); glutPostRedisplay(); } } //reshape: Handle window resizing (reshaping) events void reshape(int w, int h) { glViewport(0.0f, 0.0f, (GLfloat)w, (GLfloat)h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0f, (GLfloat)w / (GLfloat)h, 0.1, 5000.0f); //glOrtho(0.0, (GLdouble)w, 0.0, (GLdouble)h, -100, 100); //glFrustum(-1.0, 1.0, -1.0, 1.0, 0.1, 1000.0); winWidth = w; winHeight = h; } //display: Handle window redrawing events. Simply delegates to visualize(). void display(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); visualize(); glFlush(); glutSwapBuffers(); } void setup_menu(void) { int submenu_color, submenu_oliverscolor, submenu_clamp, submenu_scale, submenu_glyphs, submenu_glyphs_usage, submenu_glyphs_scalar,submenu_glyphs_vector; submenu_color = glutCreateMenu(selectColor); glutAddMenuEntry("Greyscale", COLOR_BLACKWHITE); glutAddMenuEntry("Rainbow", COLOR_RAINBOW); glutAddMenuEntry("Band", COLOR_BANDS); glutAddMenuEntry("Wilrik", COLOR_WILRIK); glutAddMenuEntry("Oliver", COLOR_OLIVER); submenu_glyphs_usage = glutCreateMenu(toggle_glyph_usage); glutAddMenuEntry("Glyphs", NULL); submenu_glyphs_scalar = glutCreateMenu(set_glyph_scalar); glutAddMenuEntry("Density", SCALAR_RHO); glutAddMenuEntry("Velocity", SCALAR_VEL); glutAddMenuEntry("Force", SCALAR_FORCE); submenu_glyphs_vector = glutCreateMenu(set_glyph_vector); glutAddMenuEntry("Velocity", VECTOR_VEL); glutAddMenuEntry("Force", VECTOR_FORCE); submenu_glyphs = glutCreateMenu(NULL); glutAddSubMenu("Use glyphs", submenu_glyphs_usage); glutAddSubMenu("Choose scalar field", submenu_glyphs_scalar); glutAddSubMenu("Choose vector field", submenu_glyphs_vector); submenu_oliverscolor = glutCreateMenu(colormap_set_num_colors); glutAddMenuEntry("0", 0); glutAddMenuEntry("1", 1); glutAddMenuEntry("2", 2); glutAddMenuEntry("4", 4); glutAddMenuEntry("8", 8); glutAddMenuEntry("16", 16); glutAddMenuEntry("32", 32); glutAddMenuEntry("256", 256); submenu_clamp = glutCreateMenu(select_dataset); glutAddMenuEntry("Rho", DATASET_RHO); glutAddMenuEntry("Vel", DATASET_VEL); glutAddMenuEntry("Force", DATASET_FORCE); glutAddMenuEntry("Velocity divergence", DATASET_DIVV); glutAddMenuEntry("Force divergence", DATASET_DIVF); submenu_scale = glutCreateMenu(toggle_autoscale); glutAddMenuEntry("Autoscale", NULL); glutCreateMenu(NULL); glutAddSubMenu("Colormap", submenu_color); glutAddSubMenu("Select Color", submenu_oliverscolor); glutAddSubMenu("Dataset", submenu_clamp); glutAddSubMenu("Autoscaling", submenu_scale); glutAddSubMenu("Glyphs", submenu_glyphs); glutAttachMenu(GLUT_RIGHT_BUTTON); } //keyboard: Handle key presses void keyboard(unsigned char key, int x, int y) { switch (key) { case 't': dt -= 0.001; break; case 'T': dt += 0.001; break; case 'c': color_dir = (color_dir +1) %3; break; case 'S': vec_scale *= 1.2f; break; case 's': vec_scale *= 0.8f; break; case 'V': visc *= 5.0f; break; case 'v': visc *= 0.2f; break; case 'y': toggle_glyph_usage(); break; case 'x': toggle_smoke_usage(); break; case 'm': scalar_col++; if (scalar_col>COLOR_OLIVER) scalar_col=COLOR_BLACKWHITE; break; case 'a': frozen = 1-frozen; break; case 'q': exit(0); break; case 'r': toggle_mouse_rotate(); break; case 'e': toggle_seed_insert(); break; default: break; } } //main: The main program int main(int argc, char **argv) { printf("Fluid Flow Simulation and Visualization\n"); printf("=======================================\n"); printf("Click and drag the mouse to steer the flow!\n"); printf("T/t: increase/decrease simulation timestep\n"); printf("S/s: increase/decrease hedgehog scaling\n"); printf("c: toggle direction coloring on/off\n"); printf("V/vy: increase decrease fluid viscosity\n"); printf("x: toggle drawing matter on/off\n"); printf("y: toggle drawing hedgehogs on/off\n"); printf("m: toggle thru scalar coloring\n"); printf("a: toggle the animation on/off\n"); printf("q: quit\n\n"); glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH); glutInitWindowSize(600, 600); glutCreateWindow("Real-time smoke simulation and visualization"); glutDisplayFunc(display); glutReshapeFunc(reshape); glutIdleFunc(do_one_simulation_step); glutKeyboardFunc(keyboard); glutMotionFunc(drag); glutMouseFunc(click); setup_menu(); init_simulation(DIM); //initialize the simulation data structures glutMainLoop(); //calls do_one_simulation_step, keyboard, display, drag, reshape return 0; }