heightmap.c
Go to the documentation of this file.
1 //========================================================================
2 // Heightmap example program using OpenGL 3 core profile
3 // Copyright (c) 2010 Olivier Delannoy
4 //
5 // This software is provided 'as-is', without any express or implied
6 // warranty. In no event will the authors be held liable for any damages
7 // arising from the use of this software.
8 //
9 // Permission is granted to anyone to use this software for any purpose,
10 // including commercial applications, and to alter it and redistribute it
11 // freely, subject to the following restrictions:
12 //
13 // 1. The origin of this software must not be misrepresented; you must not
14 // claim that you wrote the original software. If you use this software
15 // in a product, an acknowledgment in the product documentation would
16 // be appreciated but is not required.
17 //
18 // 2. Altered source versions must be plainly marked as such, and must not
19 // be misrepresented as being the original software.
20 //
21 // 3. This notice may not be removed or altered from any source
22 // distribution.
23 //
24 //========================================================================
25 
26 #include <stdlib.h>
27 #include <stdio.h>
28 #include <math.h>
29 #include <assert.h>
30 #include <stddef.h>
31 
32 #include <glad/glad.h>
33 #include <GLFW/glfw3.h>
34 
35 /* Map height updates */
36 #define MAX_CIRCLE_SIZE (5.0f)
37 #define MAX_DISPLACEMENT (1.0f)
38 #define DISPLACEMENT_SIGN_LIMIT (0.3f)
39 #define MAX_ITER (200)
40 #define NUM_ITER_AT_A_TIME (1)
41 
42 /* Map general information */
43 #define MAP_SIZE (10.0f)
44 #define MAP_NUM_VERTICES (80)
45 #define MAP_NUM_TOTAL_VERTICES (MAP_NUM_VERTICES*MAP_NUM_VERTICES)
46 #define MAP_NUM_LINES (3* (MAP_NUM_VERTICES - 1) * (MAP_NUM_VERTICES - 1) + \
47  2 * (MAP_NUM_VERTICES - 1))
48 
49 
50 /**********************************************************************
51  * Default shader programs
52  *********************************************************************/
53 
54 static const char* vertex_shader_text =
55 "#version 150\n"
56 "uniform mat4 project;\n"
57 "uniform mat4 modelview;\n"
58 "in float x;\n"
59 "in float y;\n"
60 "in float z;\n"
61 "\n"
62 "void main()\n"
63 "{\n"
64 " gl_Position = project * modelview * vec4(x, y, z, 1.0);\n"
65 "}\n";
66 
67 static const char* fragment_shader_text =
68 "#version 150\n"
69 "out vec4 color;\n"
70 "void main()\n"
71 "{\n"
72 " color = vec4(0.2, 1.0, 0.2, 1.0); \n"
73 "}\n";
74 
75 /**********************************************************************
76  * Values for shader uniforms
77  *********************************************************************/
78 
79 /* Frustum configuration */
80 static GLfloat view_angle = 45.0f;
81 static GLfloat aspect_ratio = 4.0f/3.0f;
82 static GLfloat z_near = 1.0f;
83 static GLfloat z_far = 100.f;
84 
85 /* Projection matrix */
86 static GLfloat projection_matrix[16] = {
87  1.0f, 0.0f, 0.0f, 0.0f,
88  0.0f, 1.0f, 0.0f, 0.0f,
89  0.0f, 0.0f, 1.0f, 0.0f,
90  0.0f, 0.0f, 0.0f, 1.0f
91 };
92 
93 /* Model view matrix */
94 static GLfloat modelview_matrix[16] = {
95  1.0f, 0.0f, 0.0f, 0.0f,
96  0.0f, 1.0f, 0.0f, 0.0f,
97  0.0f, 0.0f, 1.0f, 0.0f,
98  0.0f, 0.0f, 0.0f, 1.0f
99 };
100 
101 /**********************************************************************
102  * Heightmap vertex and index data
103  *********************************************************************/
104 
107 
108 /* Store uniform location for the shaders
109  * Those values are setup as part of the process of creating
110  * the shader program. They should not be used before creating
111  * the program.
112  */
113 static GLuint mesh;
114 static GLuint mesh_vbo[4];
115 
116 /**********************************************************************
117  * OpenGL helper functions
118  *********************************************************************/
119 
120 /* Creates a shader object of the specified type using the specified text
121  */
122 static GLuint make_shader(GLenum type, const char* text)
123 {
124  GLuint shader;
125  GLint shader_ok;
126  GLsizei log_length;
127  char info_log[8192];
128 
129  shader = glCreateShader(type);
130  if (shader != 0)
131  {
132  glShaderSource(shader, 1, (const GLchar**)&text, NULL);
133  glCompileShader(shader);
134  glGetShaderiv(shader, GL_COMPILE_STATUS, &shader_ok);
135  if (shader_ok != GL_TRUE)
136  {
137  fprintf(stderr, "ERROR: Failed to compile %s shader\n", (type == GL_FRAGMENT_SHADER) ? "fragment" : "vertex" );
138  glGetShaderInfoLog(shader, 8192, &log_length,info_log);
139  fprintf(stderr, "ERROR: \n%s\n\n", info_log);
140  glDeleteShader(shader);
141  shader = 0;
142  }
143  }
144  return shader;
145 }
146 
147 /* Creates a program object using the specified vertex and fragment text
148  */
149 static GLuint make_shader_program(const char* vs_text, const char* fs_text)
150 {
151  GLuint program = 0u;
152  GLint program_ok;
153  GLuint vertex_shader = 0u;
154  GLuint fragment_shader = 0u;
155  GLsizei log_length;
156  char info_log[8192];
157 
158  vertex_shader = make_shader(GL_VERTEX_SHADER, vs_text);
159  if (vertex_shader != 0u)
160  {
161  fragment_shader = make_shader(GL_FRAGMENT_SHADER, fs_text);
162  if (fragment_shader != 0u)
163  {
164  /* make the program that connect the two shader and link it */
165  program = glCreateProgram();
166  if (program != 0u)
167  {
168  /* attach both shader and link */
169  glAttachShader(program, vertex_shader);
170  glAttachShader(program, fragment_shader);
171  glLinkProgram(program);
172  glGetProgramiv(program, GL_LINK_STATUS, &program_ok);
173 
174  if (program_ok != GL_TRUE)
175  {
176  fprintf(stderr, "ERROR, failed to link shader program\n");
177  glGetProgramInfoLog(program, 8192, &log_length, info_log);
178  fprintf(stderr, "ERROR: \n%s\n\n", info_log);
179  glDeleteProgram(program);
180  glDeleteShader(fragment_shader);
181  glDeleteShader(vertex_shader);
182  program = 0u;
183  }
184  }
185  }
186  else
187  {
188  fprintf(stderr, "ERROR: Unable to load fragment shader\n");
189  glDeleteShader(vertex_shader);
190  }
191  }
192  else
193  {
194  fprintf(stderr, "ERROR: Unable to load vertex shader\n");
195  }
196  return program;
197 }
198 
199 /**********************************************************************
200  * Geometry creation functions
201  *********************************************************************/
202 
203 /* Generate vertices and indices for the heightmap
204  */
205 static void init_map(void)
206 {
207  int i;
208  int j;
209  int k;
210  GLfloat step = MAP_SIZE / (MAP_NUM_VERTICES - 1);
211  GLfloat x = 0.0f;
212  GLfloat z = 0.0f;
213  /* Create a flat grid */
214  k = 0;
215  for (i = 0 ; i < MAP_NUM_VERTICES ; ++i)
216  {
217  for (j = 0 ; j < MAP_NUM_VERTICES ; ++j)
218  {
219  map_vertices[0][k] = x;
220  map_vertices[1][k] = 0.0f;
221  map_vertices[2][k] = z;
222  z += step;
223  ++k;
224  }
225  x += step;
226  z = 0.0f;
227  }
228 #if DEBUG_ENABLED
229  for (i = 0 ; i < MAP_NUM_TOTAL_VERTICES ; ++i)
230  {
231  printf ("Vertice %d (%f, %f, %f)\n",
232  i, map_vertices[0][i], map_vertices[1][i], map_vertices[2][i]);
233 
234  }
235 #endif
236  /* create indices */
237  /* line fan based on i
238  * i+1
239  * | / i + n + 1
240  * | /
241  * |/
242  * i --- i + n
243  */
244 
245  /* close the top of the square */
246  k = 0;
247  for (i = 0 ; i < MAP_NUM_VERTICES -1 ; ++i)
248  {
249  map_line_indices[k++] = (i + 1) * MAP_NUM_VERTICES -1;
250  map_line_indices[k++] = (i + 2) * MAP_NUM_VERTICES -1;
251  }
252  /* close the right of the square */
253  for (i = 0 ; i < MAP_NUM_VERTICES -1 ; ++i)
254  {
255  map_line_indices[k++] = (MAP_NUM_VERTICES - 1) * MAP_NUM_VERTICES + i;
256  map_line_indices[k++] = (MAP_NUM_VERTICES - 1) * MAP_NUM_VERTICES + i + 1;
257  }
258 
259  for (i = 0 ; i < (MAP_NUM_VERTICES - 1) ; ++i)
260  {
261  for (j = 0 ; j < (MAP_NUM_VERTICES - 1) ; ++j)
262  {
263  int ref = i * (MAP_NUM_VERTICES) + j;
264  map_line_indices[k++] = ref;
265  map_line_indices[k++] = ref + 1;
266 
267  map_line_indices[k++] = ref;
268  map_line_indices[k++] = ref + MAP_NUM_VERTICES;
269 
270  map_line_indices[k++] = ref;
271  map_line_indices[k++] = ref + MAP_NUM_VERTICES + 1;
272  }
273  }
274 
275 #ifdef DEBUG_ENABLED
276  for (k = 0 ; k < 2 * MAP_NUM_LINES ; k += 2)
277  {
278  int beg, end;
279  beg = map_line_indices[k];
280  end = map_line_indices[k+1];
281  printf ("Line %d: %d -> %d (%f, %f, %f) -> (%f, %f, %f)\n",
282  k / 2, beg, end,
283  map_vertices[0][beg], map_vertices[1][beg], map_vertices[2][beg],
284  map_vertices[0][end], map_vertices[1][end], map_vertices[2][end]);
285  }
286 #endif
287 }
288 
289 static void generate_heightmap__circle(float* center_x, float* center_y,
290  float* size, float* displacement)
291 {
292  float sign;
293  /* random value for element in between [0-1.0] */
294  *center_x = (MAP_SIZE * rand()) / (1.0f * RAND_MAX);
295  *center_y = (MAP_SIZE * rand()) / (1.0f * RAND_MAX);
296  *size = (MAX_CIRCLE_SIZE * rand()) / (1.0f * RAND_MAX);
297  sign = (1.0f * rand()) / (1.0f * RAND_MAX);
298  sign = (sign < DISPLACEMENT_SIGN_LIMIT) ? -1.0f : 1.0f;
299  *displacement = (sign * (MAX_DISPLACEMENT * rand())) / (1.0f * RAND_MAX);
300 }
301 
302 /* Run the specified number of iterations of the generation process for the
303  * heightmap
304  */
305 static void update_map(int num_iter)
306 {
307  assert(num_iter > 0);
308  while(num_iter)
309  {
310  /* center of the circle */
311  float center_x;
312  float center_z;
313  float circle_size;
314  float disp;
315  size_t ii;
316  generate_heightmap__circle(&center_x, &center_z, &circle_size, &disp);
317  disp = disp / 2.0f;
318  for (ii = 0u ; ii < MAP_NUM_TOTAL_VERTICES ; ++ii)
319  {
320  GLfloat dx = center_x - map_vertices[0][ii];
321  GLfloat dz = center_z - map_vertices[2][ii];
322  GLfloat pd = (2.0f * (float) sqrt((dx * dx) + (dz * dz))) / circle_size;
323  if (fabs(pd) <= 1.0f)
324  {
325  /* tx,tz is within the circle */
326  GLfloat new_height = disp + (float) (cos(pd*3.14f)*disp);
327  map_vertices[1][ii] += new_height;
328  }
329  }
330  --num_iter;
331  }
332 }
333 
334 /**********************************************************************
335  * OpenGL helper functions
336  *********************************************************************/
337 
338 /* Create VBO, IBO and VAO objects for the heightmap geometry and bind them to
339  * the specified program object
340  */
342 {
343  GLuint attrloc;
344 
345  glGenVertexArrays(1, &mesh);
348  /* Prepare the data for drawing through a buffer inidices */
351 
352  /* Prepare the attributes for rendering */
353  attrloc = glGetAttribLocation(program, "x");
356  glEnableVertexAttribArray(attrloc);
357  glVertexAttribPointer(attrloc, 1, GL_FLOAT, GL_FALSE, 0, 0);
358 
359  attrloc = glGetAttribLocation(program, "z");
361  glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * MAP_NUM_TOTAL_VERTICES, &map_vertices[2][0], GL_STATIC_DRAW);
362  glEnableVertexAttribArray(attrloc);
363  glVertexAttribPointer(attrloc, 1, GL_FLOAT, GL_FALSE, 0, 0);
364 
365  attrloc = glGetAttribLocation(program, "y");
367  glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * MAP_NUM_TOTAL_VERTICES, &map_vertices[1][0], GL_DYNAMIC_DRAW);
368  glEnableVertexAttribArray(attrloc);
369  glVertexAttribPointer(attrloc, 1, GL_FLOAT, GL_FALSE, 0, 0);
370 }
371 
372 /* Update VBO vertices from source data
373  */
374 static void update_mesh(void)
375 {
377 }
378 
379 /**********************************************************************
380  * GLFW callback functions
381  *********************************************************************/
382 
383 static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
384 {
385  switch(key)
386  {
387  case GLFW_KEY_ESCAPE:
388  /* Exit program on Escape */
390  break;
391  }
392 }
393 
394 static void error_callback(int error, const char* description)
395 {
396  fprintf(stderr, "Error: %s\n", description);
397 }
398 
399 int main(int argc, char** argv)
400 {
402  int iter;
403  double dt;
404  double last_update_time;
405  int frame;
406  float f;
407  GLint uloc_modelview;
408  GLint uloc_project;
409  int width, height;
410 
411  GLuint shader_program;
412 
414 
415  if (!glfwInit())
416  exit(EXIT_FAILURE);
417 
423 
424  window = glfwCreateWindow(800, 600, "GLFW OpenGL3 Heightmap demo", NULL, NULL);
425  if (! window )
426  {
427  glfwTerminate();
428  exit(EXIT_FAILURE);
429  }
430 
431  /* Register events callback */
433 
434  glfwMakeContextCurrent(window);
436 
437  /* Prepare opengl resources for rendering */
439 
440  if (shader_program == 0u)
441  {
442  glfwTerminate();
443  exit(EXIT_FAILURE);
444  }
445 
446  glUseProgram(shader_program);
447  uloc_project = glGetUniformLocation(shader_program, "project");
448  uloc_modelview = glGetUniformLocation(shader_program, "modelview");
449 
450  /* Compute the projection matrix */
451  f = 1.0f / tanf(view_angle / 2.0f);
453  projection_matrix[5] = f;
454  projection_matrix[10] = (z_far + z_near)/ (z_near - z_far);
455  projection_matrix[11] = -1.0f;
456  projection_matrix[14] = 2.0f * (z_far * z_near) / (z_near - z_far);
457  glUniformMatrix4fv(uloc_project, 1, GL_FALSE, projection_matrix);
458 
459  /* Set the camera position */
460  modelview_matrix[12] = -5.0f;
461  modelview_matrix[13] = -5.0f;
462  modelview_matrix[14] = -20.0f;
463  glUniformMatrix4fv(uloc_modelview, 1, GL_FALSE, modelview_matrix);
464 
465  /* Create mesh data */
466  init_map();
467  make_mesh(shader_program);
468 
469  /* Create vao + vbo to store the mesh */
470  /* Create the vbo to store all the information for the grid and the height */
471 
472  /* setup the scene ready for rendering */
473  glfwGetFramebufferSize(window, &width, &height);
474  glViewport(0, 0, width, height);
475  glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
476 
477  /* main loop */
478  frame = 0;
479  iter = 0;
480  last_update_time = glfwGetTime();
481 
482  while (!glfwWindowShouldClose(window))
483  {
484  ++frame;
485  /* render the next frame */
488 
489  /* display and process events through callbacks */
490  glfwSwapBuffers(window);
491  glfwPollEvents();
492  /* Check the frame rate and update the heightmap if needed */
493  dt = glfwGetTime();
494  if ((dt - last_update_time) > 0.2)
495  {
496  /* generate the next iteration of the heightmap */
497  if (iter < MAX_ITER)
498  {
500  update_mesh();
501  iter += NUM_ITER_AT_A_TIME;
502  }
503  last_update_time = dt;
504  frame = 0;
505  }
506  }
507 
508  glfwTerminate();
509  exit(EXIT_SUCCESS);
510 }
511 
#define glDeleteShader
#define glGetShaderInfoLog
GLuint GLuint end
#define glBufferData
#define glCreateProgram
static GLfloat map_vertices[3][MAP_NUM_TOTAL_VERTICES]
Definition: heightmap.c:105
#define GL_VERTEX_SHADER
#define GL_STATIC_DRAW
khronos_float_t GLfloat
static const char * vertex_shader_text
Definition: heightmap.c:54
static void update_mesh(void)
Definition: heightmap.c:374
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
int main(int argc, char **argv)
Definition: heightmap.c:399
#define glGetAttribLocation
void *(* GLADloadproc)(const char *name)
char GLchar
static GLFWwindow * window
Definition: joysticks.c:55
#define GLFW_OPENGL_FORWARD_COMPAT
OpenGL forward-compatibility hint and attribute.
Definition: glfw3.h:945
double dt
Definition: boing.c:106
#define MAP_NUM_TOTAL_VERTICES
Definition: heightmap.c:45
#define GLFW_CONTEXT_VERSION_MAJOR
Context client API major version hint and attribute.
Definition: glfw3.h:921
static GLfloat modelview_matrix[16]
Definition: heightmap.c:94
#define GL_LINK_STATUS
static void make_mesh(GLuint program)
Definition: heightmap.c:341
GLFWAPI GLFWerrorfun glfwSetErrorCallback(GLFWerrorfun cbfun)
Sets the error callback.
Definition: init.c:309
int GLsizei
#define GLFW_FALSE
Zero.
Definition: glfw3.h:287
#define glUniformMatrix4fv
static GLuint make_shader(GLenum type, const char *text)
Definition: heightmap.c:122
#define glBufferSubData
#define GLFW_OPENGL_PROFILE
OpenGL profile hint and attribute.
Definition: glfw3.h:957
static void init_map(void)
Definition: heightmap.c:205
GLdouble GLdouble z
static GLuint mesh_vbo[4]
Definition: heightmap.c:114
#define glUseProgram
#define MAX_DISPLACEMENT
Definition: heightmap.c:37
static void generate_heightmap__circle(float *center_x, float *center_y, float *size, float *displacement)
Definition: heightmap.c:289
static void error_callback(int error, const char *description)
Definition: heightmap.c:394
static GLfloat view_angle
Definition: heightmap.c:80
#define glCreateShader
static void key_callback(GLFWwindow *window, int key, int scancode, int action, int mods)
Definition: heightmap.c:383
GLuint64 key
Definition: glext.h:8966
static GLfloat projection_matrix[16]
Definition: heightmap.c:86
#define glGetProgramiv
static const char * fragment_shader_text
Definition: heightmap.c:67
GLFWAPI int glfwInit(void)
Initializes the GLFW library.
Definition: init.c:198
GLdouble f
#define glGenVertexArrays
#define glVertexAttribPointer
#define GL_FLOAT
GLsizeiptr size
#define glEnableVertexAttribArray
#define GL_COLOR_BUFFER_BIT
#define glBindVertexArray
GLbitfield GLuint program
Definition: glext.h:1889
#define GL_LINES
int GLint
GLdouble x
#define glBindBuffer
#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
GLint j
#define glDeleteProgram
#define MAP_NUM_LINES
Definition: heightmap.c:46
static GLuint map_line_indices[2 *MAP_NUM_LINES]
Definition: heightmap.c:106
#define MAX_CIRCLE_SIZE
Definition: heightmap.c:36
#define glGetUniformLocation
#define glGetShaderiv
static void update_map(int num_iter)
Definition: heightmap.c:305
#define GL_FRAGMENT_SHADER
#define glShaderSource
#define GL_TRUE
#define GLFW_RESIZABLE
Window resize-ability window hint and attribute.
Definition: glfw3.h:774
action
Definition: enums.py:62
#define glViewport
GLAPI int gladLoadGLLoader(GLADloadproc)
Definition: glad/glad.c:1697
#define GL_DYNAMIC_DRAW
static const textual_icon exit
Definition: model-views.h:254
#define glAttachShader
GLFWAPI void glfwSetWindowShouldClose(GLFWwindow *window, int value)
Sets the close flag of the specified window.
Definition: window.c:486
#define glCompileShader
#define RAND_MAX
Definition: boing.c:110
static GLfloat z_near
Definition: heightmap.c:82
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
#define GL_FALSE
GLFWAPI double glfwGetTime(void)
Returns the value of the GLFW timer.
Definition: input.c:1275
unsigned int GLuint
GLenum type
#define glGenBuffers
#define GLFW_OPENGL_CORE_PROFILE
Definition: glfw3.h:998
#define NUM_ITER_AT_A_TIME
Definition: heightmap.c:40
static GLuint mesh
Definition: heightmap.c:113
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
#define MAP_NUM_VERTICES
Definition: heightmap.c:44
#define GL_COMPILE_STATUS
#define glLinkProgram
#define DISPLACEMENT_SIGN_LIMIT
Definition: heightmap.c:38
GLint ref
GLFWAPI void glfwTerminate(void)
Terminates the GLFW library.
Definition: init.c:243
#define glClearColor
GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow *window, GLFWkeyfun cbfun)
Sets the key callback.
Definition: input.c:791
#define glGetProgramInfoLog
GLFWAPI void glfwPollEvents(void)
Processes all pending events.
Definition: window.c:1072
#define GL_ELEMENT_ARRAY_BUFFER
#define NULL
Definition: tinycthread.c:47
unsigned int GLenum
int i
static GLuint make_shader_program(const char *vs_text, const char *fs_text)
Definition: heightmap.c:149
GLuint shader
#define GLFW_CONTEXT_VERSION_MINOR
Context client API minor version hint and attribute.
Definition: glfw3.h:927
#define MAX_ITER
Definition: heightmap.c:39
#define MAP_SIZE
Definition: heightmap.c:43
#define GL_ARRAY_BUFFER
static GLfloat aspect_ratio
Definition: heightmap.c:81
#define GL_UNSIGNED_INT
struct GLFWwindow GLFWwindow
GLFWAPI void glfwWindowHint(int hint, int value)
Sets the specified window hint to the desired value.
Definition: window.c:291
static GLfloat z_far
Definition: heightmap.c:83
GLint GLsizei width
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:47:16