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