summaryrefslogtreecommitdiffstats
path: root/Smoke/glut.c
blob: fcdaadd111f7985720c254e567534d46de166f74 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#include <stdlib.h>

#include <GL/glut.h>            //the GLUT graphics library

#include <rfftw.h>              //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;
}