GCC Code Coverage Report


Directory: ./
File: lib/geogram_gfx/GLUP/GLUP_context.h
Date: 2026-09-07 02:37:58
Exec Total Coverage
Lines: 0 364 0.0%
Functions: 0 91 0.0%
Branches: 0 164 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 #ifndef GEOGRAM_GFX_GLUP_GLUP_CONTEXT
41 #define GEOGRAM_GFX_GLUP_GLUP_CONTEXT
42
43 #include <geogram_gfx/basic/common.h>
44 #include <geogram_gfx/GLUP/GLUP.h>
45 #include <geogram_gfx/GLUP/GLUP_marching_cells.h>
46 #include <geogram_gfx/basic/GLSL.h>
47 #include <map>
48
49 /**
50 * \file geogram_gfx/GLUP/GLUP_context.h
51 * \brief Internal implementation of GLUP context.
52 */
53
54 #ifdef GEO_GL_NO_DOUBLES
55 typedef double GLdouble;
56 #endif
57
58 /**
59 * \brief Used internally
60 * \details GLUP_THICK_LINES is the primitive used to draw GLUP_LINES
61 * when mesh width is greater than 1. It is a different primitive because
62 * it needs either a geometry shader to replace line segments with quads
63 * (GLUPGLSL 150 and 440 profiles), or a pre-processing of the immediate
64 * vertex buffers to generate two additional vertices per segment with
65 * the attributes (in GLUPES profile).
66 */
67 static constexpr GLUPprimitive GLUP_THICK_LINES = GLUP_RESERVED_PRIMITIVE_1;
68
69 namespace GLUP {
70 using namespace GEO;
71
72 /**
73 * \brief Computes the inverse of a 4x4 matrix.
74 * \param[out] inv the computed inverse of \p m
75 * \param[in] m pointer to the input matrix
76 * \retval GL_TRUE if the matrix \p m is invertible
77 * \retval GL_FALSE if the matrix \p m is singular. Then
78 * \p inv receives the transpose of the comatrix of \p m
79 */
80 GLboolean invert_matrix(GLfloat inv[16], const GLfloat m[16]);
81
82 /**
83 * \brief Computes the inverse of a 4x4 matrix.
84 * \param[out] inv the computed inverse of \p m
85 * \param[in] m pointer to the input matrix
86 * \retval GL_TRUE if the matrix \p m is invertible
87 * \retval GL_FALSE if the matrix \p m is singular. Then
88 * \p inv receives the transpose of the comatrix of \p m
89 */
90 GLboolean invert_matrix(GLdouble inv[16], const GLdouble m[16]);
91
92 /**
93 * \brief Computes the product of two 4x4 matrices
94 * \param[out] out the computed product \p m1 * \p m2
95 * \param[in] m1 , m2 pointers to the input matrices
96 */
97 void mult_matrices(
98 GLfloat out[16], const GLfloat m1[16], const GLfloat m2[16]
99 );
100
101 /**
102 * \brief Computes the product of two 4x4 matrices
103 * \param[out] out the computed product \p m1 * \p m2
104 * \param[in] m1 , m2 pointers to the input matrices
105 */
106 void mult_matrices(
107 GLdouble out[16], const GLdouble m1[16], const GLdouble m2[16]
108 );
109
110 /**
111 * \brief Computes the product of a 4x4 matrix and a vector.
112 * \param[out] out the computed product \p m * \p v
113 * \param[in] m pointer to the input matrix
114 * \param[in] v pointer to the input vector
115 * \TODO: it seems that in GLSL, w = M*v uses the transpose form,
116 * maybe I should change the names !!
117 */
118 void mult_matrix_vector(
119 GLfloat out[4], const GLfloat m[16], const GLfloat v[4]
120 );
121
122
123 /**
124 * \brief Computes the product of the transpose of a
125 * 4x4 matrix and a vector.
126 * \param[out] out the computed product \p m * \p v
127 * \param[in] m pointer to the input matrix
128 * \param[in] v pointer to the input vector
129 * \TODO: it seems that in GLSL, w = M*v uses this one, maybe
130 * I should change the names !!
131 */
132 void mult_transpose_matrix_vector(
133 GLfloat out[4], const GLfloat m[16], const GLfloat v[4]
134 );
135
136
137 /**
138 * \brief Computes the product of the transpose of a
139 * 4x4 matrix and a vector.
140 * \param[out] out the computed product \p m * \p v
141 * \param[in] m pointer to the input matrix
142 * \param[in] v pointer to the input vector
143 * \TODO: it seems that in GLSL, w = M*v uses this one, maybe
144 * I should change the names !!
145 */
146 void mult_transpose_matrix_vector(
147 GLdouble out[4], const GLdouble m[16], const GLdouble v[4]
148 );
149
150 /**
151 * \brief Computes the product of a 4x4 matrix and a vector.
152 * \param[out] out the computed product \p m * \p v
153 * \param[in] m pointer to the input matrix
154 * \param[in] v pointer to the input vector
155 */
156 void mult_matrix_vector(
157 GLdouble out[4], const GLdouble m[16], const GLdouble v[4]
158 );
159
160 /**
161 * \brief Transposes a matrix in-place.
162 * \param[in,out] m a pointer to the 16 single-precision
163 * floating point coefficients of the matrix to be transposed.
164 */
165 void transpose_matrix(GLfloat m[16]);
166
167 /**
168 * \brief Transposes a matrix in-place.
169 * \param[in,out] m a pointer to the 16 double-precision
170 * floating point coefficients of the matrix to be transposed.
171 */
172 void transpose_matrix(GLdouble m[16]);
173
174 /**
175 * \brief For debugging, outputs a matrix to the standard error.
176 * \param[in] m the matrix to be displayed.
177 */
178 void show_matrix(const GLfloat m[16]);
179
180 /**
181 * \brief For debugging, outputs a matrix to the standard error.
182 * \param[in] m the matrix to be displayed.
183 */
184 void show_matrix(const GLdouble m[16]);
185
186 /**
187 * \brief For debugging, outputs a vector to the standard error.
188 * \param[in] v the vector to be displayed
189 */
190 void show_vector(const GLfloat v[4]);
191
192 /**
193 * \brief For debugging, outputs a vector to the standard error.
194 * \param[in] v the vector to be displayed
195 */
196 void show_vector(const GLdouble v[4]);
197
198 /**
199 * \brief Resets a matrix to the identity matrix.
200 * \param[out] out the matrix to be reset.
201 */
202 void load_identity_matrix(GLfloat out[16]);
203
204 /**
205 * \brief Resets a matrix to the identity matrix.
206 * \param[out] out the matrix to be reset.
207 */
208 void load_identity_matrix(GLdouble out[16]);
209
210 /**
211 * \brief Copies a vector of floats.
212 * \param[out] to a pointer to the destination vector
213 * \param[in] from a const pointer to the source vector
214 * \param[in] dim the number of components to copy
215 */
216 inline void copy_vector(GLfloat* to, const GLfloat* from, index_t dim) {
217 Memory::copy(to, from, sizeof(GLfloat)*dim);
218 }
219
220 /**
221 * \brief Copies a vector of doubles.
222 * \param[out] to a pointer to the destination vector
223 * \param[in] from a const pointer to the source vector
224 * \param[in] dim the number of components to copy
225 */
226 inline void copy_vector(GLdouble* to, const GLdouble* from, index_t dim) {
227 Memory::copy(to, from, sizeof(GLdouble)*dim);
228 }
229
230 /**
231 * \brief Copies a vector of doubles to a vector of floats.
232 * \param[out] to a pointer to the destination vector
233 * \param[in] from a const pointer to the source vector
234 * \param[in] dim the number of components to copy
235 */
236 inline void copy_vector(GLfloat* to, const GLdouble* from, index_t dim) {
237 for(index_t i=0; i<dim; ++i) {
238 to[i] = GLfloat(from[i]);
239 }
240 }
241
242 /**
243 * \brief Copies a vector of floats to a vector of doubles.
244 * \param[out] to a pointer to the destination vector
245 * \param[in] from a const pointer to the source vector
246 * \param[in] dim the number of components to copy
247 */
248 inline void copy_vector(GLdouble* to, const GLfloat* from, index_t dim) {
249 for(index_t i=0; i<dim; ++i) {
250 to[i] = GLdouble(from[i]);
251 }
252 }
253
254 /**
255 * \brief Normalizes a vector.
256 * \param[in,out] v a pointer to the 3 coordinates of the 3d
257 * vector to be normalized.
258 */
259 inline void normalize_vector(GLfloat v[3]) {
260 GLfloat s = 1.0f / ::sqrtf(v[0]*v[0]+v[1]*v[1]+v[2]*v[2]);
261 v[0] *= s;
262 v[1] *= s;
263 v[2] *= s;
264 }
265
266 /**********************************************************************/
267
268 class Context;
269
270 /**
271 * \brief A Matrix stack.
272 * \details There are three matrix stacks in a context,
273 * for modelview matrices, projection matrices and
274 * texture coordinates.
275 */
276 class MatrixStack {
277 public:
278
279 /**
280 * \brief Maximum number of matrices in a stack.
281 */
282 static const int MAX_DEPTH=16;
283
284 /**
285 * \brief MatrixStack constructor.
286 */
287 MatrixStack() : top_(0) {
288 load_identity_matrix(top());
289 }
290
291 /**
292 * \brief Gets the matrix on the top of
293 * the stack.
294 * \return a pointer to the coefficients of
295 * the matrix.
296 */
297 GLdouble* top() {
298 return stack_[top_].data();
299 }
300
301 /**
302 * \brief Pushes a copy of the top matrix.
303 */
304 void push() {
305 geo_assert(top_ != MAX_DEPTH-1);
306 GLdouble* from = top();
307 ++top_;
308 GLdouble* to = top();
309 copy_vector(to, from, 16);
310 }
311
312 /**
313 * \brief Removes a matrix from the top of
314 * the stack.
315 */
316 void pop() {
317 geo_assert(top_ != 0);
318 --top_;
319 }
320
321 protected:
322 struct Matrix {
323 GLdouble coeff[16];
324 GLdouble* data() {
325 return &coeff[0];
326 }
327 };
328
329 private:
330 Matrix stack_[MAX_DEPTH];
331 index_t top_;
332 };
333
334
335 /**
336 * \brief Number of vertices/colors/tex_coords in a GLUP buffer used
337 * by immediate mode.
338 * \details Chosen in such a way that indices in there can be stored
339 * in two bytes.
340 */
341 static const index_t IMMEDIATE_BUFFER_SIZE = 65536;
342
343 /**
344 * \brief Index of an ImmediateBuffer in the ImmediateState.
345 * \details GLUP_VERTEX_ID_ATTRIBUTE is used internally
346 */
347 enum GLUPattribute {
348 GLUP_VERTEX_ATTRIBUTE = 0,
349 GLUP_COLOR_ATTRIBUTE = 1,
350 GLUP_TEX_COORD_ATTRIBUTE = 2,
351 GLUP_NORMAL_ATTRIBUTE = 3,
352 GLUP_VERTEX_ID_ATTRIBUTE = 4
353 };
354
355 /**
356 * \brief A buffer used by GLUP in immediate mode.
357 */
358 class ImmediateBuffer {
359
360 public:
361
362 /**
363 * ImmediateBuffer constructor.
364 */
365 ImmediateBuffer() :
366 data_(nullptr),
367 dimension_(0),
368 is_enabled_(false),
369 VBO_(0) {
370 }
371
372 /**
373 * ImmediateBuffer destructor.
374 */
375 ~ImmediateBuffer() {
376 delete[] data_;
377 if(VBO_ != 0) {
378 glDeleteBuffers(1, &VBO_);
379 VBO_ = 0;
380 }
381 }
382
383 void initialize(index_t dim) {
384 data_ = new GLfloat[dim * IMMEDIATE_BUFFER_SIZE];
385 dimension_ = dim;
386 is_enabled_ = true;
387 }
388
389 /**
390 * \brief Enables this ImmediateBuffer.
391 */
392 void enable() {
393 is_enabled_ = true;
394 }
395
396 /**
397 * \brief Disables this ImmediateBuffer.
398 */
399 void disable() {
400 is_enabled_ = false;
401 }
402
403 /**
404 * \brief Tests whether this ImmediateBuffer is enabled.
405 * \retval true if this ImmediateBuffer is enabled
406 * \retval false otherwise
407 */
408 bool is_enabled() const {
409 return is_enabled_;
410 }
411
412 /**
413 * \brief Sets the current attribute value.
414 * \param[in] x , y , z , w the component of the current attribute
415 * \details Components past the dimension of the attribute
416 * are ignored (e.g., if dimension is 2, z and w are ignored).
417 */
418 void set_current(GLfloat x, GLfloat y, GLfloat z, GLfloat w) {
419 current_[0] = x;
420 current_[1] = y;
421 current_[2] = z;
422 current_[3] = w;
423 }
424
425 /**
426 * \brief Copies the current attribute value to a specified
427 * vertex in this buffer.
428 * \param[in] v the vertex index
429 * \pre v < IMMEDIATE_BUFFER_SIZE
430 */
431 void copy_current_to(index_t v) {
432 geo_debug_assert(v < IMMEDIATE_BUFFER_SIZE);
433 if(is_enabled()) {
434 copy_vector(element_ptr(v), current_, dimension());
435 }
436 }
437
438 /**
439 * \brief Copies this attribute from a vertex to another one.
440 * \param[in] to index of the destination vertex
441 * \param[in] from index of the source vertex
442 * \pre to < IMMEDIATE_BUFFER_SIZE && from < IMMEDIATE_BUFFER_SIZE
443 */
444 void copy(index_t to, index_t from) {
445 geo_debug_assert(to < IMMEDIATE_BUFFER_SIZE);
446 geo_debug_assert(from < IMMEDIATE_BUFFER_SIZE);
447 if(is_enabled()) {
448 copy_vector(element_ptr(to), element_ptr(from), dimension());
449 }
450 }
451
452 /**
453 * \brief Copies this attribute from another attribute
454 * \param[in] to index of the destination vertex
455 * \param[in] from_buffer the source buffer
456 * \param[in] from index of the source vertex
457 * \pre to < IMMEDIATE_BUFFER_SIZE && from < IMMEDIATE_BUFFER_SIZE
458 */
459 void copy(index_t to, ImmediateBuffer& from_buffer, index_t from) {
460 geo_debug_assert(to < IMMEDIATE_BUFFER_SIZE);
461 geo_debug_assert(from < IMMEDIATE_BUFFER_SIZE);
462 geo_debug_assert(from_buffer.dimension() == dimension());
463 copy_vector(
464 element_ptr(to), from_buffer.element_ptr(from), dimension()
465 );
466 }
467
468 /**
469 * \brief Gets the dimension of the attribute.
470 * \return the number of components of the attribute
471 */
472 index_t dimension() const {
473 return dimension_;
474 }
475
476 /**
477 * \brief Gets the size of the memory used by the buffer.
478 * \return the size of the buffer in bytes.
479 */
480 size_t size_in_bytes() const {
481 return IMMEDIATE_BUFFER_SIZE * dimension() * sizeof(GLfloat);
482 }
483
484 /**
485 * \brief Gets a pointer to one attribute value by index.
486 * \param[in] v index of the vertex
487 * \return a pointer to the attribute, i.e. an array of
488 * \p dimension() GLfloats
489 */
490 GLfloat* element_ptr(index_t v) {
491 geo_debug_assert(v < IMMEDIATE_BUFFER_SIZE);
492 return data_ + v*dimension_;
493 }
494
495 /**
496 * \brief Gets a pointer to the data.
497 * \return a pointer to the first attribute. All the storage
498 * is contiguous in memory.
499 */
500 GLfloat* data() {
501 return data_;
502 }
503
504 /**
505 * \brief Gets the Vertex Buffer Object.
506 * \return a modifiable reference to the Id of the Vertex Buffer
507 * Object. Can be zero if no VBO is used.
508 */
509 GLuint& VBO() {
510 return VBO_;
511 }
512
513 /**
514 * \brief ImmediateBuffer copy constructor.
515 * \param[in] rhs the ImmediateBuffer to be copied
516 * \details Should be only called with uninitialized ImmediateBuffer
517 * (else triggers an assertion failure).
518 */
519 ImmediateBuffer(
520 const ImmediateBuffer& rhs
521 ) {
522 data_ = rhs.data_;
523 dimension_ = rhs.dimension_;
524 is_enabled_ = rhs.is_enabled_;
525 VBO_ = rhs.VBO_;
526 current_[0] = rhs.current_[0];
527 current_[1] = rhs.current_[1];
528 current_[2] = rhs.current_[2];
529 current_[3] = rhs.current_[3];
530 geo_assert(data_ == nullptr);
531 }
532
533 private:
534 GLfloat* data_;
535 GLfloat current_[4];
536 index_t dimension_;
537 bool is_enabled_;
538 GLuint VBO_;
539 };
540
541 /**
542 * \brief Stores all the buffers used to implement
543 * the immediate-mode interface.
544 */
545 class ImmediateState {
546 public:
547 /**
548 * \brief ImmediateState constructor.
549 * \param[in] nb_vertices_per_primitive a pointer to an array of index_t
550 * of size GLUP_NB_PRIMITIVES that indicates for each primitive the
551 * number of vertices (3 for GLUP_TRIANGLES, 4 for GLUP_QUADS etc...).
552 */
553 ImmediateState(index_t* nb_vertices_per_primitive) :
554 current_vertex_(0),
555 max_current_vertex_(0),
556 primitive_(GLUP_POINTS),
557 VAO_(0),
558 nb_vertices_per_primitive_(nb_vertices_per_primitive)
559 {
560 buffer[GLUP_VERTEX_ATTRIBUTE].initialize(4);
561 buffer[GLUP_COLOR_ATTRIBUTE].initialize(4);
562 buffer[GLUP_TEX_COORD_ATTRIBUTE].initialize(4);
563 buffer[GLUP_NORMAL_ATTRIBUTE].initialize(4);
564
565 // Vertex is always enabled
566 buffer[GLUP_VERTEX_ATTRIBUTE].enable();
567 }
568
569 /**
570 * \brief ImmediateState destructor.
571 */
572 ~ImmediateState() {
573 if(VAO_ != 0) {
574 glupDeleteVertexArrays(1, &VAO_);
575 VAO_ = 0;
576 }
577 }
578
579 /**
580 * \brief Gets the Vertex Array Object.
581 * \return a modifiable reference to the Id of the Vertex Array Object.
582 * Can be 0 if no VAO is used.
583 */
584 GLuint& VAO() {
585 return VAO_;
586 }
587
588 /**
589 * \brief Copies an element, i.e. all the attributes
590 * attached to a vertex.
591 * \param[in] to index of the destination vertex
592 * \param[in] from index of the source vertex
593 * \details Only attributes that are enabled are copied.
594 */
595 void copy_element(index_t to, index_t from) {
596 for(index_t i=0; i<NB_IMMEDIATE_BUFFERS; ++i) {
597 buffer[i].copy(to, from);
598 }
599 }
600
601
602 /**
603 * \brief Configures the immediate state for rendering
604 * primitives of a given type.
605 * \param[in] primitive type of the primitives to be rendered
606 * \param[in] max_current_vertex optional maximum index of a vertex
607 * index in immediate buffer before flushing. Computed from primitive
608 * if unspecified. It is used by primitives that need additional
609 * vertices to be generated in the immediate buffer (e.g.,
610 * GLUP_THICK_LINES in GLUP_ES profile).
611 */
612 void begin(GLUPprimitive primitive, index_t max_current_vertex=0) {
613 current_vertex_ = 0;
614 if(max_current_vertex != 0) {
615 max_current_vertex_ = max_current_vertex;
616 } else {
617 max_current_vertex_ =
618 IMMEDIATE_BUFFER_SIZE - (
619 IMMEDIATE_BUFFER_SIZE %
620 nb_vertices_per_primitive_[primitive]
621 );
622 }
623 primitive_ = primitive;
624 }
625
626 /**
627 * \brief Advances to the next vertex.
628 * \details This copies all the current values of all enabled attributes
629 * to the current vertex position.
630 */
631 void next_vertex() {
632 for(index_t i=0; i<NB_IMMEDIATE_BUFFERS; ++i) {
633 buffer[i].copy_current_to(current_vertex_);
634 }
635 ++current_vertex_;
636 }
637
638 /**
639 * \brief Tests whether the buffers are full.
640 * \details When buffers are full, their contents need to be sent
641 * to OpenGL before calling reset(). These operations are done
642 * by the Context.
643 */
644 bool buffers_are_full() {
645 return (current_vertex_ == max_current_vertex_);
646 }
647
648 /**
649 * \brief Resets the current vertex index.
650 * \param[in] new_current_vertex optional new value
651 * of the current vertex.
652 */
653 void reset(index_t new_current_vertex = 0) {
654 current_vertex_ = new_current_vertex;
655 }
656
657 /**
658 * \brief Gets the primitive currently rendered, i.e.
659 * the argument to the latest invocation of begin()
660 */
661 GLUPprimitive primitive() const {
662 return primitive_;
663 }
664
665 /**
666 * \brief Gets the number of vertices stored in the buffers.
667 */
668 index_t nb_vertices() const {
669 return current_vertex_;
670 }
671
672 /**
673 * \brief Gets the number of primitives stored in the buffers.
674 */
675 index_t nb_primitives() const {
676 return current_vertex_ / nb_vertices_per_primitive_[
677 primitive_
678 ];
679 }
680
681 /**
682 * \brief Gets the maximum number of vertices in the buffer
683 * before the buffer is flushed.
684 * \details This number depends on the number of vertices per
685 * primitive.
686 */
687 index_t max_current_vertex() const {
688 return max_current_vertex_;
689 }
690
691 /**
692 * \brief Sets the current vertex.
693 * \details This defines the number of stored vertices in this
694 * buffer.
695 * \param[in] v the index of the current vertex.
696 */
697 void set_current_vertex(index_t v) {
698 geo_debug_assert(v <= max_current_vertex_);
699 current_vertex_ = v;
700 }
701
702 enum { NB_IMMEDIATE_BUFFERS = 4 };
703 ImmediateBuffer buffer[NB_IMMEDIATE_BUFFERS];
704
705 private:
706 index_t current_vertex_;
707 index_t max_current_vertex_;
708 GLUPprimitive primitive_;
709 GLuint VAO_;
710 index_t* nb_vertices_per_primitive_;
711 };
712
713
714 /**********************************************************/
715
716 /**
717 * \brief Base class for representing GLUP state variables.
718 */
719 class StateVariableBase {
720 public:
721
722 /**
723 * \brief StateVariableBase default constructor.
724 */
725 StateVariableBase() : address_(nullptr), context_(nullptr) {
726 }
727
728 /**
729 * \brief StateVariableBase constructor.
730 * \param[in] context a pointer to the GLUP Context
731 * \param[in] name the name of the variable, without
732 * "GLUPStateBlock." (it is prepended automatically).
733 */
734 StateVariableBase(
735 Context* context, const char* name
736 ) {
737 initialize(context,name);
738 }
739
740 /**
741 * \brief Initializes a StateVariableBase.
742 * \param[in] context a pointer to the GLUP Context
743 * \param[in] name the name of the variable, without
744 * "GLUPStateBlock." (it is prepended automatically
745 * when searching for the variable in the state).
746 */
747 void initialize(Context* context, const char* name);
748
749 /**
750 * \brief Gets the name of this StateVariableBase.
751 * \return a const reference to the name, without
752 * "GLUPStateBlock." prepended to it.
753 */
754 const std::string& name() const {
755 return name_;
756 }
757
758 protected:
759 friend class Context;
760
761 /**
762 * \brief Gets the address of the StateVariableBase.
763 * \return a pointer to the variable in the client-side
764 * representation of the UBO.
765 */
766 Memory::pointer address() const {
767 return address_;
768 }
769
770 /**
771 * \brief Indicates that the variables in the context
772 * need to be sent to OpenGL.
773 */
774 void flag_uniform_buffer_as_dirty();
775
776 Memory::pointer address_;
777 Context* context_;
778 std::string name_;
779 };
780
781 /**
782 * \brief A GLUP state variable of a given type.
783 * \tparam T the type of the state variable
784 */
785 template <class T> class StateVariable : public StateVariableBase {
786 public:
787
788 /**
789 * \brief StateVariable default constructor.
790 */
791 StateVariable() {
792 }
793
794 /**
795 * \brief StateVariableBase constructor.
796 * \param[in] context a pointer to the GLUP Context
797 * \param[in] name the name of the variable, without
798 * "GLUPStateBlock." (it is prepended automatically).
799 * \param[in] value initial value of the variable
800 */
801 StateVariable(
802 Context* context, const char* name, T value
803 ) : StateVariableBase(context, name) {
804 set(value);
805 }
806
807 /**
808 * \brief Initializes a StateVariable.
809 * \param[in] context a pointer to the GLUP Context
810 * \param[in] name the name of the variable, without
811 * "GLUPStateBlock." (it is prepended automatically).
812 * \param[in] value initial value of the variable
813 */
814 void initialize(Context* context, const char* name, T value) {
815 StateVariableBase::initialize(context, name);
816 set(value);
817 }
818
819 /**
820 * \brief Gets the value.
821 * \return the value of this StateVariable.
822 */
823 T get() const {
824 return *reinterpret_cast<T*>(address_);
825 }
826
827 /**
828 * \brief Sets the value.
829 * \param[in] val the new value
830 * \details flags the uniform buffer as dirty
831 */
832 void set(T val) {
833 *reinterpret_cast<T*>(address_) = val;
834 flag_uniform_buffer_as_dirty();
835 }
836 };
837
838 /**
839 * \brief A GLUP state variable that contains an array
840 * of floating points. This concerns both vectors and
841 * matrices.
842 */
843 class FloatsArrayStateVariable : public StateVariableBase {
844 public:
845
846 /**
847 * \brief FloatsArrayStateVariable default constructor.
848 */
849 FloatsArrayStateVariable() {
850 }
851
852 /**
853 * \brief FloatsArrayStateVariable constructor.
854 * \param[in] context a pointer to the GLUP Context
855 * \param[in] name the name of the variable, without
856 * "GLUPStateBlock." (it is prepended automatically).
857 */
858 FloatsArrayStateVariable(
859 Context* context, const char* name
860 ) : StateVariableBase(context, name) {
861 }
862
863 /**
864 * \brief Gets a pointer to the variable.
865 * \return a const pointer to the first GLUPfloat stored
866 * in the variable
867 */
868 const GLUPfloat* get_pointer() const {
869 return reinterpret_cast<const GLUPfloat*>(address_);
870 }
871
872 /**
873 * \brief Gets a modifiable pointer to the variable.
874 * \return a modifiable pointer to the first GLUPfloat stored
875 * in the variable
876 * \details This flags the uniform buffer as dirty in the
877 * Context.
878 */
879 GLUPfloat* get_pointer() {
880 // This is a non-const pointer, therefore it will be
881 // probably modified by client code (else the 'const'
882 // version of get_pointer() would have been called).
883 flag_uniform_buffer_as_dirty();
884 return reinterpret_cast<GLUPfloat*>(address_);
885 }
886 };
887
888 /**
889 * \brief A GLUP state variable that contains a vector.
890 * \details This corresponds to vec2, vec3, vec4 GLSL types.
891 */
892 class VectorStateVariable : public FloatsArrayStateVariable {
893 public:
894
895 /**
896 * \brief VectorStateVariable default constructor.
897 */
898 VectorStateVariable() : dimension_(0) {
899 }
900
901 /**
902 * \brief VectorStateVariable constructor.
903 * \param[in] context a pointer to the GLUP Context
904 * \param[in] name the name of the variable, without
905 * "GLUPStateBlock." (it is prepended automatically)
906 * \param[in] dimension 2 for vec2, 3 for vec3, 4 for vec4
907 */
908 VectorStateVariable(
909 Context* context, const char* name, index_t dimension
910 ) : FloatsArrayStateVariable(context, name), dimension_(dimension) {
911 clear();
912 }
913
914 /**
915 * \brief Initializes a VectorStateVariable.
916 * \param[in] context a pointer to the GLUP Context
917 * \param[in] name the name of the variable, without
918 * "GLUPStateBlock." (it is prepended automatically)
919 * \param[in] dimension 2 for vec2, 3 for vec3, 4 for vec4
920 */
921 void initialize(Context* context, const char* name, index_t dimension) {
922 FloatsArrayStateVariable::initialize(context, name);
923 dimension_ = dimension;
924 clear();
925 }
926
927 /**
928 * \brief Gets the dimension.
929 * \return the number of components of this vector
930 */
931 index_t dimension() const {
932 return dimension_;
933 }
934
935 /**
936 * \brief Gets the value.
937 * \param[out] x a pointer to an array of dimension()
938 * GLfloats, where to store the value
939 */
940 void get(GLUPfloat* x) const {
941 Memory::copy(x, address_, sizeof(GLUPfloat)*dimension_);
942 }
943
944 /**
945 * \brief Sets the value.
946 * \param[in] x a const pointer to an array of dimension()
947 * GLfloats that contains the new value
948 */
949 void set(const GLUPfloat* x) {
950 Memory::copy(address_, x, sizeof(GLUPfloat)*dimension_);
951 flag_uniform_buffer_as_dirty();
952 }
953
954 /**
955 * \brief clears the vector to its default value.
956 * \details For vec2, default value is (0.0, 0.0), for
957 * vec3, it is (0.0, 0.0, 0.0) and for vec4 it is
958 * (0.0, 0.0, 0.0, 1.0)
959 */
960 void clear() {
961 Memory::clear(address_, sizeof(GLUPfloat)*dimension_);
962 if(dimension_ == 4) {
963 reinterpret_cast<GLUPfloat*>(address_)[3] = 1.0f;
964 }
965 flag_uniform_buffer_as_dirty();
966 }
967
968 protected:
969 index_t dimension_;
970 };
971
972
973 /**
974 * \brief The set of state variables that represent GLUP uniform state.
975 */
976 struct UniformState {
977 vector< StateVariable<GLboolean> > toggle;
978 vector< VectorStateVariable> color;
979 VectorStateVariable light_vector;
980 VectorStateVariable light_half_vector;
981 StateVariable<GLfloat> point_size;
982 StateVariable<GLfloat> mesh_width;
983 StateVariable<GLfloat> cells_shrink;
984 StateVariable<GLint> picking_mode;
985 StateVariable<GLint> picking_id;
986 StateVariable<GLint> base_picking_id;
987 StateVariable<GLint> clipping_mode;
988 StateVariable<GLint> texture_mode;
989 StateVariable<GLint> texture_type;
990 StateVariable<GLfloat> alpha_threshold;
991 StateVariable<GLfloat> specular;
992 VectorStateVariable clip_plane;
993 VectorStateVariable world_clip_plane;
994 VectorStateVariable clip_clip_plane;
995 FloatsArrayStateVariable modelview_matrix;
996 FloatsArrayStateVariable modelviewprojection_matrix;
997 FloatsArrayStateVariable projection_matrix;
998 FloatsArrayStateVariable normal_matrix;
999 FloatsArrayStateVariable texture_matrix;
1000 FloatsArrayStateVariable inverse_modelviewprojection_matrix;
1001 FloatsArrayStateVariable inverse_modelview_matrix;
1002 FloatsArrayStateVariable inverse_projection_matrix;
1003 VectorStateVariable viewport;
1004 };
1005
1006 /**********************************************************************/
1007
1008 /**
1009 * \brief Stores the programs and vertex array object used to display
1010 * a primitive of a given type.
1011 */
1012 struct PrimitiveInfo {
1013
1014 typedef Numeric::uint64 ShaderKey;
1015
1016 /**
1017 * \brief PrimitiveInfo constructor.
1018 */
1019 PrimitiveInfo():
1020 GL_primitive(0),
1021 VAO(0),
1022 elements_VBO(0),
1023 nb_elements_per_primitive(0),
1024 primitive_elements(nullptr),
1025 vertex_gather_mode(false),
1026 implemented(false) {
1027 }
1028
1029 /**
1030 * \brief PrimitiveInfo copy constructor.
1031 * \param[in] rhs the PrimitiveInfo to be copied.
1032 * \details Should be only called with uninitialized PrimitiveInfo
1033 * (else triggers an assertion failure).
1034 */
1035 PrimitiveInfo(const PrimitiveInfo& rhs) : shader_map(rhs.shader_map) {
1036 GL_primitive = rhs.GL_primitive;
1037 VAO = rhs.VAO;
1038 elements_VBO = rhs.elements_VBO;
1039 nb_elements_per_primitive = rhs.nb_elements_per_primitive;
1040 primitive_elements = rhs.primitive_elements;
1041 vertex_gather_mode = rhs.vertex_gather_mode;
1042 implemented = rhs.implemented;
1043 geo_assert(GL_primitive == 0);
1044 geo_assert(nb_elements_per_primitive == 0);
1045 }
1046
1047 /**
1048 * \brief PrimitiveInfo destructor.
1049 * \details Deletes the programs and vertex array object if need be.
1050 */
1051 ~PrimitiveInfo() {
1052 for(auto& it : shader_map) {
1053 if(it.second != 0) {
1054 glDeleteProgram(it.second);
1055 it.second = 0;
1056 }
1057 }
1058 if(elements_VBO != 0) {
1059 glDeleteBuffers(1, &elements_VBO);
1060 }
1061 if(VAO != 0) {
1062 glupDeleteVertexArrays(1,&VAO);
1063 VAO = 0;
1064 }
1065 }
1066
1067 bool program_is_initialized(ShaderKey k) const {
1068 return (shader_map.find(k) != shader_map.end());
1069 }
1070
1071 GLuint program(ShaderKey k) const {
1072 auto it = shader_map.find(k);
1073 return ((it == shader_map.end()) ? 0 : it->second);
1074 }
1075
1076 GLenum GL_primitive;
1077 std::map<ShaderKey, GLuint> shader_map;
1078 GLuint VAO;
1079 GLuint elements_VBO;
1080 index_t nb_elements_per_primitive;
1081 index_t* primitive_elements;
1082 bool vertex_gather_mode;
1083 bool implemented;
1084 };
1085
1086 /**********************************************************************/
1087
1088 /**
1089 * \brief GLUP context stores a Uniform Buffer Object with state
1090 * variables similar to OpenGL's fixed functionality pipeline, and
1091 * a set of Vertex Buffer Objects to emulate OpenGL's immediate mode.
1092 */
1093 class Context : public GLSL::PseudoFileProvider {
1094 public:
1095 /**
1096 * \brief Gets the GLSL declaration of GLUP uniform state.
1097 * \return a pointer to GLSL source code that declares
1098 * GLUP uniform state.
1099 * \details Can be used by client-code shaders that need to
1100 * have access to the GLUP uniform state. This corresponds
1101 * to the contents of GLUPGLSL/state.h
1102 */
1103 static const char* uniform_state_declaration();
1104
1105 /**
1106 * \brief Context constructor.
1107 */
1108 Context();
1109
1110 /**
1111 * \brief Context destructor.
1112 */
1113 ~Context() override;
1114
1115
1116 /**
1117 * \brief Gets the profile name associated with this context.
1118 */
1119 virtual const char* profile_name() const = 0;
1120
1121 /**
1122 * \brief Tests whether a given GLUP primitive supports array mode.
1123 * \details If array mode is supported, then one can use glupDrawArray()
1124 * and glupDrawElements() with the specified primitive.
1125 * \param[in] prim the primitive to be tested.
1126 * \retval true if array mode is supported with \p prim
1127 * \retval false otherwise
1128 */
1129 virtual bool primitive_supports_array_mode(GLUPprimitive prim) const;
1130
1131 /**
1132 * \brief Creates the uniform state and GLSL programs.
1133 * \details This function may throw exceptions if GLSL
1134 * functionalities are not implemented in the OpenGL driver.
1135 */
1136 virtual void setup();
1137
1138 /**
1139 * \brief Binds GLUP uniform state to a program.
1140 * \param[in] program the id of the GLSL program
1141 * \details If the program uses GLUP, then it
1142 * binds the program to GLUP uniform state, else this
1143 * function does nothing.
1144 */
1145 virtual void bind_uniform_state(GLuint program);
1146
1147 /**
1148 * \brief Replaces the top of the current matrix stack
1149 * with the specified matrix.
1150 * \param[in] m the matrix that will replace the top of
1151 * the current matrix stack
1152 */
1153 void load_matrix(const GLfloat m[16]) {
1154 copy_vector(matrix_stack_[matrix_mode_].top(), m, 16);
1155 flag_matrices_as_dirty();
1156 }
1157
1158 /**
1159 * \brief Replaces the top of the current matrix stack
1160 * with the specified matrix.
1161 * \param[in] m the matrix that will replace the top of
1162 * the current matrix stack
1163 */
1164 void load_matrix(const GLdouble m[16]) {
1165 copy_vector(matrix_stack_[matrix_mode_].top(), m, 16);
1166 flag_matrices_as_dirty();
1167 }
1168
1169 /**
1170 * \brief Replaces the top of the current matrix stack
1171 * with the identity matrix.
1172 */
1173 void load_identity() {
1174 load_identity_matrix(matrix_stack_[matrix_mode_].top());
1175 flag_matrices_as_dirty();
1176 }
1177
1178 /**
1179 * \brief Post-multiplies the top of the current matrix stack
1180 * with the specified matrix.
1181 * \param[in] m the matrix that will post-multiply the
1182 * top of the current matrix stack.
1183 * \see matrix_mode()
1184 */
1185 void mult_matrix(const GLdouble m[16]) {
1186 GLdouble product[16];
1187 mult_matrices(product,m,matrix_stack_[matrix_mode_].top());
1188 load_matrix(product);
1189 }
1190
1191 /**
1192 * \brief Pushes a copy of the top of the current stack matrix
1193 * onto the current stack matrix.
1194 * \see matrix_mode(), pop_matrix()
1195 */
1196 void push_matrix() {
1197 matrix_stack_[matrix_mode_].push();
1198 }
1199
1200 /**
1201 * \brief Pops the top of the current stack matrix.
1202 */
1203 void pop_matrix() {
1204 matrix_stack_[matrix_mode_].pop();
1205 flag_matrices_as_dirty();
1206 }
1207
1208 /**
1209 * \brief Sets the current matrix stack.
1210 * \param[in] matrix one of GLUP_MODELVIEW, GLUP_PROJECT
1211 * \details This determines on which matrix stack set_matrix(),
1212 * mult_matrix(), push_matrix() and pop_matrix() operate.
1213 */
1214 void set_matrix_mode(GLUPmatrix matrix) {
1215 matrix_mode_ = matrix;
1216 }
1217
1218 /**
1219 * \brief Gets the current matrix stack.
1220 * \return The current matrix stack, i.e.
1221 * one of GLUP_MODELVIEW, GLUP_PROJECT
1222 */
1223 GLUPmatrix get_matrix_mode() const {
1224 return matrix_mode_;
1225 }
1226
1227 /**
1228 * \brief Creates a new vertex in the immediate mode
1229 * buffers.
1230 * \param[in] x , y , z , w the coordinates of the vertex
1231 * \details The color and texture coordinates of the new
1232 * vertex are initialized from the current color and
1233 * current texture coordinates.
1234 */
1235 void immediate_vertex(
1236 GLfloat x, GLfloat y, GLfloat z=0.0f, GLfloat w=1.0f
1237 ) {
1238 immediate_state_.buffer[GLUP_VERTEX_ATTRIBUTE].set_current(x,y,z,w);
1239 immediate_state_.next_vertex();
1240 if(immediate_state_.buffers_are_full()) {
1241 flush_immediate_buffers();
1242 }
1243 }
1244
1245 /**
1246 * \brief Specifies the current color for the immediate
1247 * mode buffers.
1248 * \param[in] r , g , b , a the components of the current color.
1249 */
1250 void immediate_color(
1251 GLfloat r, GLfloat g, GLfloat b, GLfloat a = 1.0f
1252 ) {
1253 immediate_state_.buffer[GLUP_COLOR_ATTRIBUTE].set_current(r,g,b,a);
1254 }
1255
1256 /**
1257 * \brief Specifies the current texture coordinates for the
1258 * immediate mode buffers.
1259 * \param[in] s , t , u , v the current texture coordinates.
1260 */
1261 void immediate_tex_coord(
1262 GLfloat s, GLfloat t=0.0f, GLfloat u=0.0f, GLfloat v=1.0f
1263 ) {
1264 immediate_state_.buffer[GLUP_TEX_COORD_ATTRIBUTE].set_current(
1265 s,t,u,v
1266 );
1267 }
1268
1269 /**
1270 * \brief Specifies the current normal vector for the
1271 * immediate mode buffers.
1272 * \param[in] x , y , z the current normal vector coordinates.
1273 */
1274 void immediate_normal(GLfloat x, GLfloat y, GLfloat z) {
1275 immediate_state_.buffer[GLUP_NORMAL_ATTRIBUTE].set_current(
1276 x,y,z,0.0f
1277 );
1278 }
1279
1280 /**
1281 * \brief Sets the user program, to be used instead of
1282 * the default GLUP programs for drawing the primitives.
1283 */
1284 void set_user_program(GLuint program) {
1285 user_program_ = program;
1286 }
1287
1288 /**
1289 * \brief Begins rendering in immediate mode.
1290 * \param[in] primitive the primitive to be rendered.
1291 * \see immediate_vertex(), immediate_color(), immediate_tex_coord()
1292 */
1293 virtual void begin(GLUPprimitive primitive);
1294
1295 /**
1296 * \brief Ends rendering in immediate mode.
1297 * \see begin()
1298 */
1299 virtual void end();
1300
1301 /**
1302 * \brief Draws primitives using current OpenGL array bindings.
1303 * \details This function operates just like glDrawArrays(),
1304 * except that its \p primitive argument is a GLUPprimitive
1305 * instead of regular OpenGL primitive. Internally it uses
1306 * a (possibly different) OpenGL primitive, as well as
1307 * a GLSL program to reinterpret it.
1308 * \param[in] primitive the GLUP primitive type
1309 * \param[in] first first index to be rendered
1310 * \param[in] count number of vertices to be rendered
1311 */
1312 virtual void draw_arrays(
1313 GLUPprimitive primitive, GLUPint first, GLUPsizei count
1314 );
1315
1316 /**
1317 * \brief Draws primitives using current OpenGL array bindings.
1318 * \details This function operates just like glDrawElements(),
1319 * except that its \p primitive argument is a GLUPprimitive
1320 * instead of regular OpenGL primitive. Internally it uses
1321 * a (possibly different) OpenGL primitive, as well as
1322 * a GLSL program to reinterpret it.
1323 * \param[in] primitive the GLUP primitive type
1324 * \param[in] count number of vertices to be rendered
1325 * \param[in] type type of element indices, as one of
1326 * GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT, or GL_UNSIGNED_INT
1327 * \param[in] indices a pointer to where the indices are stored.
1328 */
1329 virtual void draw_elements(
1330 GLUPprimitive primitive, GLUPsizei count,
1331 GLUPenum type, const GLUPvoid* indices
1332 );
1333
1334 /**
1335 * \brief Gets a pointer to the representation of a uniform
1336 * state variable in host memory from its (unqualified) name.
1337 * \param[in] name the name of the variable, without the suffix
1338 * "GLUPStateBlock."
1339 * \return a pointer to where the variable is represented in
1340 * client side.
1341 */
1342 virtual Memory::pointer get_state_variable_address(const char* name);
1343
1344 /**
1345 * \brief Gets the uniform state.
1346 * \return a reference to the uniform state
1347 */
1348 UniformState& uniform_state() {
1349 return uniform_state_;
1350 }
1351
1352 /**
1353 * \brief Gets the uniform state.
1354 * \return a const reference to the uniform state
1355 */
1356 const UniformState& uniform_state() const {
1357 return uniform_state_;
1358 }
1359
1360 /**
1361 * \brief Indicates that the OpenGL representation
1362 * of the uniform state is no longer in sync with
1363 * the local copy.
1364 */
1365 void flag_uniform_buffer_as_dirty() {
1366 uniform_buffer_dirty_ = true;
1367 }
1368
1369
1370 /**
1371 * \brief Indicates that cached lighting information
1372 * needs to be recomputed.
1373 */
1374 void flag_lighting_as_dirty() {
1375 uniform_buffer_dirty_ = true;
1376 lighting_dirty_ = true;
1377 }
1378
1379 /**
1380 * \brief Indicates that cached matrix information
1381 * needs to be recomputed.
1382 */
1383 void flag_matrices_as_dirty() {
1384 uniform_buffer_dirty_ = true;
1385 matrices_dirty_ = true;
1386 }
1387
1388 /**
1389 * \brief Gets a pointer to the values of the matrix at the
1390 * top of a given stack.
1391 * \param[in] matrix name of the stack, one of GLUP_MODELVIEW_MATRIX,
1392 * GLUP_PROJECTION_MATRIX, GLUP_TEXTURE_MATRIX
1393 */
1394 GLUPdouble* get_matrix(GLUPmatrix matrix) {
1395 geo_debug_assert(matrix < 3);
1396 return matrix_stack_[matrix].top();
1397 }
1398
1399 /**
1400 * \brief Gets the content of the virtual file
1401 * GLUP/current_profile/vertex_shader_preamble.h.
1402 * \param[in,out] sources where the content of the
1403 * virtual file should be appended
1404 */
1405 virtual void get_vertex_shader_preamble_pseudo_file(
1406 std::vector<GLSL::Source>& sources
1407 );
1408
1409 /**
1410 * \brief Gets the content of the virtual file
1411 * GLUP/current_profile/fragment_shader_preamble.h
1412 * \param[in,out] sources where the content of the
1413 * virtual file should be appended
1414 */
1415 virtual void get_fragment_shader_preamble_pseudo_file(
1416 std::vector<GLSL::Source>& sources
1417 );
1418
1419 /**
1420 * \brief Gets the content of the virtual file
1421 * GLUP/current_profile/geometry_shader_preamble.h
1422 * \param[in,out] sources where the content of the
1423 * virtual file should be appended
1424 */
1425 virtual void get_geometry_shader_preamble_pseudo_file(
1426 std::vector<GLSL::Source>& sources
1427 );
1428
1429 /**
1430 * \brief Gets the content of the virtual file
1431 * GLUP/current_profile/tess_control_shader_preamble.h
1432 * \param[in,out] sources where the content of the
1433 * virtual file should be appended
1434 */
1435 virtual void get_tess_control_shader_preamble_pseudo_file(
1436 std::vector<GLSL::Source>& sources
1437 );
1438
1439 /**
1440 * \brief Gets the content of the virtual file
1441 * GLUP/current_profile/tess_evaluation_shader_preamble.h
1442 * \param[in,out] sources where the content of the
1443 * virtual file should be appended
1444 */
1445 virtual void get_tess_evaluation_shader_preamble_pseudo_file(
1446 std::vector<GLSL::Source>& sources
1447 );
1448
1449
1450 /**
1451 * \brief Gets the content of the virtual file
1452 * GLUP/current_profile/toggles.h
1453 * \details The toggles are generated in function of the parameters
1454 * of the previous call to setup_shaders_source_for_toggles()
1455 * current configuration defined by prepare_sources_for_toggles()
1456 * \param[in,out] sources where the content of the
1457 * virtual file should be appended
1458 */
1459 virtual void get_toggles_pseudo_file(
1460 std::vector<GLSL::Source>& sources
1461 );
1462
1463 /**
1464 * \brief Gets the content of the virtual file
1465 * GLUP/current_profile/primitive.h
1466 * \details The current primitive is defined by the argument of
1467 * the previous call of setup_shaders_source_for_primitive().
1468 * \param[in,out] sources where the content of the
1469 * virtual file should be appended
1470 */
1471 virtual void get_primitive_pseudo_file(
1472 std::vector<GLSL::Source>& sources
1473 );
1474
1475 /**
1476 * \brief Gets the content of the virtual file
1477 * GLUP/current_profile/marching_cells.h
1478 * \details The current primitive is defined by the argument of
1479 * the previous call of setup_shaders_source_for_primitive().
1480 * \param[in,out] sources where the content of the
1481 * virtual file should be appended
1482 */
1483 virtual void get_marching_cells_pseudo_file(
1484 std::vector<GLSL::Source>& sources
1485 );
1486
1487 /**
1488 * \brief Sets the string that describes the settings of
1489 * the toggles for a given configuration.
1490 * \param[in] toggles_state an unsigned integer, with its bits
1491 * corresponding to the state of each toggle
1492 * \param[in] toggles_undetermined an unsigned integer, with its bits
1493 * set if the corresponding toggle state needs to be determined
1494 * dynamically from GLUP state
1495 */
1496 void setup_shaders_source_for_toggles(
1497 GLUPbitfield toggles_state,
1498 GLUPbitfield toggles_undetermined=0
1499 );
1500
1501 /**
1502 * \brief Sets the configurable GLSL sources for a given
1503 * primitive type.
1504 * \details This function needs to be called before compiling
1505 * the GLSL program.
1506 * \param[in] primitive the GLUP primitive
1507 */
1508 virtual void setup_shaders_source_for_primitive(
1509 GLUPprimitive primitive
1510 );
1511
1512 /**
1513 * \brief Gets the immediate state.
1514 * \return a reference to the immediate state.
1515 */
1516 ImmediateState& immediate_state() {
1517 return immediate_state_;
1518 }
1519
1520 /**
1521 * \brief Flushes the immediate mode buffers.
1522 */
1523 virtual void flush_immediate_buffers();
1524
1525
1526 /**
1527 * \brief Gets the name of a primitive by GLUPprimitive.
1528 * \param[in] prim a GLUPprimitive
1529 * \return the name of the primitive, as a const char pointer
1530 */
1531 static const char* glup_primitive_name(GLUPprimitive prim);
1532
1533
1534 protected:
1535
1536 /**
1537 * \brief Gets the MarchingCell that corresponds to the
1538 * current primitive.
1539 * \details The current primitive is defined by the argument of
1540 * the previous call of setup_shaders_source_for_primitive().
1541 * \return A const reference to the current MarchingCell.
1542 */
1543 const MarchingCell& get_marching_cell() const;
1544
1545 /**
1546 * \brief Tests whether an OpenGL extension is supported.
1547 * \param[in] extension the name fo the extension to be tested.
1548 * \details This function needs to be called before starting using
1549 * the extension, even if you are sure that it is supported. In
1550 * particular, WebGL specification requires that.
1551 * \retval true if the extension is supported.
1552 * \retval false otherwise.
1553 */
1554 bool extension_is_supported(const std::string& extension);
1555
1556 /**
1557 * \brief This function is called before starting to
1558 * render primitives. It is called by begin(), draw_arrays()
1559 * and draw_elements().
1560 * \details Some primitives require to change some
1561 * parameters in OpenGL. For instance, when we use
1562 * GL_PATCH to gather the vertices of hexahedra and
1563 * tetrahedra, the number of vertices per patch needs
1564 * to be specified to OpenGL.
1565 */
1566 virtual void prepare_to_draw(GLUPprimitive primitive);
1567
1568
1569 /**
1570 * \brief This function is called right after
1571 * rendering primitives. It is called by end(), draw_arrays()
1572 * and draw_elements().
1573 * \details Default implementation does nothing. This function
1574 * is meant to be overloaded by derived Context classes.
1575 */
1576 virtual void done_draw(GLUPprimitive primitive);
1577
1578 /**
1579 * \brief Initializes the representation of the uniform state.
1580 */
1581 virtual void setup_state_variables();
1582
1583
1584 /**
1585 * \brief Set-ups the buffers for immediate rendering.
1586 * \details This creates VBOs and the VAO.
1587 */
1588 virtual void setup_immediate_buffers();
1589
1590 /**
1591 * \brief Sends all the active immediate buffers to the GPU.
1592 * \details Overwrites the VBOs with the contents of the buffers.
1593 */
1594 virtual void stream_immediate_buffers();
1595
1596 /**
1597 * \brief Setups the programs and VAOs used for each primitive.
1598 */
1599 virtual void setup_primitives();
1600
1601 /**
1602 * \brief Setups GLSL programs for points.
1603 */
1604 virtual void setup_GLUP_POINTS();
1605
1606 /**
1607 * \brief Setups GLSL programs for lines.
1608 */
1609 virtual void setup_GLUP_LINES();
1610
1611 /**
1612 * \brief Setups GLSL programs for lines with width > 1.
1613 */
1614 virtual void setup_GLUP_THICK_LINES();
1615
1616 /**
1617 * \brief Setups GLSL programs for triangles.
1618 */
1619 virtual void setup_GLUP_TRIANGLES();
1620
1621 /**
1622 * \brief Setups GLSL programs for quads.
1623 */
1624 virtual void setup_GLUP_QUADS();
1625
1626 /**
1627 * \brief Setups GLSL programs for tetrahedra.
1628 */
1629 virtual void setup_GLUP_TETRAHEDRA();
1630
1631 /**
1632 * \brief Setups GLSL programs for hexahedra.
1633 */
1634 virtual void setup_GLUP_HEXAHEDRA();
1635
1636 /**
1637 * \brief Setups GLSL programs for prisms.
1638 */
1639 virtual void setup_GLUP_PRISMS();
1640
1641 /**
1642 * \brief Setups GLSL programs for pyramids.
1643 */
1644 virtual void setup_GLUP_PYRAMIDS();
1645
1646 /**
1647 * \brief Setups GLSL programs for connectors.
1648 */
1649 virtual void setup_GLUP_CONNECTORS();
1650
1651 /**
1652 * \brief Setups GLSL programs for spheres.
1653 */
1654 virtual void setup_GLUP_SPHERES();
1655
1656 /**
1657 * \brief Initializes the PrimitiveInfo associated with a
1658 * given GLUP primitive.
1659 * \param[in] glup_primitive the GLUP primitive.
1660 * \param[in] gl_primitive the GL primitive used by the implementation
1661 * \param[in] program the GLSL program used by the implementation
1662 * \param[in] bind_attrib_loc_and_link if true, binds attribute
1663 * location and links the shader
1664 */
1665 virtual void set_primitive_info(
1666 GLUPprimitive glup_primitive, GLenum gl_primitive, GLuint program,
1667 bool bind_attrib_loc_and_link = true
1668 );
1669
1670 /**
1671 * \brief Initializes the PrimitiveInfo associated with a
1672 * given GLUP primitive in vertex-gather mode.
1673 * \details In vertex-gather mode, all the coordinates of all vertices
1674 * and all attributes of the primitive are gathered into a small
1675 * number of vertices. This is required by
1676 * primitives that have a number of vertices that corresponds to no
1677 * existing OpenGL primitive (i.e., hexahedron and pyramid).
1678 * \param[in] glup_primitive the GLUP primitive.
1679 * \param[in] gl_primitive the GL primitive used to display the GLUP
1680 * primitive. The number of vertices of the GL primitive needs to
1681 * be a divisor of the number of vertices of the GLUP primitive.
1682 * \param[in] program the GLSL program used by the implementation
1683 */
1684 virtual void set_primitive_info_vertex_gather_mode(
1685 GLUPprimitive glup_primitive, GLenum gl_primitive, GLuint program
1686 );
1687
1688 /**
1689 * \brief Initializes the PrimitiveInfo associated with a
1690 * given GLUP primitive in immediate mode when an element index
1691 * buffer is required.
1692 * \details An element index buffer is required when geometry
1693 * shaders are not supported, for instance when using OpenGL ES in
1694 * webGL.
1695 * \param[in] glup_primitive the GLUP primitive.
1696 * \param[in] gl_primitive the GL primitive used to display the GLUP
1697 * primitive.
1698 * \param[in] program the GLSL program used by the implementation.
1699 * \param[in] nb_elements_per_glup_primitive the number of element
1700 * indices for each glup primitive. For instance, when drawing
1701 * GLUP tetrahedra using OpenGL triangles, there are 4*3 = 12
1702 * elements per primitive.
1703 * \param[in] element_indices a pointer to an array of
1704 * nb_elements_per_glup_primitive integers that encode the
1705 * indexing of one element. This array is replicated and shifted
1706 * to generate the element index buffer.
1707 */
1708 virtual void set_primitive_info_immediate_index_mode(
1709 GLUPprimitive glup_primitive, GLenum gl_primitive, GLuint program,
1710 index_t nb_elements_per_glup_primitive,
1711 index_t* element_indices
1712 );
1713
1714 /**
1715 * \brief Copies GLUP uniform state to OpenGL
1716 * if required.
1717 */
1718 void update_uniform_buffer() {
1719 if(uniform_buffer_dirty_) {
1720 do_update_uniform_buffer();
1721 }
1722 }
1723
1724 /**
1725 * \brief Copies GLUP uniform state to OpenGL.
1726 * \details This is the implementation of
1727 * update_uniform_buffer().
1728 */
1729 virtual void do_update_uniform_buffer();
1730
1731 /**
1732 * \brief Updates the matrices in the uniform state
1733 * from the matrices in the stacks.
1734 */
1735 virtual void update_matrices();
1736
1737 /**
1738 * \brief Updates the lighting in the uniform state.
1739 * \details Computes the half vector from the lighting
1740 * vector.
1741 */
1742 virtual void update_lighting();
1743
1744 /**
1745 * \brief Updates the base picking id and sends it to
1746 * OpenGL.
1747 */
1748 virtual void update_base_picking_id(GLint new_value);
1749
1750 /**
1751 * \brief Gets the GLSL declaration of the constant that
1752 * indicates the current primitive.
1753 * \return a string with the GLSL declaration.
1754 */
1755 std::string primitive_declaration(GLUPprimitive prim) const;
1756
1757 /**
1758 * \brief Sets the string that describes the settings of
1759 * the toggles for a given configuration.
1760 * \param[in] toggles_config the identifier of the toggles
1761 * configurations, used to index the GLSL program in the
1762 * PrimitiveInfo class
1763 */
1764 void setup_shaders_source_for_toggles_config(
1765 PrimitiveInfo::ShaderKey toggles_config
1766 ) {
1767 if(toggles_config == (1 << GLUP_PICKING)) {
1768 setup_shaders_source_for_toggles(
1769 (1 << GLUP_PICKING), // picking=true
1770 (1 << GLUP_CLIPPING) // clipping=undecided (use state)
1771 );
1772 } else {
1773 setup_shaders_source_for_toggles(GLUPbitfield(toggles_config));
1774 }
1775 }
1776
1777 /**
1778 * \brief Updates the toggles_config_ state variable from
1779 * the individual state of each toggle.
1780 */
1781 void update_toggles_config();
1782
1783 /**
1784 * \brief Creates the GLSL shader that corresponds to the
1785 * specified primitive and current toggles configuration if
1786 * not already initialized.
1787 * \param[in] primitive the primitive to be displayed
1788 */
1789 void create_program_if_needed(GLUPprimitive primitive);
1790
1791 /**
1792 * \brief Shrinks the cells in the immediate buffer.
1793 * \details Applies the shrinking factor (state variable
1794 * "cells_shrink") to all the cells stored in the current
1795 * immediate buffer. Since there is no function to query
1796 * the content of the current buffer, modidying it is
1797 * acceptable. This function is used by derived classes
1798 * (VanillaGL and ES2) that cannot shrink the cells
1799 * with a shader.
1800 */
1801 void shrink_cells_in_immediate_buffers();
1802
1803 /**
1804 * \brief Creates a buffer for uniform variables for
1805 * implementations that do not support uniform buffer
1806 * objects.
1807 * \details This function is used by ES2.
1808 */
1809 void create_CPU_side_uniform_buffer();
1810
1811 /**
1812 * \brief Binds the VBOs associated with the immediate
1813 * state buffers to the currently bound VAO.
1814 */
1815 void bind_immediate_state_buffers_to_VAO();
1816
1817 /**
1818 * \brief Updates v_is_visible_[] according to
1819 * current clipping plane.
1820 * \details Used by implementations of Context that
1821 * do not support clipping by shaders (ES2).
1822 */
1823 void classify_vertices_in_immediate_buffers();
1824
1825 /**
1826 * \brief Tests whether the cell starting at a given vertex
1827 * in the immediate buffer is clipped, according to current
1828 * clipping mode and current primitive type.
1829 * \param[in] first_v index of the first vertex of the cell in
1830 * the immediate buffer
1831 * \retval true if the cell starting at \p first_v in the
1832 * immediate buffer is clipped-out
1833 * \retval false otherwise
1834 */
1835 bool cell_is_clipped(index_t first_v);
1836
1837
1838 /**
1839 * \brief Assemble the configuration code of a primitive
1840 * relative to the clipping plane.
1841 * \param[in] first_v index of the first vertex of the
1842 * primitive in the immediate buffer
1843 * \param[in] nb_v number of vertices of the primitive
1844 * \return an integer with the i-th bit set if vertex i
1845 * is visible, and unset if it is clipped.
1846 */
1847 index_t get_config(index_t first_v, index_t nb_v) {
1848 index_t result = 0;
1849 for(index_t lv=0; lv<nb_v; ++lv) {
1850 if(v_is_visible_[first_v+lv]) {
1851 result = result | (1u << lv);
1852 }
1853 }
1854 return result;
1855 }
1856
1857 /**
1858 * \brief Computes the intersection between the clipping plane and
1859 * a segment.
1860 * \param[in] v1 index of the first extremity of the segment in the
1861 * immediate buffer
1862 * \param[in] v2 index of the second extremity of the segment in the
1863 * immediate buffer
1864 * \param[in] vi index of where to wrote the intersection in the
1865 * isect_xxx arrays
1866 */
1867 void compute_intersection(index_t v1, index_t v2, index_t vi) {
1868 const GLUPfloat* eqn = world_clip_plane_;
1869 const GLUPfloat* p1 = immediate_state_.buffer[0].element_ptr(v1);
1870 const GLUPfloat* p2 = immediate_state_.buffer[0].element_ptr(v2);
1871
1872 GLUPfloat t = -eqn[3] -(
1873 eqn[0]*p1[0] +
1874 eqn[1]*p1[1] +
1875 eqn[2]*p1[2]
1876 );
1877
1878 GLUPfloat d =
1879 eqn[0]*(p2[0]-p1[0]) +
1880 eqn[1]*(p2[1]-p1[1]) +
1881 eqn[2]*(p2[2]-p1[2]) ;
1882
1883 if(fabs(double(d)) < 1e-6) {
1884 t = 0.5f;
1885 } else {
1886 t /= d;
1887 }
1888
1889 GLUPfloat s = 1.0f - t;
1890
1891 isect_vertex_attribute_[0][4*vi+0] = s*p1[0] + t*p2[0];
1892 isect_vertex_attribute_[0][4*vi+1] = s*p1[1] + t*p2[1];
1893 isect_vertex_attribute_[0][4*vi+2] = s*p1[2] + t*p2[2];
1894 isect_vertex_attribute_[0][4*vi+3] = 1.0f;
1895
1896 for(index_t i=1; i<3; ++i) {
1897 if(immediate_state_.buffer[i].is_enabled()) {
1898 const GLUPfloat* a1 =
1899 immediate_state_.buffer[i].element_ptr(v1);
1900 const GLUPfloat* a2 =
1901 immediate_state_.buffer[i].element_ptr(v2);
1902 isect_vertex_attribute_[i][4*vi+0] = s*a1[0] + t*a2[0];
1903 isect_vertex_attribute_[i][4*vi+1] = s*a1[1] + t*a2[1];
1904 isect_vertex_attribute_[i][4*vi+2] = s*a1[2] + t*a2[2];
1905 isect_vertex_attribute_[i][4*vi+3] = s*a1[3] + t*a2[3];
1906 }
1907 }
1908 }
1909
1910 /**
1911 * \brief Copies the uniform state from client-side
1912 * memory into the currently bound program, or does
1913 * nothing if uniform buffer objects are supported.
1914 */
1915 virtual void copy_uniform_state_to_current_program();
1916
1917 /**
1918 * \brief A wrapper around glUseProgram that tests whether
1919 * uniform state needs to be sent to the program.
1920 * \details Each time a different program is used, the
1921 * uniform state can be sent to it through the virtual
1922 * function update_program_state(). If UBOs are supported,
1923 * update_program_state() does nothing.
1924 */
1925 void use_program(GLuint program) {
1926 if(program != 0 && program != latest_program_) {
1927 glUseProgram(program);
1928 latest_program_ = program;
1929 copy_uniform_state_to_current_program();
1930 } else {
1931 glUseProgram(program);
1932 }
1933 }
1934
1935 /**
1936 * \brief Creates a vertex buffer object with 16 bits integers
1937 * between 0 and 65535.
1938 * \details It is used to emulate gl_VertexID if GLSL does not
1939 * support it.
1940 */
1941 void create_vertex_id_VBO();
1942
1943 static void initialize();
1944
1945 protected:
1946
1947 // OpenGL Uniform state.
1948 GLuint default_program_;
1949 GLuint uniform_buffer_;
1950 GLuint uniform_binding_point_;
1951 GLint uniform_buffer_size_;
1952 bool uniform_buffer_dirty_;
1953
1954 // C++ Uniform state.
1955 Memory::byte* uniform_buffer_data_;
1956 UniformState uniform_state_;
1957
1958 bool lighting_dirty_;
1959
1960 // Matrix stacks.
1961 GLUPmatrix matrix_mode_;
1962 MatrixStack matrix_stack_[3];
1963 bool matrices_dirty_;
1964
1965 /**
1966 * \brief Number of vertices per primitive (3 for GLUP_TRIANGLES,
1967 * 4 for GLUP_QUADS etc...)
1968 * \details It is stored as a class member array rather than a
1969 * static array so that particular implementations can change
1970 * it according to the needs (for instance, GLUPES profile temporarily
1971 * uses quads with for vertices to render GLUP_THICK_LINES).
1972 */
1973 index_t nb_vertices_per_primitive_[GLUP_NB_PRIMITIVES];
1974
1975 // Immediate mode buffers.
1976 ImmediateState immediate_state_;
1977
1978 // Primitive informations (i.e., how to
1979 // draw a primitive of a given type).
1980 vector<PrimitiveInfo> primitive_info_;
1981
1982 // The marching cells, for computing
1983 // intersections when clipping mode
1984 // is GLUP_CLIP_SLICE_CELLS
1985 MarchingCell marching_tet_;
1986 MarchingCell marching_hex_;
1987 MarchingCell marching_prism_;
1988 MarchingCell marching_pyramid_;
1989 MarchingCell marching_connector_;
1990
1991 GLuint user_program_;
1992
1993 PrimitiveInfo::ShaderKey toggles_config_;
1994
1995 GLUPprimitive primitive_source_;
1996 GLUPbitfield toggles_source_state_;
1997 GLUPbitfield toggles_source_undetermined_;
1998
1999 bool precompile_shaders_;
2000
2001 bool use_core_profile_;
2002 bool use_ES_profile_;
2003
2004 /**
2005 * \brief Cached pointer to uniform state variable.
2006 * \details It is initialized by create_GPU_side_uniform_buffer(),
2007 * used only by VanillaGL and ES2 implementations.
2008 */
2009 GLUPfloat* world_clip_plane_;
2010
2011 /**
2012 * \brief Used by GPU-side uniform buffer.
2013 * \details It is initialized by create_GPU_side_uniform_buffer(),
2014 * used only by VanillaGL and ES2 implementations.
2015 */
2016 std::map<std::string, GLsizei> variable_to_offset_;
2017
2018 /**
2019 * \brief Indicates for a given vertex whether it is clipped or
2020 * is visible, according to the current clipping plane.
2021 * \details Used when clipping is done by software.
2022 */
2023 bool v_is_visible_[IMMEDIATE_BUFFER_SIZE];
2024
2025 /**
2026 * \brief computed intersections.
2027 * \details Used when clipping mode is GLUP_CLIP_SLICE_CELLS and
2028 * clipping is done by software.
2029 */
2030 GLUPfloat isect_vertex_attribute_[3][12*4];
2031
2032 /**
2033 * \brief Latest used GLSL program.
2034 * \details Used to check whether it changed and whether some
2035 * uniform variables need to be sent to it.
2036 */
2037 GLuint latest_program_;
2038
2039 /**
2040 * \brief A vertex buffer object with 65536 16 bits integers.
2041 * \details It is used to emulate gl_VertexID in shaders.
2042 */
2043 GLuint vertex_id_VBO_;
2044 };
2045
2046 /*********************************************************************/
2047 }
2048
2049 #endif
2050