OpenGL ES SDK for Android ARM Developer Center
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Native.cpp
Go to the documentation of this file.
1 /* Copyright (c) 2014-2017, ARM Limited and Contributors
2  *
3  * SPDX-License-Identifier: MIT
4  *
5  * Permission is hereby granted, free of charge,
6  * to any person obtaining a copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation the rights to
8  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
9  * and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
14  * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
16  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
17  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19  */
20 
35 #include <cstdio>
36 #include <cstdlib>
37 
38 #include <jni.h>
39 #include <android/log.h>
40 
41 #include "Shader.h"
42 #include "Timer.h"
43 #include "Matrix.h"
44 
45 #include "GLES3/gl3.h"
46 #include "EGL/egl.h"
47 #include "EGL/eglext.h"
48 
49 #include <string>
50 #include <cmath>
51 
52 #define LOG_TAG "libNative"
53 #define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
54 #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
55 
56 using std::string;
57 using namespace MaliSDK;
58 
64 const char* spheres_updater_vert_shader = "#version 300 es\n"
65 "\n"
66 "/** Structure that describes parameters of a single sphere moving across the scalar field. */\n"
67 "struct sphere_descriptor\n"
68 "{\n"
69 " /* Coefficients for Lissajou equations. Current coordinates calculated by formula:\n"
70 " * v(t) = start_center + lissajou_amplitude * sin(lissajou_frequency * t + lissajou_phase) */\n"
71 " vec3 start_center; /* Center in space around which sphere moves. */\n"
72 " vec3 lissajou_amplitude; /* Lissajou equation amplitudes for all axes. */\n"
73 " vec3 lissajou_frequency; /* Lissajou equation frequencies for all axes. */\n"
74 " vec3 lissajou_phase; /* Lissajou equation phases for all axes. */\n"
75 " /* Other sphere parameters. */\n"
76 " float size; /* Size of a sphere (weight or charge). */\n"
77 "};\n"
78 "\n"
79 "/* [Stage 1 Uniforms] */\n"
80 "/** Current time moment. */\n"
81 "uniform float time;\n"
82 "/* [Stage 1 Uniforms] */\n"
83 "\n"
84 "/* [Stage 1 Output data] */\n"
85 "/** Calculated sphere positions. */\n"
86 "out vec4 sphere_position;\n"
87 "/* [Stage 1 Output data] */\n"
88 "\n"
89 "/** Shader entry point. */\n"
90 "void main()\n"
91 "{\n"
92 " /* Stores information on spheres moving across the scalar field. Specified in model coordinates (range 0..1]) */\n"
93 " sphere_descriptor spheres[] = sphere_descriptor[]\n"
94 " (\n"
95 " /* (---- center ----) (--- amplitude --) (--- frequency ---) (----- phase -----) (weight)*/\n"
96 " sphere_descriptor( vec3(0.50, 0.50, 0.50), vec3(0.20, 0.25, 0.25), vec3( 11.0, 21.0, 31.0), vec3( 30.0, 45.0, 90.0), 0.100),\n"
97 " sphere_descriptor( vec3(0.50, 0.50, 0.50), vec3(0.25, 0.20, 0.25), vec3( 22.0, 32.0, 12.0), vec3( 45.0, 90.0,120.0), 0.050),\n"
98 " sphere_descriptor( vec3(0.50, 0.50, 0.50), vec3(0.25, 0.25, 0.20), vec3( 33.0, 13.0, 23.0), vec3( 90.0,120.0,150.0), 0.250)\n"
99 " );\n"
100 "\n"
101 " /* Calculate new xyz coordinates of the sphere. */\n"
102 " vec3 sphere_position3 = spheres[gl_VertexID].start_center\n"
103 " + spheres[gl_VertexID].lissajou_amplitude\n"
104 " * sin(radians(spheres[gl_VertexID].lissajou_frequency) * time + radians(spheres[gl_VertexID].lissajou_phase));\n"
105 "\n"
106 " /* Update sphere position coordinates. w-coordinte represents sphere weight. */\n"
107 " sphere_position = vec4(sphere_position3, spheres[gl_VertexID].size);\n"
108 "}\n";
109 
114 const char* spheres_updater_frag_shader = "#version 300 es\n"
115 "\n"
116 "/** Shader entry point. */\n"
117 "void main()\n"
118 "{\n"
119 "}\n";
120 
126 const char* scalar_field_vert_shader = "#version 300 es\n"
127 "\n"
128 "/** Precision to avoid division-by-zero errors. */\n"
129 "#define EPSILON 0.000001f\n"
130 "\n"
131 "/** Amount of spheres defining scalar field. This value should be synchronized between all files. */\n"
132 "#define N_SPHERES 3\n"
133 "\n"
134 "/* [Stage 2 Uniforms] */\n"
135 "/* Uniforms: */\n"
136 "/** Amount of samples taken for each axis of a scalar field; */\n"
137 "uniform int samples_per_axis;\n"
138 "\n"
139 "/** Uniform block encapsulating sphere locations. */\n"
140 "uniform spheres_uniform_block\n"
141 "{\n"
142 " vec4 input_spheres[N_SPHERES];\n"
143 "};\n"
144 "/* [Stage 2 Uniforms] */\n"
145 "\n"
146 "/* [Stage 2 Output data] */\n"
147 "/* Output data: */\n"
148 "/** Calculated scalar field value. */\n"
149 "out float scalar_field_value;\n"
150 "/* [Stage 2 Output data] */\n"
151 "\n"
152 "/* [Stage 2 decode_space_position] */\n"
153 "/** Decode coordinates in space from vertex number.\n"
154 " * Assume 3D space of samples_per_axis length for each axis and following encoding:\n"
155 " * encoded_position = x + y * samples_per_axis + z * samples_per_axis * samples_per_axis\n"
156 " *\n"
157 " * @param vertex_index Encoded vertex position\n"
158 " * @return Coordinates of a vertex in space ranged [0 .. samples_per_axis-1]\n"
159 " */\n"
160 "ivec3 decode_space_position(in int vertex_index)\n"
161 "{\n"
162 " int encoded_position = vertex_index;\n"
163 " ivec3 space_position;\n"
164 "\n"
165 " /* Calculate coordinates from vertex number. */\n"
166 " space_position.x = encoded_position % samples_per_axis;\n"
167 " encoded_position = encoded_position / samples_per_axis;\n"
168 "\n"
169 " space_position.y = encoded_position % samples_per_axis;\n"
170 " encoded_position = encoded_position / samples_per_axis;\n"
171 "\n"
172 " space_position.z = encoded_position;\n"
173 "\n"
174 " return space_position;\n"
175 "}\n"
176 "/* [Stage 2 decode_space_position] */\n"
177 "\n"
178 "/** Normalizes each coordinate interpolating input coordinates\n"
179 " * from range [0 .. samples_per_axis-1] to [0.0 .. 1.0] range.\n"
180 " *\n"
181 " * @param space_position Coordinates in range [0 .. samples_per_axis-1]\n"
182 " * @return Coordinates in range [0.0 .. 1.0]\n"
183 " */\n"
184 "/* [Stage 2 normalize_space_position_coordinates] */\n"
185 "vec3 normalize_space_position_coordinates(in ivec3 space_position)\n"
186 "{\n"
187 " vec3 normalized_space_position = vec3(space_position) / float(samples_per_axis - 1);\n"
188 "\n"
189 " return normalized_space_position;\n"
190 "}\n"
191 "/* [Stage 2 normalize_space_position_coordinates] */\n"
192 "\n"
193 "/** Calculates scalar field at user-defined location.\n"
194 " *\n"
195 " * @param position Space position for which scalar field value is calculated\n"
196 " * @return Scalar field value\n"
197 " */\n"
198 "/* [Stage 2 calculate_scalar_field_value] */\n"
199 "float calculate_scalar_field_value(in vec3 position)\n"
200 "{\n"
201 " float field_value = 0.0f;\n"
202 "\n"
203 " /* Field value in given space position influenced by all spheres. */\n"
204 " for (int i = 0; i < N_SPHERES; i++)\n"
205 " {\n"
206 " vec3 sphere_position = input_spheres[i].xyz;\n"
207 " float vertex_sphere_distance = length(distance(sphere_position, position));\n"
208 "\n"
209 " /* Field value is a sum of all spheres fields in a given space position.\n"
210 " * Sphere weight (or charge) is stored in w-coordinate.\n"
211 " */\n"
212 " field_value += input_spheres[i].w / pow(max(EPSILON, vertex_sphere_distance), 2.0);\n"
213 " }\n"
214 "\n"
215 " return field_value;\n"
216 "}\n"
217 "/* [Stage 2 calculate_scalar_field_value] */\n"
218 "\n"
219 "/** Shader entry point. */\n"
220 "void main()\n"
221 "{\n"
222 " /* Decode point space position defined by gl_VertexID. */\n"
223 " ivec3 space_position = decode_space_position(gl_VertexID);\n"
224 "\n"
225 " /* Normalize point space position. */\n"
226 " vec3 normalized_position = normalize_space_position_coordinates(space_position);\n"
227 "\n"
228 " /* Calculate field value and assign field value to output variable. */\n"
229 " scalar_field_value = calculate_scalar_field_value(normalized_position);\n"
230 "}\n";
231 
236 const char* scalar_field_frag_shader = "#version 300 es\n"
237 "\n"
238 "/** Shader entry point. */\n"
239 "void main()\n"
240 "{\n"
241 "}\n";
242 
250 const char* marching_cubes_cells_vert_shader = "#version 300 es\n"
251 "\n"
252 "/** Specify low precision for sampler3D type. */\n"
253 "precision lowp sampler3D;\n"
254 "\n"
255 "/* Uniforms: */\n"
256 "/** Scalar field is stored in a 3D texture. */\n"
257 "uniform sampler3D scalar_field;\n"
258 "\n"
259 "/** Amount of samples taken for each axis of a scalar field. */\n"
260 "uniform int cells_per_axis;\n"
261 "\n"
262 "/** Isosurface level. */\n"
263 "uniform float iso_level;\n"
264 "\n"
265 "/* Output data: */\n"
266 "/** Cell type index. */\n"
267 "flat out int cell_type_index;\n"
268 "\n"
269 "/** Calculates cell type index for provided cell and isosurface level.\n"
270 " *\n"
271 " * @param cell_corner_field_value Scalar field values in cell corners\n"
272 " * @param isolevel Scalar field value which defines isosurface level\n"
273 " */\n"
274 "/* [Stage 3 get_cell_type_index] */\n"
275 "int get_cell_type_index(in float cell_corner_field_value[8], in float isolevel)\n"
276 "{\n"
277 " int cell_type_index = 0;\n"
278 "\n"
279 " /* Iterate through all cell corners. */\n"
280 " for (int i = 0; i < 8; i++)\n"
281 " {\n"
282 " /* If corner is inside isosurface then set bit in cell type index index. */\n"
283 " if (cell_corner_field_value[i] < isolevel)\n"
284 " {\n"
285 " /* Set appropriate corner bit in cell type index. */\n"
286 " cell_type_index |= (1<<i);\n"
287 " }\n"
288 " }\n"
289 "\n"
290 " return cell_type_index;\n"
291 "}\n"
292 "/* [Stage 3 get_cell_type_index] */\n"
293 "\n"
294 "/** Decode coordinates in space from cell number.\n"
295 " * Assume cubical space of cells_per_axis cells length by each axis and following encoding:\n"
296 " * encoded_position = x + y * cells_per_axis + z * cells_per_axis * cells_per_axis\n"
297 " *\n"
298 " * @param cell_index Encoded cell position\n"
299 " * @return Coordinates of a cell in space ranged [0 .. cells_per_axis-1]\n"
300 " */\n"
301 "/* [Stage 3 decode_space_position] */\n"
302 "ivec3 decode_space_position(in int cell_index)\n"
303 "{\n"
304 " ivec3 space_position;\n"
305 " int encoded_position = cell_index;\n"
306 "\n"
307 " /* Calculate coordinates from encoded position */\n"
308 " space_position.x = encoded_position % cells_per_axis;\n"
309 " encoded_position = encoded_position / cells_per_axis;\n"
310 "\n"
311 " space_position.y = encoded_position % cells_per_axis;\n"
312 " encoded_position = encoded_position / cells_per_axis;\n"
313 "\n"
314 " space_position.z = encoded_position;\n"
315 "\n"
316 " return space_position;\n"
317 "}\n"
318 "/* [Stage 3 decode_space_position] */\n"
319 "\n"
320 "/** Shader entry point. */\n"
321 "void main()\n"
322 "{\n"
323 " /* Cubic cell has exactly 8 corners. */\n"
324 " const int corners_in_cell = 8;\n"
325 "\n"
326 " /* Cell corners in space relatively to cell's base point [0]. */\n"
327 " const ivec3 cell_corners_offsets[corners_in_cell] = ivec3[]\n"
328 " (\n"
329 " ivec3(0, 0, 0),\n"
330 " ivec3(1, 0, 0),\n"
331 " ivec3(1, 0, 1),\n"
332 " ivec3(0, 0, 1),\n"
333 " ivec3(0, 1, 0),\n"
334 " ivec3(1, 1, 0),\n"
335 " ivec3(1, 1, 1),\n"
336 " ivec3(0, 1, 1)\n"
337 " );\n"
338 "\n"
339 " /* Scalar field texture size, used for normalization purposes. */\n"
340 " vec3 scalar_field_normalizers = vec3(textureSize(scalar_field, 0)) - vec3(1, 1, 1);\n"
341 "\n"
342 " /* Scalar field value in corners. Corners numbered according to Marching Cubes algorithm. */\n"
343 " float scalar_field_in_cell_corners[8];\n"
344 "\n"
345 " /* Find cell position processed by this shader instance (defined by gl_VertexID). */\n"
346 " ivec3 space_position = decode_space_position(gl_VertexID);\n"
347 "\n"
348 " /* [Stage 3 Gather values for the current cell] */\n"
349 " /* Find scalar field values in cell corners. */\n"
350 " for (int i = 0; i < corners_in_cell; i++)\n"
351 " {\n"
352 " /* Calculate cell corner processed at this iteration. */\n"
353 " ivec3 cell_corner = space_position + cell_corners_offsets[i];\n"
354 "\n"
355 " /* Calculate cell corner's actual position ([0.0 .. 1.0] range.) */\n"
356 " vec3 normalized_cell_corner = vec3(cell_corner) / scalar_field_normalizers;\n"
357 "\n"
358 " /* Get scalar field value in cell corner from scalar field texture. */\n"
359 " scalar_field_in_cell_corners[i] = textureLod(scalar_field, normalized_cell_corner, 0.0).r;\n"
360 " }\n"
361 " /* [Stage 3 Gather values for the current cell] */\n"
362 "\n"
363 " /* Get cube type index. */\n"
364 " cell_type_index = get_cell_type_index(scalar_field_in_cell_corners, iso_level);\n"
365 "}\n";
366 
371 const char* marching_cubes_cells_frag_shader = "#version 300 es\n"
372 "\n"
373 "/** Shader entry point. */\n"
374 "void main()\n"
375 "{\n"
376 "}\n";
377 
388 const char* marching_cubes_triangles_vert_shader = "#version 300 es\n"
389 "\n"
390 "precision highp isampler2D; /**< Specify high precision for isampler2D type. */\n"
391 "precision highp isampler3D; /**< Specify high precision for isampler3D type. */\n"
392 "precision highp sampler2D; /**< Specify high precision for sampler2D type. */\n"
393 "precision highp sampler3D; /**< Specify high precision for sampler3D type. */\n"
394 "\n"
395 "/** Precision to avoid division-by-zero errors. */\n"
396 "#define EPSILON 0.000001f\n"
397 "\n"
398 "/** Amount of cells taken for each axis of a scalar field. */\n"
399 "#define CELLS_PER_AXIS (samples_per_axis - 1)\n"
400 "\n"
401 "/** Maximum amount of vertices a single cell can define. */\n"
402 "const int mc_vertices_per_cell = 15;\n"
403 "\n"
404 "/* Uniforms: */\n"
405 "/** Amount of samples taken for each axis of a scalar field. */\n"
406 "uniform int samples_per_axis;\n"
407 "\n"
408 "/** A signed integer 3D texture is used to deliver cell type data. */\n"
409 "uniform isampler3D cell_types;\n"
410 "\n"
411 "/** A 3D texture is used to deliver scalar field data. */\n"
412 "uniform sampler3D scalar_field;\n"
413 "\n"
414 "/** A 2D texture representing tri_table lookup array. Array contains edge numbers (in sense of Marching Cubes algorithm).\n"
415 " As input parameters (indices to texture) should be specified cell type index and combined vertex-triangle number. */\n"
416 "uniform isampler2D tri_table;\n"
417 "\n"
418 "/** Combined model view and projection matrices. */\n"
419 "uniform mat4 mvp;\n"
420 "\n"
421 "/** Isosurface level. */\n"
422 "uniform float iso_level;\n"
423 "\n"
424 "/* Phong shading output variables for fragment shader. */\n"
425 "out vec4 phong_vertex_position; /**< position of the vertex in world space. */\n"
426 "out vec3 phong_vertex_normal_vector; /**< surface normal vector in world space. */\n"
427 "out vec3 phong_vertex_color; /**< vertex color for fragment colorisation. */\n"
428 "\n"
429 "\n"
430 "/** Function approximates scalar field derivative along begin_vertex<->end_vertex axis.\n"
431 " * Field derivative calculated as a scalar field difference between specified vertices\n"
432 " * divided by distance between vertices.\n"
433 " *\n"
434 " * @param begin_vertex begin vertex\n"
435 " * @param end_vertex end vertex\n"
436 " * @return scalar field derivative along begin_vertex<->end_vertex axis\n"
437 " */\n"
438 "float calc_partial_derivative(vec3 begin_vertex, vec3 end_vertex)\n"
439 "{\n"
440 " float field_value_begin = textureLod(scalar_field, begin_vertex, 0.0).r;\n"
441 " float field_value_end = textureLod(scalar_field, end_vertex, 0.0).r;\n"
442 "\n"
443 " return (field_value_end - field_value_begin) / distance(begin_vertex, end_vertex);\n"
444 "}\n"
445 "\n"
446 "/** Finds normal in given cell corner vertex. Normal calculated as a vec3(dF/dx, dF/dy, dF/dz)\n"
447 " * dFs are calculated as difference of scalar field values in corners of this or adjacent cells.\n"
448 " *\n"
449 " * @param p1 vertex for which normal is to be calculated\n"
450 " * @return normal vector to surface in p1\n"
451 " */\n"
452 "vec3 calc_cell_corner_normal(in vec3 p1)\n"
453 "{\n"
454 " vec3 result;\n"
455 " vec3 delta;\n"
456 "\n"
457 " /* Use neighbour samples to calculate derivative. */\n"
458 " delta = vec3(1.0/float(samples_per_axis - 1), 0, 0);\n"
459 " result.x = calc_partial_derivative(p1 - delta, p1 + delta);\n"
460 "\n"
461 " delta = vec3(0.0, 1.0/float(samples_per_axis - 1), 0.0);\n"
462 " result.y = calc_partial_derivative(p1 - delta, p1 + delta);\n"
463 "\n"
464 " delta = vec3(0.0, 0.0, 1.0/float(samples_per_axis - 1));\n"
465 " result.z = calc_partial_derivative(p1 - delta, p1 + delta);\n"
466 "\n"
467 " return result;\n"
468 "}\n"
469 "\n"
470 "/** Calculates normal for an edge vertex like in an orignal SIGGRAPH paper.\n"
471 " * First finds normal vectors in edge begin vertex and in edge end vertex, then interpolate.\n"
472 " *\n"
473 " * @param start_vertex_portion influence of edge_start vertex\n"
474 " * @param edge_start normalized coordinates of edge start vertex\n"
475 " * @param edge_end normalized coordinates of edge end vertex\n"
476 " * @return normal to surface vector in edge position specified\n"
477 " */\n"
478 "vec3 calc_phong_normal(in float start_vertex_portion, in vec3 edge_start, in vec3 edge_end)\n"
479 "{\n"
480 " /* Find normal vector in begin vertex of the edge. */\n"
481 " vec3 edge_start_normal = calc_cell_corner_normal(edge_start);\n"
482 " /* Find normal vector in end vertex of the edge. */\n"
483 " vec3 edge_end_normal = calc_cell_corner_normal(edge_end);\n"
484 "\n"
485 " /* Interpolate normal vector. */\n"
486 " return mix(edge_end_normal, edge_start_normal, start_vertex_portion);\n"
487 "}\n"
488 "\n"
489 "/** Decodes cell coordinates from vertex identifier.\n"
490 " * Assumes 3D space of CELLS_PER_AXIS cells for each axis and\n"
491 " * mc_vertices_per_cell triangles-generating vertices per cell\n"
492 " * encoded in vertex identifier according to following formula:\n"
493 " * encoded_position = mc_vertex_no + mc_vertices_per_cell * (x + CELLS_PER_AXIS * (y + CELLS_PER_AXIS * z))\n"
494 " *\n"
495 " * @param encoded_position_argument encoded position\n"
496 " * @return cell coordinates ranged [0 .. CELLS_PER_AXIS-1] in x,y,z, and decoded vertex number in w.\n"
497 " */\n"
498 "/* [Stage 4 decode_cell_position] */\n"
499 "ivec4 decode_cell_position(in int encoded_position_argument)\n"
500 "{\n"
501 " ivec4 cell_position;\n"
502 " int encoded_position = encoded_position_argument;\n"
503 "\n"
504 " /* Decode combined triangle and vertex number. */\n"
505 " cell_position.w = encoded_position % mc_vertices_per_cell;\n"
506 " encoded_position = encoded_position / mc_vertices_per_cell;\n"
507 "\n"
508 " /* Decode coordinates from encoded position. */\n"
509 " cell_position.x = encoded_position % CELLS_PER_AXIS;\n"
510 " encoded_position = encoded_position / CELLS_PER_AXIS;\n"
511 "\n"
512 " cell_position.y = encoded_position % CELLS_PER_AXIS;\n"
513 " encoded_position = encoded_position / CELLS_PER_AXIS;\n"
514 "\n"
515 " cell_position.z = encoded_position;\n"
516 "\n"
517 " return cell_position;\n"
518 "}\n"
519 "/* [Stage 4 decode_cell_position] */\n"
520 "\n"
521 "/** Identifies cell type for provided cell position.\n"
522 " *\n"
523 " * @param cell_position non-normalized cell position in space\n"
524 " * @return cell type in sense of Macrhing Cubes algorithm\n"
525 " */\n"
526 "int get_cell_type(in ivec3 cell_position)\n"
527 "{\n"
528 " vec3 cell_position_normalized = vec3(cell_position) / float(CELLS_PER_AXIS - 1);\n"
529 "\n"
530 " /* Get cell type index of cell to which currently processed vertex (triangle_and_vertex_number) belongs */\n"
531 " int cell_type_index = textureLod(cell_types, cell_position_normalized, 0.0).r;\n"
532 "\n"
533 " return cell_type_index;\n"
534 "}\n"
535 "\n"
536 "/** Performs a table lookup with cell type index and combined vertex-triangle number specified\n"
537 " * to locate an edge number which vertex is currently processed.\n"
538 " *\n"
539 " * @param cell_type_index cell type index (in Marching Cubes algorthm sense)\n"
540 " * @param combined_triangle_no_and_vertex_no combined vertex and triangle numbers (by formula tringle*3 + vertex)\n"
541 " *\n"
542 " * @return edge number (in sense of Marching Cubes algorithm) or -1 if vertex does not belong to any edge\n"
543 " */\n"
544 "int get_edge_number(in int cell_type_index, in int combined_triangle_no_and_vertex_no)\n"
545 "{\n"
546 " /* Normalize indices for texture lookup: [0..14] -> [0.0..1.0], [0..255] -> [0.0..1.0]. */\n"
547 " vec2 tri_table_index = vec2(float(combined_triangle_no_and_vertex_no)/14.0, float(cell_type_index)/255.0);\n"
548 "\n"
549 " return textureLod(tri_table, tri_table_index, 0.0).r;\n"
550 "}\n"
551 "\n"
552 "/** Function calculates edge begin or edge end coordinates for specified cell and edge.\n"
553 " *\n"
554 " * @param cell_origin_corner_coordinates normalized cell origin coordinates\n"
555 " * @param edge_number edge number which coorinates being calculated\n"
556 " * @param is_edge_start_vertex true to request edge start vertex coordinates, false for end edge vertex\n"
557 " * @return normalized edge start or end vertex coordinates\n"
558 "*/\n"
559 "vec3 get_edge_coordinates(in vec3 cell_origin_corner_coordinates, in int edge_number, in bool is_edge_start_vertex)\n"
560 "{\n"
561 " /* These two arrays contain vertex indices which define a cell edge specified by index of arrays. */\n"
562 " const int edge_begins_in_cell_corner[12] = int[] ( 0,1,2,3,4,5,6,7,0,1,2,3 );\n"
563 " const int edge_ends_in_cell_corner[12] = int[] ( 1,2,3,0,5,6,7,4,4,5,6,7 );\n"
564 " /* Defines offsets by axes for each of 8 cell corneres. */\n"
565 " const ivec3 cell_corners_offsets[8] = ivec3[8]\n"
566 " (\n"
567 " ivec3(0, 0, 0),\n"
568 " ivec3(1, 0, 0),\n"
569 " ivec3(1, 0, 1),\n"
570 " ivec3(0, 0, 1),\n"
571 " ivec3(0, 1, 0),\n"
572 " ivec3(1, 1, 0),\n"
573 " ivec3(1, 1, 1),\n"
574 " ivec3(0, 1, 1)\n"
575 " );\n"
576 "\n"
577 " /* Edge corner number (number is in sense of Marching Cubes algorithm). */\n"
578 " int edge_corner_no;\n"
579 "\n"
580 " if (is_edge_start_vertex)\n"
581 " {\n"
582 " /* Use start cell corner of the edge. */\n"
583 " edge_corner_no = edge_begins_in_cell_corner[edge_number];\n"
584 " }\n"
585 " else\n"
586 " {\n"
587 " /* Use end cell corner of the edge. */\n"
588 " edge_corner_no = edge_ends_in_cell_corner[edge_number];\n"
589 " }\n"
590 "\n"
591 " /* Normalized cell corner coordinate offsets (to cell origin corner). */\n"
592 " vec3 normalized_corner_offsets = vec3(cell_corners_offsets[edge_corner_no]) / float(samples_per_axis - 1);\n"
593 "\n"
594 " /* Normalized cell corner coordinates. */\n"
595 " vec3 edge_corner = cell_origin_corner_coordinates + normalized_corner_offsets;\n"
596 "\n"
597 " return edge_corner;\n"
598 "}\n"
599 "\n"
600 "/** Function calculates how close start_corner vertex to intersetction point.\n"
601 " *\n"
602 " * @param start_corner beginning of edge\n"
603 " * @param end_corner end of edge\n"
604 " * @param iso_level scalar field value level defining isosurface\n"
605 " * @return start vertex portion (1.0, if isosurface comes through start vertex)\n"
606 " */\n"
607 "float get_start_corner_portion(in vec3 start_corner, in vec3 end_corner, in float iso_level)\n"
608 "{\n"
609 " float result;\n"
610 " float start_field_value = textureLod(scalar_field, start_corner, 0.0).r;\n"
611 " float end_field_value = textureLod(scalar_field, end_corner, 0.0).r;\n"
612 " float field_delta = abs(start_field_value - end_field_value);\n"
613 "\n"
614 " if (field_delta > EPSILON)\n"
615 " {\n"
616 " /* Calculate start vertex portion. */\n"
617 " result = abs(end_field_value - iso_level) / field_delta;\n"
618 " }\n"
619 " else\n"
620 " {\n"
621 " /* Field values are too close in value to evaluate. Assume middle of an edge. */\n"
622 " result = 0.5;\n"
623 " }\n"
624 "\n"
625 " return result;\n"
626 "}\n"
627 "\n"
628 "/** Shader entry point. */\n"
629 "void main()\n"
630 "{\n"
631 " /* [Stage 4 Decode space position] */\n"
632 " /* Split gl_vertexID into cell position and vertex number processed by this shader instance. */\n"
633 " ivec4 cell_position_and_vertex_no = decode_cell_position(gl_VertexID);\n"
634 " ivec3 cell_position = cell_position_and_vertex_no.xyz;\n"
635 " int triangle_and_vertex_number = cell_position_and_vertex_no.w;\n"
636 " /* [Stage 4 Decode space position] */\n"
637 "\n"
638 " /* [Stage 4 Get cell type and edge number] */\n"
639 " /* Get cell type for cell current vertex belongs to. */\n"
640 " int cell_type_index = get_cell_type(cell_position);\n"
641 "\n"
642 " /* Get edge of the cell to which belongs processed vertex. */\n"
643 " int edge_number = get_edge_number(cell_type_index, triangle_and_vertex_number);\n"
644 " /* [Stage 4 Get cell type and edge number] */\n"
645 "\n"
646 " /* Check if this is not a vertex of dummy triangle. */\n"
647 " if (edge_number != -1)\n"
648 " {\n"
649 " /* [Stage 4 Calculate cell origin] */\n"
650 " /* Calculate normalized coordinates in space of cell origin corner. */\n"
651 " vec3 cell_origin_corner = vec3(cell_position) / float(samples_per_axis - 1);\n"
652 " /* [Stage 4 Calculate cell origin] */\n"
653 "\n"
654 " /* [Stage 4 Calculate start and end edge coordinates] */\n"
655 " /* Calculate start and end edge coordinates. */\n"
656 " vec3 start_corner = get_edge_coordinates(cell_origin_corner, edge_number, true);\n"
657 " vec3 end_corner = get_edge_coordinates(cell_origin_corner, edge_number, false);\n"
658 " /* [Stage 4 Calculate start and end edge coordinates] */\n"
659 "\n"
660 " /* [Stage 4 Calculate middle edge vertex] */\n"
661 " /* Calculate share of start point of an edge. */\n"
662 " float start_vertex_portion = get_start_corner_portion(start_corner, end_corner, iso_level);\n"
663 "\n"
664 " /* Calculate ''middle'' edge vertex. This vertex is moved closer to start or end vertices of the edge. */\n"
665 " vec3 edge_middle_vertex = mix(end_corner, start_corner, start_vertex_portion);\n"
666 " /* [Stage 4 Calculate middle edge vertex] */\n"
667 "\n"
668 " /* [Stage 4 Calculate middle edge normal] */\n"
669 " /* Calculate normal to surface in the ''middle'' vertex. */\n"
670 " vec3 vertex_normal = calc_phong_normal(start_vertex_portion, start_corner, end_corner);\n"
671 " /* [Stage 4 Calculate middle edge normal] */\n"
672 "\n"
673 " /* Update vertex shader outputs. */\n"
674 " gl_Position = mvp * vec4(edge_middle_vertex, 1.0); /* Transform vertex position with MVP-matrix. */\n"
675 " phong_vertex_position = gl_Position; /* Set vertex position for fragment shader. */\n"
676 " phong_vertex_normal_vector = vertex_normal; /* Set normal vector to surface for fragment shader. */\n"
677 " phong_vertex_color = vec3(0.7); /* Set vertex color for fragment shader. */\n"
678 " }\n"
679 " else\n"
680 " {\n"
681 " /* [Stage 4 Discard dummy triangle] */\n"
682 " /* This cell type generates fewer triangles, and this particular one should be discarded. */\n"
683 " gl_Position = vec4(0); /* Discard vertex by setting its coordinate in infinity. */\n"
684 " phong_vertex_position = gl_Position;\n"
685 " phong_vertex_normal_vector = vec3(0);\n"
686 " phong_vertex_color = vec3(0);\n"
687 " /* [Stage 4 Discard dummy triangle] */\n"
688 " }\n"
689 "}\n";
690 
696 const char* marching_cubes_triangles_frag_shader = "#version 300 es\n"
697 "\n"
698 "/** Specify low precision for float type. */\n"
699 "precision lowp float;\n"
700 "\n"
701 "/* Uniforms: */\n"
702 "/** Current time moment. */\n"
703 "uniform float time;\n"
704 "\n"
705 "/** Position of the vertex (and fragment) in world space. */\n"
706 "in vec4 phong_vertex_position;\n"
707 "\n"
708 "/** Surface normal vector in world space. */\n"
709 "in vec3 phong_vertex_normal_vector;\n"
710 "\n"
711 "/** Color passed from vertex shader. */\n"
712 "in vec3 phong_vertex_color;\n"
713 "\n"
714 "/* Output data: */\n"
715 "/** Fragment color. */\n"
716 "out vec4 FragColor;\n"
717 "\n"
718 "/** Shader entry point. Main steps are described in comments below. */\n"
719 "void main()\n"
720 "{\n"
721 " /* Distance to light source. */\n"
722 " const float light_distance = 5.0;\n"
723 "\n"
724 " /* Add some movement to light source. */\n"
725 " float theta = float(time);\n"
726 " float phi = float(time)/3.0;\n"
727 "\n"
728 " vec3 light_location = vec3\n"
729 " (\n"
730 " light_distance * cos(theta) * sin(phi),\n"
731 " light_distance * cos(theta) * cos(phi),\n"
732 " light_distance * sin(theta)\n"
733 " );\n"
734 "\n"
735 " /* Scene ambient color. */\n"
736 " const vec3 ambient_color = vec3(0.1, 0.1, 0.1);\n"
737 " const float attenuation = 1.0;\n"
738 " const float shiness = 3.0;\n"
739 "\n"
740 " /* Normalize directions. */\n"
741 " vec3 normal_direction = normalize(phong_vertex_normal_vector);\n"
742 " vec3 view_direction = normalize(vec3(vec4(0.0, 0.0, 1.0, 0.0) - phong_vertex_position));\n"
743 " vec3 light_direction = normalize(light_location);\n"
744 "\n"
745 " /** Calculate ambient lighting component of directional light. */\n"
746 " vec3 ambient_lighting = ambient_color * phong_vertex_color;\n"
747 "\n"
748 " /** Calculate diffuse reflection lighting component of directional light. */\n"
749 " vec3 diffuse_reflection = attenuation * phong_vertex_color\n"
750 " * max(0.0, dot(normal_direction, light_direction));\n"
751 "\n"
752 " /** Calculate specular reflection lighting component of directional light. */\n"
753 " vec3 specular_reflection = vec3(0.0, 0.0, 0.0);\n"
754 "\n"
755 " if (dot(normal_direction, light_direction) >= 0.0)\n"
756 " {\n"
757 " /* Light source on the right side. */\n"
758 " specular_reflection = attenuation * phong_vertex_color\n"
759 " * pow(max(0.0, dot(reflect(-light_direction, normal_direction), view_direction)), shiness);\n"
760 " }\n"
761 "\n"
762 " /** Calculate fragment lighting as sum of previous three component. */\n"
763 " FragColor = vec4(ambient_lighting + diffuse_reflection + specular_reflection, 1.0);\n"
764 "}\n";
765 
766 /* General metaballs example properties. */
770 unsigned int window_width = 256;
771 unsigned int window_height = 256;
773 /* Marching Cubes algorithm-specific constants. */
796 /* [tri_table chosen part for documentation] */
798 {
799  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
800  0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
801  0, 1, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
802  1, 8, 3, 9, 8, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
803 /* [tri_table chosen part for documentation] */
804  1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
805  0, 8, 3, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1,
806  9, 2, 10, 0, 2, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1,
807  2, 8, 3, 2, 10, 8, 10, 9, 8, -1, -1, -1, -1, -1, -1,
808  3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
809  0, 11, 2, 8, 11, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1,
810  1, 9, 0, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1,
811  1, 11, 2, 1, 9, 11, 9, 8, 11, -1, -1, -1, -1, -1, -1,
812  3, 10, 1, 11, 10, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1,
813  0, 10, 1, 0, 8, 10, 8, 11, 10, -1, -1, -1, -1, -1, -1,
814  3, 9, 0, 3, 11, 9, 11, 10, 9, -1, -1, -1, -1, -1, -1,
815  9, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1,
816  4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
817  4, 3, 0, 7, 3, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1,
818  0, 1, 9, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1,
819  4, 1, 9, 4, 7, 1, 7, 3, 1, -1, -1, -1, -1, -1, -1,
820  1, 2, 10, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1,
821  3, 4, 7, 3, 0, 4, 1, 2, 10, -1, -1, -1, -1, -1, -1,
822  9, 2, 10, 9, 0, 2, 8, 4, 7, -1, -1, -1, -1, -1, -1,
823  2, 10, 9, 2, 9, 7, 2, 7, 3, 7, 9, 4, -1, -1, -1,
824  8, 4, 7, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1,
825  11, 4, 7, 11, 2, 4, 2, 0, 4, -1, -1, -1, -1, -1, -1,
826  9, 0, 1, 8, 4, 7, 2, 3, 11, -1, -1, -1, -1, -1, -1,
827  4, 7, 11, 9, 4, 11, 9, 11, 2, 9, 2, 1, -1, -1, -1,
828  3, 10, 1, 3, 11, 10, 7, 8, 4, -1, -1, -1, -1, -1, -1,
829  1, 11, 10, 1, 4, 11, 1, 0, 4, 7, 11, 4, -1, -1, -1,
830  4, 7, 8, 9, 0, 11, 9, 11, 10, 11, 0, 3, -1, -1, -1,
831  4, 7, 11, 4, 11, 9, 9, 11, 10, -1, -1, -1, -1, -1, -1,
832  9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
833  9, 5, 4, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1,
834  0, 5, 4, 1, 5, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1,
835  8, 5, 4, 8, 3, 5, 3, 1, 5, -1, -1, -1, -1, -1, -1,
836  1, 2, 10, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1,
837  3, 0, 8, 1, 2, 10, 4, 9, 5, -1, -1, -1, -1, -1, -1,
838  5, 2, 10, 5, 4, 2, 4, 0, 2, -1, -1, -1, -1, -1, -1,
839  2, 10, 5, 3, 2, 5, 3, 5, 4, 3, 4, 8, -1, -1, -1,
840  9, 5, 4, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1,
841  0, 11, 2, 0, 8, 11, 4, 9, 5, -1, -1, -1, -1, -1, -1,
842  0, 5, 4, 0, 1, 5, 2, 3, 11, -1, -1, -1, -1, -1, -1,
843  2, 1, 5, 2, 5, 8, 2, 8, 11, 4, 8, 5, -1, -1, -1,
844  10, 3, 11, 10, 1, 3, 9, 5, 4, -1, -1, -1, -1, -1, -1,
845  4, 9, 5, 0, 8, 1, 8, 10, 1, 8, 11, 10, -1, -1, -1,
846  5, 4, 0, 5, 0, 11, 5, 11, 10, 11, 0, 3, -1, -1, -1,
847  5, 4, 8, 5, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1,
848  9, 7, 8, 5, 7, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1,
849  9, 3, 0, 9, 5, 3, 5, 7, 3, -1, -1, -1, -1, -1, -1,
850  0, 7, 8, 0, 1, 7, 1, 5, 7, -1, -1, -1, -1, -1, -1,
851  1, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1,
852  9, 7, 8, 9, 5, 7, 10, 1, 2, -1, -1, -1, -1, -1, -1,
853  10, 1, 2, 9, 5, 0, 5, 3, 0, 5, 7, 3, -1, -1, -1,
854  8, 0, 2, 8, 2, 5, 8, 5, 7, 10, 5, 2, -1, -1, -1,
855  2, 10, 5, 2, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1,
856  7, 9, 5, 7, 8, 9, 3, 11, 2, -1, -1, -1, -1, -1, -1,
857  9, 5, 7, 9, 7, 2, 9, 2, 0, 2, 7, 11, -1, -1, -1,
858  2, 3, 11, 0, 1, 8, 1, 7, 8, 1, 5, 7, -1, -1, -1,
859  11, 2, 1, 11, 1, 7, 7, 1, 5, -1, -1, -1, -1, -1, -1,
860  9, 5, 8, 8, 5, 7, 10, 1, 3, 10, 3, 11, -1, -1, -1,
861  5, 7, 0, 5, 0, 9, 7, 11, 0, 1, 0, 10, 11, 10, 0,
862  11, 10, 0, 11, 0, 3, 10, 5, 0, 8, 0, 7, 5, 7, 0,
863  11, 10, 5, 7, 11, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1,
864  10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
865  0, 8, 3, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1,
866  9, 0, 1, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1,
867  1, 8, 3, 1, 9, 8, 5, 10, 6, -1, -1, -1, -1, -1, -1,
868  1, 6, 5, 2, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
869  1, 6, 5, 1, 2, 6, 3, 0, 8, -1, -1, -1, -1, -1, -1,
870  9, 6, 5, 9, 0, 6, 0, 2, 6, -1, -1, -1, -1, -1, -1,
871  5, 9, 8, 5, 8, 2, 5, 2, 6, 3, 2, 8, -1, -1, -1,
872  2, 3, 11, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1,
873  11, 0, 8, 11, 2, 0, 10, 6, 5, -1, -1, -1, -1, -1, -1,
874  0, 1, 9, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1, -1, -1,
875  5, 10, 6, 1, 9, 2, 9, 11, 2, 9, 8, 11, -1, -1, -1,
876  6, 3, 11, 6, 5, 3, 5, 1, 3, -1, -1, -1, -1, -1, -1,
877  0, 8, 11, 0, 11, 5, 0, 5, 1, 5, 11, 6, -1, -1, -1,
878  3, 11, 6, 0, 3, 6, 0, 6, 5, 0, 5, 9, -1, -1, -1,
879  6, 5, 9, 6, 9, 11, 11, 9, 8, -1, -1, -1, -1, -1, -1,
880  5, 10, 6, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1,
881  4, 3, 0, 4, 7, 3, 6, 5, 10, -1, -1, -1, -1, -1, -1,
882  1, 9, 0, 5, 10, 6, 8, 4, 7, -1, -1, -1, -1, -1, -1,
883  10, 6, 5, 1, 9, 7, 1, 7, 3, 7, 9, 4, -1, -1, -1,
884  6, 1, 2, 6, 5, 1, 4, 7, 8, -1, -1, -1, -1, -1, -1,
885  1, 2, 5, 5, 2, 6, 3, 0, 4, 3, 4, 7, -1, -1, -1,
886  8, 4, 7, 9, 0, 5, 0, 6, 5, 0, 2, 6, -1, -1, -1,
887  7, 3, 9, 7, 9, 4, 3, 2, 9, 5, 9, 6, 2, 6, 9,
888  3, 11, 2, 7, 8, 4, 10, 6, 5, -1, -1, -1, -1, -1, -1,
889  5, 10, 6, 4, 7, 2, 4, 2, 0, 2, 7, 11, -1, -1, -1,
890  0, 1, 9, 4, 7, 8, 2, 3, 11, 5, 10, 6, -1, -1, -1,
891  9, 2, 1, 9, 11, 2, 9, 4, 11, 7, 11, 4, 5, 10, 6,
892  8, 4, 7, 3, 11, 5, 3, 5, 1, 5, 11, 6, -1, -1, -1,
893  5, 1, 11, 5, 11, 6, 1, 0, 11, 7, 11, 4, 0, 4, 11,
894  0, 5, 9, 0, 6, 5, 0, 3, 6, 11, 6, 3, 8, 4, 7,
895  6, 5, 9, 6, 9, 11, 4, 7, 9, 7, 11, 9, -1, -1, -1,
896  10, 4, 9, 6, 4, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1,
897  4, 10, 6, 4, 9, 10, 0, 8, 3, -1, -1, -1, -1, -1, -1,
898  10, 0, 1, 10, 6, 0, 6, 4, 0, -1, -1, -1, -1, -1, -1,
899  8, 3, 1, 8, 1, 6, 8, 6, 4, 6, 1, 10, -1, -1, -1,
900  1, 4, 9, 1, 2, 4, 2, 6, 4, -1, -1, -1, -1, -1, -1,
901  3, 0, 8, 1, 2, 9, 2, 4, 9, 2, 6, 4, -1, -1, -1,
902  0, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1,
903  8, 3, 2, 8, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1,
904  10, 4, 9, 10, 6, 4, 11, 2, 3, -1, -1, -1, -1, -1, -1,
905  0, 8, 2, 2, 8, 11, 4, 9, 10, 4, 10, 6, -1, -1, -1,
906  3, 11, 2, 0, 1, 6, 0, 6, 4, 6, 1, 10, -1, -1, -1,
907  6, 4, 1, 6, 1, 10, 4, 8, 1, 2, 1, 11, 8, 11, 1,
908  9, 6, 4, 9, 3, 6, 9, 1, 3, 11, 6, 3, -1, -1, -1,
909  8, 11, 1, 8, 1, 0, 11, 6, 1, 9, 1, 4, 6, 4, 1,
910  3, 11, 6, 3, 6, 0, 0, 6, 4, -1, -1, -1, -1, -1, -1,
911  6, 4, 8, 11, 6, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1,
912  7, 10, 6, 7, 8, 10, 8, 9, 10, -1, -1, -1, -1, -1, -1,
913  0, 7, 3, 0, 10, 7, 0, 9, 10, 6, 7, 10, -1, -1, -1,
914  10, 6, 7, 1, 10, 7, 1, 7, 8, 1, 8, 0, -1, -1, -1,
915  10, 6, 7, 10, 7, 1, 1, 7, 3, -1, -1, -1, -1, -1, -1,
916  1, 2, 6, 1, 6, 8, 1, 8, 9, 8, 6, 7, -1, -1, -1,
917  2, 6, 9, 2, 9, 1, 6, 7, 9, 0, 9, 3, 7, 3, 9,
918  7, 8, 0, 7, 0, 6, 6, 0, 2, -1, -1, -1, -1, -1, -1,
919  7, 3, 2, 6, 7, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1,
920  2, 3, 11, 10, 6, 8, 10, 8, 9, 8, 6, 7, -1, -1, -1,
921  2, 0, 7, 2, 7, 11, 0, 9, 7, 6, 7, 10, 9, 10, 7,
922  1, 8, 0, 1, 7, 8, 1, 10, 7, 6, 7, 10, 2, 3, 11,
923  11, 2, 1, 11, 1, 7, 10, 6, 1, 6, 7, 1, -1, -1, -1,
924  8, 9, 6, 8, 6, 7, 9, 1, 6, 11, 6, 3, 1, 3, 6,
925  0, 9, 1, 11, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1,
926  7, 8, 0, 7, 0, 6, 3, 11, 0, 11, 6, 0, -1, -1, -1,
927  7, 11, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
928  7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
929  3, 0, 8, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1,
930  0, 1, 9, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1,
931  8, 1, 9, 8, 3, 1, 11, 7, 6, -1, -1, -1, -1, -1, -1,
932  10, 1, 2, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1,
933  1, 2, 10, 3, 0, 8, 6, 11, 7, -1, -1, -1, -1, -1, -1,
934  2, 9, 0, 2, 10, 9, 6, 11, 7, -1, -1, -1, -1, -1, -1,
935  6, 11, 7, 2, 10, 3, 10, 8, 3, 10, 9, 8, -1, -1, -1,
936  7, 2, 3, 6, 2, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1,
937  7, 0, 8, 7, 6, 0, 6, 2, 0, -1, -1, -1, -1, -1, -1,
938  2, 7, 6, 2, 3, 7, 0, 1, 9, -1, -1, -1, -1, -1, -1,
939  1, 6, 2, 1, 8, 6, 1, 9, 8, 8, 7, 6, -1, -1, -1,
940  10, 7, 6, 10, 1, 7, 1, 3, 7, -1, -1, -1, -1, -1, -1,
941  10, 7, 6, 1, 7, 10, 1, 8, 7, 1, 0, 8, -1, -1, -1,
942  0, 3, 7, 0, 7, 10, 0, 10, 9, 6, 10, 7, -1, -1, -1,
943  7, 6, 10, 7, 10, 8, 8, 10, 9, -1, -1, -1, -1, -1, -1,
944  6, 8, 4, 11, 8, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1,
945  3, 6, 11, 3, 0, 6, 0, 4, 6, -1, -1, -1, -1, -1, -1,
946  8, 6, 11, 8, 4, 6, 9, 0, 1, -1, -1, -1, -1, -1, -1,
947  9, 4, 6, 9, 6, 3, 9, 3, 1, 11, 3, 6, -1, -1, -1,
948  6, 8, 4, 6, 11, 8, 2, 10, 1, -1, -1, -1, -1, -1, -1,
949  1, 2, 10, 3, 0, 11, 0, 6, 11, 0, 4, 6, -1, -1, -1,
950  4, 11, 8, 4, 6, 11, 0, 2, 9, 2, 10, 9, -1, -1, -1,
951  10, 9, 3, 10, 3, 2, 9, 4, 3, 11, 3, 6, 4, 6, 3,
952  8, 2, 3, 8, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1,
953  0, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1,
954  1, 9, 0, 2, 3, 4, 2, 4, 6, 4, 3, 8, -1, -1, -1,
955  1, 9, 4, 1, 4, 2, 2, 4, 6, -1, -1, -1, -1, -1, -1,
956  8, 1, 3, 8, 6, 1, 8, 4, 6, 6, 10, 1, -1, -1, -1,
957  10, 1, 0, 10, 0, 6, 6, 0, 4, -1, -1, -1, -1, -1, -1,
958  4, 6, 3, 4, 3, 8, 6, 10, 3, 0, 3, 9, 10, 9, 3,
959  10, 9, 4, 6, 10, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1,
960  4, 9, 5, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1,
961  0, 8, 3, 4, 9, 5, 11, 7, 6, -1, -1, -1, -1, -1, -1,
962  5, 0, 1, 5, 4, 0, 7, 6, 11, -1, -1, -1, -1, -1, -1,
963  11, 7, 6, 8, 3, 4, 3, 5, 4, 3, 1, 5, -1, -1, -1,
964  9, 5, 4, 10, 1, 2, 7, 6, 11, -1, -1, -1, -1, -1, -1,
965  6, 11, 7, 1, 2, 10, 0, 8, 3, 4, 9, 5, -1, -1, -1,
966  7, 6, 11, 5, 4, 10, 4, 2, 10, 4, 0, 2, -1, -1, -1,
967  3, 4, 8, 3, 5, 4, 3, 2, 5, 10, 5, 2, 11, 7, 6,
968  7, 2, 3, 7, 6, 2, 5, 4, 9, -1, -1, -1, -1, -1, -1,
969  9, 5, 4, 0, 8, 6, 0, 6, 2, 6, 8, 7, -1, -1, -1,
970  3, 6, 2, 3, 7, 6, 1, 5, 0, 5, 4, 0, -1, -1, -1,
971  6, 2, 8, 6, 8, 7, 2, 1, 8, 4, 8, 5, 1, 5, 8,
972  9, 5, 4, 10, 1, 6, 1, 7, 6, 1, 3, 7, -1, -1, -1,
973  1, 6, 10, 1, 7, 6, 1, 0, 7, 8, 7, 0, 9, 5, 4,
974  4, 0, 10, 4, 10, 5, 0, 3, 10, 6, 10, 7, 3, 7, 10,
975  7, 6, 10, 7, 10, 8, 5, 4, 10, 4, 8, 10, -1, -1, -1,
976  6, 9, 5, 6, 11, 9, 11, 8, 9, -1, -1, -1, -1, -1, -1,
977  3, 6, 11, 0, 6, 3, 0, 5, 6, 0, 9, 5, -1, -1, -1,
978  0, 11, 8, 0, 5, 11, 0, 1, 5, 5, 6, 11, -1, -1, -1,
979  6, 11, 3, 6, 3, 5, 5, 3, 1, -1, -1, -1, -1, -1, -1,
980  1, 2, 10, 9, 5, 11, 9, 11, 8, 11, 5, 6, -1, -1, -1,
981  0, 11, 3, 0, 6, 11, 0, 9, 6, 5, 6, 9, 1, 2, 10,
982  11, 8, 5, 11, 5, 6, 8, 0, 5, 10, 5, 2, 0, 2, 5,
983  6, 11, 3, 6, 3, 5, 2, 10, 3, 10, 5, 3, -1, -1, -1,
984  5, 8, 9, 5, 2, 8, 5, 6, 2, 3, 8, 2, -1, -1, -1,
985  9, 5, 6, 9, 6, 0, 0, 6, 2, -1, -1, -1, -1, -1, -1,
986  1, 5, 8, 1, 8, 0, 5, 6, 8, 3, 8, 2, 6, 2, 8,
987  1, 5, 6, 2, 1, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1,
988  1, 3, 6, 1, 6, 10, 3, 8, 6, 5, 6, 9, 8, 9, 6,
989  10, 1, 0, 10, 0, 6, 9, 5, 0, 5, 6, 0, -1, -1, -1,
990  0, 3, 8, 5, 6, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1,
991  10, 5, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
992  11, 5, 10, 7, 5, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1,
993  11, 5, 10, 11, 7, 5, 8, 3, 0, -1, -1, -1, -1, -1, -1,
994  5, 11, 7, 5, 10, 11, 1, 9, 0, -1, -1, -1, -1, -1, -1,
995  10, 7, 5, 10, 11, 7, 9, 8, 1, 8, 3, 1, -1, -1, -1,
996  11, 1, 2, 11, 7, 1, 7, 5, 1, -1, -1, -1, -1, -1, -1,
997  0, 8, 3, 1, 2, 7, 1, 7, 5, 7, 2, 11, -1, -1, -1,
998  9, 7, 5, 9, 2, 7, 9, 0, 2, 2, 11, 7, -1, -1, -1,
999  7, 5, 2, 7, 2, 11, 5, 9, 2, 3, 2, 8, 9, 8, 2,
1000  2, 5, 10, 2, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1,
1001  8, 2, 0, 8, 5, 2, 8, 7, 5, 10, 2, 5, -1, -1, -1,
1002  9, 0, 1, 5, 10, 3, 5, 3, 7, 3, 10, 2, -1, -1, -1,
1003  9, 8, 2, 9, 2, 1, 8, 7, 2, 10, 2, 5, 7, 5, 2,
1004  1, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1005  0, 8, 7, 0, 7, 1, 1, 7, 5, -1, -1, -1, -1, -1, -1,
1006  9, 0, 3, 9, 3, 5, 5, 3, 7, -1, -1, -1, -1, -1, -1,
1007  9, 8, 7, 5, 9, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1008  5, 8, 4, 5, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1,
1009  5, 0, 4, 5, 11, 0, 5, 10, 11, 11, 3, 0, -1, -1, -1,
1010  0, 1, 9, 8, 4, 10, 8, 10, 11, 10, 4, 5, -1, -1, -1,
1011  10, 11, 4, 10, 4, 5, 11, 3, 4, 9, 4, 1, 3, 1, 4,
1012  2, 5, 1, 2, 8, 5, 2, 11, 8, 4, 5, 8, -1, -1, -1,
1013  0, 4, 11, 0, 11, 3, 4, 5, 11, 2, 11, 1, 5, 1, 11,
1014  0, 2, 5, 0, 5, 9, 2, 11, 5, 4, 5, 8, 11, 8, 5,
1015  9, 4, 5, 2, 11, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1016  2, 5, 10, 3, 5, 2, 3, 4, 5, 3, 8, 4, -1, -1, -1,
1017  5, 10, 2, 5, 2, 4, 4, 2, 0, -1, -1, -1, -1, -1, -1,
1018  3, 10, 2, 3, 5, 10, 3, 8, 5, 4, 5, 8, 0, 1, 9,
1019  5, 10, 2, 5, 2, 4, 1, 9, 2, 9, 4, 2, -1, -1, -1,
1020  8, 4, 5, 8, 5, 3, 3, 5, 1, -1, -1, -1, -1, -1, -1,
1021  0, 4, 5, 1, 0, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1022  8, 4, 5, 8, 5, 3, 9, 0, 5, 0, 3, 5, -1, -1, -1,
1023  9, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1024  4, 11, 7, 4, 9, 11, 9, 10, 11, -1, -1, -1, -1, -1, -1,
1025  0, 8, 3, 4, 9, 7, 9, 11, 7, 9, 10, 11, -1, -1, -1,
1026  1, 10, 11, 1, 11, 4, 1, 4, 0, 7, 4, 11, -1, -1, -1,
1027  3, 1, 4, 3, 4, 8, 1, 10, 4, 7, 4, 11, 10, 11, 4,
1028  4, 11, 7, 9, 11, 4, 9, 2, 11, 9, 1, 2, -1, -1, -1,
1029  9, 7, 4, 9, 11, 7, 9, 1, 11, 2, 11, 1, 0, 8, 3,
1030  11, 7, 4, 11, 4, 2, 2, 4, 0, -1, -1, -1, -1, -1, -1,
1031  11, 7, 4, 11, 4, 2, 8, 3, 4, 3, 2, 4, -1, -1, -1,
1032  2, 9, 10, 2, 7, 9, 2, 3, 7, 7, 4, 9, -1, -1, -1,
1033  9, 10, 7, 9, 7, 4, 10, 2, 7, 8, 7, 0, 2, 0, 7,
1034  3, 7, 10, 3, 10, 2, 7, 4, 10, 1, 10, 0, 4, 0, 10,
1035  1, 10, 2, 8, 7, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1036  4, 9, 1, 4, 1, 7, 7, 1, 3, -1, -1, -1, -1, -1, -1,
1037  4, 9, 1, 4, 1, 7, 0, 8, 1, 8, 7, 1, -1, -1, -1,
1038  4, 0, 3, 7, 4, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1039  4, 8, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1040  9, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1041  3, 0, 9, 3, 9, 11, 11, 9, 10, -1, -1, -1, -1, -1, -1,
1042  0, 1, 10, 0, 10, 8, 8, 10, 11, -1, -1, -1, -1, -1, -1,
1043  3, 1, 10, 11, 3, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1044  1, 2, 11, 1, 11, 9, 9, 11, 8, -1, -1, -1, -1, -1, -1,
1045  3, 0, 9, 3, 9, 11, 1, 2, 9, 2, 11, 9, -1, -1, -1,
1046  0, 2, 11, 8, 0, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1047  3, 2, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1048  2, 3, 8, 2, 8, 10, 10, 8, 9, -1, -1, -1, -1, -1, -1,
1049  9, 10, 2, 0, 9, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1050  2, 3, 8, 2, 8, 10, 0, 1, 8, 1, 10, 8, -1, -1, -1,
1051  1, 10, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1052  1, 3, 8, 9, 1, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1053  0, 9, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1054  0, 3, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1055  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
1056 };
1057 
1060 
1062 const int n_spheres = 3;
1063 
1066 
1069 
1070 
1071 /* 1. Calculate sphere positions stage variable data. */
1078 
1081 
1084 
1086 const GLchar* spheres_updater_uniform_time_name = "time";
1089 
1091 const GLchar* sphere_position_varying_name = "sphere_position";
1092 
1093 
1094 /* 2. Scalar field generation stage variable data. */
1101 
1104 
1107 
1109 const GLchar* scalar_field_uniform_samples_per_axis_name = "samples_per_axis";
1112 
1114 const GLchar* scalar_field_uniform_spheres_name = "spheres_uniform_block";
1117 
1119 const GLchar* scalar_field_value_varying_name = "scalar_field_value";
1120 
1123 
1124 
1125 /* 3. Marching Cubes cell-splitting stage variable data. */
1132 
1134 const GLchar* marching_cubes_cells_uniform_cells_per_axis_name = "cells_per_axis";
1137 
1142 
1147 
1149 const GLchar* marching_cubes_cells_varying_name = "cell_type_index";
1150 
1153 
1156 
1159 
1160 
1161 /* 4. Marching Cubes algorithm triangle generation and rendering stage variable data. */
1168 
1173 
1178 
1183 
1188 
1193 
1198 
1200 const GLchar* marching_cubes_triangles_uniform_sphere_positions_name = "sphere_positions_uniform_block";
1203 
1208 
1211 
1214 
1215 
1221 {
1222  /* Define projection properties. */
1223  float degreesToRadiansCoefficient = atanf(1) / 45; /* Coefficient to recalculate degrees to radians. */
1224  float frustum_fovy = 45.0f; /* 45 degrees field of view in the y direction. */
1225  float frustum_aspect = (float)window_width/(float)window_height; /* Aspect ratio. */
1226  float frustum_z_near = 0.01f; /* How close the viewer is to the near clipping plane. */
1227  float frustum_z_far = 100.0f; /* How far the viewer is from the far clipping plane. */
1228  float camera_distance = 2.5f; /* Distance from camera to scene center. */
1229 
1230  /* Matrix that stores temporary matrix data for translation transformations. */
1231  Matrix mat4_translate = Matrix::createTranslation(-0.5, -0.5, -0.5);
1232 
1233  /* Matrix that stores temporary matrix data for scale transformations. */
1234  Matrix mat4_scale = Matrix::createScaling ( 2.0, 2.0, 2.0);
1235 
1236  /* Matrix that transforms the vertices from model space to world space. */
1237  /* Translate and scale coordinates from [0..1] to [-1..1] range for full visibility. */
1238  Matrix mat4_model_view = mat4_scale * mat4_translate;
1239 
1240  /* Pull the camera back from the scene center. */
1241  mat4_model_view[14] -= float(camera_distance);
1242 
1243  /* Create the perspective matrix from frustum parameters. */
1244  Matrix mat4_perspective = Matrix::matrixPerspective(degreesToRadiansCoefficient * frustum_fovy, frustum_aspect, frustum_z_near, frustum_z_far);
1245 
1246  /* MVP (Model View Perspective) matrix is a result of multiplication of Perspective Matrix by Model View Matrix. */
1247  mvp = mat4_perspective * mat4_model_view;
1248 }
1249 
1250 
1257 {
1258  /* Store window width and height. */
1259  window_width = width;
1261 
1262  /* Specify one byte alignment for pixels rows in memory for pack and unpack buffers. */
1263  GL_CHECK(glPixelStorei(GL_UNPACK_ALIGNMENT, 1));
1264  GL_CHECK(glPixelStorei(GL_PACK_ALIGNMENT, 1));
1265 
1266  /* 1. Calculate sphere positions stage. */
1267  /* Create sphere updater program object. */
1268  spheres_updater_program_id = GL_CHECK(glCreateProgram());
1269 
1270  /* Load and compile sphere updater shaders. */
1273 
1274  /* Attach the shaders. */
1277 
1278  /* [Stage 1 Specifying output variables] */
1279  /* Specify shader varyings (output variables) we are interested in capturing. */
1280  GL_CHECK(glTransformFeedbackVaryings(spheres_updater_program_id, 1, &sphere_position_varying_name, GL_SEPARATE_ATTRIBS));
1281 
1282  /* Link the program object. */
1283  GL_CHECK(glLinkProgram(spheres_updater_program_id));
1284  /* [Stage 1 Specifying output variables] */
1285 
1286  /* [Stage 1 Specifying input variables] */
1287  /* Get input uniform location. */
1289  /* [Stage 1 Specifying input variables] */
1290 
1291  /* Activate spheres updater program. */
1292  GL_CHECK(glUseProgram(spheres_updater_program_id));
1293 
1294  /* [Stage 1 Allocate buffer for output values] */
1295  /* Generate buffer object id. Define required storage space sufficient to hold sphere positions data. */
1297  GL_CHECK(glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, spheres_updater_sphere_positions_buffer_object_id));
1298  GL_CHECK(glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, n_spheres * n_sphere_position_components * sizeof(GLfloat), NULL, GL_STATIC_DRAW));
1299  GL_CHECK(glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, 0));
1300  /* [Stage 1 Allocate buffer for output values] */
1301 
1302  /* [Stage 1 Transform feedback object initialization] */
1303  /* Generate and bind transform feedback object. */
1304  GL_CHECK(glGenTransformFeedbacks(1, &spheres_updater_transform_feedback_object_id));
1306 
1307  /* Bind buffers to store calculated sphere positions. */
1308  GL_CHECK(glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, spheres_updater_sphere_positions_buffer_object_id));
1309  GL_CHECK(glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0));
1310  /* [Stage 1 Transform feedback object initialization] */
1311 
1312  /* 2. Scalar field generation stage. */
1313  /* Create scalar field generator program object. */
1314  scalar_field_program_id = GL_CHECK(glCreateProgram());
1315 
1316  /* Load and compile scalar field generator shaders. */
1319 
1320  /* Attach the shaders. */
1323 
1324  /* Specify shader varyings (output variables) we are interested in capturing. */
1325  GL_CHECK(glTransformFeedbackVaryings(scalar_field_program_id, 1, &scalar_field_value_varying_name, GL_SEPARATE_ATTRIBS));
1326 
1327  /* Link the program object. */
1328  GL_CHECK(glLinkProgram(scalar_field_program_id));
1329 
1330  /* Get input uniform locations. */
1333 
1334  /* Activate scalar field generating program. */
1335  GL_CHECK(glUseProgram(scalar_field_program_id));
1336 
1337  /* Initialize uniforms constant throughout rendering loop. */
1339 
1340  /* Set binding point for uniform block. */
1342  GL_CHECK(glBindBufferBase(GL_UNIFORM_BUFFER, 0, spheres_updater_sphere_positions_buffer_object_id));
1343 
1344  /* Generate buffer object id. Define required storage space sufficient to hold scalar field data. */
1345  GL_CHECK(glGenBuffers(1, &scalar_field_buffer_object_id));
1346  GL_CHECK(glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, scalar_field_buffer_object_id));
1347 
1348  GL_CHECK(glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, samples_in_3d_space * sizeof(GLfloat), NULL, GL_STATIC_DRAW));
1349  GL_CHECK(glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, 0));
1350 
1351  /* Generate and bind transform feedback object. */
1352  GL_CHECK(glGenTransformFeedbacks(1, &scalar_field_transform_feedback_object_id));
1354 
1355  /* Bind buffer to store calculated scalar field values. */
1356  GL_CHECK(glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, scalar_field_buffer_object_id));
1357  GL_CHECK(glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0));
1358 
1359  /* [Stage 2 Creating texture] */
1360  /* Generate texture object to hold scalar field data. */
1361  GL_CHECK(glGenTextures(1, &scalar_field_texture_object_id));
1362 
1363  /* Scalar field uses GL_TEXTURE_3D target of texture unit 1. */
1364  GL_CHECK(glActiveTexture(GL_TEXTURE1));
1366 
1367  /* Prepare texture storage for scalar field values. */
1369  /* [Stage 2 Creating texture] */
1370 
1371  /* Tune texture settings to use it as a data source. */
1372  GL_CHECK(glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ));
1373  GL_CHECK(glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ));
1374  GL_CHECK(glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 0 ));
1375  GL_CHECK(glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 0 ));
1376  GL_CHECK(glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
1377  GL_CHECK(glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
1378  GL_CHECK(glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE));
1379 
1380 
1381  /* 3. Marching Cubes cell-splitting stage. */
1382  /* Create a program object to execute Marching Cubes algorithm cell splitting stage. */
1383  marching_cubes_cells_program_id = GL_CHECK(glCreateProgram());
1384 
1385  /* Marching cubes algorithm shaders initialisation. */
1388 
1389  /* Attach the shaders. */
1392 
1393  /* Specify shader varyings (output variables) we are interested in capturing. */
1394  GL_CHECK(glTransformFeedbackVaryings(marching_cubes_cells_program_id, 1, &marching_cubes_cells_varying_name, GL_SEPARATE_ATTRIBS));
1395 
1396  /* Link the program object. */
1397  GL_CHECK(glLinkProgram(marching_cubes_cells_program_id));
1398 
1399  /* Get input uniform locations. */
1403 
1404  /* Activate cell-splitting program. */
1406 
1407  /* Initialize uniforms constant throughout rendering loop. */
1411 
1412  /* Generate buffer object id and allocate memory to store scalar field values. */
1414  GL_CHECK(glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, marching_cubes_cells_types_buffer_id));
1415  GL_CHECK(glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, cells_in_3d_space * sizeof(GLint), NULL, GL_STATIC_DRAW));
1416  GL_CHECK(glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, 0));
1417 
1418  /* Generate and bind transform feedback object. */
1419  GL_CHECK(glGenTransformFeedbacks(1, &marching_cubes_cells_transform_feedback_object_id));
1421 
1422  /* Bind buffer to store calculated cell type data. */
1423  GL_CHECK(glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, marching_cubes_cells_types_buffer_id));
1424  GL_CHECK(glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0));
1425 
1426  /* [Stage 3 Creating texture] */
1427  /* Generate a texture object to hold cell type data. (We will explain why the texture later). */
1429 
1430  /* Marching cubes cell type data uses GL_TEXTURE_3D target of texture unit 2. */
1431  GL_CHECK(glActiveTexture(GL_TEXTURE2));
1433 
1434  /* Prepare texture storage for marching cube cell type data. */
1435  GL_CHECK(glTexStorage3D(GL_TEXTURE_3D, 1, GL_R32I, cells_per_axis, cells_per_axis, cells_per_axis));
1436  /* [Stage 3 Creating texture] */
1437 
1438  /* Tune texture settings to use it as a data source. */
1439  GL_CHECK(glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ));
1440  GL_CHECK(glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ));
1441  GL_CHECK(glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 0 ));
1442  GL_CHECK(glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 0 ));
1443  GL_CHECK(glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
1444  GL_CHECK(glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
1445  GL_CHECK(glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE));
1446 
1447 
1448  /* 4. Marching Cubes algorithm triangle generation and rendering stage. */
1449  /* Create a program object that we will use for triangle generation and rendering stage. */
1450  marching_cubes_triangles_program_id = GL_CHECK(glCreateProgram());
1451 
1452  /* Initialize shaders for the triangle generation and rendering stage. */
1455 
1456  /* Attach the shaders. */
1459 
1460  /* Link the program object. */
1462 
1463  /* Get input uniform locations. */
1472 
1473  /* Activate triangle generating and rendering program. */
1475 
1476  /* Initialize model view projection matrix. */
1477  calc_mvp(mvp);
1478 
1479  /* Initialize uniforms constant throughout rendering loop. */
1485  GL_CHECK(glUniformMatrix4fv(marching_cubes_triangles_uniform_mvp_id, 1, GL_FALSE, mvp.getAsArray()));
1486 
1487  /* Allocate memory for buffer */
1488  GL_CHECK(glBindBuffer(GL_UNIFORM_BUFFER, spheres_updater_sphere_positions_buffer_object_id));
1489 
1490  /* Generate an Id for a texture object to hold look-up array data (tri_table). */
1492 
1493  /* Lookup array (tri_table) uses GL_TEXTURE_2D target of texture unit 4. */
1494  GL_CHECK(glActiveTexture(GL_TEXTURE4));
1495  GL_CHECK(glBindTexture(GL_TEXTURE_2D, marching_cubes_triangles_lookup_table_texture_id));
1496 
1497  /* Tune texture settings to use it as a data source. */
1498  GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ));
1499  GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ));
1500  GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0 ));
1501  GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0 ));
1502  GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
1503  GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
1504 
1505  /* Load lookup table (tri_table) into texture. */
1506  GL_CHECK(glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32I, mc_vertices_per_cell, mc_cells_types_count));
1507  GL_CHECK(glTexSubImage2D(GL_TEXTURE_2D, /* Use texture bound to GL_TEXTURE_2D */
1508  0, /* Base image level */
1509  0, /* From the texture origin */
1510  0, /* From the texture origin */
1511  mc_vertices_per_cell, /* Width will represent vertices in all 5 triangles */
1512  mc_cells_types_count, /* Height will represent cell type */
1513  GL_RED_INTEGER, /* Texture will have only one component */
1514  GL_INT, /* ... of type int */
1515  tri_table /* Data will be copied directly from tri_table */
1516  ));
1517 
1518  /* Generate a vertex array object. We'll go with the explanation later. */
1519  GL_CHECK(glGenVertexArrays(1, &marching_cubes_triangles_vao_id));
1520 
1521  /* In OpenGL ES, draw calls require a bound vertex array object.
1522  * Even though we're not using any per-vertex attribute data, we still need to bind a vertex array object.
1523  */
1524  GL_CHECK(glBindVertexArray(marching_cubes_triangles_vao_id));
1525 
1526  /* Enable facet culling, depth testing and specify front face for polygons. */
1527  GL_CHECK(glEnable (GL_DEPTH_TEST));
1528  GL_CHECK(glEnable (GL_CULL_FACE ));
1529  GL_CHECK(glFrontFace(GL_CW ));
1530 
1531  /* Start counting time. */
1532  timer.reset();
1533 }
1534 
1536 void renderFrame(void)
1537 {
1538  /* Update time. */
1539  model_time = timer.getTime();
1540 
1541  /*
1542  * Rendering section
1543  */
1544  /* Clear the buffers that we are going to render to in a moment. */
1545  GL_CHECK(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));
1546 
1547  /* [Stage 1 Calculate sphere positions stage] */
1548  /* 1. Calculate sphere positions stage.
1549  *
1550  * At this stage we calculate new sphere positions in space
1551  * according to current time moment.
1552  */
1553  /* [Stage 1 Bind buffers to store calculated sphere position values] */
1554  /* Bind buffers to store calculated sphere position values. */
1556  /* [Stage 1 Bind buffers to store calculated sphere position values] */
1557 
1558  /* [Stage 1 Enable GL_RASTERIZER_DISCARD] */
1559  /* Shorten GL pipeline: we will use vertex shader only. */
1560  GL_CHECK(glEnable(GL_RASTERIZER_DISCARD));
1561  /* [Stage 1 Enable GL_RASTERIZER_DISCARD] */
1562  {
1563  /* Select program for sphere positions generation stage. */
1564  GL_CHECK(glUseProgram(spheres_updater_program_id));
1565 
1566  /* [Stage 1 Specify input arguments to vertex shader] */
1567  /* Specify input arguments to vertex shader. */
1569  /* [Stage 1 Specify input arguments to vertex shader] */
1570 
1571  /* [Stage 1 Activate transform feedback mode] */
1572  /* Activate transform feedback mode. */
1573  GL_CHECK(glBeginTransformFeedback(GL_POINTS));
1574  /* [Stage 1 Activate transform feedback mode] */
1575  {
1576  /* [Stage 1 Execute n_spheres times vertex shader] */
1577  /* Run sphere positions calculation. */
1578  GL_CHECK(glDrawArrays(GL_POINTS, 0, n_spheres));
1579  /* [Stage 1 Execute n_spheres times vertex shader] */
1580  }
1581  /* [Stage 1 Deactivate transform feedback mode] */
1582  GL_CHECK(glEndTransformFeedback());
1583  /* [Stage 1 Deactivate transform feedback mode] */
1584  }
1585  /* [Stage 1 Disable GL_RASTERIZER_DISCARD] */
1586  GL_CHECK(glDisable(GL_RASTERIZER_DISCARD));
1587  /* [Stage 1 Disable GL_RASTERIZER_DISCARD] */
1588 
1589  /* Unbind buffers used at this stage. */
1590  GL_CHECK(glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0));
1591  /* [Stage 1 Calculate sphere positions stage] */
1592 
1593 
1594  /* [Stage 2 Scalar field generation stage] */
1595  /* 2. Scalar field generation stage.
1596  *
1597  * At this stage we calculate scalar field and store it in buffer
1598  * and later copy from buffer to texture.
1599  */
1600  /* Bind sphere positions data buffer to GL_UNIFORM_BUFFER. */
1601  GL_CHECK(glBindBuffer(GL_UNIFORM_BUFFER, spheres_updater_sphere_positions_buffer_object_id));
1602 
1603  /* Bind buffer object to store calculated scalar field values. */
1605 
1606  /* Shorten GL pipeline: we will use vertex shader only. */
1607  GL_CHECK(glEnable(GL_RASTERIZER_DISCARD));
1608  {
1609  /* Select program for scalar field generation stage. */
1610  GL_CHECK(glUseProgram(scalar_field_program_id));
1611 
1612  /* Activate transform feedback mode. */
1613  GL_CHECK(glBeginTransformFeedback(GL_POINTS));
1614  {
1615  /* Run scalar field calculation for all vertices in space. */
1616  GL_CHECK(glDrawArrays(GL_POINTS, 0, samples_in_3d_space));
1617  }
1618  GL_CHECK(glEndTransformFeedback());
1619  }
1620  GL_CHECK(glDisable(GL_RASTERIZER_DISCARD));
1621 
1622  /* Unbind buffers used at this stage. */
1623  GL_CHECK(glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0));
1624  /* [Stage 2 Scalar field generation stage] */
1625 
1626  /* Copy scalar field values from buffer into texture bound to target GL_TEXTURE_3D of texture unit 1.
1627  * We need to move this data to a texture object, as there is no way we could access data
1628  * stored within a buffer object in an OpenGL ES 3.0 shader.
1629  */
1630  /* [Stage 2 Scalar field generation stage move data to texture] */
1631  GL_CHECK(glActiveTexture(GL_TEXTURE1));
1632  GL_CHECK(glBindBuffer (GL_PIXEL_UNPACK_BUFFER, scalar_field_buffer_object_id));
1633  GL_CHECK(glTexSubImage3D(GL_TEXTURE_3D, /* Use texture bound to GL_TEXTURE_3D */
1634  0, /* Base image level */
1635  0, /* From the texture origin */
1636  0, /* From the texture origin */
1637  0, /* From the texture origin */
1638  samples_per_axis, /* Texture have same width as scalar field in buffer */
1639  samples_per_axis, /* Texture have same height as scalar field in buffer */
1640  samples_per_axis, /* Texture have same depth as scalar field in buffer */
1641  GL_RED, /* Scalar field gathered in buffer has only one component */
1642  GL_FLOAT, /* Scalar field gathered in buffer is of float type */
1643  NULL /* Scalar field gathered in buffer bound to GL_PIXEL_UNPACK_BUFFER target */
1644  ));
1645  /* [Stage 2 Scalar field generation stage move data to texture] */
1646 
1647 
1648  /* 3. Marching cube algorithm cell splitting stage.
1649  *
1650  * At this stage we analyze isosurface in each cell of space and
1651  * assign one of 256 possible types to each cell. Cell type data
1652  * for each cell is stored in attached buffer.
1653  */
1654  /* Bind buffer to store cell type data. */
1656 
1657  /* Shorten GL pipeline: we will use vertex shader only. */
1658  GL_CHECK(glEnable(GL_RASTERIZER_DISCARD));
1659  {
1660  /* Select program for Marching Cubes algorthim's cell splitting stage. */
1662 
1663  /* Activate transform feedback mode. */
1664  GL_CHECK(glBeginTransformFeedback(GL_POINTS));
1665  {
1666  /* [Stage 3 Execute vertex shader] */
1667  /* Run Marching Cubes algorithm cell splitting stage for all cells. */
1668  GL_CHECK(glDrawArrays(GL_POINTS, 0, cells_in_3d_space));
1669  /* [Stage 3 Execute vertex shader] */
1670  }
1671  GL_CHECK(glEndTransformFeedback());
1672  }
1673  GL_CHECK(glDisable(GL_RASTERIZER_DISCARD));
1674 
1675  /* Unbind buffers used at this stage. */
1676  GL_CHECK(glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0));
1677 
1678  /* Copy data from buffer into texture bound to target GL_TEXTURE2 in texture unit 2.
1679  * We need to move this data to a texture object, as there is no way we could access data
1680  * stored within a buffer object in a OpenGL ES 3.0 shader.
1681  */
1682  GL_CHECK(glActiveTexture(GL_TEXTURE2));
1683  GL_CHECK(glBindBuffer (GL_PIXEL_UNPACK_BUFFER, marching_cubes_cells_types_buffer_id));
1684  GL_CHECK(glTexSubImage3D(GL_TEXTURE_3D, /* Use texture bound to GL_TEXTURE_3D */
1685  0, /* Base image level */
1686  0, /* From the texture origin */
1687  0, /* From the texture origin */
1688  0, /* From the texture origin */
1689  cells_per_axis, /* Texture have same width as cells by width in buffer */
1690  cells_per_axis, /* Texture have same height as cells by height in buffer */
1691  cells_per_axis, /* Texture have same depth as cells by depth in buffer */
1692  GL_RED_INTEGER, /* Cell types gathered in buffer have only one component */
1693  GL_INT, /* Cell types gathered in buffer are of int type */
1694  NULL /* Cell types gathered in buffer bound to GL_PIXEL_UNPACK_BUFFER target */
1695  ));
1696 
1697 
1698  /* 4. Marching Cubes algorithm triangle generation stage.
1699  *
1700  * At this stage, we render exactly (3 vertices * 5 triangles per cell *
1701  * amount of cells the scalar field is split to) triangle vertices.
1702  * Then render triangularized geometry.
1703  */
1704  GL_CHECK(glActiveTexture(GL_TEXTURE0));
1705 
1706  /* Activate triangle generating and rendering program. */
1708 
1709  /* Specify input arguments to vertex shader. */
1711 
1712  /* [Stage 4 Run triangle generating and rendering program] */
1713  /* Run triangle generating and rendering program. */
1714  GL_CHECK(glDrawArrays(GL_TRIANGLES, 0, cells_in_3d_space * triangles_per_cell * vertices_per_triangle));
1715  /* [Stage 4 Run triangle generating and rendering program] */
1716 }
1717 
1719 void cleanup()
1720 {
1721  GL_CHECK(glDeleteVertexArrays (1, &marching_cubes_triangles_vao_id ));
1724  GL_CHECK(glDeleteProgram ( marching_cubes_triangles_program_id ));
1726  GL_CHECK(glDeleteTextures (1, &marching_cubes_cells_types_texture_object_id ));
1727  GL_CHECK(glDeleteTransformFeedbacks(1, &marching_cubes_cells_transform_feedback_object_id));
1728  GL_CHECK(glDeleteBuffers (1, &marching_cubes_cells_types_buffer_id ));
1729  GL_CHECK(glDeleteShader ( marching_cubes_cells_frag_shader_id ));
1730  GL_CHECK(glDeleteShader ( marching_cubes_cells_vert_shader_id ));
1731  GL_CHECK(glDeleteProgram ( marching_cubes_cells_program_id ));
1732  GL_CHECK(glDeleteTextures (1, &scalar_field_texture_object_id ));
1733  GL_CHECK(glDeleteTransformFeedbacks(1, &scalar_field_transform_feedback_object_id ));
1734  GL_CHECK(glDeleteBuffers (1, &scalar_field_buffer_object_id ));
1735  GL_CHECK(glDeleteShader ( scalar_field_frag_shader_id ));
1736  GL_CHECK(glDeleteShader ( scalar_field_vert_shader_id ));
1737  GL_CHECK(glDeleteProgram ( scalar_field_program_id ));
1738  GL_CHECK(glDeleteTransformFeedbacks(1, &spheres_updater_transform_feedback_object_id ));
1740  GL_CHECK(glDeleteShader ( spheres_updater_frag_shader_id ));
1741  GL_CHECK(glDeleteShader ( spheres_updater_vert_shader_id ));
1742  GL_CHECK(glDeleteProgram ( spheres_updater_program_id ));
1743 }
1744 
1745 
1746 extern "C"
1747 {
1749  (JNIEnv *env, jclass jcls, jint width, jint height)
1750  {
1751  /* Initialze OpenGL ES and model environment for metaballs: allocate buffers and textures, bind them, etc. */
1752  setupGraphics(width, height);
1753  }
1754 
1756  (JNIEnv *env, jclass jcls)
1757  {
1758  /* Render a frame */
1759  renderFrame();
1760  }
1761 
1763  (JNIEnv *, jclass)
1764  {
1765  cleanup();
1766  }
1767 }
void setupGraphics(int width, int height)
Definition: Native.cpp:1256
const GLint tri_table[mc_cells_types_count *mc_vertices_per_cell]
Definition: Native.cpp:797
const GLchar * marching_cubes_triangles_uniform_cell_types_sampler_name
Definition: Native.cpp:1190
JNIEXPORT void JNICALL Java_com_arm_malideveloper_openglessdk_metaballs_NativeLibrary_uninit(JNIEnv *, jclass)
Definition: Native.cpp:1763
void cleanup()
Definition: Native.cpp:1719
#define GL_CHECK(x)
Definition: Native.cpp:64
float getTime()
Returns the time passed since object creation or since reset() was last called.
Definition: Timer.cpp:109
GLuint marching_cubes_triangles_uniform_cell_types_sampler_id
Definition: Native.cpp:1192
const char * scalar_field_vert_shader
Definition: Native.cpp:126
unsigned int window_height
Definition: Native.cpp:771
const GLchar * marching_cubes_triangles_uniform_mvp_name
Definition: Native.cpp:1185
GLuint marching_cubes_cells_program_id
Definition: Native.cpp:1127
const GLuint cells_in_3d_space
Definition: Native.cpp:777
const GLchar * marching_cubes_cells_uniform_scalar_field_sampler_name
Definition: Native.cpp:1144
GLint GLsizei GLsizei height
Definition: gl2ext.h:179
GLuint marching_cubes_cells_vert_shader_id
Definition: Native.cpp:1129
void calc_mvp(Matrix &mvp)
Definition: Native.cpp:1220
const GLuint vertices_per_triangle
Definition: Native.cpp:778
const GLchar * scalar_field_uniform_samples_per_axis_name
Definition: Native.cpp:1109
GLuint marching_cubes_cells_types_texture_object_id
Definition: Native.cpp:1158
GLuint marching_cubes_triangles_uniform_samples_per_axis_id
Definition: Native.cpp:1172
Functions for manipulating matrices.
Definition: Matrix.h:31
const GLchar * marching_cubes_cells_uniform_isolevel_name
Definition: Native.cpp:1139
const char * spheres_updater_vert_shader
Definition: Native.cpp:64
GLuint marching_cubes_triangles_uniform_sphere_positions_id
Definition: Native.cpp:1202
const GLuint mc_cells_types_count
Definition: Native.cpp:781
const GLchar * sphere_position_varying_name
Definition: Native.cpp:1091
GLfloat model_time
Definition: Native.cpp:767
GLuint marching_cubes_cells_types_buffer_id
Definition: Native.cpp:1155
const GLchar * marching_cubes_cells_varying_name
Definition: Native.cpp:1149
GLuint marching_cubes_triangles_lookup_table_texture_id
Definition: Native.cpp:1210
static Matrix createTranslation(float x, float y, float z)
Create and return a translation matrix.
Definition: Matrix.cpp:414
Provides a platform independent high resolution timer.
Definition: Timer.h:37
GLfloat isosurface_level
Definition: Native.cpp:769
static Matrix createScaling(float x, float y, float z)
Create and return a scaling matrix.
Definition: Matrix.cpp:403
const GLchar * marching_cubes_triangles_uniform_tri_table_sampler_name
Definition: Native.cpp:1205
const GLuint samples_per_axis
Definition: Native.cpp:774
static Matrix matrixPerspective(float FOV, float ratio, float zNear, float zFar)
Create and return a perspective projection matrix.
Definition: Matrix.cpp:425
GLuint marching_cubes_cells_uniform_isolevel_id
Definition: Native.cpp:1141
const GLuint mc_vertices_per_cell
Definition: Native.cpp:780
GLuint marching_cubes_cells_uniform_scalar_field_sampler_id
Definition: Native.cpp:1146
GLuint marching_cubes_cells_transform_feedback_object_id
Definition: Native.cpp:1152
#define GL_TRANSFORM_FEEDBACK
Definition: gl2ext.h:1090
GLuint scalar_field_vert_shader_id
Definition: Native.cpp:1098
const GLuint tesselation_level
Definition: Native.cpp:768
GLuint marching_cubes_triangles_uniform_scalar_field_sampler_id
Definition: Native.cpp:1197
GLuint spheres_updater_frag_shader_id
Definition: Native.cpp:1077
const char * spheres_updater_frag_shader
Definition: Native.cpp:114
float * getAsArray(void)
Get the matrix elements as a column major order array.
Definition: Matrix.cpp:78
GLuint scalar_field_program_id
Definition: Native.cpp:1096
GLuint marching_cubes_triangles_uniform_tri_table_sampler_id
Definition: Native.cpp:1207
const GLuint triangles_per_cell
Definition: Native.cpp:779
GLuint marching_cubes_triangles_vert_shader_id
Definition: Native.cpp:1167
const char * scalar_field_frag_shader
Definition: Native.cpp:236
Matrix mvp
Definition: Native.cpp:1068
void reset()
Resets the timer to 0.0f.
Definition: Timer.cpp:100
const GLchar * marching_cubes_triangles_uniform_sphere_positions_name
Definition: Native.cpp:1200
const GLchar * scalar_field_uniform_spheres_name
Definition: Native.cpp:1114
const GLchar * marching_cubes_triangles_uniform_scalar_field_sampler_name
Definition: Native.cpp:1195
GLuint scalar_field_frag_shader_id
Definition: Native.cpp:1100
GLuint marching_cubes_cells_frag_shader_id
Definition: Native.cpp:1131
GLuint spheres_updater_vert_shader_id
Definition: Native.cpp:1075
GLuint spheres_updater_program_id
Definition: Native.cpp:1073
const GLchar * marching_cubes_triangles_uniform_isolevel_name
Definition: Native.cpp:1175
GLuint spheres_updater_transform_feedback_object_id
Definition: Native.cpp:1083
GLuint scalar_field_texture_object_id
Definition: Native.cpp:1122
void renderFrame(void)
Definition: Native.cpp:1536
unsigned int window_width
Definition: Native.cpp:770
const GLchar * spheres_updater_uniform_time_name
Definition: Native.cpp:1086
const GLuint samples_in_3d_space
Definition: Native.cpp:775
GLuint marching_cubes_triangles_frag_shader_id
Definition: Native.cpp:1165
GLuint marching_cubes_triangles_uniform_time_id
Definition: Native.cpp:1182
GLuint marching_cubes_triangles_vao_id
Definition: Native.cpp:1213
const GLchar * marching_cubes_triangles_uniform_samples_per_axis_name
Definition: Native.cpp:1170
const GLchar * marching_cubes_triangles_uniform_time_name
Definition: Native.cpp:1180
#define GL_TEXTURE_3D
Definition: gl2ext.h:1613
const GLuint cells_per_axis
Definition: Native.cpp:776
Timer timer
Definition: Native.cpp:1059
GLuint marching_cubes_triangles_program_id
Definition: Native.cpp:1163
const int n_sphere_position_components
Definition: Native.cpp:1065
const char * marching_cubes_cells_frag_shader
Definition: Native.cpp:371
GLuint marching_cubes_cells_uniform_cells_per_axis_id
Definition: Native.cpp:1136
GLuint scalar_field_uniform_spheres_id
Definition: Native.cpp:1116
const char * marching_cubes_triangles_vert_shader
Definition: Native.cpp:388
const char * marching_cubes_cells_vert_shader
Definition: Native.cpp:250
const GLchar * marching_cubes_cells_uniform_cells_per_axis_name
Definition: Native.cpp:1134
JNIEXPORT void JNICALL Java_com_arm_malideveloper_openglessdk_metaballs_NativeLibrary_init(JNIEnv *env, jclass jcls, jint width, jint height)
Definition: Native.cpp:1749
precision highp float
Definition: hiz_cull.cs:37
GLuint scalar_field_uniform_samples_per_axis_id
Definition: Native.cpp:1111
GLint GLsizei width
Definition: gl2ext.h:179
typedef GLfloat(GL_APIENTRYP PFNGLGETPATHLENGTHNVPROC)(GLuint path
GLuint marching_cubes_triangles_uniform_isolevel_id
Definition: Native.cpp:1177
JNIEXPORT void JNICALL Java_com_arm_malideveloper_openglessdk_metaballs_NativeLibrary_step(JNIEnv *env, jclass jcls)
Definition: Native.cpp:1756
static void processShader(GLuint *shader, const char *filename, GLint shaderType)
Create shader, load in source, compile, and dump debug as necessary.
Definition: Shader.cpp:29
GLuint scalar_field_transform_feedback_object_id
Definition: Native.cpp:1106
typedef GLuint(GL_APIENTRYP PFNGLGETDEBUGMESSAGELOGKHRPROC)(GLuint count
const char * marching_cubes_triangles_frag_shader
Definition: Native.cpp:696
GLuint spheres_updater_uniform_time_id
Definition: Native.cpp:1088
const int n_spheres
Definition: Native.cpp:1062
GLuint marching_cubes_triangles_uniform_mvp_id
Definition: Native.cpp:1187
const GLchar * scalar_field_value_varying_name
Definition: Native.cpp:1119
GLuint spheres_updater_sphere_positions_buffer_object_id
Definition: Native.cpp:1080
GLuint scalar_field_buffer_object_id
Definition: Native.cpp:1103