Geogram Version 1.8.5
A programming library of geometric algorithms
Loading...
Searching...
No Matches
GLUP_context.h
Go to the documentation of this file.
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
47#include <map>
48
54#ifdef GEO_GL_NO_DOUBLES
55typedef double GLdouble;
56#endif
57
58namespace GLUP {
59 using namespace GEO;
60
69 GLboolean invert_matrix(GLfloat inv[16], const GLfloat m[16]);
70
79 GLboolean invert_matrix(GLdouble inv[16], const GLdouble m[16]);
80
87 GLfloat out[16], const GLfloat m1[16], const GLfloat m2[16]
88 );
89
96 GLdouble out[16], const GLdouble m1[16], const GLdouble m2[16]
97 );
98
108 GLfloat out[4], const GLfloat m[16], const GLfloat v[4]
109 );
110
111
122 GLfloat out[4], const GLfloat m[16], const GLfloat v[4]
123 );
124
125
136 GLdouble out[4], const GLdouble m[16], const GLdouble v[4]
137 );
138
146 GLdouble out[4], const GLdouble m[16], const GLdouble v[4]
147 );
148
154 void transpose_matrix(GLfloat m[16]);
155
161 void transpose_matrix(GLdouble m[16]);
162
167 void show_matrix(const GLfloat m[16]);
168
173 void show_matrix(const GLdouble m[16]);
174
179 void show_vector(const GLfloat v[4]);
180
185 void show_vector(const GLdouble v[4]);
186
191 void load_identity_matrix(GLfloat out[16]);
192
197 void load_identity_matrix(GLdouble out[16]);
198
205 inline void copy_vector(GLfloat* to, const GLfloat* from, index_t dim) {
206 Memory::copy(to, from, sizeof(GLfloat)*dim);
207 }
208
215 inline void copy_vector(GLdouble* to, const GLdouble* from, index_t dim) {
216 Memory::copy(to, from, sizeof(GLdouble)*dim);
217 }
218
225 inline void copy_vector(GLfloat* to, const GLdouble* from, index_t dim) {
226 for(index_t i=0; i<dim; ++i) {
227 to[i] = GLfloat(from[i]);
228 }
229 }
230
237 inline void copy_vector(GLdouble* to, const GLfloat* from, index_t dim) {
238 for(index_t i=0; i<dim; ++i) {
239 to[i] = GLdouble(from[i]);
240 }
241 }
242
248 inline void normalize_vector(GLfloat v[3]) {
249 GLfloat s = 1.0f / ::sqrtf(v[0]*v[0]+v[1]*v[1]+v[2]*v[2]);
250 v[0] *= s;
251 v[1] *= s;
252 v[2] *= s;
253 }
254
255
261 extern index_t nb_vertices_per_primitive[];
262
263 /**********************************************************************/
264
265 class Context;
266
274 public:
275
279 static const int MAX_DEPTH=16;
280
284 MatrixStack() : top_(0) {
286 }
287
294 GLdouble* top() {
295 return stack_[top_].data();
296 }
297
301 void push() {
302 geo_assert(top_ != MAX_DEPTH-1);
303 GLdouble* from = top();
304 ++top_;
305 GLdouble* to = top();
306 copy_vector(to, from, 16);
307 }
308
313 void pop() {
314 geo_assert(top_ != 0);
315 --top_;
316 }
317
318 protected:
319 struct Matrix {
320 GLdouble coeff[16];
321 GLdouble* data() {
322 return &coeff[0];
323 }
324 };
325
326 private:
327 Matrix stack_[MAX_DEPTH];
328 index_t top_;
329 };
330
331
338 static const index_t IMMEDIATE_BUFFER_SIZE = 65536;
339
345 GLUP_VERTEX_ATTRIBUTE = 0,
346 GLUP_COLOR_ATTRIBUTE = 1,
347 GLUP_TEX_COORD_ATTRIBUTE = 2,
348 GLUP_NORMAL_ATTRIBUTE = 3,
349 GLUP_VERTEX_ID_ATTRIBUTE = 4
350 };
351
356
357 public:
358
363 data_(nullptr),
364 dimension_(0),
365 is_enabled_(false),
366 VBO_(0) {
367 }
368
373 delete[] data_;
374 if(VBO_ != 0) {
375 glDeleteBuffers(1, &VBO_);
376 VBO_ = 0;
377 }
378 }
379
380 void initialize(index_t dim) {
381 data_ = new GLfloat[dim * IMMEDIATE_BUFFER_SIZE];
382 dimension_ = dim;
383 is_enabled_ = true;
384 }
385
389 void enable() {
390 is_enabled_ = true;
391 }
392
396 void disable() {
397 is_enabled_ = false;
398 }
399
405 bool is_enabled() const {
406 return is_enabled_;
407 }
408
415 void set_current(GLfloat x, GLfloat y, GLfloat z, GLfloat w) {
416 current_[0] = x;
417 current_[1] = y;
418 current_[2] = z;
419 current_[3] = w;
420 }
421
429 geo_debug_assert(v < IMMEDIATE_BUFFER_SIZE);
430 if(is_enabled()) {
431 copy_vector(element_ptr(v), current_, dimension());
432 }
433 }
434
441 void copy(index_t to, index_t from) {
442 geo_debug_assert(to < IMMEDIATE_BUFFER_SIZE);
443 geo_debug_assert(from < IMMEDIATE_BUFFER_SIZE);
444 if(is_enabled()) {
446 }
447 }
448
454 return dimension_;
455 }
456
461 size_t size_in_bytes() const {
462 return IMMEDIATE_BUFFER_SIZE * dimension() * sizeof(GLfloat);
463 }
464
471 GLfloat* element_ptr(index_t v) {
472 geo_debug_assert(v < IMMEDIATE_BUFFER_SIZE);
473 return data_ + v*dimension_;
474 }
475
481 GLfloat* data() {
482 return data_;
483 }
484
490 GLuint& VBO() {
491 return VBO_;
492 }
493
501 const ImmediateBuffer& rhs
502 ) {
503 data_ = rhs.data_;
504 dimension_ = rhs.dimension_;
505 is_enabled_ = rhs.is_enabled_;
506 VBO_ = rhs.VBO_;
507 current_[0] = rhs.current_[0];
508 current_[1] = rhs.current_[1];
509 current_[2] = rhs.current_[2];
510 current_[3] = rhs.current_[3];
511 geo_assert(data_ == nullptr);
512 }
513
514 private:
515 GLfloat* data_;
516 GLfloat current_[4];
517 index_t dimension_;
518 bool is_enabled_;
519 GLuint VBO_;
520 };
521
527 public:
532 current_vertex_(0),
533 max_current_vertex_(0),
534 primitive_(GLUP_POINTS),
535 VAO_(0)
536 {
537 buffer[GLUP_VERTEX_ATTRIBUTE].initialize(4);
538 buffer[GLUP_COLOR_ATTRIBUTE].initialize(4);
539 buffer[GLUP_TEX_COORD_ATTRIBUTE].initialize(4);
540 buffer[GLUP_NORMAL_ATTRIBUTE].initialize(4);
541
542 // Vertex is always enabled
543 buffer[GLUP_VERTEX_ATTRIBUTE].enable();
544 }
545
550 if(VAO_ != 0) {
551 glupDeleteVertexArrays(1, &VAO_);
552 VAO_ = 0;
553 }
554 }
555
561 GLuint& VAO() {
562 return VAO_;
563 }
564
572 void copy_element(index_t to, index_t from) {
573 for(index_t i=0; i<NB_IMMEDIATE_BUFFERS; ++i) {
574 buffer[i].copy(to, from);
575 }
576 }
577
578
585 current_vertex_ = 0;
586 max_current_vertex_ =
587 IMMEDIATE_BUFFER_SIZE - (
588 IMMEDIATE_BUFFER_SIZE %
590 );
591 primitive_ = primitive;
592 }
593
599 void next_vertex() {
600 for(index_t i=0; i<NB_IMMEDIATE_BUFFERS; ++i) {
601 buffer[i].copy_current_to(current_vertex_);
602 }
603 ++current_vertex_;
604 }
605
613 return (current_vertex_ == max_current_vertex_);
614 }
615
619 void reset() {
620 current_vertex_ = 0;
621 }
622
628 return primitive_;
629 }
630
635 return current_vertex_;
636 }
637
642 return current_vertex_ / nb_vertices_per_primitive[
643 primitive_
644 ];
645 }
646
654 return max_current_vertex_;
655 }
656
664 geo_debug_assert(v <= max_current_vertex_);
665 current_vertex_ = v;
666 }
667
668 enum { NB_IMMEDIATE_BUFFERS = 4 };
669 ImmediateBuffer buffer[NB_IMMEDIATE_BUFFERS];
670
671 private:
672 index_t current_vertex_;
673 index_t max_current_vertex_;
674 GLUPprimitive primitive_;
675 GLuint VAO_;
676 };
677
678
679 /**********************************************************/
680
685 public:
686
690 StateVariableBase() : address_(nullptr), context_(nullptr) {
691 }
692
700 Context* context, const char* name
701 ) {
702 initialize(context,name);
703 }
704
712 void initialize(Context* context, const char* name);
713
719 const std::string& name() const {
720 return name_;
721 }
722
723 protected:
724 friend class Context;
725
732 return address_;
733 }
734
740
741 Memory::pointer address_;
742 Context* context_;
743 std::string name_;
744 };
745
750 template <class T> class StateVariable : public StateVariableBase {
751 public:
752
757 }
758
767 Context* context, const char* name, T value
769 set(value);
770 }
771
779 void initialize(Context* context, const char* name, T value) {
781 set(value);
782 }
783
788 T get() const {
789 return *reinterpret_cast<T*>(address_);
790 }
791
797 void set(T val) {
798 *reinterpret_cast<T*>(address_) = val;
800 }
801 };
802
809 public:
810
816
824 Context* context, const char* name
825 ) : StateVariableBase(context, name) {
826 }
827
833 const GLUPfloat* get_pointer() const {
834 return reinterpret_cast<const GLUPfloat*>(address_);
835 }
836
844 GLUPfloat* get_pointer() {
845 // This is a non-const pointer, therefore it will be
846 // probably modified by client code (else the 'const'
847 // version of get_pointer() would have been called).
849 return reinterpret_cast<GLUPfloat*>(address_);
850 }
851 };
852
858 public:
859
863 VectorStateVariable() : dimension_(0) {
864 }
865
878
888 dimension_ = dimension;
889 clear();
890 }
891
897 return dimension_;
898 }
899
905 void get(GLUPfloat* x) const {
906 Memory::copy(x, address_, sizeof(GLUPfloat)*dimension_);
907 }
908
914 void set(const GLUPfloat* x) {
915 Memory::copy(address_, x, sizeof(GLUPfloat)*dimension_);
917 }
918
925 void clear() {
926 Memory::clear(address_, sizeof(GLUPfloat)*dimension_);
927 if(dimension_ == 4) {
928 reinterpret_cast<GLUPfloat*>(address_)[3] = 1.0f;
929 }
931 }
932
933 protected:
934 index_t dimension_;
935 };
936
937
944 VectorStateVariable light_vector;
945 VectorStateVariable light_half_vector;
946 StateVariable<GLfloat> point_size;
947 StateVariable<GLfloat> mesh_width;
948 StateVariable<GLfloat> cells_shrink;
949 StateVariable<GLint> picking_mode;
950 StateVariable<GLint> picking_id;
951 StateVariable<GLint> base_picking_id;
952 StateVariable<GLint> clipping_mode;
953 StateVariable<GLint> texture_mode;
954 StateVariable<GLint> texture_type;
955 StateVariable<GLfloat> alpha_threshold;
956 StateVariable<GLfloat> specular;
957 VectorStateVariable clip_plane;
958 VectorStateVariable world_clip_plane;
959 VectorStateVariable clip_clip_plane;
960 FloatsArrayStateVariable modelview_matrix;
961 FloatsArrayStateVariable modelviewprojection_matrix;
962 FloatsArrayStateVariable projection_matrix;
963 FloatsArrayStateVariable normal_matrix;
964 FloatsArrayStateVariable texture_matrix;
965 FloatsArrayStateVariable inverse_modelviewprojection_matrix;
966 FloatsArrayStateVariable inverse_modelview_matrix;
967 FloatsArrayStateVariable inverse_projection_matrix;
968 VectorStateVariable viewport;
969 };
970
971 /**********************************************************************/
972
978
979 typedef Numeric::uint64 ShaderKey;
980
985 GL_primitive(0),
986 VAO(0),
987 elements_VBO(0),
988 nb_elements_per_primitive(0),
989 primitive_elements(nullptr),
990 vertex_gather_mode(false),
991 implemented(false) {
992 }
993
1000 PrimitiveInfo(const PrimitiveInfo& rhs) : shader_map(rhs.shader_map) {
1001 GL_primitive = rhs.GL_primitive;
1002 VAO = rhs.VAO;
1003 elements_VBO = rhs.elements_VBO;
1004 nb_elements_per_primitive = rhs.nb_elements_per_primitive;
1005 primitive_elements = rhs.primitive_elements;
1006 vertex_gather_mode = rhs.vertex_gather_mode;
1007 implemented = rhs.implemented;
1008 geo_assert(GL_primitive == 0);
1009 geo_assert(nb_elements_per_primitive == 0);
1010 }
1011
1017 for(auto& it : shader_map) {
1018 if(it.second != 0) {
1019 glDeleteProgram(it.second);
1020 it.second = 0;
1021 }
1022 }
1023 if(elements_VBO != 0) {
1024 glDeleteBuffers(1, &elements_VBO);
1025 }
1026 if(VAO != 0) {
1027 glupDeleteVertexArrays(1,&VAO);
1028 VAO = 0;
1029 }
1030 }
1031
1032 bool program_is_initialized(ShaderKey k) const {
1033 return (shader_map.find(k) != shader_map.end());
1034 }
1035
1036 GLuint program(ShaderKey k) const {
1037 auto it = shader_map.find(k);
1038 return ((it == shader_map.end()) ? 0 : it->second);
1039 }
1040
1041 GLenum GL_primitive;
1042 std::map<ShaderKey, GLuint> shader_map;
1043 GLuint VAO;
1044 GLuint elements_VBO;
1045 index_t nb_elements_per_primitive;
1046 index_t* primitive_elements;
1047 bool vertex_gather_mode;
1048 bool implemented;
1049 };
1050
1051 /**********************************************************************/
1052
1059 public:
1068 static const char* uniform_state_declaration();
1069
1074
1078 ~Context() override;
1079
1080
1084 virtual const char* profile_name() const = 0;
1085
1095
1101 virtual void setup();
1102
1110 virtual void bind_uniform_state(GLuint program);
1111
1118 void load_matrix(const GLfloat m[16]) {
1119 copy_vector(matrix_stack_[matrix_mode_].top(), m, 16);
1121 }
1122
1129 void load_matrix(const GLdouble m[16]) {
1130 copy_vector(matrix_stack_[matrix_mode_].top(), m, 16);
1132 }
1133
1139 load_identity_matrix(matrix_stack_[matrix_mode_].top());
1141 }
1142
1150 void mult_matrix(const GLdouble m[16]) {
1151 GLdouble product[16];
1152 mult_matrices(product,m,matrix_stack_[matrix_mode_].top());
1153 load_matrix(product);
1154 }
1155
1162 matrix_stack_[matrix_mode_].push();
1163 }
1164
1168 void pop_matrix() {
1169 matrix_stack_[matrix_mode_].pop();
1171 }
1172
1179 void set_matrix_mode(GLUPmatrix matrix) {
1180 matrix_mode_ = matrix;
1181 }
1182
1188 GLUPmatrix get_matrix_mode() const {
1189 return matrix_mode_;
1190 }
1191
1201 GLfloat x, GLfloat y, GLfloat z=0.0f, GLfloat w=1.0f
1202 ) {
1203 immediate_state_.buffer[GLUP_VERTEX_ATTRIBUTE].set_current(x,y,z,w);
1204 immediate_state_.next_vertex();
1205 if(immediate_state_.buffers_are_full()) {
1207 }
1208 }
1209
1216 GLfloat r, GLfloat g, GLfloat b, GLfloat a = 1.0f
1217 ) {
1218 immediate_state_.buffer[GLUP_COLOR_ATTRIBUTE].set_current(r,g,b,a);
1219 }
1220
1227 GLfloat s, GLfloat t=0.0f, GLfloat u=0.0f, GLfloat v=1.0f
1228 ) {
1229 immediate_state_.buffer[GLUP_TEX_COORD_ATTRIBUTE].set_current(
1230 s,t,u,v
1231 );
1232 }
1233
1239 void immediate_normal(GLfloat x, GLfloat y, GLfloat z) {
1240 immediate_state_.buffer[GLUP_NORMAL_ATTRIBUTE].set_current(
1241 x,y,z,0.0f
1242 );
1243 }
1244
1249 void set_user_program(GLuint program) {
1250 user_program_ = program;
1251 }
1252
1258 virtual void begin(GLUPprimitive primitive);
1259
1264 virtual void end();
1265
1277 virtual void draw_arrays(
1278 GLUPprimitive primitive, GLUPint first, GLUPsizei count
1279 );
1280
1294 virtual void draw_elements(
1295 GLUPprimitive primitive, GLUPsizei count,
1296 GLUPenum type, const GLUPvoid* indices
1297 );
1298
1308
1314 return uniform_state_;
1315 }
1316
1322 return uniform_state_;
1323 }
1324
1331 uniform_buffer_dirty_ = true;
1332 }
1333
1334
1340 uniform_buffer_dirty_ = true;
1341 lighting_dirty_ = true;
1342 }
1343
1349 uniform_buffer_dirty_ = true;
1350 matrices_dirty_ = true;
1351 }
1352
1359 GLUPdouble* get_matrix(GLUPmatrix matrix) {
1360 geo_debug_assert(matrix < 3);
1361 return matrix_stack_[matrix].top();
1362 }
1363
1371 std::vector<GLSL::Source>& sources
1372 );
1373
1381 std::vector<GLSL::Source>& sources
1382 );
1383
1391 std::vector<GLSL::Source>& sources
1392 );
1393
1401 std::vector<GLSL::Source>& sources
1402 );
1403
1411 std::vector<GLSL::Source>& sources
1412 );
1413
1414
1425 std::vector<GLSL::Source>& sources
1426 );
1427
1437 std::vector<GLSL::Source>& sources
1438 );
1439
1449 std::vector<GLSL::Source>& sources
1450 );
1451
1462 GLUPbitfield toggles_state,
1463 GLUPbitfield toggles_undetermined=0
1464 );
1465
1474 GLUPprimitive primitive
1475 );
1476
1482 return immediate_state_;
1483 }
1484
1489
1490 protected:
1491
1500
1510 bool extension_is_supported(const std::string& extension);
1511
1518
1529 virtual void prepare_to_draw(GLUPprimitive primitive);
1530
1531
1539 virtual void done_draw(GLUPprimitive primitive);
1540
1545
1546
1552
1558
1562 virtual void setup_primitives();
1563
1567 virtual void setup_GLUP_POINTS();
1568
1572 virtual void setup_GLUP_LINES();
1573
1577 virtual void setup_GLUP_TRIANGLES();
1578
1582 virtual void setup_GLUP_QUADS();
1583
1588
1592 virtual void setup_GLUP_HEXAHEDRA();
1593
1597 virtual void setup_GLUP_PRISMS();
1598
1602 virtual void setup_GLUP_PYRAMIDS();
1603
1608
1612 virtual void setup_GLUP_SPHERES();
1613
1624 GLUPprimitive glup_primitive, GLenum gl_primitive, GLuint program,
1625 bool bind_attrib_loc_and_link = true
1626 );
1627
1643 GLUPprimitive glup_primitive, GLenum gl_primitive, GLuint program
1644 );
1645
1667 GLUPprimitive glup_primitive, GLenum gl_primitive, GLuint program,
1668 index_t nb_elements_per_glup_primitive,
1669 index_t* element_indices
1670 );
1671
1677 if(uniform_buffer_dirty_) {
1679 }
1680 }
1681
1688
1693 virtual void update_matrices();
1694
1700 virtual void update_lighting();
1701
1706 virtual void update_base_picking_id(GLint new_value);
1707
1713 std::string primitive_declaration(GLUPprimitive prim) const;
1714
1723 PrimitiveInfo::ShaderKey toggles_config
1724 ) {
1725 if(toggles_config == (1 << GLUP_PICKING)) {
1727 (1 << GLUP_PICKING), // picking=true
1728 (1 << GLUP_CLIPPING) // clipping=undecided (use state)
1729 );
1730 } else {
1731 setup_shaders_source_for_toggles(GLUPbitfield(toggles_config));
1732 }
1733 }
1734
1740
1748
1760
1768
1774
1783
1795
1796
1807 index_t result = 0;
1808 for(index_t lv=0; lv<nb_v; ++lv) {
1809 if(v_is_visible_[first_v+lv]) {
1810 result = result | (1u << lv);
1811 }
1812 }
1813 return result;
1814 }
1815
1827 const GLUPfloat* eqn = world_clip_plane_;
1828 const GLUPfloat* p1 = immediate_state_.buffer[0].element_ptr(v1);
1829 const GLUPfloat* p2 = immediate_state_.buffer[0].element_ptr(v2);
1830
1831 GLUPfloat t = -eqn[3] -(
1832 eqn[0]*p1[0] +
1833 eqn[1]*p1[1] +
1834 eqn[2]*p1[2]
1835 );
1836
1837 GLUPfloat d =
1838 eqn[0]*(p2[0]-p1[0]) +
1839 eqn[1]*(p2[1]-p1[1]) +
1840 eqn[2]*(p2[2]-p1[2]) ;
1841
1842 if(fabs(double(d)) < 1e-6) {
1843 t = 0.5f;
1844 } else {
1845 t /= d;
1846 }
1847
1848 GLUPfloat s = 1.0f - t;
1849
1850 isect_vertex_attribute_[0][4*vi+0] = s*p1[0] + t*p2[0];
1851 isect_vertex_attribute_[0][4*vi+1] = s*p1[1] + t*p2[1];
1852 isect_vertex_attribute_[0][4*vi+2] = s*p1[2] + t*p2[2];
1853 isect_vertex_attribute_[0][4*vi+3] = 1.0f;
1854
1855 for(index_t i=1; i<3; ++i) {
1856 if(immediate_state_.buffer[i].is_enabled()) {
1857 const GLUPfloat* a1 =
1858 immediate_state_.buffer[i].element_ptr(v1);
1859 const GLUPfloat* a2 =
1860 immediate_state_.buffer[i].element_ptr(v2);
1861 isect_vertex_attribute_[i][4*vi+0] = s*a1[0] + t*a2[0];
1862 isect_vertex_attribute_[i][4*vi+1] = s*a1[1] + t*a2[1];
1863 isect_vertex_attribute_[i][4*vi+2] = s*a1[2] + t*a2[2];
1864 isect_vertex_attribute_[i][4*vi+3] = s*a1[3] + t*a2[3];
1865 }
1866 }
1867 }
1868
1875
1884 void use_program(GLuint program) {
1885 if(program != 0 && program != latest_program_) {
1886 glUseProgram(program);
1887 latest_program_ = program;
1889 } else {
1890 glUseProgram(program);
1891 }
1892 }
1893
1901
1902 static void initialize();
1903
1904 protected:
1905
1906 // OpenGL Uniform state.
1907 GLuint default_program_;
1908 GLuint uniform_buffer_;
1909 GLuint uniform_binding_point_;
1910 GLint uniform_buffer_size_;
1911 bool uniform_buffer_dirty_;
1912
1913 // C++ Uniform state.
1914 Memory::byte* uniform_buffer_data_;
1915 UniformState uniform_state_;
1916
1917 bool lighting_dirty_;
1918
1919 // Matrix stacks.
1920 GLUPmatrix matrix_mode_;
1921 MatrixStack matrix_stack_[3];
1922 bool matrices_dirty_;
1923
1924 // Immediate mode buffers.
1925 ImmediateState immediate_state_;
1926
1927 // Primitive informations (i.e., how to
1928 // draw a primitive of a given type).
1929 vector<PrimitiveInfo> primitive_info_;
1930
1931 // The marching cells, for computing
1932 // intersections when clipping mode
1933 // is GLUP_CLIP_SLICE_CELLS
1934 MarchingCell marching_tet_;
1935 MarchingCell marching_hex_;
1936 MarchingCell marching_prism_;
1937 MarchingCell marching_pyramid_;
1938 MarchingCell marching_connector_;
1939
1940 GLuint user_program_;
1941
1942 PrimitiveInfo::ShaderKey toggles_config_;
1943
1944 GLUPprimitive primitive_source_;
1945 GLUPbitfield toggles_source_state_;
1946 GLUPbitfield toggles_source_undetermined_;
1947
1948 bool precompile_shaders_;
1949
1950 bool use_core_profile_;
1951 bool use_ES_profile_;
1952
1959
1965 std::map<std::string, GLsizei> variable_to_offset_;
1966
1972 bool v_is_visible_[IMMEDIATE_BUFFER_SIZE];
1973
1979 GLUPfloat isect_vertex_attribute_[3][12*4];
1980
1987
1993 };
1994
1995 /*********************************************************************/
1996}
1997
1998#endif
Utilities for manipulating GLSL shaders.
GLUP: GL Useful Primitives.
void GLUP_API glupDeleteVertexArrays(GLUPsizei n, const GLUPuint *arrays)
Deletes vertex array objects.
GLUPprimitive
Symbolic values corresponding to GLUP primitive types.
Definition GLUP.h:504
void mult_matrix_vector(GLfloat out[4], const GLfloat m[16], const GLfloat v[4])
Computes the product of a 4x4 matrix and a vector.
void load_identity_matrix(GLfloat out[16])
Resets a matrix to the identity matrix.
GLUPattribute
Index of an ImmediateBuffer in the ImmediateState.
index_t nb_vertices_per_primitive[]
Gives the number of vertices for each GLUP primitive.
GLboolean invert_matrix(GLfloat inv[16], const GLfloat m[16])
Computes the inverse of a 4x4 matrix.
void normalize_vector(GLfloat v[3])
Normalizes a vector.
void mult_transpose_matrix_vector(GLfloat out[4], const GLfloat m[16], const GLfloat v[4])
Computes the product of the transpose of a 4x4 matrix and a vector.
void transpose_matrix(GLfloat m[16])
Transposes a matrix in-place.
void copy_vector(GLfloat *to, const GLfloat *from, index_t dim)
Copies a vector of floats.
void show_matrix(const GLfloat m[16])
For debugging, outputs a matrix to the standard error.
void mult_matrices(GLfloat out[16], const GLfloat m1[16], const GLfloat m2[16])
Computes the product of two 4x4 matrices.
void show_vector(const GLfloat v[4])
For debugging, outputs a vector to the standard error.
Implementation of the marching cells algorithms.
#define geo_assert(x)
Verifies that a condition is met.
Definition assert.h:149
#define geo_debug_assert(x)
Verifies that a condition is met.
Definition assert.h:195
A class that can register functions to the GLSL pseudo file system.
Definition GLSL.h:175
Vector with aligned memory allocation.
Definition memory.h:623
GLUP context stores a Uniform Buffer Object with state variables similar to OpenGL's fixed functional...
const MarchingCell & get_marching_cell() const
Gets the MarchingCell that corresponds to the current primitive.
Context()
Context constructor.
void setup_shaders_source_for_toggles_config(PrimitiveInfo::ShaderKey toggles_config)
Sets the string that describes the settings of the toggles for a given configuration.
virtual void get_marching_cells_pseudo_file(std::vector< GLSL::Source > &sources)
Gets the content of the virtual file GLUP/current_profile/marching_cells.h.
virtual void update_matrices()
Updates the matrices in the uniform state from the matrices in the stacks.
virtual void done_draw(GLUPprimitive primitive)
This function is called right after rendering primitives. It is called by end(), draw_arrays() and dr...
virtual void set_primitive_info(GLUPprimitive glup_primitive, GLenum gl_primitive, GLuint program, bool bind_attrib_loc_and_link=true)
Initializes the PrimitiveInfo associated with a given GLUP primitive.
virtual void get_geometry_shader_preamble_pseudo_file(std::vector< GLSL::Source > &sources)
Gets the content of the virtual file GLUP/current_profile/geometry_shader_preamble....
void set_user_program(GLuint program)
Sets the user program, to be used instead of the default GLUP programs for drawing the primitives.
void immediate_color(GLfloat r, GLfloat g, GLfloat b, GLfloat a=1.0f)
Specifies the current color for the immediate mode buffers.
void mult_matrix(const GLdouble m[16])
Post-multiplies the top of the current matrix stack with the specified matrix.
static const char * uniform_state_declaration()
Gets the GLSL declaration of GLUP uniform state.
GLUPdouble * get_matrix(GLUPmatrix matrix)
Gets a pointer to the values of the matrix at the top of a given stack.
UniformState & uniform_state()
Gets the uniform state.
virtual Memory::pointer get_state_variable_address(const char *name)
Gets a pointer to the representation of a uniform state variable in host memory from its (unqualified...
virtual void bind_uniform_state(GLuint program)
Binds GLUP uniform state to a program.
virtual void setup_primitives()
Setups the programs and VAOs used for each primitive.
~Context() override
Context destructor.
virtual void setup_shaders_source_for_primitive(GLUPprimitive primitive)
Sets the configurable GLSL sources for a given primitive type.
void load_matrix(const GLdouble m[16])
Replaces the top of the current matrix stack with the specified matrix.
void setup_shaders_source_for_toggles(GLUPbitfield toggles_state, GLUPbitfield toggles_undetermined=0)
Sets the string that describes the settings of the toggles for a given configuration.
virtual void setup_GLUP_PRISMS()
Setups GLSL programs for prisms.
GLUPfloat * world_clip_plane_
Cached pointer to uniform state variable.
std::string primitive_declaration(GLUPprimitive prim) const
Gets the GLSL declaration of the constant that indicates the current primitive.
void pop_matrix()
Pops the top of the current stack matrix.
void immediate_vertex(GLfloat x, GLfloat y, GLfloat z=0.0f, GLfloat w=1.0f)
Creates a new vertex in the immediate mode buffers.
void create_vertex_id_VBO()
Creates a vertex buffer object with 16 bits integers between 0 and 65535.
virtual void update_lighting()
Updates the lighting in the uniform state.
index_t get_config(index_t first_v, index_t nb_v)
Assemble the configuration code of a primitive relative to the clipping plane.
virtual void setup_GLUP_TETRAHEDRA()
Setups GLSL programs for tetrahedra.
void compute_intersection(index_t v1, index_t v2, index_t vi)
Computes the intersection between the clipping plane and a segment.
void shrink_cells_in_immediate_buffers()
Shrinks the cells in the immediate buffer.
virtual void setup_GLUP_LINES()
Setups GLSL programs for lines.
virtual void setup_state_variables()
Initializes the representation of the uniform state.
std::map< std::string, GLsizei > variable_to_offset_
Used by GPU-side uniform buffer.
virtual void prepare_to_draw(GLUPprimitive primitive)
This function is called before starting to render primitives. It is called by begin(),...
void flag_uniform_buffer_as_dirty()
Indicates that the OpenGL representation of the uniform state is no longer in sync with the local cop...
virtual void begin(GLUPprimitive primitive)
Begins rendering in immediate mode.
GLUPmatrix get_matrix_mode() const
Gets the current matrix stack.
GLUPfloat isect_vertex_attribute_[3][12 *4]
computed intersections.
bool extension_is_supported(const std::string &extension)
Tests whether an OpenGL extension is supported.
void classify_vertices_in_immediate_buffers()
Updates v_is_visible_[] according to current clipping plane.
GLuint latest_program_
Latest used GLSL program.
virtual void flush_immediate_buffers()
Flushes the immediate mode buffers.
virtual void stream_immediate_buffers()
Sends all the active immediate buffers to the GPU.
virtual void draw_elements(GLUPprimitive primitive, GLUPsizei count, GLUPenum type, const GLUPvoid *indices)
Draws primitives using current OpenGL array bindings.
void use_program(GLuint program)
A wrapper around glUseProgram that tests whether uniform state needs to be sent to the program.
virtual void set_primitive_info_vertex_gather_mode(GLUPprimitive glup_primitive, GLenum gl_primitive, GLuint program)
Initializes the PrimitiveInfo associated with a given GLUP primitive in vertex-gather mode.
GLuint vertex_id_VBO_
A vertex buffer object with 65536 16 bits integers.
virtual void get_tess_control_shader_preamble_pseudo_file(std::vector< GLSL::Source > &sources)
Gets the content of the virtual file GLUP/current_profile/tess_control_shader_preamble....
virtual void set_primitive_info_immediate_index_mode(GLUPprimitive glup_primitive, GLenum gl_primitive, GLuint program, index_t nb_elements_per_glup_primitive, index_t *element_indices)
Initializes the PrimitiveInfo associated with a given GLUP primitive in immediate mode when an elemen...
void immediate_normal(GLfloat x, GLfloat y, GLfloat z)
Specifies the current normal vector for the immediate mode buffers.
virtual void setup_GLUP_PYRAMIDS()
Setups GLSL programs for pyramids.
virtual void setup_GLUP_SPHERES()
Setups GLSL programs for spheres.
virtual void get_primitive_pseudo_file(std::vector< GLSL::Source > &sources)
Gets the content of the virtual file GLUP/current_profile/primitive.h.
virtual void setup_GLUP_CONNECTORS()
Setups GLSL programs for connectors.
virtual void setup_GLUP_HEXAHEDRA()
Setups GLSL programs for hexahedra.
virtual void get_fragment_shader_preamble_pseudo_file(std::vector< GLSL::Source > &sources)
Gets the content of the virtual file GLUP/current_profile/fragment_shader_preamble....
bool cell_is_clipped(index_t first_v)
Tests whether the cell starting at a given vertex in the immediate buffer is clipped,...
virtual void do_update_uniform_buffer()
Copies GLUP uniform state to OpenGL.
void set_matrix_mode(GLUPmatrix matrix)
Sets the current matrix stack.
ImmediateState & immediate_state()
Gets the immediate state.
virtual void get_vertex_shader_preamble_pseudo_file(std::vector< GLSL::Source > &sources)
Gets the content of the virtual file GLUP/current_profile/vertex_shader_preamble.h.
void load_matrix(const GLfloat m[16])
Replaces the top of the current matrix stack with the specified matrix.
void update_toggles_config()
Updates the toggles_config_ state variable from the individual state of each toggle.
virtual void setup_GLUP_TRIANGLES()
Setups GLSL programs for triangles.
virtual void get_tess_evaluation_shader_preamble_pseudo_file(std::vector< GLSL::Source > &sources)
Gets the content of the virtual file GLUP/current_profile/tess_evaluation_shader_preamble....
virtual void setup_GLUP_QUADS()
Setups GLSL programs for quads.
const char * glup_primitive_name(GLUPprimitive prim)
Gets the name of a primitive by GLUPprimitive.
virtual bool primitive_supports_array_mode(GLUPprimitive prim) const
Tests whether a given GLUP primitive supports array mode.
virtual void setup()
Creates the uniform state and GLSL programs.
void immediate_tex_coord(GLfloat s, GLfloat t=0.0f, GLfloat u=0.0f, GLfloat v=1.0f)
Specifies the current texture coordinates for the immediate mode buffers.
void flag_matrices_as_dirty()
Indicates that cached matrix information needs to be recomputed.
virtual void setup_immediate_buffers()
Set-ups the buffers for immediate rendering.
virtual void end()
Ends rendering in immediate mode.
void bind_immediate_state_buffers_to_VAO()
Binds the VBOs associated with the immediate state buffers to the currently bound VAO.
void load_identity()
Replaces the top of the current matrix stack with the identity matrix.
virtual const char * profile_name() const =0
Gets the profile name associated with this context.
void push_matrix()
Pushes a copy of the top of the current stack matrix onto the current stack matrix.
virtual void update_base_picking_id(GLint new_value)
Updates the base picking id and sends it to OpenGL.
void update_uniform_buffer()
Copies GLUP uniform state to OpenGL if required.
void create_CPU_side_uniform_buffer()
Creates a buffer for uniform variables for implementations that do not support uniform buffer objects...
virtual void get_toggles_pseudo_file(std::vector< GLSL::Source > &sources)
Gets the content of the virtual file GLUP/current_profile/toggles.h.
const UniformState & uniform_state() const
Gets the uniform state.
void create_program_if_needed(GLUPprimitive primitive)
Creates the GLSL shader that corresponds to the specified primitive and current toggles configuration...
virtual void copy_uniform_state_to_current_program()
Copies the uniform state from client-side memory into the currently bound program,...
virtual void setup_GLUP_POINTS()
Setups GLSL programs for points.
void flag_lighting_as_dirty()
Indicates that cached lighting information needs to be recomputed.
virtual void draw_arrays(GLUPprimitive primitive, GLUPint first, GLUPsizei count)
Draws primitives using current OpenGL array bindings.
bool v_is_visible_[IMMEDIATE_BUFFER_SIZE]
Indicates for a given vertex whether it is clipped or is visible, according to the current clipping p...
A GLUP state variable that contains an array of floating points. This concerns both vectors and matri...
const GLUPfloat * get_pointer() const
Gets a pointer to the variable.
FloatsArrayStateVariable()
FloatsArrayStateVariable default constructor.
FloatsArrayStateVariable(Context *context, const char *name)
FloatsArrayStateVariable constructor.
GLUPfloat * get_pointer()
Gets a modifiable pointer to the variable.
A buffer used by GLUP in immediate mode.
GLuint & VBO()
Gets the Vertex Buffer Object.
bool is_enabled() const
Tests whether this ImmediateBuffer is enabled.
GLfloat * data()
Gets a pointer to the data.
GLfloat * element_ptr(index_t v)
Gets a pointer to one attribute value by index.
void set_current(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
Sets the current attribute value.
size_t size_in_bytes() const
Gets the size of the memory used by the buffer.
void enable()
Enables this ImmediateBuffer.
index_t dimension() const
Gets the dimension of the attribute.
ImmediateBuffer(const ImmediateBuffer &rhs)
ImmediateBuffer copy constructor.
void copy(index_t to, index_t from)
Copies this attribute from a vertex to another one.
void copy_current_to(index_t v)
Copies the current attribute value to a specified vertex in this buffer.
void disable()
Disables this ImmediateBuffer.
Stores all the buffers used to implement the immediate-mode interface.
GLUPprimitive primitive() const
Gets the primitive currently rendered, i.e. the argument to the latest invocation of begin()
void set_current_vertex(index_t v)
Sets the current vertex.
void begin(GLUPprimitive primitive)
Configures the immediate state for rendering primitives of a given type.
void reset()
Resets the current vertex index to zero.
GLuint & VAO()
Gets the Vertex Array Object.
void copy_element(index_t to, index_t from)
Copies an element, i.e. all the attributes attached to a vertex.
index_t nb_primitives() const
Gets the number of primitives stored in the buffers.
index_t max_current_vertex() const
Gets the maximum number of vertices in the buffer before the buffer is flushed.
index_t nb_vertices() const
Gets the number of vertices stored in the buffers.
~ImmediateState()
ImmediateState destructor.
ImmediateState()
ImmediateState constructor.
void next_vertex()
Advances to the next vertex.
bool buffers_are_full()
Tests whether the buffers are full.
Implements the MarchingCells algorithm.
A Matrix stack.
void push()
Pushes a copy of the top matrix.
MatrixStack()
MatrixStack constructor.
void pop()
Removes a matrix from the top of the stack.
GLdouble * top()
Gets the matrix on the top of the stack.
static const int MAX_DEPTH
Maximum number of matrices in a stack.
Base class for representing GLUP state variables.
void flag_uniform_buffer_as_dirty()
Indicates that the variables in the context need to be sent to OpenGL.
StateVariableBase()
StateVariableBase default constructor.
Memory::pointer address() const
Gets the address of the StateVariableBase.
StateVariableBase(Context *context, const char *name)
StateVariableBase constructor.
const std::string & name() const
Gets the name of this StateVariableBase.
void initialize(Context *context, const char *name)
Initializes a StateVariableBase.
A GLUP state variable of a given type.
void initialize(Context *context, const char *name, T value)
Initializes a StateVariable.
StateVariable(Context *context, const char *name, T value)
StateVariableBase constructor.
void set(T val)
Sets the value.
T get() const
Gets the value.
StateVariable()
StateVariable default constructor.
A GLUP state variable that contains a vector.
VectorStateVariable(Context *context, const char *name, index_t dimension)
VectorStateVariable constructor.
void get(GLUPfloat *x) const
Gets the value.
index_t dimension() const
Gets the dimension.
void set(const GLUPfloat *x)
Sets the value.
VectorStateVariable()
VectorStateVariable default constructor.
void initialize(Context *context, const char *name, index_t dimension)
Initializes a VectorStateVariable.
void clear()
clears the vector to its default value.
Common include file, providing basic definitions. Should be included before anything else by all head...
unsigned char byte
Unsigned byte type.
Definition memory.h:80
byte * pointer
Pointer to unsigned byte(s)
Definition memory.h:92
void clear(void *addr, size_t size)
Clears a memory block.
Definition memory.h:104
void copy(void *to, const void *from, size_t size)
Copies a memory block.
Definition memory.h:117
uint64_t uint64
Definition numeric.h:99
Global Vorpaline namespace.
Definition algorithm.h:64
geo_index_t index_t
The type for storing and manipulating indices.
Definition numeric.h:287
Stores the programs and vertex array object used to display a primitive of a given type.
~PrimitiveInfo()
PrimitiveInfo destructor.
PrimitiveInfo()
PrimitiveInfo constructor.
PrimitiveInfo(const PrimitiveInfo &rhs)
PrimitiveInfo copy constructor.
The set of state variables that represent GLUP uniform state.