wave.c
Go to the documentation of this file.
1 /*****************************************************************************
2  * Wave Simulation in OpenGL
3  * (C) 2002 Jakob Thomsen
4  * http://home.in.tum.de/~thomsen
5  * Modified for GLFW by Sylvain Hellegouarch - sh@programmationworld.com
6  * Modified for variable frame rate by Marcus Geelnard
7  * 2003-Jan-31: Minor cleanups and speedups / MG
8  * 2010-10-24: Formatting and cleanup - Camilla Löwy
9  *****************************************************************************/
10 
11 #if defined(_MSC_VER)
12  // Make MS math.h define M_PI
13  #define _USE_MATH_DEFINES
14 #endif
15 
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <math.h>
19 
20 #include <glad/glad.h>
21 #include <GLFW/glfw3.h>
22 
23 #include <linmath.h>
24 
25 // Maximum delta T to allow for differential calculations
26 #define MAX_DELTA_T 0.01
27 
28 // Animation speed (10.0 looks good)
29 #define ANIMATION_SPEED 10.0
30 
31 GLfloat alpha = 210.f, beta = -70.f;
32 GLfloat zoom = 2.f;
33 
34 double cursorX;
35 double cursorY;
36 
37 struct Vertex
38 {
39  GLfloat x, y, z;
40  GLfloat r, g, b;
41 };
42 
43 #define GRIDW 50
44 #define GRIDH 50
45 #define VERTEXNUM (GRIDW*GRIDH)
46 
47 #define QUADW (GRIDW - 1)
48 #define QUADH (GRIDH - 1)
49 #define QUADNUM (QUADW*QUADH)
50 
53 
54 /* The grid will look like this:
55  *
56  * 3 4 5
57  * *---*---*
58  * | | |
59  * | 0 | 1 |
60  * | | |
61  * *---*---*
62  * 0 1 2
63  */
64 
65 //========================================================================
66 // Initialize grid geometry
67 //========================================================================
68 
69 void init_vertices(void)
70 {
71  int x, y, p;
72 
73  // Place the vertices in a grid
74  for (y = 0; y < GRIDH; y++)
75  {
76  for (x = 0; x < GRIDW; x++)
77  {
78  p = y * GRIDW + x;
79 
80  vertex[p].x = (GLfloat) (x - GRIDW / 2) / (GLfloat) (GRIDW / 2);
81  vertex[p].y = (GLfloat) (y - GRIDH / 2) / (GLfloat) (GRIDH / 2);
82  vertex[p].z = 0;
83 
84  if ((x % 4 < 2) ^ (y % 4 < 2))
85  vertex[p].r = 0.0;
86  else
87  vertex[p].r = 1.0;
88 
89  vertex[p].g = (GLfloat) y / (GLfloat) GRIDH;
90  vertex[p].b = 1.f - ((GLfloat) x / (GLfloat) GRIDW + (GLfloat) y / (GLfloat) GRIDH) / 2.f;
91  }
92  }
93 
94  for (y = 0; y < QUADH; y++)
95  {
96  for (x = 0; x < QUADW; x++)
97  {
98  p = 4 * (y * QUADW + x);
99 
100  quad[p + 0] = y * GRIDW + x; // Some point
101  quad[p + 1] = y * GRIDW + x + 1; // Neighbor at the right side
102  quad[p + 2] = (y + 1) * GRIDW + x + 1; // Upper right neighbor
103  quad[p + 3] = (y + 1) * GRIDW + x; // Upper neighbor
104  }
105  }
106 }
107 
108 double dt;
109 double p[GRIDW][GRIDH];
110 double vx[GRIDW][GRIDH], vy[GRIDW][GRIDH];
111 double ax[GRIDW][GRIDH], ay[GRIDW][GRIDH];
112 
113 //========================================================================
114 // Initialize grid
115 //========================================================================
116 
117 void init_grid(void)
118 {
119  int x, y;
120  double dx, dy, d;
121 
122  for (y = 0; y < GRIDH; y++)
123  {
124  for (x = 0; x < GRIDW; x++)
125  {
126  dx = (double) (x - GRIDW / 2);
127  dy = (double) (y - GRIDH / 2);
128  d = sqrt(dx * dx + dy * dy);
129  if (d < 0.1 * (double) (GRIDW / 2))
130  {
131  d = d * 10.0;
132  p[x][y] = -cos(d * (M_PI / (double)(GRIDW * 4))) * 100.0;
133  }
134  else
135  p[x][y] = 0.0;
136 
137  vx[x][y] = 0.0;
138  vy[x][y] = 0.0;
139  }
140  }
141 }
142 
143 
144 //========================================================================
145 // Draw scene
146 //========================================================================
147 
149 {
150  // Clear the color and depth buffers
152 
153  // We don't want to modify the projection matrix
155  glLoadIdentity();
156 
157  // Move back
158  glTranslatef(0.0, 0.0, -zoom);
159  // Rotate the view
160  glRotatef(beta, 1.0, 0.0, 0.0);
161  glRotatef(alpha, 0.0, 0.0, 1.0);
162 
164 
165  glfwSwapBuffers(window);
166 }
167 
168 
169 //========================================================================
170 // Initialize Miscellaneous OpenGL state
171 //========================================================================
172 
173 void init_opengl(void)
174 {
175  // Use Gouraud (smooth) shading
177 
178  // Switch on the z-buffer
180 
183  glVertexPointer(3, GL_FLOAT, sizeof(struct Vertex), vertex);
184  glColorPointer(3, GL_FLOAT, sizeof(struct Vertex), &vertex[0].r); // Pointer to the first color
185 
186  glPointSize(2.0);
187 
188  // Background color is black
189  glClearColor(0, 0, 0, 0);
190 }
191 
192 
193 //========================================================================
194 // Modify the height of each vertex according to the pressure
195 //========================================================================
196 
197 void adjust_grid(void)
198 {
199  int pos;
200  int x, y;
201 
202  for (y = 0; y < GRIDH; y++)
203  {
204  for (x = 0; x < GRIDW; x++)
205  {
206  pos = y * GRIDW + x;
207  vertex[pos].z = (float) (p[x][y] * (1.0 / 50.0));
208  }
209  }
210 }
211 
212 
213 //========================================================================
214 // Calculate wave propagation
215 //========================================================================
216 
217 void calc_grid(void)
218 {
219  int x, y, x2, y2;
220  double time_step = dt * ANIMATION_SPEED;
221 
222  // Compute accelerations
223  for (x = 0; x < GRIDW; x++)
224  {
225  x2 = (x + 1) % GRIDW;
226  for(y = 0; y < GRIDH; y++)
227  ax[x][y] = p[x][y] - p[x2][y];
228  }
229 
230  for (y = 0; y < GRIDH; y++)
231  {
232  y2 = (y + 1) % GRIDH;
233  for(x = 0; x < GRIDW; x++)
234  ay[x][y] = p[x][y] - p[x][y2];
235  }
236 
237  // Compute speeds
238  for (x = 0; x < GRIDW; x++)
239  {
240  for (y = 0; y < GRIDH; y++)
241  {
242  vx[x][y] = vx[x][y] + ax[x][y] * time_step;
243  vy[x][y] = vy[x][y] + ay[x][y] * time_step;
244  }
245  }
246 
247  // Compute pressure
248  for (x = 1; x < GRIDW; x++)
249  {
250  x2 = x - 1;
251  for (y = 1; y < GRIDH; y++)
252  {
253  y2 = y - 1;
254  p[x][y] = p[x][y] + (vx[x2][y] - vx[x][y] + vy[x][y2] - vy[x][y]) * time_step;
255  }
256  }
257 }
258 
259 
260 //========================================================================
261 // Print errors
262 //========================================================================
263 
264 static void error_callback(int error, const char* description)
265 {
266  fprintf(stderr, "Error: %s\n", description);
267 }
268 
269 
270 //========================================================================
271 // Handle key strokes
272 //========================================================================
273 
274 void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
275 {
276  if (action != GLFW_PRESS)
277  return;
278 
279  switch (key)
280  {
281  case GLFW_KEY_ESCAPE:
283  break;
284  case GLFW_KEY_SPACE:
285  init_grid();
286  break;
287  case GLFW_KEY_LEFT:
288  alpha += 5;
289  break;
290  case GLFW_KEY_RIGHT:
291  alpha -= 5;
292  break;
293  case GLFW_KEY_UP:
294  beta -= 5;
295  break;
296  case GLFW_KEY_DOWN:
297  beta += 5;
298  break;
299  case GLFW_KEY_PAGE_UP:
300  zoom -= 0.25f;
301  if (zoom < 0.f)
302  zoom = 0.f;
303  break;
304  case GLFW_KEY_PAGE_DOWN:
305  zoom += 0.25f;
306  break;
307  default:
308  break;
309  }
310 }
311 
312 
313 //========================================================================
314 // Callback function for mouse button events
315 //========================================================================
316 
317 void mouse_button_callback(GLFWwindow* window, int button, int action, int mods)
318 {
319  if (button != GLFW_MOUSE_BUTTON_LEFT)
320  return;
321 
322  if (action == GLFW_PRESS)
323  {
325  glfwGetCursorPos(window, &cursorX, &cursorY);
326  }
327  else
329 }
330 
331 
332 //========================================================================
333 // Callback function for cursor motion events
334 //========================================================================
335 
337 {
339  {
340  alpha += (GLfloat) (x - cursorX) / 10.f;
341  beta += (GLfloat) (y - cursorY) / 10.f;
342 
343  cursorX = x;
344  cursorY = y;
345  }
346 }
347 
348 
349 //========================================================================
350 // Callback function for scroll events
351 //========================================================================
352 
353 void scroll_callback(GLFWwindow* window, double x, double y)
354 {
355  zoom += (float) y / 4.f;
356  if (zoom < 0)
357  zoom = 0;
358 }
359 
360 
361 //========================================================================
362 // Callback function for framebuffer resize events
363 //========================================================================
364 
366 {
367  float ratio = 1.f;
368  mat4x4 projection;
369 
370  if (height > 0)
371  ratio = (float) width / (float) height;
372 
373  // Setup viewport
374  glViewport(0, 0, width, height);
375 
376  // Change to the projection matrix and set our viewing volume
378  mat4x4_perspective(projection,
379  60.f * (float) M_PI / 180.f,
380  ratio,
381  1.f, 1024.f);
382  glLoadMatrixf((const GLfloat*) projection);
383 }
384 
385 
386 //========================================================================
387 // main
388 //========================================================================
389 
390 int main(int argc, char* argv[])
391 {
393  double t, dt_total, t_old;
394  int width, height;
395 
397 
398  if (!glfwInit())
399  exit(EXIT_FAILURE);
400 
401  window = glfwCreateWindow(640, 480, "Wave Simulation", NULL, NULL);
402  if (!window)
403  {
404  glfwTerminate();
405  exit(EXIT_FAILURE);
406  }
407 
413 
414  glfwMakeContextCurrent(window);
416  glfwSwapInterval(1);
417 
418  glfwGetFramebufferSize(window, &width, &height);
419  framebuffer_size_callback(window, width, height);
420 
421  // Initialize OpenGL
422  init_opengl();
423 
424  // Initialize simulation
425  init_vertices();
426  init_grid();
427  adjust_grid();
428 
429  // Initialize timer
430  t_old = glfwGetTime() - 0.01;
431 
432  while (!glfwWindowShouldClose(window))
433  {
434  t = glfwGetTime();
435  dt_total = t - t_old;
436  t_old = t;
437 
438  // Safety - iterate if dt_total is too large
439  while (dt_total > 0.f)
440  {
441  // Select iteration time step
442  dt = dt_total > MAX_DELTA_T ? MAX_DELTA_T : dt_total;
443  dt_total -= dt;
444 
445  // Calculate wave propagation
446  calc_grid();
447  }
448 
449  // Compute height of each vertex
450  adjust_grid();
451 
452  // Draw wave grid to OpenGL display
453  draw_scene(window);
454 
455  glfwPollEvents();
456  }
457 
458  glfwTerminate();
459  exit(EXIT_SUCCESS);
460 }
461 
#define MAX_DELTA_T
Definition: wave.c:26
#define glShadeModel
GLFWAPI void glfwSetInputMode(GLFWwindow *window, int mode, int value)
Sets an input option for the specified window.
Definition: input.c:484
#define glEnableClientState
GLint y
#define GLFW_KEY_LEFT
Definition: glfw3.h:419
GLfloat t
Definition: particles.c:71
vec4 mat4x4[4]
Definition: linmath.h:83
double cursorY
Definition: wave.c:35
khronos_float_t GLfloat
GLFWAPI int glfwGetInputMode(GLFWwindow *window, int mode)
Returns the value of an input option for the specified window.
Definition: input.c:461
void mouse_button_callback(GLFWwindow *window, int button, int action, int mods)
Definition: wave.c:317
GLfloat zoom
Definition: wave.c:32
#define glRotatef
#define GL_VERTEX_ARRAY
The header of the GLFW 3 API.
GLFWAPI GLFWglproc glfwGetProcAddress(const char *procname)
Returns the address of the specified function for the current context.
Definition: context.c:741
#define glVertexPointer
GLfloat x
Definition: particles.c:73
GLfloat GLfloat p
Definition: glext.h:12687
void *(* GLADloadproc)(const char *name)
double p[GRIDW][GRIDH]
Definition: wave.c:109
static GLFWwindow * window
Definition: joysticks.c:55
GLfloat y
Definition: particles.c:73
GLdouble GLdouble GLdouble y2
#define GLFW_KEY_UP
Definition: glfw3.h:421
double vy[GRIDW][GRIDH]
Definition: wave.c:110
#define GL_PROJECTION
void init_vertices(void)
Definition: wave.c:69
#define GLFW_CURSOR
Definition: glfw3.h:1001
void key_callback(GLFWwindow *window, int key, int scancode, int action, int mods)
Definition: wave.c:274
void draw_scene(GLFWwindow *window)
Definition: wave.c:148
#define GLFW_KEY_SPACE
Definition: glfw3.h:360
#define GRIDH
Definition: wave.c:44
#define glPointSize
GLfloat r
Definition: wave.c:40
GLFWAPI GLFWerrorfun glfwSetErrorCallback(GLFWerrorfun cbfun)
Sets the error callback.
Definition: init.c:309
GLFWAPI GLFWmousebuttonfun glfwSetMouseButtonCallback(GLFWwindow *window, GLFWmousebuttonfun cbfun)
Sets the mouse button callback.
Definition: input.c:821
void framebuffer_size_callback(GLFWwindow *window, int width, int height)
Definition: wave.c:365
struct Vertex vertex[VERTEXNUM]
Definition: wave.c:52
int main(int argc, char *argv[])
Definition: wave.c:390
#define GLFW_MOUSE_BUTTON_LEFT
Definition: glfw3.h:546
#define GLFW_KEY_PAGE_DOWN
Definition: glfw3.h:423
GLFWAPI GLFWframebuffersizefun glfwSetFramebufferSizeCallback(GLFWwindow *window, GLFWframebuffersizefun cbfun)
Sets the framebuffer resize callback for the specified window.
Definition: window.c:1050
d
Definition: rmse.py:171
#define glLoadIdentity
#define GLFW_KEY_PAGE_UP
Definition: glfw3.h:422
#define GRIDW
Definition: wave.c:43
#define glEnable
static void mat4x4_perspective(mat4x4 m, float y_fov, float aspect, float n, float f)
Definition: linmath.h:357
GLuint64 key
Definition: glext.h:8966
#define GLFW_CURSOR_DISABLED
Definition: glfw3.h:1008
#define GL_SMOOTH
GLFWAPI int glfwInit(void)
Initializes the GLFW library.
Definition: init.c:198
GLdouble f
GLfloat GLfloat GLfloat alpha
#define GL_FLOAT
#define GL_COLOR_BUFFER_BIT
#define GLFW_CURSOR_NORMAL
Definition: glfw3.h:1006
GLdouble GLdouble r
static void error_callback(int error, const char *description)
Definition: wave.c:264
GLdouble x
GLFWAPI void glfwSwapInterval(int interval)
Sets the swap interval for the current context.
Definition: context.c:658
GLdouble GLdouble x2
#define glLoadMatrixf
#define GLFW_KEY_ESCAPE
Definition: glfw3.h:412
#define glClear
GLint GLsizei GLsizei height
GLFWAPI void glfwSwapBuffers(GLFWwindow *window)
Swaps the front and back buffers of the specified window.
Definition: context.c:641
GLFWAPI void glfwMakeContextCurrent(GLFWwindow *window)
Makes the context of the specified window current for the calling thread.
Definition: context.c:611
#define glTranslatef
GLfloat beta
Definition: wave.c:31
void calc_grid(void)
Definition: wave.c:217
#define GL_QUADS
double ay[GRIDW][GRIDH]
Definition: wave.c:111
GLFWAPI GLFWcursorposfun glfwSetCursorPosCallback(GLFWwindow *window, GLFWcursorposfun cbfun)
Sets the cursor position callback.
Definition: input.c:832
GLuint quad[4 *QUADNUM]
Definition: wave.c:51
GLfloat g
Definition: wave.c:40
void init_opengl(void)
Definition: wave.c:173
action
Definition: enums.py:62
GLAPI int gladLoadGLLoader(GLADloadproc)
Definition: glad/glad.c:1697
#define glViewport
#define GL_DEPTH_BUFFER_BIT
#define GL_MODELVIEW
static const textual_icon exit
Definition: model-views.h:254
GLfloat z
Definition: particles.c:73
GLFWAPI void glfwSetWindowShouldClose(GLFWwindow *window, int value)
Sets the close flag of the specified window.
Definition: window.c:486
GLfloat b
Definition: wave.c:40
GLFWAPI GLFWwindow * glfwCreateWindow(int width, int height, const char *title, GLFWmonitor *monitor, GLFWwindow *share)
Creates a window and its associated context.
Definition: window.c:151
#define GLFW_TRUE
One.
Definition: glfw3.h:279
double ax[GRIDW][GRIDH]
Definition: wave.c:111
GLFWAPI void glfwGetCursorPos(GLFWwindow *window, double *xpos, double *ypos)
Retrieves the position of the cursor relative to the client area of the window.
Definition: input.c:637
#define GLFW_KEY_DOWN
Definition: glfw3.h:420
GLFWAPI double glfwGetTime(void)
Returns the value of the GLFW timer.
Definition: input.c:1275
void init_grid(void)
Definition: wave.c:117
unsigned int GLuint
double t_old
Definition: boing.c:105
GLFWAPI GLFWscrollfun glfwSetScrollCallback(GLFWwindow *window, GLFWscrollfun cbfun)
Sets the scroll callback.
Definition: input.c:854
GLFWAPI void glfwGetFramebufferSize(GLFWwindow *window, int *width, int *height)
Retrieves the size of the framebuffer of the specified window.
Definition: window.c:647
#define glDrawElements
GLFWAPI void glfwTerminate(void)
Terminates the GLFW library.
Definition: init.c:243
#define GL_COLOR_ARRAY
#define glClearColor
GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow *window, GLFWkeyfun cbfun)
Sets the key callback.
Definition: input.c:791
float rs2_vector::* pos
GLFWAPI void glfwPollEvents(void)
Processes all pending events.
Definition: window.c:1072
void adjust_grid(void)
Definition: wave.c:197
double vx[GRIDW][GRIDH]
Definition: wave.c:110
#define NULL
Definition: tinycthread.c:47
#define VERTEXNUM
Definition: wave.c:45
void scroll_callback(GLFWwindow *window, double x, double y)
Definition: wave.c:353
#define glColorPointer
#define GLFW_KEY_RIGHT
Definition: glfw3.h:418
#define GLFW_PRESS
The key or mouse button was pressed.
Definition: glfw3.h:304
#define QUADNUM
Definition: wave.c:49
#define QUADH
Definition: wave.c:48
#define QUADW
Definition: wave.c:47
double dt
Definition: wave.c:108
void cursor_position_callback(GLFWwindow *window, double x, double y)
Definition: wave.c:336
#define glMatrixMode
#define GL_UNSIGNED_INT
struct GLFWwindow GLFWwindow
#define ANIMATION_SPEED
Definition: wave.c:29
GLint GLsizei width
double cursorX
Definition: wave.c:34
#define GL_DEPTH_TEST
GLFWAPI int glfwWindowShouldClose(GLFWwindow *window)
Checks the close flag of the specified window.
Definition: window.c:477


librealsense2
Author(s): Sergey Dorodnicov , Doron Hirshberg , Mark Horn , Reagan Lopez , Itay Carpis
autogenerated on Mon May 3 2021 02:50:23