Basilisk CFD
Adaptive Cartesian mesh PDE framework
Loading...
Searching...
No Matches
output.h
Go to the documentation of this file.
1/** @file output.h
2 */
3/**
4## Output PPM to screen on GPUs
5
6When running on GPUs the [output_ppm()](/src/output.h#output_ppm)
7function can be used to display a field directly on the video
8display. The syntax is the same as that of `output_ppm()` with the
9exception of the `fps` parameter which specifies the maximum number of
10frames-per-second to display.
11
12For example
13
14~~~literatec
15 output_ppm (f, fp = NULL, fps = 30, map = jet, spread = -1, linear = true);
16~~~
17
18will display field `f` with a maximum of 30 frames per second.
19
20When the mouse/keyboard focus is on the window, the following keys can
21be used to control the simulation:
22
23* SPACE : start/pause
24* S : do a single timestep
25* Q : exits
26
27The simulation can also be started in 'pause' mode using
28
29~~~literatec
30 Display.paused = true;
31~~~
32
33before calling 'run()'. */
34
35typedef struct {
39
40static struct {
41 bool paused, step;
42} Display = {false, false};
43
44static void key_callback (GLFWwindow * window, int key, int scancode, int action, int mods)
45{
46 switch (key) {
47
48 case GLFW_KEY_SPACE:
49 if (action == GLFW_RELEASE)
50 Display.paused = !Display.paused;
51 break;
52
53 case GLFW_KEY_Q:
54 if (action == GLFW_PRESS)
55 exit (1);
56 break;
57
58 case GLFW_KEY_S:
59 if (action == GLFW_PRESS || action == GLFW_REPEAT) {
60 Display.paused = true;
61 Display.step = true;
62 }
63 break;
64
65 }
66}
67
69 scalar f,
70 FILE * fp = stdout,
71 int n = N,
72 char * file = NULL,
73 float min = 0, float max = 0, float spread = 5,
74 double z = 0,
75 bool linear = false,
76 coord box[2] = {{X0, Y0}, {X0 + L0, Y0 + L0*Dimensions.y/Dimensions.x}},
77 scalar mask = {-1},
78 Colormap map = jet,
79 char * opt = NULL,
80 int fps = 0)
81{
82 if (display->frameStartTime < 0.) // window has been closed by user
83 return;
84
85 glFinish(); // synchronize CPU and GPU
86 if (fp || file || (fps && glfwGetTime() - display->frameStartTime > 1./fps)) {
87
88 /**
89 Automatic boundary conditions seem to conflict with the
90 foreach_region() fragment shader loop below, so we apply them
91 manually if necessary. */
92
93 if (linear)
94 boundary ({f});
95
96 /**
97 This code should be the same as
98 [output_ppm](/src/output.h#output_ppm), from here ... */
99
100 // default values
101 if (!min && !max) {
102 stats s = statsf (f);
103 if (spread < 0.)
104 min = s.min, max = s.max;
105 else {
106 double avg = s.sum/s.volume;
107 min = avg - spread*s.stddev; max = avg + spread*s.stddev;
108 }
109 }
110 box[0].z = z, box[1].z = z;
111
112 coord cn = {n};
113 double delta = (box[1].x - box[0].x)/n;
114 cn.y = (int)((box[1].y - box[0].y)/delta);
115 if (((int)cn.y) % 2) cn.y++;
116
117 /**
118 ... to here. */
119
120 if (!display->window) {
122 display->window = glfwCreateWindow (cn.x, cn.y, f.name, NULL, GPUContext.window);
125
126 // Bind and create VAO, otherwise, we can't do anything in OpenGL.
127 GLuint vao;
128 GL_C (glGenVertexArrays (1, &vao));
130
131 // create vertices of fullscreen quad.
132 float vertices[] = {
133 +0.0f, +0.0f,
134 +1.0f, +0.0f,
135 +0.0f, +1.0f,
136 +1.0f, +0.0f,
137 +1.0f, +1.0f,
138 +0.0f, +1.0f
139 };
140 // upload geometry to GPU.
141 GLuint vbo;
142 GL_C (glGenBuffers (1, &vbo));
144 GL_C (glBufferData (GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW));
145
146 // setup some reasonable default GL state.
148 GL_C (glDepthMask (false));
154 GL_C (glUseProgram (0));
155 GPUContext.current_shader = -1;
158 GL_C (glPointSize (1));
159
160 // enable vertex buffer used for full screen quad rendering.
161 // this buffer is used for all rendering, from now on.
164 GL_C (glVertexAttribPointer ((GLuint)0, 2, GL_FLOAT, GL_FALSE, 2*sizeof(float), (void*)0));
165 }
166 else {
167 glfwSetWindowSize (display->window, cn.x, cn.y);
169 }
170
171 GL_C (glViewport(0, 0, cn.x, cn.y));
173 GL_C (glClearColor (0., 0.0f, 0.0f, 0.0f));
175
176 double dmap[NCMAP][3];
177 (* map) (dmap);
178 vec4 cmap[NCMAP];
179 for (int i = 0; i < NCMAP; i++) {
180 cmap[i].r = dmap[i][0];
181 cmap[i].g = dmap[i][1];
182 cmap[i].b = dmap[i][2];
183 cmap[i].a = 0.;
184 }
185
186 GPUContext.fragment_shader = true;
187
188 coord p;
189 foreach_region (p, box, cn, gpu) {
190 double v;
191 if (mask.i >= 0) { // masking
192 if (linear) {
193 double m = interpolate_linear (point, mask, p.x, p.y, p.z);
194 if (m < 0.)
195 v = nodata;
196 else
197 v = interpolate_linear (point, f, p.x, p.y, p.z);
198 }
199 else {
200 if (mask[] < 0.)
201 v = nodata;
202 else
203 v = f[];
204 }
205 }
206 else if (linear)
207 v = interpolate_linear (point, f, p.x, p.y, p.z);
208 else
209 v = f[];
210 if (v == nodata)
211 FragColor = (vec4){0,0,0,0};
212 else {
213 int i;
214 float val = max != min ? (v - min)/(max - min) : 0., coef;
215 if (val <= 0.) i = 0, coef = 0.;
216 else if (val >= 1.) i = NCMAP - 2, coef = 1.;
217 else {
218 i = (int)(val*(NCMAP - 1));
219 coef = val*(NCMAP - 1) - i;
220 }
221 FragColor = (vec4) mix (cmap[i], cmap[i + 1], coef);
222 }
223 }
224
225 GPUContext.fragment_shader = false;
226
227 if (fps)
228 glfwSwapBuffers (display->window);
229 display->frameStartTime = glfwGetTime();
230
231 /**
232 File output */
233
234 if (file || fp) {
235 if (file)
236 fp = open_image (file, opt);
237
238 fprintf (fp, "P6\n%g %g 255\n", cn.x, cn.y);
239 unsigned char * ppm = malloc (sizeof(unsigned char)*3*cn.x*cn.y);
240 GL_C (glReadPixels (0, 0, cn.x, cn.y, GL_RGB, GL_UNSIGNED_BYTE, ppm));
241 size_t len = 3*cn.x;
242 unsigned char * line = ppm + len*((size_t) cn.y - 1);
243 for (int i = 0; i < cn.y; i++, line -= len)
244 fwrite (line, sizeof(unsigned char), len, fp);
245 free (ppm);
246
247 if (file)
249 else
250 fflush (fp);
251 }
252
254 }
255
256 if (fps) {
257 do
259 while (Display.paused && !Display.step);
260 Display.step = false;
261 }
262
263 if (display->window && glfwWindowShouldClose (display->window)) {
264 glfwDestroyWindow (display->window);
265 display->frameStartTime = -1; // window closed
266 return;
267 }
268}
269
270#define output_ppm(...) do { \
271 static OutputPPMGPU _display = {0}; \
272 output_ppm_gpu (&_display, __VA_ARGS__); \
273 } while (0)
if TRASH define &&NewPid *& val(newpid, 0, 0, 0)) -> pid > 0) @else @ define is_newpid()(((NewPid *)&val(newpid, 0, 0, 0)) ->pid > 0) @endif Array *linear_tree(size_t size, scalar newpid)
Definition balance.h:13
int min
Definition balance.h:192
#define boundary(...)
static double interpolate_linear(Point point, scalar v, double xp=0., double yp=0., double zp=0.)
define m((k)==0 &&(l)==0 &&(m)==0) macro2 foreach_point(double _x=0.
free(list1)
void spread
Definition centered.h:199
int y
Definition common.h:76
int x
Definition common.h:76
int z
Definition common.h:76
void display(const char *commands, bool overwrite=false)
Definition common.h:527
#define nodata
Definition common.h:7
ivec Dimensions
Definition common.h:173
double L0
Definition common.h:36
int N
Definition common.h:39
double X0
Definition common.h:34
double Y0
Definition common.h:34
scalar f[]
The primary fields are:
Definition two-phase.h:56
#define p
Definition tree.h:320
define sysmalloc malloc define syscalloc calloc define sysrealloc realloc define sysfree free define systrdup strdup define file
Definition config.h:120
Point point
Definition conserving.h:86
else return n
Definition curvature.h:101
trace bool box(bool notics=false, float lc[3]={0}, float lw=1.)
Definition draw.h:1397
scalar s
Definition embed-tree.h:56
double v[2]
Definition embed.h:383
scalar scalar coord coord double double * coef
For non-degenerate cases, the gradient is obtained using either second- or third-order estimates.
Definition embed.h:380
scalar int i
Definition embed.h:74
static int line
Definition errors.c:754
#define GL_TRUE
Definition glad.h:142
#define glClearColor
Definition glad.h:1921
#define GL_LESS
Definition glad.h:152
#define glGenBuffers
Definition glad.h:3225
#define glBindBuffer
Definition glad.h:3219
#define glEnable
Definition glad.h:1942
#define glBindVertexArray
Definition glad.h:3801
#define GL_DEPTH_TEST
Definition glad.h:200
#define glDepthFunc
Definition glad.h:1963
#define glReadPixels
Definition glad.h:1975
#define glFinish
Definition glad.h:1945
#define GL_RGB
Definition glad.h:287
#define GL_FLOAT
Definition glad.h:258
#define glEnableVertexAttribArray
Definition glad.h:3298
#define GL_ARRAY_BUFFER
Definition glad.h:859
#define glGenVertexArrays
Definition glad.h:3807
#define glColorMask
Definition glad.h:1933
#define glBindFramebuffer
Definition glad.h:3756
#define glPointSize
Definition glad.h:1888
#define GL_UNSIGNED_BYTE
Definition glad.h:253
#define GL_CCW
Definition glad.h:186
#define glVertexAttribPointer
Definition glad.h:3532
#define GL_CULL_FACE
Definition glad.h:196
#define glDepthMask
Definition glad.h:1936
#define glBufferData
Definition glad.h:3231
#define GL_COLOR_BUFFER_BIT
Definition glad.h:140
#define glBindTexture
Definition glad.h:2828
#define GL_FRAMEBUFFER
Definition glad.h:1189
#define glFrontFace
Definition glad.h:1879
#define GL_BLEND
Definition glad.h:217
unsigned int GLuint
Definition glad.h:101
#define glViewport
Definition glad.h:2017
#define GL_STATIC_DRAW
Definition glad.h:873
#define GL_FALSE
Definition glad.h:141
#define GL_TEXTURE_2D
Definition glad.h:245
#define glUseProgram
Definition glad.h:3361
#define glDisable
Definition glad.h:1939
#define glClear
Definition glad.h:1918
#define GL_C(stmt)
Definition gpu.h:37
static struct @7 GPUContext
GLFWwindow * window
Definition gpu.h:13
bool paused
Definition output.h:41
bool step
Definition output.h:41
static void key_callback(GLFWwindow *window, int key, int scancode, int action, int mods)
Definition output.h:44
void output_ppm_gpu(OutputPPMGPU *display, scalar f, FILE *fp=stdout, int n=N, char *file=NULL, float min=0, float max=0, float spread=5, double z=0, bool linear=false, coord box[2]={{X0, Y0}, {X0+L0, Y0+L0 *Dimensions.y/Dimensions.x}}, scalar mask={-1}, Colormap map=jet, char *opt=NULL, int fps=0)
Definition output.h:68
static struct @8 Display
static gpu
Definition include.c:978
static int
Definition include.c:978
size_t max
Definition mtrace.h:8
FILE * fp
Definition mtrace.h:7
FILE * open_image(const char *file, const char *options)
Definition output.h:428
#define NCMAP
Definition output.h:194
void(* Colormap)(double cmap[127][3])
Definition output.h:196
void jet(double cmap[127][3])
Definition output.h:198
void close_image(const char *file, FILE *fp)
Definition output.h:508
float frameStartTime
Definition output.h:36
GLFWwindow * window
Definition output.h:37
Definition common.h:78
double y
Definition common.h:79
int y
Definition common.h:142
int x
Definition common.h:140
The statsf() function returns the minimum, maximum, volume sum, standard deviation and volume for fie...
Definition utils.h:166
Definition common.h:561
float r
Definition common.h:562
macro mask(double func)
Definition tree.h:1432
stats statsf(scalar f)
Definition utils.h:170
src vof fflush(ferr)