GCC Code Coverage Report


Directory: ./
File: lib/geogram_gfx/GLUP/GLUP_context_GLSL.cpp
Date: 2026-09-07 02:28:19
Exec Total Coverage
Lines: 0 189 0.0%
Functions: 0 36 0.0%
Branches: 0 89 0.0%

Line Branch Exec Source
1 /*
2 * Copyright (c) 2000-2022 Inria
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * * Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * * Neither the name of the ALICE Project-Team nor the names of its
14 * contributors may be used to endorse or promote products derived from this
15 * software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
28 *
29 * Contact: Bruno Levy
30 *
31 * https://www.inria.fr/fr/bruno-levy
32 *
33 * Inria,
34 * Domaine de Voluceau,
35 * 78150 Le Chesnay - Rocquencourt
36 * FRANCE
37 *
38 */
39
40 #include <geogram_gfx/GLUP/GLUP_context_GLSL.h>
41 #include <geogram_gfx/basic/GLSL.h>
42 #include <geogram/basic/command_line.h>
43 #include <geogram/basic/progress.h>
44 #include <geogram/basic/logger.h>
45
46
47 namespace GLUP {
48 using namespace GEO;
49
50 /******************************************************/
51
52 #ifdef GEO_GL_140
53
54 Context_GLSL140::Context_GLSL140() {
55 }
56
57 void Context_GLSL140::setup() {
58 Context::setup();
59 }
60
61 const char* Context_GLSL140::profile_name() const {
62 return "GLUP140";
63 }
64
65 void Context_GLSL140::setup_GLUP_POINTS() {
66 set_primitive_info(
67 GLUP_POINTS, GL_POINTS,
68 GLSL::compile_program_with_includes_no_link(
69 this,
70 "//stage GL_VERTEX_SHADER\n"
71 "//import <GLUPGLSL/points_vertex_shader.h>\n",
72 "//stage GL_FRAGMENT_SHADER\n"
73 "//import <GLUPGLSL/spheres_fragment_shader.h>\n"
74 )
75 );
76 }
77
78 void Context_GLSL140::setup_GLUP_LINES() {
79 set_primitive_info(
80 GLUP_LINES, GL_LINES,
81 GLSL::compile_program_with_includes_no_link(
82 this,
83 "//stage GL_VERTEX_SHADER\n"
84 "//import <GLUPGLSL/vertex_shader.h>\n",
85 "//stage GL_FRAGMENT_SHADER\n"
86 "//import <GLUPGLSL/lines_fragment_shader.h>\n"
87 )
88 );
89 }
90
91 void Context_GLSL140::setup_GLUP_THICK_LINES() {
92 // For now, fallbacks to GLUP_LINES, to be implemented...
93 set_primitive_info(
94 GLUP_THICK_LINES, GL_LINES,
95 GLSL::compile_program_with_includes_no_link(
96 this,
97 "//stage GL_VERTEX_SHADER\n"
98 "//import <GLUPGLSL/vertex_shader.h>\n",
99 "//stage GL_FRAGMENT_SHADER\n"
100 "//import <GLUPGLSL/lines_fragment_shader.h>\n"
101 )
102 );
103 }
104
105 void Context_GLSL140::setup_GLUP_SPHERES() {
106 set_primitive_info(
107 GLUP_SPHERES, GL_POINTS,
108 GLSL::compile_program_with_includes_no_link(
109 this,
110 "//stage GL_VERTEX_SHADER\n"
111 "//import <GLUPGLSL/spheres_vertex_shader.h>\n",
112 "//stage GL_FRAGMENT_SHADER\n"
113 "//import <GLUPGLSL/spheres_fragment_shader.h>\n"
114 )
115 );
116 }
117
118 void Context_GLSL140::setup_GLUP_TRIANGLES() {
119 set_primitive_info(
120 GLUP_TRIANGLES, GL_TRIANGLES,
121 GLSL::compile_program_with_includes_no_link(
122 this,
123 "//stage GL_VERTEX_SHADER\n"
124 "//import <GLUPGLSL/vertex_shader.h>\n",
125 "//stage GL_FRAGMENT_SHADER\n"
126 "//import <GLUPGLSL/fragment_shader.h>\n"
127 )
128 );
129 }
130
131 /******************* pseudo-files ******************************/
132
133 static void OES_extensions(std::vector<GLSL::Source>& sources) {
134 // To be checked: seems that these functionalities are
135 // standard with OpenGL ES 3.0 and greater (which we
136 // imply because we use here in/out instead of attribute)
137 #ifndef GEO_OS_ANDROID
138 sources.push_back(
139 "#ifdef GL_ES\n"
140 " #extension GL_OES_texture_3D : enable \n"
141 " #extension GL_OES_standard_derivatives : enable \n"
142 " #extension GL_OES_geometry_shader : enable \n"
143 " #extension GL_OES_tessellation_shader : enable \n"
144 "#endif\n"
145 );
146 #endif
147 }
148
149 void Context_GLSL140::get_vertex_shader_preamble_pseudo_file(
150 std::vector<GLSL::Source>& sources
151 ) {
152 #if defined(GEO_OS_ANDROID)
153 sources.push_back("#version 320 es\n");
154 sources.push_back("precision lowp sampler3D;\n");
155 sources.push_back("precision highp float;\n");
156 sources.push_back("precision highp int;\n");
157 sources.push_back("#define GLUP_NO_GL_CLIPPING\n");
158 #elif defined(GEO_OS_APPLE)
159 sources.push_back("#version 150\n");
160 #else
161 sources.push_back("#version 150 core\n");
162 #endif
163 sources.push_back("#define GLUP_VERTEX_SHADER\n");
164 OES_extensions(sources);
165 }
166
167 void Context_GLSL140::get_fragment_shader_preamble_pseudo_file(
168 std::vector<GLSL::Source>& sources
169 ) {
170 #if defined(GEO_OS_ANDROID)
171 sources.push_back("#version 320 es\n");
172 sources.push_back("precision lowp sampler3D;\n");
173 sources.push_back("precision highp float;\n");
174 sources.push_back("precision highp int;\n");
175 sources.push_back("#define GLUP_NO_GL_CLIPPING\n");
176 #elif defined(GEO_OS_APPLE)
177 sources.push_back("#version 150\n");
178 #else
179 sources.push_back("#version 150 core\n");
180 #endif
181
182 sources.push_back(
183 "#define GLUP_FRAGMENT_SHADER\n"
184 "#ifndef GL_ES\n"
185 "#extension GL_ARB_conservative_depth : enable\n"
186 "#endif\n"
187 );
188
189 OES_extensions(sources);
190 }
191
192 void Context_GLSL140::get_primitive_pseudo_file(
193 std::vector<GLSL::Source>& sources
194 ) {
195 Context::get_primitive_pseudo_file(sources);
196 if(primitive_source_ == GLUP_TRIANGLES) {
197 sources.push_back("#define GLUP_NO_GEOMETRY_SHADER\n");
198 }
199 }
200
201 #endif
202
203 /******************************************************/
204
205 #ifdef GEO_GL_150
206
207 Context_GLSL150::Context_GLSL150() {
208 }
209
210 void Context_GLSL150::setup() {
211 Context_GLSL140::setup();
212 marching_tet_.create_UBO();
213 marching_hex_.create_UBO();
214 marching_prism_.create_UBO();
215 marching_pyramid_.create_UBO();
216 marching_connector_.create_UBO();
217 }
218
219 const char* Context_GLSL150::profile_name() const {
220 return "GLUP150";
221 }
222
223 /****************** Primitives implementation *************************/
224
225 void Context_GLSL150::setup_GLUP_THICK_LINES() {
226 // For GLUP_THICK_LINES, gl_ClipDistance is computed in
227 // geometry shader (and it is an error to write to it
228 // both in vertex and geometry shaders, this is why
229 // we have a specialized vertex shader for GLUP_THICK_LINES).
230 set_primitive_info(
231 GLUP_THICK_LINES, GL_LINES,
232 GLSL::compile_program_with_includes_no_link(
233 this,
234 "//stage GL_VERTEX_SHADER\n"
235 "//import <GLUPGLSL/thick_lines_vertex_shader.h>\n",
236 "//stage GL_FRAGMENT_SHADER\n"
237 "//import <GLUPGLSL/thick_lines_fragment_shader.h>\n",
238 "//stage GL_GEOMETRY_SHADER\n"
239 "//import <GLUPGLSL/geometry_shader_preamble.h>\n"
240 "//import <GLUPGLSL/thick_lines_geometry_shader.h>\n"
241 )
242 );
243 }
244
245 void Context_GLSL150::setup_GLUP_TRIANGLES() {
246 set_primitive_info(
247 GLUP_TRIANGLES, GL_TRIANGLES,
248 GLSL::compile_program_with_includes_no_link(
249 this,
250 "//stage GL_VERTEX_SHADER\n"
251 "//import <GLUPGLSL/vertex_shader.h>\n",
252 "//stage GL_FRAGMENT_SHADER\n"
253 "//import <GLUPGLSL/fragment_shader.h>\n",
254 "//stage GL_GEOMETRY_SHADER\n"
255 "//import <GLUPGLSL/geometry_shader_preamble.h>\n"
256 "void main() {\n"
257 " gl_PrimitiveID = gl_PrimitiveIDIn;\n"
258 " get_vertices();\n"
259 " draw_triangle(0,1,2,true);\n"
260 "}\n"
261 )
262 );
263 }
264
265 void Context_GLSL150::setup_GLUP_QUADS() {
266 set_primitive_info(
267 GLUP_QUADS, GL_LINES_ADJACENCY,
268 GLSL::compile_program_with_includes_no_link(
269 this,
270 "//stage GL_VERTEX_SHADER\n"
271 "//import <GLUPGLSL/vertex_shader.h>\n",
272 "//stage GL_FRAGMENT_SHADER\n"
273 "//import <GLUPGLSL/fragment_shader.h>\n",
274 "//stage GL_GEOMETRY_SHADER\n"
275 "//import <GLUPGLSL/geometry_shader_preamble.h>\n"
276 "void main() {\n"
277 " gl_PrimitiveID = gl_PrimitiveIDIn;\n"
278 " get_vertices();\n"
279 " draw_quad(0,1,3,2,true);\n"
280 "}\n"
281 )
282 );
283 }
284
285 void Context_GLSL150::setup_GLUP_TETRAHEDRA() {
286
287 GLuint program = GLSL::compile_program_with_includes_no_link(
288 this,
289 "//stage GL_VERTEX_SHADER\n"
290 "//import <GLUPGLSL/vertex_shader.h>\n",
291 "//stage GL_FRAGMENT_SHADER\n"
292 "//import <GLUPGLSL/fragment_shader.h>\n",
293 "//stage GL_GEOMETRY_SHADER\n"
294 "//import <GLUPGLSL/geometry_shader_preamble.h>\n"
295 "//import <GLUPGLSL/marching_cells.h>\n"
296 "void main() {\n"
297 "if(draw_clipped_cell()) { return; } \n"
298 "emit_vertex(2, vec4(1.0, 0.0, 0.0, 0.0), compute_clip_coords());\n"
299 "emit_vertex(0, vec4(0.0, 1.0, 0.0, 0.0), compute_clip_coords());\n"
300 "emit_vertex(1, vec4(0.0, 0.0, 1.0, 0.0), compute_clip_coords());\n"
301 "emit_vertex(3, vec4(1.0, 0.0, 0.0, 0.0), compute_clip_coords());\n"
302 "EndPrimitive();\n"
303 "emit_vertex(0, vec4(1.0, 0.0, 0.0, 0.0), compute_clip_coords());\n"
304 "emit_vertex(2, vec4(0.0, 1.0, 0.0, 0.0), compute_clip_coords());\n"
305 "emit_vertex(3, vec4(0.0, 0.0, 1.0, 0.0), compute_clip_coords());\n"
306 "emit_vertex(1, vec4(1.0, 0.0, 0.0, 0.0), compute_clip_coords());\n"
307 "}\n"
308 );
309 set_primitive_info(GLUP_TETRAHEDRA, GL_LINES_ADJACENCY,program);
310 marching_tet_.bind_uniform_state(program);
311 }
312
313 void Context_GLSL150::setup_GLUP_CONNECTORS() {
314 GLuint program = GLSL::compile_program_with_includes_no_link(
315 this,
316 "//stage GL_VERTEX_SHADER\n"
317 "//import <GLUPGLSL/vertex_shader.h>\n",
318 "//stage GL_FRAGMENT_SHADER\n"
319 "//import <GLUPGLSL/fragment_shader.h>\n",
320 "//stage GL_GEOMETRY_SHADER\n"
321 "//import <GLUPGLSL/geometry_shader_preamble.h>\n"
322 "//import <GLUPGLSL/marching_cells.h>\n"
323 "void main() {\n"
324 " if(draw_clipped_cell()) { return; } \n"
325 " draw_quad(0,1,3,2,compute_clip_coords());\n"
326 " draw_triangle(2,1,0,compute_clip_coords());\n"
327 " draw_triangle(3,2,0,compute_clip_coords());\n"
328 "}\n"
329 );
330 set_primitive_info(GLUP_CONNECTORS, GL_LINES_ADJACENCY, program);
331 marching_connector_.bind_uniform_state(program);
332 }
333
334 void Context_GLSL150::setup_GLUP_PRISMS() {
335 GLuint program = GLSL::compile_program_with_includes_no_link(
336 this,
337 "//stage GL_VERTEX_SHADER\n"
338 "//import <GLUPGLSL/vertex_shader.h>\n",
339 "//stage GL_FRAGMENT_SHADER\n"
340 "//import <GLUPGLSL/fragment_shader.h>\n",
341 "//stage GL_GEOMETRY_SHADER\n"
342 "//import <GLUPGLSL/geometry_shader_preamble.h>\n"
343 "//import <GLUPGLSL/marching_cells.h>\n"
344 "void main() {\n"
345 " if(draw_clipped_cell()) { return; } \n"
346 " draw_triangle(0,1,2,compute_clip_coords());\n"
347 " draw_triangle(5,4,3,compute_clip_coords());\n"
348 " draw_quad(0,3,1,4,compute_clip_coords());\n"
349 " draw_quad(0,2,3,5,compute_clip_coords());\n"
350 " draw_quad(1,4,2,5,compute_clip_coords());\n"
351 "}\n"
352 );
353 set_primitive_info(GLUP_PRISMS, GL_TRIANGLES_ADJACENCY, program);
354 marching_prism_.bind_uniform_state(program);
355 }
356
357 void Context_GLSL150::setup_GLUP_HEXAHEDRA() {
358 GLuint program = GLSL::compile_program_with_includes_no_link(
359 this,
360 "//stage GL_VERTEX_SHADER\n"
361 "//import <GLUPGLSL/gather_vertex_shader.h>\n",
362 "//stage GL_FRAGMENT_SHADER\n"
363 "//import <GLUPGLSL/fragment_shader.h>\n",
364 "//stage GL_GEOMETRY_SHADER\n"
365 "//import <GLUPGLSL/geometry_shader_preamble.h>\n"
366 "//import <GLUPGLSL/marching_cells.h>\n"
367 "void main() {\n"
368 "if(draw_clipped_cell()) { return; } \n"
369 "emit_vertex(6,vec4(0.0,1.0,0.0,1.0),compute_clip_coords());\n"
370 "emit_vertex(7,vec4(1.0,0.0,0.0,1.0),compute_clip_coords());\n"
371 "emit_vertex(4,vec4(0.0,1.0,1.0,0.0),compute_clip_coords());\n"
372 "emit_vertex(5,vec4(1.0,0.0,1.0,0.0),compute_clip_coords());\n"
373 "emit_vertex(0,vec4(0.0,1.0,0.0,1.0),compute_clip_coords());\n"
374 "emit_vertex(1,vec4(1.0,0.0,0.0,1.0),compute_clip_coords());\n"
375 "emit_vertex(2,vec4(0.0,1.0,1.0,0.0),compute_clip_coords());\n"
376 "emit_vertex(3,vec4(1.0,0.0,1.0,0.0),compute_clip_coords());\n"
377 "emit_vertex(6,vec4(0.0,1.0,0.0,1.0),compute_clip_coords());\n"
378 "emit_vertex(7,vec4(1.0,0.0,0.0,1.0),compute_clip_coords());\n"
379 "EndPrimitive();\n"
380 "draw_quad(4,0,6,2,compute_clip_coords());\n"
381 "draw_quad(1,5,3,7,compute_clip_coords());\n"
382 "}\n"
383 );
384 set_primitive_info_vertex_gather_mode(
385 GLUP_HEXAHEDRA, GL_LINES_ADJACENCY, program
386 );
387 marching_hex_.bind_uniform_state(program);
388 }
389
390 void Context_GLSL150::setup_GLUP_PYRAMIDS() {
391 GLuint program = GLSL::compile_program_with_includes_no_link(
392 this,
393 "//stage GL_VERTEX_SHADER\n"
394 "//import <GLUPGLSL/gather_vertex_shader.h>\n",
395 "//stage GL_FRAGMENT_SHADER\n"
396 "//import <GLUPGLSL/fragment_shader.h>\n",
397 "//stage GL_GEOMETRY_SHADER\n"
398 "//import <GLUPGLSL/geometry_shader_preamble.h>\n"
399 "//import <GLUPGLSL/marching_cells.h>\n"
400 "void main() {\n"
401 " if(draw_clipped_cell()) { return; }\n"
402 " draw_quad(0,1,3,2,compute_clip_coords());\n"
403 " draw_triangle(0,4,1,compute_clip_coords());\n"
404 " draw_triangle(0,3,4,compute_clip_coords());\n"
405 " draw_triangle(2,4,3,compute_clip_coords());\n"
406 " draw_triangle(2,1,4,compute_clip_coords());\n"
407 "}\n"
408 );
409 GEO_CHECK_GL();
410 set_primitive_info_vertex_gather_mode(
411 GLUP_PYRAMIDS, GL_POINTS, program
412 );
413 GEO_CHECK_GL();
414 marching_pyramid_.bind_uniform_state(program);
415 GEO_CHECK_GL();
416 }
417
418 void Context_GLSL150::get_geometry_shader_layout(
419 std::vector<GLSL::Source>& sources
420 ) {
421 switch(primitive_source_) {
422 case GLUP_POINTS:
423 case GLUP_SPHERES:
424 case GLUP_LINES:
425 break;
426 case GLUP_THICK_LINES:
427 sources.push_back(
428 "layout(lines) in;\n"
429 "layout(triangle_strip, max_vertices = 4) out;\n"
430 );
431 break;
432 case GLUP_TRIANGLES:
433 sources.push_back(
434 "layout(triangles) in;\n"
435 "layout(triangle_strip, max_vertices = 3) out;\n"
436 );
437 break;
438 case GLUP_QUADS:
439 sources.push_back(
440 "layout(lines_adjacency) in;\n"
441 "layout(triangle_strip, max_vertices = 4) out;\n"
442 );
443 break;
444 case GLUP_TETRAHEDRA:
445 sources.push_back(
446 "layout(lines_adjacency) in;\n"
447 "layout(triangle_strip, max_vertices = 8) out;\n"
448 );
449 break;
450 case GLUP_HEXAHEDRA:
451 sources.push_back(
452 "layout(lines_adjacency) in;\n"
453 "layout(triangle_strip, max_vertices = 18) out;\n"
454 );
455 break;
456 case GLUP_PRISMS:
457 sources.push_back(
458 "layout(triangles_adjacency) in;\n"
459 "layout(triangle_strip, max_vertices = 24) out;\n"
460 );
461 break;
462 case GLUP_PYRAMIDS:
463 sources.push_back(
464 "layout(points) in;\n"
465 "layout(triangle_strip, max_vertices = 28) out;\n"
466 );
467 break;
468 case GLUP_CONNECTORS:
469 sources.push_back(
470 "layout(lines_adjacency) in;\n"
471 "layout(triangle_strip, max_vertices = 12) out;\n"
472 );
473 break;
474 case GLUP_NB_PRIMITIVES:
475 geo_assert_not_reached;
476 }
477 }
478
479 void Context_GLSL150::get_geometry_shader_preamble_pseudo_file(
480 std::vector<GLSL::Source>& sources
481 ) {
482 #if defined(GEO_OS_ANDROID)
483 sources.push_back("#version 320 es\n");
484 sources.push_back("precision lowp sampler3D;\n");
485 sources.push_back("precision highp float;\n");
486 sources.push_back("precision highp int;\n");
487 sources.push_back("#define GLUP_NO_GL_CLIPPING\n");
488 #elif defined(GEO_OS_APPLE)
489 sources.push_back("#version 150\n");
490 #else
491 sources.push_back("#version 150 core\n");
492 #endif
493 sources.push_back("#define GLUP_GEOMETRY_SHADER\n");
494 OES_extensions(sources);
495
496 get_geometry_shader_layout(sources);
497 }
498
499 void Context_GLSL150::get_primitive_pseudo_file(
500 std::vector<GLSL::Source>& sources
501 ) {
502 Context::get_primitive_pseudo_file(sources);
503 if(primitive_source_ == GLUP_HEXAHEDRA) {
504 sources.push_back("#define GLUP_VERTEX_GATHER\n");
505 sources.push_back(
506 "const int glup_nb_vertices_per_GL_v=2;\n"
507 );
508 } else if(primitive_source_ == GLUP_PYRAMIDS) {
509 sources.push_back("#define GLUP_VERTEX_GATHER\n");
510 sources.push_back(
511 "const int glup_nb_vertices_per_GL_v=5;\n"
512 );
513 }
514 }
515
516 /****** GLUP440 implementation *****************************************/
517
518 Context_GLSL440::Context_GLSL440() {
519 use_tessellation_ =
520 GEO::CmdLine::get_arg_bool("gfx:GLSL_tesselation");
521 }
522
523 const char* Context_GLSL440::profile_name() const {
524 return "GLUP440";
525 }
526
527 void Context_GLSL440::setup_GLUP_HEXAHEDRA() {
528 if(!GEO::CmdLine::get_arg_bool("gfx:GLSL_tesselation")) {
529 Context_GLSL150::setup_GLUP_HEXAHEDRA();
530 return;
531 }
532 GLuint program = GLSL::compile_program_with_includes_no_link(
533 this,
534 "//stage GL_VERTEX_SHADER\n"
535 "//import <GLUPGLSL/vertex_shader.h>\n",
536 "//stage GL_FRAGMENT_SHADER\n"
537 "//import <GLUPGLSL/fragment_shader.h>\n",
538 "//stage GL_TESS_EVALUATION_SHADER\n"
539 "//import <GLUPGLSL/tess_evaluation_shader.h>\n",
540 "//stage GL_GEOMETRY_SHADER\n"
541 "//import <GLUPGLSL/geometry_shader_preamble.h>\n"
542 "//import <GLUPGLSL/marching_cells.h>\n"
543 "void main() {\n"
544 "if(draw_clipped_cell()) { return; } \n"
545 "emit_vertex(6,vec4(0.0,1.0,0.0,1.0),compute_clip_coords());\n"
546 "emit_vertex(7,vec4(1.0,0.0,0.0,1.0),compute_clip_coords());\n"
547 "emit_vertex(4,vec4(0.0,1.0,1.0,0.0),compute_clip_coords());\n"
548 "emit_vertex(5,vec4(1.0,0.0,1.0,0.0),compute_clip_coords());\n"
549 "emit_vertex(0,vec4(0.0,1.0,0.0,1.0),compute_clip_coords());\n"
550 "emit_vertex(1,vec4(1.0,0.0,0.0,1.0),compute_clip_coords());\n"
551 "emit_vertex(2,vec4(0.0,1.0,1.0,0.0),compute_clip_coords());\n"
552 "emit_vertex(3,vec4(1.0,0.0,1.0,0.0),compute_clip_coords());\n"
553 "emit_vertex(6,vec4(0.0,1.0,0.0,1.0),compute_clip_coords());\n"
554 "emit_vertex(7,vec4(1.0,0.0,0.0,1.0),compute_clip_coords());\n"
555 "EndPrimitive();\n"
556 "draw_quad(4,0,6,2,compute_clip_coords());\n"
557 "draw_quad(1,5,3,7,compute_clip_coords());\n"
558 "}\n"
559 );
560 set_primitive_info(
561 GLUP_HEXAHEDRA, GL_PATCHES, program
562 );
563 marching_hex_.bind_uniform_state(program);
564 }
565
566 void Context_GLSL440::setup_GLUP_PYRAMIDS() {
567 if(!GEO::CmdLine::get_arg_bool("gfx:GLSL_tesselation")) {
568 Context_GLSL150::setup_GLUP_PYRAMIDS();
569 return;
570 }
571 GLuint program = GLSL::compile_program_with_includes_no_link(
572 this,
573 "//stage GL_VERTEX_SHADER\n"
574 "//import <GLUPGLSL/vertex_shader.h>\n",
575 "//stage GL_FRAGMENT_SHADER\n"
576 "//import <GLUPGLSL/fragment_shader.h>\n",
577 "//stage GL_TESS_EVALUATION_SHADER\n"
578 "//import <GLUPGLSL/tess_evaluation_shader.h>\n",
579 "//stage GL_GEOMETRY_SHADER\n"
580 "//import <GLUPGLSL/geometry_shader_preamble.h>\n"
581 "//import <GLUPGLSL/marching_cells.h>\n"
582 "void main() {\n"
583 " if(draw_clipped_cell()) { return; } \n"
584 " draw_quad(0,1,3,2,compute_clip_coords());\n"
585 " draw_triangle(0,4,1,compute_clip_coords());\n"
586 " draw_triangle(0,3,4,compute_clip_coords());\n"
587 " draw_triangle(2,4,3,compute_clip_coords());\n"
588 " draw_triangle(2,1,4,compute_clip_coords());\n"
589 "}\n"
590 );
591 set_primitive_info(
592 GLUP_PYRAMIDS, GL_PATCHES, program
593 );
594 marching_pyramid_.bind_uniform_state(program);
595 }
596
597 /***********************************************************************/
598
599
600 void Context_GLSL440::get_vertex_shader_preamble_pseudo_file(
601 std::vector<GLSL::Source>& sources
602 ) {
603 #ifdef GEO_OS_APPLE
604 sources.push_back("#version 440\n");
605 #else
606 sources.push_back("#version 440 core\n");
607 #endif
608 sources.push_back("#define GLUP_VERTEX_SHADER\n");
609 OES_extensions(sources);
610 }
611
612 void Context_GLSL440::get_fragment_shader_preamble_pseudo_file(
613 std::vector<GLSL::Source>& sources
614 ) {
615 #ifdef GEO_OS_APPLE
616 sources.push_back("#version 440\n");
617 #else
618 sources.push_back("#version 440 core\n");
619 #endif
620 sources.push_back(
621 "#define GLUP_FRAGMENT_SHADER\n"
622 "#extension GL_ARB_conservative_depth : enable\n"
623 );
624 OES_extensions(sources);
625 }
626
627 void Context_GLSL440::get_geometry_shader_preamble_pseudo_file(
628 std::vector<GLSL::Source>& sources
629 ) {
630 #ifdef GEO_OS_APPLE
631 sources.push_back("#version 440\n");
632 #else
633 sources.push_back("#version 440 core\n");
634 #endif
635 sources.push_back("#define GLUP_GEOMETRY_SHADER\n");
636 OES_extensions(sources);
637 get_geometry_shader_layout(sources);
638 }
639
640 void Context_GLSL440::get_tess_evaluation_shader_preamble_pseudo_file(
641 std::vector<GLSL::Source>& sources
642 ) {
643 #ifdef GEO_OS_APPLE
644 sources.push_back("#version 440\n");
645 #else
646 sources.push_back("#version 440 core\n");
647 #endif
648 sources.push_back("#define GLUP_TESS_EVALUATION_SHADER\n");
649 OES_extensions(sources);
650 }
651
652 void Context_GLSL440::get_primitive_pseudo_file(
653 std::vector<GLSL::Source>& sources
654 ) {
655 Context::get_primitive_pseudo_file(sources);
656 if(use_tessellation_) {
657 if(primitive_source_ == GLUP_HEXAHEDRA) {
658 sources.push_back("#define GLUP_TESS_GATHER\n");
659 sources.push_back("#define GLUP_TESS_MULTI_VERTEX\n");
660 sources.push_back(
661 "const int glup_nb_vertices_per_GL_v=4;\n"
662 );
663 } else if(primitive_source_ == GLUP_PYRAMIDS) {
664 sources.push_back("#define GLUP_TESS_GATHER\n");
665 sources.push_back(
666 "const int glup_nb_vertices_per_GL_v=5;\n"
667 );
668 }
669 } else {
670 if(primitive_source_ == GLUP_HEXAHEDRA) {
671 sources.push_back("#define GLUP_VERTEX_GATHER\n");
672 sources.push_back(
673 "const int glup_nb_vertices_per_GL_v=2;\n"
674 );
675 } else if(primitive_source_ == GLUP_PYRAMIDS) {
676 sources.push_back("#define GLUP_VERTEX_GATHER\n");
677 sources.push_back(
678 "const int glup_nb_vertices_per_GL_v=5;\n"
679 );
680 }
681 }
682 }
683
684 void Context_GLSL440::get_geometry_shader_layout(
685 std::vector<GLSL::Source>& sources
686 ) {
687 switch(primitive_source_) {
688 case GLUP_POINTS:
689 case GLUP_LINES:
690 case GLUP_THICK_LINES:
691 case GLUP_TRIANGLES:
692 case GLUP_QUADS:
693 case GLUP_TETRAHEDRA:
694 case GLUP_PRISMS:
695 case GLUP_CONNECTORS:
696 case GLUP_SPHERES:
697 Context_GLSL150::get_geometry_shader_layout(sources);
698 break;
699
700 case GLUP_HEXAHEDRA:
701 sources.push_back(
702 "layout(lines) in;\n"
703 "layout(triangle_strip, max_vertices = 18) out;\n"
704 );
705 break;
706
707 case GLUP_PYRAMIDS:
708 sources.push_back(
709 "layout(lines) in;\n"
710 "layout(triangle_strip, max_vertices = 28) out;\n"
711 );
712 break;
713
714 case GLUP_NB_PRIMITIVES:
715 geo_assert_not_reached;
716 }
717 }
718 #endif
719 }
720