glVertex  5.5.2
glvertex_core.h
Go to the documentation of this file.
1 // (c) by Stefan Roettger, licensed under MIT license
2 // glVertex core header-only library
3 
6 #ifndef GLVERTEX_CORE_H
7 #define GLVERTEX_CORE_H
8 
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 
13 #include <vector>
14 #include <string>
15 #include <sstream>
16 #include <map>
17 
18 #include "glslmath.h"
19 #include "glvertex_gl.h"
20 #include "glvertex_io.h"
21 #include "glvertex_string.h"
22 
25 {
26  LGL_NVIDIA = 1,
27  LGL_ATI,
28  LGL_INTEL,
29  LGL_UNKNOWN
30 };
31 
34 {
35  LGL_NONE = 0,
36  LGL_LINES,
37  LGL_LINE_STRIP,
38  LGL_TRIANGLES,
39  LGL_TRIANGLE_STRIP,
40  LGL_TRIANGLE_FAN,
41  LGL_QUADS,
42  LGL_QUAD_STRIP
43 };
44 
47 {
48  LGL_PROJECTION = 1,
49  LGL_MODELVIEW,
50  LGL_PREMODEL,
51  LGL_TEXTURE,
52  LGL_PRETEX
53 };
54 
57 {
58  LGL_TEXGEN_NONE = 0,
59  LGL_TEXGEN_LINEAR,
60  LGL_TEXGEN_NORMAL,
61  LGL_TEXGEN_HEMISPHERE,
62  LGL_TEXGEN_HEDGEHOG,
63  LGL_TEXGEN_NORMAL_HEMISPHERE,
64  LGL_TEXGEN_NORMAL_HEDGEHOG,
65  LGL_TEXGEN_MIXED_HEMISPHERE,
66  LGL_TEXGEN_MIXED_HEDGEHOG
67 };
68 
71 {
72  LGL_BLEND_NONE = 0,
73  LGL_BLEND_MULT,
74  LGL_BLEND_ALPHA,
75  LGL_BLEND_ADD,
76  LGL_BLEND_SUB,
77  LGL_BLEND_MAX,
78  LGL_BLEND_MIN
79 };
80 
83 {
84  LGL_FILL = 1,
85  LGL_LINE,
86  LGL_BARYCENTRIC
87 };
88 
91 {
92  LGL_INTERLACE_NONE = 0,
93  LGL_INTERLACE_HORIZONTAL_LEFT,
94  LGL_INTERLACE_HORIZONTAL_RIGHT,
95  LGL_INTERLACE_VERTICAL_TOP,
96  LGL_INTERLACE_VERTICAL_BOTTOM,
97 };
98 
101 {
102  LGL_VERBOSITY_NONE = 0,
103  LGL_VERBOSITY_MESSAGES = 1,
104  LGL_VERBOSITY_ERRORS = 2,
105  LGL_VERBOSITY_WARNINGS = 3
106 };
107 
108 #define LGL_NUM_BUFFERS 6
109 
110 #ifndef LGL_NUM_ATTRIBUTES
111 # define LGL_NUM_ATTRIBUTES 4
112 #endif
113 
114 #define LGL_VERTEX_BUFFER 0
115 #define LGL_COLOR_BUFFER 1
116 #define LGL_NORMAL_BUFFER 2
117 #define LGL_TEXCOORD_BUFFER 3
118 #define LGL_BARYCENTRIC_BUFFER 4
119 #define LGL_ATTRIBUTE_BUFFER 5
120 
121 #define LGL_VERTEX_LOCATION 0
122 #define LGL_COLOR_LOCATION 1
123 #define LGL_NORMAL_LOCATION 2
124 #define LGL_TEXCOORD_LOCATION 3
125 #define LGL_BARYCENTRIC_LOCATION 4
126 #define LGL_ATTRIBUTE_LOCATION 5
127 
128 #define LGL_NUM_SHADERS 12
129 
130 #ifndef LGL_CORE
131 # define LGL_NUM_CLIPPLANES 6
132 #else
133 # define LGL_NUM_CLIPPLANES 8
134 #endif
135 
136 #include "glvertex_shaders.h"
137 
155 template <class VEC4, const GLenum gl_type>
156 class lgl
157 {
158 public:
159 
161  lgl(const std::string &name = "",
162  bool immediate = false,
163  bool storagetype = true)
164  : name_(name),
165  immediate_(immediate),
166  storagetype_(storagetype),
167  vertex_(0), copied_(false), copy_(false),
168  color_(1), normal_(0), texcoord_(0),
169  hascolor_(false), hasnormal_(false), hastexcoord_(false)
170  {
171  initialize();
172 
173  if (instances_ == 0)
174  initializeStatic();
175 
176  instances_++;
177  }
178 
179  virtual ~lgl()
180  {
181  finalize();
182 
183  if (initGL_)
184  finalizeOpenGL();
185 
186  instances_--;
187 
188  if (instances_ == 0)
189  {
190  finalizeStatic();
191 
192  if (initStaticGL_)
193  {
194  finalizeStaticOpenGL();
195 
196  // call exit-gl hook
197  exit_gl_hook();
198  }
199  }
200  }
201 
203  std::string getName() const
204  {
205  return(name_);
206  }
207 
209  void setName(std::string name = "")
210  {
211  name_ = name;
212  }
213 
214 private:
215 
216  lgl(const lgl &copy) {} // copy ctor unavailable by design
217  lgl& operator = (const lgl &copy) {} // assignment operator unavailable by design
218 
219  union lgl_uniform_union
220  {
221  int int_value;
222  float float_value;
223  float vec2f_value[2];
224  float vec3f_value[3];
225  float vec4f_value[4];
226  float mat2f_value[4];
227  float mat3f_value[9];
228  float mat4f_value[16];
229  };
230 
231  enum lgl_uniform_enum
232  {
233  lgl_no_type,
234  lgl_int_type,
235  lgl_float_type,
236  lgl_vec2f_type,
237  lgl_vec3f_type,
238  lgl_vec4f_type,
239  lgl_mat2f_type,
240  lgl_mat3f_type,
241  lgl_mat4f_type
242  };
243 
244  struct lgl_uniform_struct
245  {
246  GLint loc;
247  std::string uniform;
248  lgl_uniform_enum type;
249  lgl_uniform_union value;
250  bool warn;
251  };
252 
253  typedef std::map<std::string, unsigned int> lgl_uniform_map_type;
254  typedef std::vector<lgl_uniform_struct> lgl_uniform_location_type;
255 
256 public:
257 
258  void lglVertex(const vec4 &v)
259  {
260  if (!started_)
261  {
262  lglError("invalid vertex specification");
263  return;
264  }
265 
266  if (!immediate_ && rendered_)
267  {
268  lglError("invalid vbo modification");
269  return;
270  }
271 
272  if (premodel_matrix_identity_.back())
273  {
274  if (copy_)
275  {
276  lglPlainVertex(v);
277  if (primitive_ == LGL_QUAD_STRIP) lglPlainVertex(v);
278  copy_ = false;
279  }
280 
281  lglPlainVertex(v, color_, texcoord_, normal_);
282  }
283  else
284  {
285  if (!hasnormal_)
286  {
287  vec4 p = premodel_matrix_.back() * v;
288 
289  if (copy_)
290  {
291  lglPlainVertex(p);
292  if (primitive_ == LGL_QUAD_STRIP) lglPlainVertex(p);
293  copy_ = false;
294  }
295 
296  lglPlainVertex(p, color_, texcoord_);
297  }
298  else
299  {
300  if (premodel_matrix_recompute_.back())
301  {
302  premodel_matrix_it_.back() = mat3(premodel_matrix_.back().invert().transpose());
303  premodel_matrix_recompute_.back() = false;
304  }
305 
306  vec4 p = premodel_matrix_.back() * v;
307  vec3 n = premodel_matrix_it_.back() * normal_;
308 
309  if (copy_)
310  {
311  lglPlainVertex(p);
312  if (primitive_ == LGL_QUAD_STRIP) lglPlainVertex(p);
313  copy_ = false;
314  }
315 
316  lglPlainVertex(p, color_, texcoord_, n);
317  }
318  }
319 
320  if (rearrange_)
321  rearrangeQuads();
322 
323  copied_ = false;
324  }
325 
326 protected:
327 
328  void lglPlainVertex(const vec4 &v,
329  const vec4f &c = vec4f(1),
330  const vec4f &t = vec4f(0),
331  const vec3f &n = vec3f(0))
332  {
333  vertex_ = v;
334 
335  if (!enlarge()) return;
336 
337  if (storagetype_) vertices_[size_] = v;
338  else verticesf_[size_] = v;
339 
340  colors_[size_] = c;
341  normals_[size_] = n;
342 
343  if (texgen_ != LGL_TEXGEN_NONE)
344  {
345  vec4 texcoord = texgen(v, n);
346  if (!pretex_matrix_identity_.back()) texcoord = pretex_matrix_.back() * texcoord;
347  texcoords_[size_] = texcoord;
348  hastexcoord_ = true;
349  }
350  else
351  {
352  vec4 texcoord = t;
353  if (!pretex_matrix_identity_.back()) texcoord = pretex_matrix_.back() * texcoord;
354  texcoords_[size_] = texcoord;
355  }
356 
357  if (hasattributes_)
358  for (unsigned int i=0; i<LGL_NUM_ATTRIBUTES; i++)
359  if (hasattribute_[i])
360  attributes_[size_*LGL_NUM_ATTRIBUTES+i] = attribute_[i];
361 
362  switch (primitive_)
363  {
364  case LGL_LINES:
365  case LGL_LINE_STRIP:
366  if (size_%2 == 0) barycentrics_[size_] = vec3f(1,0,1);
367  else barycentrics_[size_] = vec3f(0,1,1);
368  break;
369  case LGL_TRIANGLE_FAN:
370  if (size_ == 0) barycentrics_[size_] = vec3f(1,0,0);
371  else
372  if (size_%2 == 1) barycentrics_[size_] = vec3f(0,1,0);
373  else barycentrics_[size_] = vec3f(0,0,1);
374  break;
375  case LGL_QUADS:
376  switch (size_%4)
377  {
378  case 0: barycentrics_[size_] = vec3f(0,0,0.25); break;
379  case 1: barycentrics_[size_] = vec3f(1,0,0.25); break;
380  case 2: barycentrics_[size_] = vec3f(1,1,0.75); break;
381  case 3: barycentrics_[size_] = vec3f(0,1,0.75); break;
382  }
383  break;
384  case LGL_QUAD_STRIP:
385  switch (size_%4)
386  {
387  case 0: barycentrics_[size_] = vec3f(0,0,0.25); break;
388  case 1: barycentrics_[size_] = vec3f(1,0,0.25); break;
389  case 2: barycentrics_[size_] = vec3f(0,1,0.75); break;
390  case 3: barycentrics_[size_] = vec3f(1,1,0.75); break;
391  }
392  break;
393  case LGL_TRIANGLE_STRIP:
394  case LGL_TRIANGLES:
395  default:
396  switch (size_%3)
397  {
398  case 0: barycentrics_[size_] = vec3f(1,0,0); break;
399  case 1: barycentrics_[size_] = vec3f(0,1,0); break;
400  case 2: barycentrics_[size_] = vec3f(0,0,1); break;
401  }
402  break;
403  }
404 
405  vec3 v3 = v;
406 
407  if (size_ == 0)
408  {
409  bboxmin_ = bboxmax_ = v3;
410  }
411  else
412  {
413  if (v3.x < bboxmin_.x) bboxmin_.x = v3.x;
414  else if (v3.x > bboxmax_.x) bboxmax_.x = v3.x;
415  if (v3.y < bboxmin_.y) bboxmin_.y = v3.y;
416  else if (v3.y > bboxmax_.y) bboxmax_.y = v3.y;
417  if (v3.z < bboxmin_.z) bboxmin_.z = v3.z;
418  else if (v3.z > bboxmax_.z) bboxmax_.z = v3.z;
419  }
420 
421  size_++;
422  modified_ = true;
423  }
424 
425  vec4 texgen(const vec4 &v, const vec3f &n)
426  {
427  vec4 texcoord = v;
428 
429  switch (texgen_)
430  {
431  default:
432  break;
433  case LGL_TEXGEN_NORMAL:
434  texcoord = normalize(n);
435  break;
436  case LGL_TEXGEN_HEMISPHERE:
437  {
438  double x = texcoord.x;
439  double y = texcoord.y;
440  double z = texcoord.z;
441  double alpha = atan2(z, x);
442  double beta = atan2(sqrt(x*x+z*z), fabs(y));
443  double r = beta / PI;
444  r = (2*r + r*r)/3;
445  texcoord.x = r * cos(alpha) + 0.5;
446  texcoord.y = r * sin(alpha) + 0.5;
447  texcoord.z = 0;
448  break;
449  }
450  case LGL_TEXGEN_HEDGEHOG:
451  {
452  double x = texcoord.x;
453  double y = texcoord.y;
454  double z = texcoord.z;
455  double alpha = atan2(z, x);
456  double beta = atan2(sqrt(x*x+z*z), y);
457  double r = 0.5 * beta / PI;
458  r = (r < 0.5)? 2*(r + r*r)/3 : 2*r - (1 + 2*r*r)/3;
459  texcoord.x = r * cos(alpha) + 0.5;
460  texcoord.y = r * sin(alpha) + 0.5;
461  texcoord.z = 0;
462  break;
463  }
464  case LGL_TEXGEN_NORMAL_HEMISPHERE:
465  {
466  texcoord = normalize(n);
467  double x = texcoord.x;
468  double y = texcoord.y;
469  double z = texcoord.z;
470  double alpha = atan2(z, x);
471  double beta = atan2(sqrt(x*x+z*z), fabs(y));
472  double r = beta / PI;
473  r = (2*r + r*r)/3;
474  texcoord.x = r * cos(alpha) + 0.5;
475  texcoord.y = r * sin(alpha) + 0.5;
476  texcoord.z = 0;
477  break;
478  }
479  case LGL_TEXGEN_NORMAL_HEDGEHOG:
480  {
481  texcoord = normalize(n);
482  double x = texcoord.x;
483  double y = texcoord.y;
484  double z = texcoord.z;
485  double alpha = atan2(z, x);
486  double beta = atan2(sqrt(x*x+z*z), y);
487  double r = 0.5 * beta / PI;
488  r = (r < 0.5)? 2*(r + r*r)/3 : 2*r - (1 + 2*r*r)/3;
489  texcoord.x = r * cos(alpha) + 0.5;
490  texcoord.y = r * sin(alpha) + 0.5;
491  texcoord.z = 0;
492  break;
493  }
494  case LGL_TEXGEN_MIXED_HEMISPHERE:
495  {
496  double x = texcoord.x;
497  double y = texcoord.y;
498  double z = texcoord.z;
499  double alpha = atan2(z, x);
500  double beta = atan2(sqrt(x*x+z*z), fabs(y));
501  double r = beta / PI;
502  r = (2*r + r*r)/3;
503  texcoord.x = r * cos(alpha) + 0.5;
504  texcoord.y = r * sin(alpha) + 0.5;
505  texcoord.z = 0;
506  vec4 t = normalize(n);
507  x = t.x;
508  y = t.y;
509  z = t.z;
510  alpha = atan2(z, x);
511  beta = atan2(sqrt(x*x+z*z), fabs(y));
512  r = beta / PI;
513  r = (2*r + r*r)/3;
514  r *= texgen_mix_;
515  texcoord.x += r * cos(alpha);
516  texcoord.y += r * sin(alpha);
517  break;
518  }
519  case LGL_TEXGEN_MIXED_HEDGEHOG:
520  {
521  double x = texcoord.x;
522  double y = texcoord.y;
523  double z = texcoord.z;
524  double alpha = atan2(z, x);
525  double beta = atan2(sqrt(x*x+z*z), y);
526  double r = 0.5 * beta / PI;
527  r = (r < 0.5)? 2*(r + r*r)/3 : 2*r - (1 + 2*r*r)/3;
528  texcoord.x = r * cos(alpha) + 0.5;
529  texcoord.y = r * sin(alpha) + 0.5;
530  texcoord.z = 0;
531  vec4 t = normalize(n);
532  x = t.x;
533  y = t.y;
534  z = t.z;
535  alpha = atan2(z, x);
536  beta = atan2(sqrt(x*x+z*z), y);
537  r = 0.5 * beta / PI;
538  r = (r < 0.5)? 2*(r + r*r)/3 : 2*r - (1 + 2*r*r)/3;
539  r *= texgen_mix_;
540  texcoord.x += r * cos(alpha);
541  texcoord.y += r * sin(alpha);
542  break;
543  }
544  }
545 
546  return(texcoord);
547  }
548 
549  bool enlarge()
550  {
551  if (maxsize_ == 0)
552  {
553  maxsize_ = 1024;
554 
555  if (storagetype_)
556  {
557  void *vbuffer = malloc(maxsize_*sizeof(VEC4));
558  if ((vertices_=(VEC4 *)vbuffer) == NULL) return(false);
559  }
560  else
561  {
562  void *vbuffer = malloc(maxsize_*sizeof(vec4f));
563  if ((verticesf_=(vec4f *)vbuffer) == NULL) return(false);
564  }
565 
566  void *cbuffer = malloc(maxsize_*sizeof(vec4f));
567  if ((colors_=(vec4f *)cbuffer) == NULL) return(false);
568 
569  void *nbuffer = malloc(maxsize_*sizeof(vec3f));
570  if ((normals_=(vec3f *)nbuffer) == NULL) return(false);
571 
572  void *tbuffer = malloc(maxsize_*sizeof(vec4f));
573  if ((texcoords_=(vec4f *)tbuffer) == NULL) return(false);
574 
575  void *bbuffer = malloc(maxsize_*sizeof(vec3f));
576  if ((barycentrics_=(vec3f *)bbuffer) == NULL) return(false);
577 
578  void *abuffer = malloc(maxsize_*LGL_NUM_ATTRIBUTES*sizeof(vec4f));
579  if ((attributes_=(vec4f *)abuffer) == NULL) return(false);
580  }
581  else if (size_ >= maxsize_)
582  {
583  if (storagetype_)
584  {
585  void *vbuffer = realloc((void *)vertices_, 2*maxsize_*sizeof(VEC4));
586  if ((vertices_=(VEC4 *)vbuffer) == NULL) return(false);
587  }
588  else
589  {
590  void *vbuffer = realloc((void *)verticesf_, 2*maxsize_*sizeof(vec4f));
591  if ((verticesf_=(vec4f *)vbuffer) == NULL) return(false);
592  }
593 
594  void *cbuffer = realloc((void *)colors_, 2*maxsize_*sizeof(vec4f));
595  if ((colors_=(vec4f *)cbuffer) == NULL) return(false);
596 
597  void *nbuffer = realloc((void *)normals_, 2*maxsize_*sizeof(vec3f));
598  if ((normals_=(vec3f *)nbuffer) == NULL) return(false);
599 
600  void *tbuffer = realloc((void *)texcoords_, 2*maxsize_*sizeof(vec4f));
601  if ((texcoords_=(vec4f *)tbuffer) == NULL) return(false);
602 
603  void *bbuffer = realloc((void *)barycentrics_, 2*maxsize_*sizeof(vec3f));
604  if ((barycentrics_=(vec3f *)bbuffer) == NULL) return(false);
605 
606  void *abuffer = realloc((void *)attributes_, 2*maxsize_*LGL_NUM_ATTRIBUTES*sizeof(vec4f));
607  if ((attributes_=(vec4f *)abuffer) == NULL) return(false);
608 
609  maxsize_ *= 2;
610  }
611 
612  return(true);
613  }
614 
615  void shrink()
616  {
617  if (maxsize_ != size_)
618  {
619  maxsize_ = size_;
620 
621  if (maxsize_ == 0)
622  {
623  if (storagetype_)
624  {
625  free(vertices_);
626  vertices_ = NULL;
627  }
628  else
629  {
630  free(verticesf_);
631  verticesf_ = NULL;
632  }
633  }
634  else
635  {
636  if (storagetype_)
637  {
638  void *vbuffer = realloc((void *)vertices_, maxsize_*sizeof(VEC4));
639  vertices_ = (VEC4 *)vbuffer;
640  }
641  else
642  {
643  void *vbuffer = realloc((void *)verticesf_, maxsize_*sizeof(vec4f));
644  verticesf_ = (vec4f *)vbuffer;
645  }
646  }
647 
648  if (maxsize_ == 0 || !hascolor_)
649  {
650  free(colors_);
651  colors_ = NULL;
652  }
653  else
654  {
655  void *cbuffer = realloc((void *)colors_, maxsize_*sizeof(vec4f));
656  colors_ = (vec4f *)cbuffer;
657  }
658 
659  if (maxsize_ == 0 || !hasnormal_)
660  {
661  free(normals_);
662  normals_ = NULL;
663  }
664  else
665  {
666  void *nbuffer = realloc((void *)normals_, maxsize_*sizeof(vec3f));
667  normals_ = (vec3f *)nbuffer;
668  }
669 
670  if (maxsize_ == 0 || !hastexcoord_)
671  {
672  free(texcoords_);
673  texcoords_ = NULL;
674  }
675  else
676  {
677  void *tbuffer = realloc((void *)texcoords_, maxsize_*sizeof(vec4f));
678  texcoords_ = (vec4f *)tbuffer;
679  }
680 
681  if (maxsize_ == 0)
682  {
683  free(barycentrics_);
684  barycentrics_ = NULL;
685  }
686  else
687  {
688  void *bbuffer = realloc((void *)barycentrics_, maxsize_*sizeof(vec3f));
689  barycentrics_ = (vec3f *)bbuffer;
690  }
691 
692  if (maxsize_ == 0 || !hasattributes_)
693  {
694  free(attributes_);
695  attributes_ = NULL;
696  }
697  else
698  {
699  void *abuffer = realloc((void *)attributes_, maxsize_*LGL_NUM_ATTRIBUTES*sizeof(vec4f));
700  attributes_ = (vec4f *)abuffer;
701  }
702  }
703  }
704 
705 public:
706 
708  void reset()
709  {
710  size_ = 0;
711  hascolor_ = hasnormal_ = hastexcoord_ = false;
712 
713  if (hasattributes_)
714  {
715  for (unsigned int i=0; i<LGL_NUM_ATTRIBUTES; i++)
716  hasattribute_[i] = false;
717 
718  hasattributes_ = false;
719  }
720 
721  copied_ = false;
722  copy_ = false;
723 
724  bboxmin_ = bboxmax_ = vec3(NAN);
725 
726  started_ = false;
727  rearrange_ = false;
728 
729  modified_ = false;
730  rendered_ = false;
731  applied_ = false;
732 
733  primitives_ = 0;
734  }
735 
737  void clear()
738  {
739  reset();
740  shrink();
741  }
742 
743 protected:
744 
745  void copyVertex(int index1, int index2)
746  {
747  if (storagetype_) vertices_[index2] = vertices_[index1];
748  else verticesf_[index2] = verticesf_[index1];
749 
750  colors_[index2] = colors_[index1];
751  normals_[index2] = normals_[index1];
752  texcoords_[index2] = texcoords_[index1];
753  barycentrics_[index2] = barycentrics_[index1];
754 
755  if (hasattributes_)
756  for (unsigned int i=0; i<LGL_NUM_ATTRIBUTES; i++)
757  if (hasattribute_[i])
758  attributes_[index2*LGL_NUM_ATTRIBUTES+i] = attributes_[index1*LGL_NUM_ATTRIBUTES+i];
759  }
760 
761  void duplicateVertex(int index)
762  {
763  if (enlarge())
764  {
765  copyVertex(index, size_);
766  size_++;
767  }
768  }
769 
770  void swapVertex(int index1, int index2)
771  {
772  if (enlarge())
773  {
774  copyVertex(index1, size_);
775  copyVertex(index2, index1);
776  copyVertex(size_, index2);
777  }
778  }
779 
780  void rearrangeQuads()
781  {
782  if (size_ == 4)
783  {
784  swapVertex(size_-1, size_-2);
785 
786  barycentrics_[size_-4] = vec3f(1,0,0);
787  barycentrics_[size_-3] = vec3f(0,1,0);
788  barycentrics_[size_-2] = vec3f(0,0,1);
789  barycentrics_[size_-1] = vec3f(1,0,0);
790  }
791  else if (size_ > 4)
792  {
793  if ((size_-4)%6 == 1)
794  {
795  duplicateVertex(size_-2);
796  swapVertex(size_-2, size_-1);
797  size_++;
798  }
799 
800  if ((size_-4)%6 == 0)
801  {
802  swapVertex(size_-1, size_-2);
803 
804  barycentrics_[size_-4] = vec3f(1,0,0);
805  barycentrics_[size_-3] = vec3f(0,1,0);
806  barycentrics_[size_-2] = vec3f(0,0,1);
807  barycentrics_[size_-1] = vec3f(1,0,0);
808  }
809  }
810  }
811 
812 public:
813 
815  void lglVertex(double x, double y, double z, double w = 1)
816  {
817  lglVertex(vec4(x,y,z,w));
818  }
819 
820  void lglColor(const vec4f &c)
821  {
822  if (disable_coloring_)
823  return;
824 
825  if (immediate_)
826  actual_ = color_ = c;
827  else
828  if (started_)
829  color_ = c;
830  else
831  actual_ = c;
832 
833  if (started_)
834  hascolor_ = true;
835  }
836 
838  void lglColor(float r, float g, float b, float a = 1)
839  {
840  lglColor(vec4f(r,g,b,a));
841  }
842 
845  {
846  if (started_)
847  return(color_);
848  else
849  return(actual_);
850  }
851 
852  void lglNormal(const vec3f &n)
853  {
854  if (disable_lighting_)
855  return;
856 
857  if (!started_)
858  lglError("invalid normal specification");
859  else
860  {
861  normal_ = n;
862  hasnormal_ = true;
863  }
864  }
865 
867  void lglNormal(float x, float y, float z)
868  {
869  lglNormal(vec3f(x,y,z));
870  }
871 
872  void lglTexCoord(const vec4f &t)
873  {
874  if (disable_texturing_)
875  return;
876 
877  if (!started_)
878  lglError("invalid texcoord specification");
879  else
880  {
881  texcoord_ = t;
882  hastexcoord_ = true;
883  }
884  }
885 
887  void lglTexCoord(float s, float t = 0, float r = 0, float w = 1)
888  {
889  lglTexCoord(vec4f(s,t,r,w));
890  }
891 
892  void lglAttribute(const vec4f &a, unsigned int n = 0)
893  {
894  if (!started_)
895  lglError("invalid attribute specification");
896  else
897  if (size_ > 0 && !hasattribute_[n])
898  lglError("mismatching attribute specification");
899  else
900  if (n >= LGL_NUM_ATTRIBUTES)
901  lglError("invalid attribute number");
902  else
903  {
904  attribute_[n] = a;
905  hasattribute_[n] = true;
906  hasattributes_ = true;
907  }
908  }
909 
911  void lglAttribute(float x, float y, float z, float w = 1.0f, unsigned int n = 0)
912  {
913  lglAttribute(vec4f(x,y,z,w), n);
914  }
915 
917  void lglBegin(lgl_primitive_enum primitive)
918  {
919  if (started_)
920  {
921  lglError("invalid begin operation");
922  return;
923  }
924 
925  if (immediate_)
926  reset();
927 
928  started_ = true;
929 
930 #if (LGL_OPENGL_VERSION >= 31) || defined(LGL_GLES)
931 
932  // quad strips are not allowed with opengl >= 3.1 or opengl es
933  // use identically behaving triangle strips instead
934  if (primitive == LGL_QUAD_STRIP)
935  primitive = LGL_TRIANGLE_STRIP;
936 
937  // quads are not allowed with opengl >= 3.1 or opengl es
938  // rearrange incoming vertices as triangle strip instead
939  if (primitive == LGL_QUADS)
940  {
941  primitive = LGL_TRIANGLE_STRIP;
942 
943  if (size_ == 0) rearrange_ = true;
944  else if (!rearrange_) lglError("unmatched primitive type");
945  }
946 
947 #endif
948 
949  if (immediate_)
950  primitive_ = primitive;
951  else
952  {
953  if (size_ == 0)
954  primitive_ = primitive;
955  else
956  {
957  if (primitive != primitive_)
958  lglError("unmatched primitive type");
959 
960  if (primitive_ == LGL_LINE_STRIP || primitive_ == LGL_TRIANGLE_FAN)
961  lglError("invalid primitive type");
962 
963  if (primitive_==LGL_TRIANGLE_STRIP || primitive_==LGL_QUAD_STRIP)
964  if (!rearrange_)
965  {
966  if (!copied_)
967  {
968  lglPlainVertex(vertex_);
969  if (primitive_ == LGL_QUAD_STRIP) lglPlainVertex(vertex_);
970  copied_ = true;
971  }
972  copy_ = true;
973  }
974  }
975 
976  primitives_++;
977  }
978  }
979 
981  void lglEnd()
982  {
983  if (!started_)
984  {
985  lglError("invalid end operation");
986  return;
987  }
988 
989  started_ = false;
990 
991 #ifdef LGL_CORE
992 
993  usedprogram_ = 0;
994 
995 #endif
996 
997  if (immediate_)
998  {
999  lglRender();
1000  size_ = 0;
1001  }
1002  }
1003 
1006  unsigned int vertices,
1007  const float *vertex_array, // 3 components
1008  const float *color_array, // 4 components
1009  const float *normal_array = NULL, // 3 components
1010  const float *texcoord_array = NULL) // 4 components
1011  {
1012  const float *colors = color_array;
1013  const float *normals = normal_array;
1014  const float *texcoords = texcoord_array;
1015  lglBegin(primitive);
1016  for (unsigned int i=0; i<vertices; i++)
1017  {
1018  if (color_array) {lglColor(*colors, *(colors+1), *(colors+2), *(colors+3)); colors+=4;}
1019  if (normal_array) {lglNormal(*normals, *(normals+1), *(normals+2)); normals+=3;}
1020  if (texcoord_array) {lglTexCoord(*texcoords, *(texcoords+1), *(texcoords+2), *(texcoords+3)); texcoords+=4;}
1021  lglVertex(*vertex_array, *(vertex_array+1), *(vertex_array+2)); vertex_array+=3;
1022  }
1023  lglEnd();
1024  }
1025 
1028  const float *interleaved_array,
1029  unsigned int vertices,
1030  int colors = 0, // color components (0, 3 or 4)
1031  int normals = 0, // normal components (0 or 3)
1032  int texcoords = 0) // texcoord components (0, 1, 2, 3 or 4)
1033  {
1034  const float *array = interleaved_array;
1035  lglBegin(primitive);
1036  for (unsigned int i=0; i<vertices; i++)
1037  {
1038  vec3 vertex(*array, *(array+1), *(array+2)); array+=3;
1039  if (colors == 3) {lglColor(*array, *(array+1), *(array+2)); array+=3;}
1040  else if (colors == 4) {lglColor(*array, *(array+1), *(array+2), *(array+3)); array+=4;}
1041  if (normals == 3) {lglNormal(*array, *(array+1), *(array+2)); array+=3;}
1042  if (texcoords == 1) {lglTexCoord(*array); array++;}
1043  else if (texcoords == 2) {lglTexCoord(*array, *(array+1)); array+=2;}
1044  else if (texcoords == 3) {lglTexCoord(*array, *(array+1), *(array+2)); array+=3;}
1045  else if (texcoords == 4) {lglTexCoord(*array, *(array+1), *(array+2), *(array+3)); array+=4;}
1046  lglVertex(vertex);
1047  }
1048  lglEnd();
1049  }
1050 
1053  {
1054  hascolor_ = false;
1055  }
1056 
1059  {
1060  hasnormal_ = false;
1061  }
1062 
1065  {
1066  hastexcoord_ = false;
1067  }
1068 
1071  {
1072  hasattributes_ = false;
1073 
1074  for (unsigned int i=0; i<LGL_NUM_ATTRIBUTES; i++)
1075  hasattribute_[i] = false;
1076  }
1077 
1079  virtual void lglRender(const lgl *vbo = NULL)
1080  {
1081  if (started_)
1082  {
1083  lglError("invalid render operation");
1084  return;
1085  }
1086 
1087  if (!initStaticGL_)
1088  {
1089  initializeStaticOpenGL();
1090  initStaticGL_ = true;
1091  }
1092 
1093  if (!initGL_)
1094  {
1095  initializeOpenGL();
1096  initGL_ = true;
1097 
1098  // call init-gl hook
1099  init_gl_hook();
1100  }
1101 
1102  if (!immediate_)
1103  shrink();
1104 
1105  if (size_ > 0)
1106  {
1107  if (!checkMatrixStacks()) return;
1108 
1109  // view culling
1110  if (cull_)
1111  if (size_ >= cull_minsize_)
1112  {
1113  mat4 mv = lglGetModelViewMatrix();
1114  mat4 mvi = mv.invert();
1115  mat4 mvt = mv.transpose();
1116  vec3 origin = vec3(0,0,0);
1117  vec3 direction = vec3(0,0,-1);
1118 
1119  origin = mvi * vec4(origin);
1120  direction = (mat3(mvt) * direction).normalize();
1121 
1122  if (!glslmath::vtest_plane_bbox(origin, direction, lglGetCenter(), lglGetExtent()))
1123  return;
1124  }
1125 
1126  // copy state and program from vbo
1127  if (vbo)
1128  {
1129  lglCloneState(vbo);
1130 
1131  if (vbo->lglCustomProgram())
1132  lglCopyProgram(vbo);
1133  else
1134  lglCopyUniforms(vbo);
1135  }
1136 
1137 #ifdef LGL_CORE
1138 
1139  GLenum usage = GL_NONE;
1140 
1141  if (immediate_) usage = GL_STREAM_DRAW;
1142  else usage = GL_STATIC_DRAW;
1143 
1144  bool vao = false;
1145 
1146 #if defined(LGL_GL3) || defined(LGL_GLES3)
1147 
1148  // bind vao
1149  glBindVertexArray(array_);
1150  vao = true;
1151 
1152 #endif
1153 
1154  // update vbo (vertices)
1155  if (modified_ || !vao)
1156  {
1157  glBindBuffer(GL_ARRAY_BUFFER, buffers_[LGL_VERTEX_BUFFER]);
1158  if (modified_)
1159  {
1160  if (storagetype_) glBufferData(GL_ARRAY_BUFFER, size_*sizeof(VEC4), vertices_, usage);
1161  else glBufferData(GL_ARRAY_BUFFER, size_*sizeof(vec4f), verticesf_, usage);
1162  }
1163  glVertexAttribPointer(LGL_VERTEX_LOCATION, 4, storagetype_?gl_type:GL_FLOAT, GL_FALSE, 0, 0);
1164  glBindBuffer(GL_ARRAY_BUFFER, 0);
1165  }
1166 
1167  // enable vbo (vertices)
1168  glEnableVertexAttribArray(LGL_VERTEX_LOCATION);
1169 
1170  // update vbo (colors)
1171  if (hascolor_)
1172  if (modified_ || !vao)
1173  {
1174  glBindBuffer(GL_ARRAY_BUFFER, buffers_[LGL_COLOR_BUFFER]);
1175  if (modified_) glBufferData(GL_ARRAY_BUFFER, size_*sizeof(vec4f), colors_, usage);
1176  glVertexAttribPointer(LGL_COLOR_LOCATION, 4, GL_FLOAT, GL_FALSE, 0, 0);
1177  glBindBuffer(GL_ARRAY_BUFFER, 0);
1178  }
1179 
1180  // enable vbo (colors)
1181  if (lglActiveColoring())
1182  glEnableVertexAttribArray(LGL_COLOR_LOCATION);
1183 
1184  // update vbo (normals)
1185  if (hasnormal_)
1186  if (modified_ || !vao)
1187  {
1188  glBindBuffer(GL_ARRAY_BUFFER, buffers_[LGL_NORMAL_BUFFER]);
1189  if (modified_) glBufferData(GL_ARRAY_BUFFER, size_*sizeof(vec3f), normals_, usage);
1190  glVertexAttribPointer(LGL_NORMAL_LOCATION, 3, GL_FLOAT, GL_FALSE, 0, 0);
1191  glBindBuffer(GL_ARRAY_BUFFER, 0);
1192  }
1193 
1194  // enable vbo (normals)
1195  if (lglActiveLighting())
1196  glEnableVertexAttribArray(LGL_NORMAL_LOCATION);
1197 
1198  // update vbo (texture coordinates)
1199  if (hastexcoord_)
1200  if (modified_ || !vao)
1201  {
1202  glBindBuffer(GL_ARRAY_BUFFER, buffers_[LGL_TEXCOORD_BUFFER]);
1203  if (modified_) glBufferData(GL_ARRAY_BUFFER, size_*sizeof(vec4f), texcoords_, usage);
1204  glVertexAttribPointer(LGL_TEXCOORD_LOCATION, 4, GL_FLOAT, GL_FALSE, 0, 0);
1205  glBindBuffer(GL_ARRAY_BUFFER, 0);
1206  }
1207 
1208  // enable vbo (texture coordinates)
1209  if (lglActiveTexturing())
1210  glEnableVertexAttribArray(LGL_TEXCOORD_LOCATION);
1211 
1212  // update vbo (barycentric coordinates)
1213  if (modified_ || !vao)
1214  {
1215  glBindBuffer(GL_ARRAY_BUFFER, buffers_[LGL_BARYCENTRIC_BUFFER]);
1216  if (modified_) glBufferData(GL_ARRAY_BUFFER, size_*sizeof(vec3f), barycentrics_, usage);
1217  glVertexAttribPointer(LGL_BARYCENTRIC_LOCATION, 3, GL_FLOAT, GL_FALSE, 0, 0);
1218  glBindBuffer(GL_ARRAY_BUFFER, 0);
1219  }
1220 
1221  // enable vbo (barycentric coordinates)
1222  if (polygonmode_==LGL_LINE || polygonmode_==LGL_BARYCENTRIC)
1223  glEnableVertexAttribArray(LGL_BARYCENTRIC_LOCATION);
1224 
1225  // enable vbo (generic attributes)
1226  if (hasattributes_)
1227  {
1228  if (modified_ || !vao)
1229  {
1230  glBindBuffer(GL_ARRAY_BUFFER, buffers_[LGL_ATTRIBUTE_BUFFER]);
1231  if (modified_) glBufferData(GL_ARRAY_BUFFER, size_*LGL_NUM_ATTRIBUTES*sizeof(vec4f), attributes_, usage);
1232  for (unsigned int i=0; i<LGL_NUM_ATTRIBUTES; i++)
1233  if (hasattribute_[i])
1234  glVertexAttribPointer(LGL_ATTRIBUTE_LOCATION+i, 4, GL_FLOAT, GL_FALSE, LGL_NUM_ATTRIBUTES*sizeof(vec4f), (void *)(i*sizeof(vec4f)));
1235  glBindBuffer(GL_ARRAY_BUFFER, 0);
1236  }
1237 
1238  for (unsigned int i=0; i<LGL_NUM_ATTRIBUTES; i++)
1239  if (hasattribute_[i])
1240  glEnableVertexAttribArray(LGL_ATTRIBUTE_LOCATION+i);
1241  }
1242 
1243 #else
1244 
1245  // enable vertex array
1246  if (storagetype_) glVertexPointer(4, gl_type, 0, vertices_);
1247  else glVertexPointer(4, GL_FLOAT, 0, verticesf_);
1248  glEnableClientState(GL_VERTEX_ARRAY);
1249 
1250  // enable color array
1251  if (lglActiveColoring())
1252  {
1253  glColorPointer(4, GL_FLOAT, 0, colors_);
1254  glEnableClientState(GL_COLOR_ARRAY);
1255  }
1256  else
1257  glColor4f(actual_.r, actual_.g, actual_.b, actual_.a);
1258 
1259  // enable normal array
1260  if (lglActiveLighting())
1261  {
1262  glNormalPointer(GL_FLOAT, 0, normals_);
1263  glEnableClientState(GL_NORMAL_ARRAY);
1264  }
1265 
1266  // enable texture coordinate array
1267  if (lglActiveTexturing())
1268  {
1269  glTexCoordPointer(4, GL_FLOAT, 0, texcoords_);
1270  glEnableClientState(GL_TEXTURE_COORD_ARRAY);
1271  }
1272 
1273 #endif
1274 
1275 #ifdef LGL_CORE
1276 
1277  // get previous shader program
1278  GLint prev_program;
1279  glGetIntegerv(GL_CURRENT_PROGRAM, &prev_program);
1280 
1281  // use shader program
1282  GLuint program = lglGetActiveProgram();
1283  glUseProgram(program);
1284 
1285 #endif
1286 
1287 #ifdef LGL_CORE
1288 
1289  // get actual color
1290  vec4f color = actual_;
1291 
1292  // check for immediate mode
1293  if (immediate_)
1294  if (lglActiveColoring()) color = vec4f(1);
1295 
1296  // get model-view matrix
1297  mat4 mv = modelview_matrix_.back();
1298 
1299  // get local model matrix
1300  if (!model_matrix_identity_)
1301  mv = mv * model_matrix_;
1302 
1303  // get global manip matrix
1304  if (manip_matrix_apply_ && !manip_matrix_identity_)
1305  mv = manip_matrix_ * mv;
1306 
1307  // get model-view-projection matrix
1308  mat4 mvp = projection_matrix_.back() * mv;
1309 
1310  // get inverse transpose model-view matrix
1311  mat4 mvit = mv.invert().transpose();
1312 
1313  // get texture matrix
1314  mat4 tm = texture_matrix_.back();
1315 
1316  // get local texture matrix
1317  if (!tex_matrix_identity_)
1318  tm = tm * tex_matrix_;
1319 
1320  // get light vector
1321  vec4f light = light_;
1322 
1323  // update shader locations
1324  if (program != usedprogram_)
1325  {
1326  usedprogram_ = program;
1327 
1328  // get uniform location of actual color
1329  color_loc_ = glGetUniformLocation(program, "color");
1330 
1331  // get uniform location of model-view-projection matrix
1332  mvp_loc_ = glGetUniformLocation(program, "mvp");
1333 
1334  // check for presence of model-view-projection matrix
1335  if (mvp_loc_ < 0)
1336  lglWarning("uniform location not found: model-view-projection matrix (mvp)");
1337 
1338  // get uniform locations of model-view matrices
1339  mv_loc_ = glGetUniformLocation(program, "mv");
1340  mvit_loc_ = glGetUniformLocation(program, "mvit");
1341 
1342  // get uniform location of texture matrix
1343  tm_loc_ = glGetUniformLocation(program, "tm");
1344 
1345  // get uniform locations of standard program parameters
1346  if (!lglCustomProgram())
1347  {
1348  if (lglActiveLighting())
1349  {
1350  light_loc_ = glGetUniformLocation(program, "light");
1351 
1352  if (light_loc_ < 0)
1353  lglWarning("uniform location not found: light");
1354 
1355  kaIa_loc_ = glGetUniformLocation(program, "kaIa");
1356 
1357  if (kaIa_loc_ < 0)
1358  lglWarning("uniform location not found: lighting term (kaIa)");
1359 
1360  kdId_loc_ = glGetUniformLocation(program, "kdId");
1361 
1362  if (kdId_loc_ < 0)
1363  lglWarning("uniform location not found: lighting term (kdId)");
1364 
1365  ksIs_loc_ = glGetUniformLocation(program, "ksIs");
1366 
1367  if (ksIs_loc_ < 0)
1368  lglWarning("uniform location not found: lighting term (ksIs)");
1369 
1370  exponent_loc_ = glGetUniformLocation(program, "exponent");
1371 
1372  if (exponent_loc_ < 0)
1373  lglWarning("uniform location not found: lighting term (exponent)");
1374 
1375  falloff_loc_ = glGetUniformLocation(program, "falloff");
1376 
1377  if (falloff_loc_ < 0)
1378  lglWarning("uniform location not found: lighting term (falloff)");
1379  }
1380 
1381  if (lglActiveTexturing())
1382  {
1383  sampler_loc_ = glGetUniformLocation(program, "sampler");
1384 
1385  if (sampler_loc_ < 0)
1386  lglWarning("uniform location not found: sampler");
1387  }
1388 
1389  alphatest_loc_ = glGetUniformLocation(program, "alphatest");
1390 
1391  if (alphatest_loc_ < 0)
1392  lglWarning("uniform location not found: alphatest");
1393 
1394  clipping_loc_ = glGetUniformLocation(program, "clipping");
1395 
1396  if (clipping_loc_ < 0)
1397  lglWarning("uniform location not found: clipping");
1398 
1399  clipplane_loc_ = glGetUniformLocation(program, "clipplane");
1400 
1401  if (clipplane_loc_ < 0)
1402  lglWarning("uniform location not found: clipplane");
1403 
1404  fogdensity_loc_ = glGetUniformLocation(program, "fogdensity");
1405  fogcolor_loc_ = glGetUniformLocation(program, "fogcolor");
1406 
1407  if (fogdensity_loc_ < 0)
1408  lglWarning("uniform location not found: fogdensity");
1409 
1410  if (fogcolor_loc_ < 0)
1411  lglWarning("uniform location not found: fogcolor");
1412 
1413  wireframe_loc_ = glGetUniformLocation(program, "wireframe");
1414 
1415  if (wireframe_loc_ < 0)
1416  lglWarning("uniform location not found: wireframe");
1417 
1418  interlacing_loc_ = glGetUniformLocation(program, "interlacing");
1419 
1420  if (interlacing_loc_ < 0)
1421  lglWarning("uniform location not found: interlacing");
1422  }
1423  }
1424 
1425  // set actual color
1426  if (color_loc_ >= 0) glUniform4fv(color_loc_, 1, (const float *)color);
1427 
1428  // set model-view-projection matrix
1429  if (mvp_loc_ >= 0) glUniformMatrix4fv(mvp_loc_, 1, GL_FALSE, (const float *)mat4f(mvp));
1430 
1431  // set model-view matrices
1432  if (mv_loc_ >= 0) glUniformMatrix4fv(mv_loc_, 1, GL_FALSE, (const float *)mat4f(mv));
1433  if (mvit_loc_ >= 0) glUniformMatrix4fv(mvit_loc_, 1, GL_FALSE, (const float *)mat4f(mvit));
1434 
1435  // set texture matrix
1436  if (tm_loc_ >= 0) glUniformMatrix4fv(tm_loc_, 1, GL_FALSE, (const float *)mat4f(tm));
1437 
1438  // set program parameters
1439  if (!lglCustomProgram())
1440  {
1441  // set standard lighting parameters
1442  if (lglActiveLighting())
1443  {
1444  glUniform4fv(light_loc_, 1, (const float *)light);
1445 
1446  glUniform3fv(kaIa_loc_, 1, (const float *)vec3f(ka_*Ia_));
1447  glUniform3fv(kdId_loc_, 1, (const float *)vec3f(kd_*Id_));
1448  glUniform3fv(ksIs_loc_, 1, (const float *)vec3f(ks_*Is_));
1449 
1450  glUniform1f(exponent_loc_, exponent_);
1451  glUniform3fv(falloff_loc_, 1, (const float *)vec3f(falloff_));
1452  }
1453 
1454  // set standard texturing parameters
1455  if (lglActiveTexturing())
1456  {
1457  glUniform1i(sampler_loc_, 0);
1458 
1459  if (texid2D_ != 0)
1460  {
1461  glBindTexture(GL_TEXTURE_2D, texid2D_);
1462  }
1463 #if !defined(LGL_GLES) || defined (LGL_GLES3)
1464  else if (texid3D_ != 0)
1465  {
1466  glBindTexture(GL_TEXTURE_3D, texid3D_);
1467  }
1468 #endif
1469  }
1470 
1471  // set standard alpha testing parameters
1472  glUniform3fv(alphatest_loc_, 1, (const float *)vec3f(alphatest_));
1473 
1474  // set standard clipping parameters
1475  glUniform1f(clipping_loc_, (clipping_>0)?1.0f:0.0f);
1476  if (clipping_)
1477  for (unsigned int i=0; i<LGL_NUM_CLIPPLANES; i++)
1478  glUniform4fv(clipplane_loc_+i, 1, (const float *)vec4f(clipplane_[i]));
1479 
1480  // set standard fogging parameters
1481  glUniform1f(fogdensity_loc_, fogdensity_);
1482  glUniform4fv(fogcolor_loc_, 1, (const float *)vec4f(fogcolor_));
1483 
1484  // set standard polygon mode parameter
1485  glUniform1f(wireframe_loc_, (polygonmode_==LGL_LINE)?1.0f:0.0f);
1486 
1487  // set standard interlacing parameters
1488  glUniform4fv(interlacing_loc_, 1, (const float *)setupStereoMode(interlacing_));
1489  }
1490 
1491  // set custom program parameters
1492  for (typename lgl_uniform_location_type::const_iterator i = locations_.begin(); i != locations_.end(); i++)
1493  {
1494  GLint loc = i->loc;
1495 
1496  if (loc < 0)
1497  {
1498  std::string uniform = i->uniform;
1499  loc = glGetUniformLocation(program, uniform.c_str());
1500  }
1501 
1502  if (loc < 0)
1503  {
1504  if (i->warn)
1505  lglWarning("uniform location not found: " + i->uniform);
1506  }
1507  else
1508  {
1509  switch (i->type)
1510  {
1511  case lgl_int_type: glUniform1i(loc, i->value.int_value); break;
1512  case lgl_float_type: glUniform1f(loc, i->value.float_value); break;
1513  case lgl_vec2f_type: glUniform2fv(loc, 1, i->value.vec2f_value); break;
1514  case lgl_vec3f_type: glUniform3fv(loc, 1, i->value.vec3f_value); break;
1515  case lgl_vec4f_type: glUniform4fv(loc, 1, i->value.vec4f_value); break;
1516  case lgl_mat2f_type: glUniformMatrix2fv(loc, 1, GL_FALSE, i->value.mat2f_value); break;
1517  case lgl_mat3f_type: glUniformMatrix3fv(loc, 1, GL_FALSE, i->value.mat3f_value); break;
1518  case lgl_mat4f_type: glUniformMatrix4fv(loc, 1, GL_FALSE, i->value.mat4f_value); break;
1519  case lgl_no_type: if (i->warn) lglWarning("using undefined uniform: " + i->uniform); break;
1520  }
1521  }
1522  }
1523 
1524 #else
1525 
1526  // get light vector
1527  vec4f light = light_;
1528 
1529  // set projection matrix
1530  glMatrixMode(GL_PROJECTION);
1531  glLoadMatrixf((const float *)mat4f(projection_matrix_.back()));
1532 
1533  // set model-view matrix
1534  glMatrixMode(GL_MODELVIEW);
1535  glLoadIdentity();
1536  glLightfv(GL_LIGHT0, GL_POSITION, (const float *)light);
1537  if (clipping_ > 0)
1538  for (unsigned int i=0; i<LGL_NUM_CLIPPLANES; i++)
1539  {
1540  GLdouble clipplane[4] = {clipplane_[i].x, clipplane_[i].y, clipplane_[i].z, clipplane_[i].w};
1541  glClipPlane(GL_CLIP_PLANE0+i, clipplane);
1542  }
1543  if (model_matrix_identity_)
1544  if (!manip_matrix_apply_ || manip_matrix_identity_)
1545  glLoadMatrixf((const float *)mat4f(modelview_matrix_.back()));
1546  else
1547  glLoadMatrixf((const float *)mat4f(manip_matrix_ * modelview_matrix_.back()));
1548  else
1549  if (!manip_matrix_apply_ || manip_matrix_identity_)
1550  glLoadMatrixf((const float *)mat4f(modelview_matrix_.back() * model_matrix_));
1551  else
1552  glLoadMatrixf((const float *)mat4f(manip_matrix_ * modelview_matrix_.back() * model_matrix_));
1553 
1554  // set texture matrix
1555  glMatrixMode(GL_TEXTURE);
1556  if (tex_matrix_identity_)
1557  glLoadMatrixf((const float *)mat4f(texture_matrix_.back()));
1558  else
1559  glLoadMatrixf((const float *)mat4f(texture_matrix_.back() * tex_matrix_));
1560  glMatrixMode(GL_MODELVIEW);
1561 
1562  // enable lighting
1563  if (lglActiveLighting())
1564  {
1565  glLightfv(GL_LIGHT0, GL_AMBIENT, (const float *)vec4f(ka_*Ia_));
1566  glLightfv(GL_LIGHT0, GL_DIFFUSE, (const float *)vec4f(kd_*Id_));
1567  glLightfv(GL_LIGHT0, GL_SPECULAR, (const float *)vec4f(ks_*Is_));
1568  glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, falloff_.x);
1569  glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, falloff_.y);
1570  glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, falloff_.z);
1571  glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (const float *)vec4f(1));
1572  glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, exponent_);
1573  glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
1574 
1575  glEnable(GL_COLOR_MATERIAL);
1576  glEnable(GL_LIGHT0);
1577  glEnable(GL_LIGHTING);
1578 
1579  glEnable(GL_NORMALIZE);
1580  }
1581 
1582  // enable texturing
1583  if (lglActiveTexturing())
1584  {
1585  if (texid2D_ != 0)
1586  {
1587  glBindTexture(GL_TEXTURE_2D, texid2D_);
1588  glEnable(GL_TEXTURE_2D);
1589  }
1590  else if (texid3D_ != 0)
1591  {
1592  glBindTexture(GL_TEXTURE_3D, texid3D_);
1593  glEnable(GL_TEXTURE_3D);
1594  }
1595 
1596  glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
1597  }
1598 
1599  // enable clipping
1600  if (clipping_ > 0)
1601  for (unsigned int i=0; i<LGL_NUM_CLIPPLANES; i++)
1602  if (clipplane_[i] != vec4(0,0,0,0))
1603  glEnable(GL_CLIP_PLANE0+i);
1604 
1605  // enable fogging
1606  if (fogdensity_ > 0.0f)
1607  {
1608  GLfloat color[4];
1609 
1610  color[0] = fogcolor_.r;
1611  color[1] = fogcolor_.g;
1612  color[2] = fogcolor_.b;
1613  color[3] = fogcolor_.a;
1614 
1615  glFogfv(GL_FOG_COLOR, color);
1616  glFogi(GL_FOG_MODE, GL_EXP2);
1617  glFogf(GL_FOG_DENSITY, fogdensity_);
1618 
1619  glEnable(GL_FOG);
1620  }
1621 
1622  // set polygon mode
1623  if (polygonmode_ == LGL_LINE)
1624  glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
1625 
1626 #endif
1627 
1628  // call pre-render hook
1629  pre_render_hook();
1630 
1631  // get rendering primitive type
1632  GLenum p = GL_NONE;
1633  switch (primitive_)
1634  {
1635  case LGL_LINES: p = GL_LINES; break;
1636  case LGL_LINE_STRIP: p = GL_LINE_STRIP; break;
1637  case LGL_TRIANGLES: p = GL_TRIANGLES; break;
1638  case LGL_TRIANGLE_STRIP: p = GL_TRIANGLE_STRIP; break;
1639  case LGL_TRIANGLE_FAN: p = GL_TRIANGLE_FAN; break;
1640 #if (LGL_OPENGL_VERSION < 31) && !defined(LGL_GLES)
1641  case LGL_QUADS: p = GL_QUADS; break;
1642  case LGL_QUAD_STRIP: p = GL_QUAD_STRIP; break;
1643 #endif
1644  default: break;
1645  }
1646 
1647  // render primitives
1648  if (p != GL_NONE)
1649  glDrawArrays(p, 0, size_);
1650 
1651  // call post-render hook
1652  post_render_hook();
1653 
1654 #ifdef LGL_CORE
1655 
1656  // restore previous program
1657  glUseProgram(prev_program);
1658 
1659  // reset program state
1660  if (!lglCustomProgram())
1661  if (lglActiveTexturing())
1662  {
1663  if (texid2D_ != 0)
1664  {
1665  glBindTexture(GL_TEXTURE_2D, 0);
1666  glDisable(GL_TEXTURE_2D);
1667  }
1668 #if !defined(LGL_GLES) || defined(LGL_GLES3)
1669  else if (texid3D_ != 0)
1670  {
1671  glBindTexture(GL_TEXTURE_3D, 0);
1672  glDisable(GL_TEXTURE_3D);
1673  }
1674 #endif
1675  }
1676 
1677 #else
1678 
1679  // reset lighting
1680  if (lglActiveLighting())
1681  {
1682  glDisable(GL_COLOR_MATERIAL);
1683  glDisable(GL_LIGHT0);
1684  glDisable(GL_LIGHTING);
1685  glDisable(GL_NORMALIZE);
1686  }
1687 
1688  // reset texturing
1689  if (lglActiveTexturing())
1690  {
1691  if (texid2D_ != 0)
1692  {
1693  glBindTexture(GL_TEXTURE_2D, 0);
1694  glDisable(GL_TEXTURE_2D);
1695  }
1696  else if (texid3D_ != 0)
1697  {
1698  glBindTexture(GL_TEXTURE_3D, 0);
1699  glDisable(GL_TEXTURE_3D);
1700  }
1701  }
1702 
1703  // reset clipping
1704  if (clipping_ > 0)
1705  for (unsigned int i=0; i<LGL_NUM_CLIPPLANES; i++)
1706  if (clipplane_[i] != vec4(0,0,0,0))
1707  glDisable(GL_CLIP_PLANE0+i);
1708 
1709  // reset fogging
1710  if (fogdensity_ > 0.0f)
1711  glDisable(GL_FOG);
1712 
1713  // reset polygon mode
1714  if (polygonmode_ == LGL_LINE)
1715  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
1716 
1717 #endif
1718 
1719 #ifdef LGL_CORE
1720 
1721  // reset vbo (vertices)
1722  glDisableVertexAttribArray(LGL_VERTEX_LOCATION);
1723 
1724  // reset vbo (colors)
1725  if (lglActiveColoring())
1726  glDisableVertexAttribArray(LGL_COLOR_LOCATION);
1727 
1728  // reset vbo (normals)
1729  if (lglActiveLighting())
1730  glDisableVertexAttribArray(LGL_NORMAL_LOCATION);
1731 
1732  // reset vbo (texture coordinates)
1733  if (lglActiveTexturing())
1734  glDisableVertexAttribArray(LGL_TEXCOORD_LOCATION);
1735 
1736  // reset vbo (barycentric coordinates)
1737  if (polygonmode_==LGL_LINE || polygonmode_==LGL_BARYCENTRIC)
1738  glDisableVertexAttribArray(LGL_BARYCENTRIC_LOCATION);
1739 
1740  // reset vbo (generic attributes)
1741  if (hasattributes_)
1742  for (unsigned int i=0; i<LGL_NUM_ATTRIBUTES; i++)
1743  if (hasattribute_[i])
1744  glDisableVertexAttribArray(LGL_ATTRIBUTE_LOCATION+i);
1745 
1746 #if defined(LGL_GL3) || defined(LGL_GLES3)
1747 
1748  // reset vao
1749  glBindVertexArray(0);
1750 
1751 #endif
1752 
1753 #else
1754 
1755  // reset vertex array
1756  glDisableClientState(GL_VERTEX_ARRAY);
1757 
1758  // reset color array
1759  if (lglActiveColoring())
1760  glDisableClientState(GL_COLOR_ARRAY);
1761 
1762  // reset normal array
1763  if (lglActiveLighting())
1764  glDisableClientState(GL_NORMAL_ARRAY);
1765 
1766  // reset texture coordinate array
1767  if (lglActiveTexturing())
1768  glDisableClientState(GL_TEXTURE_COORD_ARRAY);
1769 
1770 #endif
1771  }
1772 
1773  // ray casting
1774  lglRayCast(this);
1775 
1776  // scene export
1777  lglExport(this);
1778 
1779  modified_ = false;
1780  rendered_ = true;
1781  }
1782 
1785  {
1786  return(primitive_);
1787  }
1788 
1790  int lglGetVertexCount() const
1791  {
1792  return(size_);
1793  }
1794 
1797  {
1798  return(primitives_);
1799  }
1800 
1803  void lglGetBoundingBox(vec3 &bboxmin, vec3 &bboxmax) const
1804  {
1805  bboxmin = bboxmin_;
1806  bboxmax = bboxmax_;
1807  }
1808 
1812  double lglGetBoundingSphere(vec3 &center) const
1813  {
1814  center = lglGetCenter();
1815  return(lglGetRadius());
1816  }
1817 
1820  {
1821  return(0.5*(bboxmin_+bboxmax_));
1822  }
1823 
1826  {
1827  return(bboxmax_-bboxmin_);
1828  }
1829 
1832  double lglGetRadius() const
1833  {
1834  if (bboxmin_.x <= bboxmax_.x &&
1835  bboxmin_.y <= bboxmax_.y &&
1836  bboxmin_.z <= bboxmax_.z)
1837  return((0.5*(bboxmax_-bboxmin_)).length());
1838 
1839  return(0);
1840  }
1841 
1844  double lglGetNorm() const
1845  {
1846  if (bboxmin_.x <= bboxmax_.x &&
1847  bboxmin_.y <= bboxmax_.y &&
1848  bboxmin_.z <= bboxmax_.z)
1849  return((0.5*(bboxmax_-bboxmin_)).norm());
1850 
1851  return(0);
1852  }
1853 
1856  double lglGetMaxExtent() const
1857  {
1858  if (bboxmin_.x <= bboxmax_.x &&
1859  bboxmin_.y <= bboxmax_.y &&
1860  bboxmin_.z <= bboxmax_.z)
1861  {
1862  vec3 ext = bboxmax_-bboxmin_;
1863  double maxext = ext.x;
1864  if (ext.y > maxext) maxext = ext.y;
1865  if (ext.z > maxext) maxext = ext.z;
1866  return(maxext);
1867  }
1868 
1869  return(0);
1870  }
1871 
1874  double lglGetMaxAbsCoord() const
1875  {
1876  if (bboxmin_.x <= bboxmax_.x &&
1877  bboxmin_.y <= bboxmax_.y &&
1878  bboxmin_.z <= bboxmax_.z)
1879  {
1880  double maxabs = bboxmax_.x;
1881  if (bboxmax_.y > maxabs) maxabs = bboxmax_.y;
1882  if (bboxmax_.z > maxabs) maxabs = bboxmax_.z;
1883  if (-bboxmin_.x > maxabs) maxabs = -bboxmin_.x;
1884  if (-bboxmin_.y > maxabs) maxabs = -bboxmin_.y;
1885  if (-bboxmin_.z > maxabs) maxabs = -bboxmin_.z;
1886  return(maxabs);
1887  }
1888 
1889  return(0);
1890  }
1891 
1893  std::vector<vec4> lglGetVertexCoordinates() const
1894  {
1895  std::vector<vec4> vertices;
1896  for (int i=0; i<size_; i++) vertices.push_back(vertices_[i]);
1897  return(vertices);
1898  }
1899 
1901  std::vector<vec4f> lglGetColorAttributes() const
1902  {
1903  std::vector<vec4f> colors;
1904  if (hascolor_)
1905  for (int i=0; i<size_; i++) colors.push_back(colors_[i]);
1906  return(colors);
1907  }
1908 
1910  std::vector<vec3f> lglGetNormalAttributes() const
1911  {
1912  std::vector<vec3f> normals;
1913  if (hasnormal_)
1914  for (int i=0; i<size_; i++) normals.push_back(normals_[i]);
1915  return(normals);
1916  }
1917 
1919  std::vector<vec4f> lglGetTexCoordAttributes() const
1920  {
1921  std::vector<vec4f> texcoords;
1922  if (hastexcoord_)
1923  for (int i=0; i<size_; i++) texcoords.push_back(texcoords_[i]);
1924  return(texcoords);
1925  }
1926 
1928  void lglAppendVerticesTo(lgl *vbo) const
1929  {
1930  if (size_ == 0) return;
1931 
1932  if (hascolor_) vbo->hascolor_ = true;
1933 
1934  if (vbo->size_ == 0)
1935  {
1936  vbo->primitive_ = primitive_;
1937  if (hasnormal_) vbo->hasnormal_ = true;
1938  if (hastexcoord_) vbo->hastexcoord_ = true;
1939  vbo->primitives_ = primitives_;
1940  }
1941  else
1942  {
1943  if (primitive_ == LGL_LINE_STRIP ||
1944  primitive_ == LGL_TRIANGLE_FAN)
1945  {
1946  lglError("invalid primitive type");
1947  return;
1948  }
1949 
1950  if (primitive_ != vbo->primitive_ ||
1951  hasnormal_ != vbo->hasnormal_ ||
1952  hastexcoord_ != vbo->hastexcoord_ ||
1953  hasattributes_ || vbo->hasattributes_)
1954  {
1955  lglError("unmatched primitive type");
1956  return;
1957  }
1958 
1959  if (primitive_==LGL_TRIANGLE_STRIP || primitive_==LGL_QUAD_STRIP)
1960  {
1961  vbo->lglPlainVertex(vbo->vertices_[vbo->size_-1]);
1962  if (primitive_ == LGL_QUAD_STRIP)
1963  {
1964  vbo->lglPlainVertex(vbo->vertices_[vbo->size_-1]);
1965  vbo->lglPlainVertex(vertices_[0]);
1966  }
1967  vbo->lglPlainVertex(vertices_[0]);
1968  }
1969 
1970  vbo->primitives_ += primitives_;
1971  }
1972 
1973  for (int i=0; i<size_; i++)
1974  vbo->lglPlainVertex(vertices_[i],
1975  hascolor_?colors_[i]:vec4f(1),
1976  hastexcoord_?texcoords_[i]:vec4f(0),
1977  hasnormal_?normals_[i]:vec3f(0));
1978  }
1979 
1981  void lglMatrixMode(lgl_matrixmode_enum mode = LGL_MODELVIEW)
1982  {
1983  matrixmode_ = mode;
1984  }
1985 
1988  {
1989  return(matrixmode_);
1990  }
1991 
1994  {
1995  if (!checkVertexScope()) return;
1996  if (!checkMatrixStacks()) return;
1997 
1998  if (matrixmode_ == LGL_MODELVIEW)
1999  modelview_matrix_.back() = mat4(1);
2000  else if (matrixmode_ == LGL_PREMODEL)
2001  {
2002  premodel_matrix_.back() = mat4(1);
2003  premodel_matrix_identity_.back() = true;
2004  premodel_matrix_it_.back() = mat3(1);
2005  premodel_matrix_recompute_.back() = false;
2006  }
2007  else if (matrixmode_ == LGL_PROJECTION)
2008  projection_matrix_.back() = mat4(1);
2009  else if (matrixmode_ == LGL_TEXTURE)
2010  texture_matrix_.back() = mat4(1);
2011  else
2012  {
2013  pretex_matrix_.back() = mat4(1);
2014  pretex_matrix_identity_.back() = true;
2015  }
2016  }
2017 
2019  void lglLoadMatrix(const mat4 &matrix)
2020  {
2021  if (!checkVertexScope()) return;
2022  if (!checkMatrixStacks()) return;
2023 
2024  if (matrixmode_ == LGL_MODELVIEW)
2025  modelview_matrix_.back() = matrix;
2026  else if (matrixmode_ == LGL_PREMODEL)
2027  {
2028  premodel_matrix_.back() = matrix;
2029  premodel_matrix_identity_.back() = false;
2030  premodel_matrix_recompute_.back() = true;
2031  }
2032  else if (matrixmode_ == LGL_PROJECTION)
2033  projection_matrix_.back() = matrix;
2034  else if (matrixmode_ == LGL_TEXTURE)
2035  texture_matrix_.back() = matrix;
2036  else
2037  {
2038  pretex_matrix_.back() = matrix;
2039  pretex_matrix_identity_.back() = false;
2040  }
2041  }
2042 
2044  void lglMultMatrix(const mat4 &matrix)
2045  {
2046  if (!checkVertexScope()) return;
2047  if (!checkMatrixStacks()) return;
2048 
2049  if (matrixmode_ == LGL_MODELVIEW)
2050  modelview_matrix_.back() = modelview_matrix_.back() * matrix;
2051  else if (matrixmode_ == LGL_PREMODEL)
2052  {
2053  premodel_matrix_.back() = premodel_matrix_.back() * matrix;
2054  premodel_matrix_identity_.back() = false;
2055  premodel_matrix_recompute_.back() = true;
2056  }
2057  else if (matrixmode_ == LGL_PROJECTION)
2058  projection_matrix_.back() = projection_matrix_.back() * matrix;
2059  else if (matrixmode_ == LGL_TEXTURE)
2060  texture_matrix_.back() = texture_matrix_.back() * matrix;
2061  else
2062  {
2063  pretex_matrix_.back() = pretex_matrix_.back() * matrix;
2064  pretex_matrix_identity_.back() = false;
2065  }
2066  }
2067 
2070  {
2071  if (!checkVertexScope()) return;
2072  if (!checkMatrixStacks()) return;
2073 
2074  if (matrixmode_ == LGL_MODELVIEW)
2075  modelview_matrix_.push_back(modelview_matrix_.back());
2076  else if (matrixmode_ == LGL_PREMODEL)
2077  {
2078  premodel_matrix_.push_back(premodel_matrix_.back());
2079  premodel_matrix_identity_.push_back(premodel_matrix_identity_.back());
2080  premodel_matrix_it_.push_back(premodel_matrix_it_.back());
2081  premodel_matrix_recompute_.push_back(premodel_matrix_recompute_.back());
2082  }
2083  else if (matrixmode_ == LGL_PROJECTION)
2084  projection_matrix_.push_back(projection_matrix_.back());
2085  else if (matrixmode_ == LGL_TEXTURE)
2086  texture_matrix_.push_back(texture_matrix_.back());
2087  else
2088  {
2089  pretex_matrix_.push_back(pretex_matrix_.back());
2090  pretex_matrix_identity_.push_back(pretex_matrix_identity_.back());
2091  }
2092  }
2093 
2096  {
2097  if (!checkVertexScope()) return;
2098  if (!checkMatrixStacks()) return;
2099 
2100  if (matrixmode_ == LGL_MODELVIEW)
2101  modelview_matrix_.pop_back();
2102  else if (matrixmode_ == LGL_PREMODEL)
2103  {
2104  premodel_matrix_.pop_back();
2105  premodel_matrix_identity_.pop_back();
2106  premodel_matrix_it_.pop_back();
2107  premodel_matrix_recompute_.pop_back();
2108  }
2109  else if (matrixmode_ == LGL_PROJECTION)
2110  projection_matrix_.pop_back();
2111  else if (matrixmode_ == LGL_TEXTURE)
2112  texture_matrix_.pop_back();
2113  else
2114  {
2115  pretex_matrix_.pop_back();
2116  pretex_matrix_identity_.pop_back();
2117  }
2118 
2119  checkMatrixStacks();
2120  }
2121 
2124  {
2125  if (!checkMatrixStacks()) return(mat4(1));
2126 
2127  if (matrixmode_ == LGL_MODELVIEW)
2128  return(modelview_matrix_.back());
2129  else if (matrixmode_ == LGL_PREMODEL)
2130  return(premodel_matrix_.back());
2131  else if (matrixmode_ == LGL_PROJECTION)
2132  return(projection_matrix_.back());
2133  else if (matrixmode_ == LGL_TEXTURE)
2134  return(texture_matrix_.back());
2135  else
2136  return(pretex_matrix_.back());
2137  }
2138 
2141  {
2142  if (!checkMatrixStacks()) return(mat4(1));
2143 
2144  // get projection matrix
2145  mat4 p = projection_matrix_.back();
2146 
2147  return(p);
2148  }
2149 
2152  {
2153  if (!checkMatrixStacks()) return(mat4(1));
2154 
2155  // get model-view matrix
2156  mat4 mv = modelview_matrix_.back();
2157 
2158  // get local model matrix
2159  if (!model_matrix_identity_)
2160  mv = mv * model_matrix_;
2161 
2162  // get global manip matrix
2163  if (manip_matrix_apply_ && !manip_matrix_identity_)
2164  mv = manip_matrix_ * mv;
2165 
2166  return(mv);
2167  }
2168 
2171  {
2172  // invert model-view matrix
2173  return(lglGetModelViewMatrix().invert());
2174  }
2175 
2178  {
2179  // invert and transpose model-view matrix
2180  return(lglGetModelViewMatrix().invert().transpose());
2181  }
2182 
2185  {
2186  // multiply model-view and projection matrix
2188  }
2189 
2192  {
2193  if (!checkMatrixStacks()) return(mat4(1));
2194 
2195  // get texture matrix
2196  mat4 tm = texture_matrix_.back();
2197 
2198  return(tm);
2199  }
2200 
2202  void lglScale(const vec4 &c)
2203  {
2204  if (c != vec4(1,1,1,1))
2206  }
2207 
2209  void lglScale(double s, double t, double r, double w = 1)
2210  {
2211  lglScale(vec4(s,t,r,w));
2212  }
2213 
2215  void lglScale(double s, double w = 1)
2216  {
2217  lglScale(vec4(s,s,s,w));
2218  }
2219 
2221  void lglTranslate(const vec4 &v)
2222  {
2223  if (v != vec4(0,0,0,0))
2225  }
2226 
2228  void lglTranslate(double x, double y, double z, double w = 1)
2229  {
2230  lglTranslate(vec4(x,y,z,w));
2231  }
2232 
2234  void lglRotate(double angle, const vec3 &v)
2235  {
2236  if (angle != 0)
2237  lglMultMatrix(mat4::rotate(angle, v));
2238  }
2239 
2241  void lglRotate(double angle, double vx, double vy, double vz)
2242  {
2243  lglRotate(angle, vec3(vx,vy,vz));
2244  }
2245 
2247  void lglRotateX(double angle)
2248  {
2249  lglRotate(angle, vec3(1,0,0));
2250  }
2251 
2253  void lglRotateY(double angle)
2254  {
2255  lglRotate(angle, vec3(0,1,0));
2256  }
2257 
2259  void lglRotateZ(double angle)
2260  {
2261  lglRotate(angle, vec3(0,0,1));
2262  }
2263 
2265  void lglOrtho(double left, double right, double bottom, double top, double nearp = -1, double farp = 1)
2266  {
2267  lglMultMatrix(mat4::ortho(left, right, bottom, top, nearp, farp));
2268  }
2269 
2271  void lglFrustum(double left, double right, double bottom, double top, double nearp, double farp)
2272  {
2273  lglMultMatrix(mat4::frustum(left, right, bottom, top, nearp, farp));
2274  }
2275 
2277  void lglParallel(const vec3 &p,const vec3 &n,const vec3 &d)
2278  {
2279  lglMultMatrix(mat4::parallel(p, n, d));
2280  }
2281 
2283  void lglPerspective(double fovy, double aspect, double nearp, double farp)
2284  {
2285  fovy_ = fovy;
2286  aspect_ = aspect;
2287  nearp_ = nearp;
2288  farp_ = farp;
2289 
2290  lglMultMatrix(mat4::perspective(fovy, aspect, nearp, farp));
2291  }
2292 
2294  double getFovy()
2295  {
2296  return(fovy_);
2297  }
2298 
2300  double getAspect()
2301  {
2302  return(aspect_);
2303  }
2304 
2306  double getNear()
2307  {
2308  return(nearp_);
2309  }
2310 
2312  double getFar()
2313  {
2314  return(farp_);
2315  }
2316 
2318  void lglLookAt(const vec3 &eye, const vec3 &at, const vec3 &up = vec3(0,1,0))
2319  {
2320  eye_ = eye;
2321  at_ = at;
2322  up_ = up;
2323 
2324  lglMultMatrix(mat4::lookat(eye, at, up));
2325  }
2326 
2328  void lglLookAt(double eye_x, double eye_y, double eye_z,
2329  double at_x, double at_y, double at_z,
2330  double up_x = 0, double up_y = 1, double up_z = 0)
2331  {
2332  lglLookAt(vec3(eye_x,eye_y,eye_z), vec3(at_x,at_y,at_z), vec3(up_x,up_y,up_z));
2333  }
2334 
2336  vec3 getEye() const
2337  {
2338  return(eye_);
2339  }
2340 
2342  vec3 getLookAt() const
2343  {
2344  return(at_);
2345  }
2346 
2348  vec3 getUp() const
2349  {
2350  return(up_);
2351  }
2352 
2355  {
2356  lgl_matrixmode_enum mode = matrixmode_;
2357  matrixmode_ = LGL_PROJECTION;
2358  lglLoadIdentity();
2359  matrixmode_ = mode;
2360  }
2361 
2363  void lglProjection(const mat4 &projection)
2364  {
2365  lgl_matrixmode_enum mode = matrixmode_;
2366  matrixmode_ = LGL_PROJECTION;
2367  lglLoadMatrix(projection);
2368  matrixmode_ = mode;
2369  }
2370 
2372  void lglProjection(double left, double right, double bottom, double top, double nearp, double farp)
2373  {
2374  lglProjection(mat4::ortho(left, right, bottom, top, nearp, farp));
2375  }
2376 
2378  void lglProjection(double fovy, double aspect, double nearp, double farp)
2379  {
2380  fovy_ = fovy;
2381  aspect_ = aspect;
2382  nearp_ = nearp;
2383  farp_ = farp;
2384 
2385  lglProjection(mat4::perspective(fovy, aspect, nearp, farp));
2386  }
2387 
2390  {
2391  lgl_matrixmode_enum mode = matrixmode_;
2392  matrixmode_ = LGL_MODELVIEW;
2393  lglLoadIdentity();
2394  matrixmode_ = mode;
2395  }
2396 
2398  void lglModelView(const mat4 &modelview)
2399  {
2400  lgl_matrixmode_enum mode = matrixmode_;
2401  matrixmode_ = LGL_MODELVIEW;
2402  lglLoadMatrix(modelview);
2403  matrixmode_ = mode;
2404  }
2405 
2407  void lglView(const vec3 &eye, const vec3 &at, const vec3 &up = vec3(0,1,0))
2408  {
2409  eye_ = eye;
2410  at_ = at;
2411  up_ = up;
2412 
2413  lglModelView(mat4::lookat(eye, at, up));
2414  }
2415 
2417  void lglView(double eye_x, double eye_y, double eye_z,
2418  double at_x, double at_y, double at_z,
2419  double up_x = 0, double up_y = 1, double up_z = 0)
2420  {
2421  lglView(vec3(eye_x,eye_y,eye_z), vec3(at_x,at_y,at_z), vec3(up_x,up_y,up_z));
2422  }
2423 
2425  void lglTexture()
2426  {
2427  lgl_matrixmode_enum mode = matrixmode_;
2428  matrixmode_ = LGL_TEXTURE;
2429  lglLoadIdentity();
2430  matrixmode_ = mode;
2431  }
2432 
2434  void lglTexture(const mat4 &texture)
2435  {
2436  lgl_matrixmode_enum mode = matrixmode_;
2437  matrixmode_ = LGL_TEXTURE;
2438  lglLoadMatrix(texture);
2439  matrixmode_ = mode;
2440  }
2441 
2443  static void lglManip(bool on = true)
2444  {
2445  manip_matrix_apply_ = on;
2446  }
2447 
2449  static void lglManip(const mat4 &manip)
2450  {
2451  manip_matrix_ = manip * manip_matrix_;
2452  manip_matrix_identity_ = false;
2453  manip_matrix_apply_ = true;
2454  }
2455 
2457  static void lglManip(double focus, double angle, double tilt, double zoom)
2458  {
2459  mat4 rotate = mat4::rotate(-tilt, vec3(1,0,0)) * mat4::rotate(-angle, vec3(0,1,0));
2460  mat4 scale = mat4::scale(zoom);
2461  lglManip(mat4::translate(vec3(0,0,-focus)) * scale * rotate * mat4::translate(vec3(0,0,focus)));
2462  }
2463 
2465  static void lglManip(double dx, double dy, double zoom = 1)
2466  {
2467  double fovy = fovy_;
2468  double aspect = aspect_;
2469 
2470  if (fovy == 0) fovy_ = 360;
2471  if (aspect == 0) aspect_ = 1;
2472 
2473  mat4 scale = mat4::scale(zoom);
2474 
2475  if (eye_==at_ || up_==vec3(0))
2476  {
2477  mat4 rotate = mat4::rotate(-dy*fovy, vec3(1,0,0)) * mat4::rotate(-dx*fovy*aspect, vec3(0,1,0));
2478  lglManip(scale * rotate);
2479  manip_matrix_apply_ = false;
2480  }
2481  else
2482  {
2483  double focus = (at_-eye_).length();
2484  mat4 v = mat4::lookat(eye_, at_, up_) * mat4::translate(at_);
2485  mat4 rotatex = mat4::rotate(-dx*fovy*aspect, up_);
2486  mat4 rotatey = mat4::rotate(-dy*fovy, vec3(1,0,0));
2487  lglManip(mat4::translate(vec3(0,0,-focus)) * scale * rotatey * mat4::translate(vec3(0,0,focus)));
2488  lglManip(v * rotatex * v.invert());
2489  }
2490  }
2491 
2493  static void lglManip(vec2 delta, double zoom = 1)
2494  {
2495  lglManip(delta.x, delta.y, zoom);
2496  }
2497 
2499  static void lglResetManip()
2500  {
2501  manip_matrix_ = mat4(1);
2502  manip_matrix_identity_ = true;
2503  manip_matrix_apply_ = false;
2504  }
2505 
2508  {
2509  return(manip_matrix_);
2510  }
2511 
2513  static bool lglIsManipApplied()
2514  {
2515  return(manip_matrix_apply_);
2516  }
2517 
2520  {
2521  return(manip_matrix_.invert().transpose());
2522  }
2523 
2525  void lglModel()
2526  {
2527  model_matrix_ = mat4(1);
2528  model_matrix_identity_ = true;
2529  }
2530 
2532  void lglModel(const mat4 &model)
2533  {
2534  model_matrix_ = model;
2535  model_matrix_identity_ = false;
2536  }
2537 
2540  {
2541  return(model_matrix_);
2542  }
2543 
2546  {
2547  return(model_matrix_.invert().transpose());
2548  }
2549 
2552  {
2553  if (started_)
2554  {
2555  lglError("missing end operation");
2556  return;
2557  }
2558 
2559  if (size_ > 0)
2560  {
2561  mat4 m = lglGetModelMatrix();
2563 
2564  for (int i=0; i<size_; i++)
2565  {
2566  if (hasnormal_) normals_[i] = mit * normals_[i];
2567  vertices_[i] = m * vertices_[i];
2568  }
2569 
2570  modified_ = true;
2571 
2572  lglModel();
2573  }
2574  }
2575 
2577  void lglTex()
2578  {
2579  tex_matrix_ = mat4(1);
2580  tex_matrix_identity_ = true;
2581  }
2582 
2584  void lglTex(const mat4 &tex)
2585  {
2586  tex_matrix_ = tex;
2587  tex_matrix_identity_ = false;
2588  }
2589 
2591  void lglTex(const vec4 &scale, const vec4 &offset)
2592  {
2594  }
2595 
2598  {
2599  return(tex_matrix_);
2600  }
2601 
2604  {
2605  if (started_)
2606  {
2607  lglError("missing end operation");
2608  return;
2609  }
2610 
2611  if (size_ > 0)
2612  {
2613  mat4 m = lglGetTexMatrix();
2614 
2615  for (int i=0; i<size_; i++)
2616  if (hastexcoord_) texcoords_[i] = m * texcoords_[i];
2617 
2618  modified_ = true;
2619 
2620  lglTex();
2621  }
2622  }
2623 
2626  void lglApplyColor(const vec4f &c)
2627  {
2628  if (started_)
2629  {
2630  lglError("missing end operation");
2631  return;
2632  }
2633 
2634  if (size_ > 0)
2635  {
2636  hascolor_ = true;
2637 
2638  for (int i=0; i<size_; i++)
2639  colors_[i] *= c;
2640 
2641  modified_ = true;
2642  }
2643 
2644  applied_ = true;
2645  }
2646 
2648  static bool lglSupportsGLSL()
2649  {
2650 #ifdef LGL_CORE
2651  return(true);
2652 #else
2653  return(false);
2654 #endif
2655  }
2656 
2658  static std::string lglGetGLSLVersionString()
2659  {
2660 #ifdef LGL_CORE
2661 
2662  const GLubyte *version = glGetString(GL_SHADING_LANGUAGE_VERSION);
2663  return((const char *)version);
2664 
2665 #else
2666 
2667  return("none");
2668 
2669 #endif
2670  }
2671 
2673  static std::string lglPlainGLSLVertexShader()
2674  {
2675  return(std::string(lgl_plain_vertex_shader_header)+
2676  lgl_plain_vertex_shader);
2677  }
2678 
2680  static std::string lglPlainGLSLFragmentShader()
2681  {
2682  return(std::string(lgl_plain_fragment_shader_header)+
2683  lgl_plain_fragment_shader);
2684  }
2685 
2687  static std::string lglPlainGLSLProgram()
2688  {
2690  }
2691 
2693  static std::string lglBasicGLSLVertexShader(bool colors = false, bool normals = false, bool texcoords = false)
2694  {
2695  if (!texcoords)
2696  if (!normals)
2697  if (!colors)
2698  return(std::string(lgl_default_vertex_shader_header)+
2699  lgl_default_vertex_shader_clipping+
2700  lgl_default_vertex_shader1);
2701  else
2702  return(std::string(lgl_default_vertex_shader_header)+
2703  lgl_default_vertex_shader_clipping+
2704  lgl_default_vertex_shader2);
2705  else
2706  if (!colors)
2707  return(std::string(lgl_default_vertex_shader_header)+
2708  lgl_default_vertex_shader_lighting+
2709  lgl_default_vertex_shader_clipping+
2710  lgl_default_vertex_shader3);
2711  else
2712  return(std::string(lgl_default_vertex_shader_header)+
2713  lgl_default_vertex_shader_lighting+
2714  lgl_default_vertex_shader_clipping+
2715  lgl_default_vertex_shader4);
2716  else
2717  if (!normals)
2718  if (!colors)
2719  return(std::string(lgl_default_vertex_shader_header)+
2720  lgl_default_vertex_shader_clipping+
2721  lgl_default_vertex_shader5);
2722  else
2723  return(std::string(lgl_default_vertex_shader_header)+
2724  lgl_default_vertex_shader_clipping+
2725  lgl_default_vertex_shader6);
2726  else
2727  if (!colors)
2728  return(std::string(lgl_default_vertex_shader_header)+
2729  lgl_default_vertex_shader_lighting+
2730  lgl_default_vertex_shader_clipping+
2731  lgl_default_vertex_shader7);
2732  else
2733  return(std::string(lgl_default_vertex_shader_header)+
2734  lgl_default_vertex_shader_lighting+
2735  lgl_default_vertex_shader_clipping+
2736  lgl_default_vertex_shader8);
2737  }
2738 
2740  static std::string lglBasicGLSLFragmentShader(bool colors = false, bool normals = false, bool texcoords = false, bool tex3D = false)
2741  {
2742  if (!texcoords)
2743  if (!normals)
2744  if (!colors)
2745  return(std::string(lgl_default_fragment_shader_header)+
2746  lgl_default_fragment_shader_alphatesting+
2747  lgl_default_fragment_shader_clipping+
2748  lgl_default_fragment_shader_interlacing+
2749  lgl_default_fragment_shader1);
2750  else
2751  return(std::string(lgl_default_fragment_shader_header)+
2752  lgl_default_fragment_shader_alphatesting+
2753  lgl_default_fragment_shader_clipping+
2754  lgl_default_fragment_shader_interlacing+
2755  lgl_default_fragment_shader2);
2756  else
2757  if (!colors)
2758  return(std::string(lgl_default_fragment_shader_header)+
2759  lgl_default_fragment_shader_lighting+
2760  lgl_default_fragment_shader_alphatesting+
2761  lgl_default_fragment_shader_clipping+
2762  lgl_default_fragment_shader_interlacing+
2763  lgl_default_fragment_shader3);
2764  else
2765  return(std::string(lgl_default_fragment_shader_header)+
2766  lgl_default_fragment_shader_lighting+
2767  lgl_default_fragment_shader_alphatesting+
2768  lgl_default_fragment_shader_clipping+
2769  lgl_default_fragment_shader_interlacing+
2770  lgl_default_fragment_shader4);
2771  else
2772  if (!tex3D)
2773  if (!normals)
2774  if (!colors)
2775  return(std::string(lgl_default_fragment_shader_header)+
2776  lgl_default_fragment_shader_alphatesting+
2777  lgl_default_fragment_shader_clipping+
2778  lgl_default_fragment_shader_interlacing+
2779  lgl_default_fragment_shader5_2D);
2780  else
2781  return(std::string(lgl_default_fragment_shader_header)+
2782  lgl_default_fragment_shader_alphatesting+
2783  lgl_default_fragment_shader_clipping+
2784  lgl_default_fragment_shader_interlacing+
2785  lgl_default_fragment_shader6_2D);
2786  else
2787  if (!colors)
2788  return(std::string(lgl_default_fragment_shader_header)+
2789  lgl_default_fragment_shader_lighting+
2790  lgl_default_fragment_shader_alphatesting+
2791  lgl_default_fragment_shader_clipping+
2792  lgl_default_fragment_shader_interlacing+
2793  lgl_default_fragment_shader7_2D);
2794  else
2795  return(std::string(lgl_default_fragment_shader_header)+
2796  lgl_default_fragment_shader_lighting+
2797  lgl_default_fragment_shader_alphatesting+
2798  lgl_default_fragment_shader_clipping+
2799  lgl_default_fragment_shader_interlacing+
2800  lgl_default_fragment_shader8_2D);
2801  else
2802  if (!normals)
2803  if (!colors)
2804  return(std::string(lgl_default_fragment_shader_header)+
2805  lgl_default_fragment_shader_alphatesting+
2806  lgl_default_fragment_shader_clipping+
2807  lgl_default_fragment_shader_interlacing+
2808  lgl_default_fragment_shader5_3D);
2809  else
2810  return(std::string(lgl_default_fragment_shader_header)+
2811  lgl_default_fragment_shader_alphatesting+
2812  lgl_default_fragment_shader_clipping+
2813  lgl_default_fragment_shader_interlacing+
2814  lgl_default_fragment_shader6_3D);
2815  else
2816  if (!colors)
2817  return(std::string(lgl_default_fragment_shader_header)+
2818  lgl_default_fragment_shader_lighting+
2819  lgl_default_fragment_shader_alphatesting+
2820  lgl_default_fragment_shader_clipping+
2821  lgl_default_fragment_shader_interlacing+
2822  lgl_default_fragment_shader7_3D);
2823  else
2824  return(std::string(lgl_default_fragment_shader_header)+
2825  lgl_default_fragment_shader_lighting+
2826  lgl_default_fragment_shader_alphatesting+
2827  lgl_default_fragment_shader_clipping+
2828  lgl_default_fragment_shader_interlacing+
2829  lgl_default_fragment_shader8_3D);
2830  }
2831 
2832 protected:
2833 
2834  static void tweakShader(std::string &shader)
2835  {
2836 #ifdef LGL_GLES
2837 
2838  lgl_string::stringReplaceAll(shader, "#version 120", "#version 100");
2839  lgl_string::stringReplaceAll(shader, ".0f", ".0");
2840 
2841 #endif
2842  }
2843 
2844 public:
2845 
2847  static GLuint lglCompileGLSLVertexShader(std::string shader)
2848  {
2849 #ifdef LGL_CORE
2850 
2851 #ifdef _WIN32
2852  initWGLprocs();
2853 #endif
2854 
2855  tweakShader(shader);
2856 
2857  GLint length = shader.size();
2858  GLuint shader_id = glCreateShader(GL_VERTEX_SHADER);
2859 
2860  const char *source = shader.c_str();
2861  glShaderSource(shader_id, 1, &source, &length);
2862  glCompileShader(shader_id);
2863 
2864  GLint status;
2865  glGetShaderiv(shader_id, GL_COMPILE_STATUS, &status);
2866 
2867  if (status == GL_FALSE)
2868  {
2869  GLint infolength;
2870  glGetShaderiv(shader_id, GL_INFO_LOG_LENGTH, &infolength);
2871  char *info = new char[infolength+1];
2872  glGetShaderInfoLog(shader_id, infolength, NULL, info);
2873  lglError("GLSL vertex shader:");
2874  lglError(source);
2875  lglError("GLSL vertex shader errors: " + std::string(info));
2876  delete[] info;
2877 
2878  glDeleteShader(shader_id);
2879  shader_id = 0;
2880  }
2881 
2882  return(shader_id);
2883 
2884 #else
2885 
2886  lglError("vertex programs unsupported");
2887  return(0);
2888 
2889 #endif
2890  }
2891 
2893  static GLuint lglCompileGLSLFragmentShader(std::string shader)
2894  {
2895 #ifdef LGL_CORE
2896 
2897 #ifdef _WIN32
2898  initWGLprocs();
2899 #endif
2900 
2901  tweakShader(shader);
2902 
2903  GLint length = shader.size();
2904  GLuint shader_id = glCreateShader(GL_FRAGMENT_SHADER);
2905 
2906  const char *source = shader.c_str();
2907  glShaderSource(shader_id, 1, &source, &length);
2908  glCompileShader(shader_id);
2909 
2910  GLint status;
2911  glGetShaderiv(shader_id, GL_COMPILE_STATUS, &status);
2912 
2913  if (status == GL_FALSE)
2914  {
2915  GLint infolength;
2916  glGetShaderiv(shader_id, GL_INFO_LOG_LENGTH, &infolength);
2917  char *info = new char[infolength+1];
2918  glGetShaderInfoLog(shader_id, infolength, NULL, info);
2919  lglError("GLSL fragment shader:");
2920  lglError(source);
2921  lglError("GLSL fragment shader errors: " + std::string(info));
2922  delete[] info;
2923 
2924  glDeleteShader(shader_id);
2925  shader_id = 0;
2926  }
2927 
2928  return(shader_id);
2929 
2930 #else
2931 
2932  lglError("fragment programs unsupported");
2933  return(0);
2934 
2935 #endif
2936  }
2937 
2939  static GLuint lglLinkGLSLProgram(GLuint vertex_shader_id, GLuint fragment_shader_id, GLuint custom_shader_program = 0)
2940  {
2941 #ifdef LGL_CORE
2942 
2943 #ifdef _WIN32
2944  initWGLprocs();
2945 #endif
2946 
2947  GLuint shader_program = custom_shader_program;
2948 
2949  if (vertex_shader_id!=0 && fragment_shader_id!=0)
2950  {
2951  if (shader_program == 0)
2952  {
2953  shader_program = glCreateProgram();
2954 
2955  glBindAttribLocation(shader_program, LGL_VERTEX_LOCATION, "vertex_position");
2956  glBindAttribLocation(shader_program, LGL_COLOR_LOCATION, "vertex_color");
2957  glBindAttribLocation(shader_program, LGL_NORMAL_LOCATION, "vertex_normal");
2958  glBindAttribLocation(shader_program, LGL_TEXCOORD_LOCATION, "vertex_texcoord");
2959  glBindAttribLocation(shader_program, LGL_BARYCENTRIC_LOCATION, "vertex_barycentric");
2960  }
2961 
2962  for (unsigned int i=0; i<LGL_NUM_ATTRIBUTES; i++)
2963  {
2964  std::ostringstream vertex_attribute;
2965  vertex_attribute << "vertex_attribute" << i;
2966 
2967  glBindAttribLocation(shader_program, LGL_ATTRIBUTE_LOCATION+i, vertex_attribute.str().c_str());
2968  }
2969 
2970  glAttachShader(shader_program, vertex_shader_id);
2971  glAttachShader(shader_program, fragment_shader_id);
2972 
2973  glLinkProgram(shader_program);
2974 
2975  GLint status;
2976  glGetProgramiv(shader_program, GL_LINK_STATUS, &status);
2977 
2978  if (status == GL_FALSE)
2979  {
2980  GLint infolength;
2981  glGetProgramiv(shader_program, GL_INFO_LOG_LENGTH, &infolength);
2982  char *info = new char[infolength+1];
2983  glGetProgramInfoLog(shader_program, infolength, NULL, info);
2984  lglError("GLSL linker errors: " + std::string(info));
2985  delete[] info;
2986 
2987  glDeleteProgram(shader_program);
2988  shader_program = 0;
2989  }
2990  else
2991  {
2992  glDetachShader(shader_program, vertex_shader_id);
2993  glDetachShader(shader_program, fragment_shader_id);
2994  }
2995  }
2996 
2997  return(shader_program);
2998 
2999 #else
3000 
3001  return(0);
3002 
3003 #endif
3004  }
3005 
3007  static GLuint lglCompileGLSLProgram(std::string vertex_shader, std::string fragment_shader)
3008  {
3009 #ifdef LGL_CORE
3010 
3011  GLuint vertex_shader_id = lglCompileGLSLVertexShader(vertex_shader);
3012 
3013  if (vertex_shader_id != 0)
3014  {
3015  GLuint fragment_shader_id = lglCompileGLSLFragmentShader(fragment_shader);
3016 
3017  if (fragment_shader_id != 0)
3018  {
3019  GLuint shader_program = lglLinkGLSLProgram(vertex_shader_id, fragment_shader_id);
3020 
3021  lglDeleteGLSLShader(vertex_shader_id);
3022  lglDeleteGLSLShader(fragment_shader_id);
3023 
3024  return(shader_program);
3025  }
3026  else
3027  lglDeleteGLSLShader(vertex_shader_id);
3028  }
3029 
3030  return(0);
3031 
3032 #else
3033 
3034  return(0);
3035 
3036 #endif
3037  }
3038 
3040  static GLuint lglLoadGLSLProgram(const char *vertex_shader_file, const char *fragment_shader_file)
3041  {
3042 #ifdef LGL_CORE
3043 
3044  GLuint program = 0;
3045 
3046  std::string vertex_shader = lglReadTextFile(vertex_shader_file);
3047  std::string fragment_shader = lglReadTextFile(fragment_shader_file);
3048 
3049  if (!vertex_shader.empty() && !fragment_shader.empty())
3050  program = lgl::lglCompileGLSLProgram(vertex_shader, fragment_shader);
3051  else
3052  lglError("unable to load shader file");
3053 
3054  return(program);
3055 
3056 #else
3057 
3058  return(0);
3059 
3060 #endif
3061  }
3062 
3064  static std::string lglCombineGLSLProgram(const std::string &vertex_shader, const std::string &fragment_shader)
3065  {
3066  return(vertex_shader+"---\n"+fragment_shader);
3067  }
3068 
3070  static bool lglSplitGLSLProgram(std::string shader,
3071  std::string &vertex_shader, std::string &fragment_shader)
3072  {
3073  size_t pos = shader.find("---");
3074 
3075  if (pos < shader.size())
3076  {
3077  size_t pos1 = pos;
3078 
3079  while (shader[pos1]=='-' && pos1>0) pos1--;
3080 
3081  while ((shader[pos1]==' ' || shader[pos1]=='\t' ||
3082  shader[pos1]=='\n' || shader[pos1]=='\r') && pos1>0) pos1--;
3083 
3084  vertex_shader = shader.substr(0, pos1+1);
3085 
3086  if (vertex_shader.size() == 0)
3087  return(false);
3088 
3089  vertex_shader += "\n";
3090 
3091  size_t pos2 = pos;
3092 
3093  while (shader[pos2]=='-' && pos2+1<shader.size()) pos2++;
3094 
3095  while ((shader[pos2]==' ' || shader[pos2]=='\t' ||
3096  shader[pos2]=='\n' || shader[pos2]=='\r') && pos2+1<shader.size()) pos2++;
3097 
3098  fragment_shader = shader.substr(pos2);
3099 
3100  if (fragment_shader.size() == 0)
3101  return(false);
3102 
3103  fragment_shader += "\n";
3104 
3105  return(true);
3106  }
3107 
3108  return(false);
3109  }
3110 
3112  static GLuint lglCompileGLSLProgram(std::string shader = "")
3113  {
3114  std::string vertex_shader;
3115  std::string fragment_shader;
3116 
3117  if (shader == "")
3118  shader = lglPlainGLSLProgram();
3119 
3120  if (lglSplitGLSLProgram(shader, vertex_shader, fragment_shader))
3121  return(lglCompileGLSLProgram(vertex_shader, fragment_shader));
3122 
3123  return(0);
3124  }
3125 
3127  static GLuint lglLoadGLSLProgram(const char *shader_file)
3128  {
3129 #ifdef LGL_CORE
3130 
3131  GLuint program = 0;
3132 
3133  std::string shader = lglReadTextFile(shader_file);
3134  program = lgl::lglCompileGLSLProgram(shader);
3135 
3136  return(program);
3137 
3138 #else
3139 
3140  return(0);
3141 
3142 #endif
3143  }
3144 
3146  static void lglDeleteGLSLShader(GLuint shader_id)
3147  {
3148 #ifdef LGL_CORE
3149 
3150 #ifdef _WIN32
3151  initWGLprocs();
3152 #endif
3153 
3154  if (shader_id != 0)
3155  glDeleteShader(shader_id);
3156 
3157 #endif
3158  }
3159 
3161  static void lglDeleteGLSLProgram(GLuint program)
3162  {
3163 #ifdef LGL_CORE
3164 
3165 #ifdef _WIN32
3166  initWGLprocs();
3167 #endif
3168 
3169  if (program != 0)
3170  glDeleteProgram(program);
3171 
3172 #endif
3173  }
3174 
3178  void lglUseProgram(GLuint program, bool clear = true)
3179  {
3180 #ifdef LGL_CORE
3181 
3182  if (program == 0)
3183  lglError("invalid GLSL program");
3184 
3185  if (program != program_)
3186  {
3187  program_ = program;
3188 
3189  if (clear)
3190  {
3191  uniforms_.clear();
3192  locations_.clear();
3193  }
3194  }
3195 
3196 #endif
3197  }
3198 
3202  void lglUseDefaultProgram(bool clear = true)
3203  {
3204 #ifdef LGL_CORE
3205 
3206  if (program_ != 0)
3207  {
3208  program_ = 0;
3209  usedprogram_ = 0;
3210 
3211  if (clear)
3212  {
3213  uniforms_.clear();
3214  locations_.clear();
3215  }
3216  }
3217 
3218 #endif
3219  }
3220 
3222  void lglReplaceDefaultProgram(GLuint program, bool colors = false, bool normals = true, bool texcoords = false, bool tex3D = false)
3223  {
3224 #ifdef LGL_CORE
3225 
3226  int num = 0;
3227 
3228  if (colors) num |= 1;
3229  if (normals) num |= 2;
3230  if (texcoords) num |= 4;
3231 
3232  if (texcoords && tex3D) num += 4;
3233 
3234  custom_programs_[num] = program;
3235 
3236  usedprogram_ = 0;
3237 
3238 #endif
3239  }
3240 
3242  GLuint lglGetProgram() const
3243  {
3244 #ifdef LGL_CORE
3245 
3246  return(program_);
3247 
3248 #else
3249 
3250  return(0);
3251 
3252 #endif
3253  }
3254 
3256  void lglReuseProgram(GLuint program)
3257  {
3258 #ifdef LGL_CORE
3259 
3260  if (program != 0)
3261  lglUseProgram(program, false);
3262  else
3263  lglUseDefaultProgram(false);
3264 
3265 #endif
3266  }
3267 
3269  bool lglCustomProgram() const
3270  {
3271 #ifdef LGL_CORE
3272 
3273  if (program_>0 && polygonmode_!=LGL_LINE)
3274  return(true);
3275 
3276 #endif
3277 
3278  return(false);
3279  }
3280 
3282  GLuint lglGetActiveProgram() const
3283  {
3284 #ifdef LGL_CORE
3285 
3286  GLuint program;
3287 
3288  if (lglCustomProgram())
3289  program = program_;
3290  else
3291  {
3292  int num = 0;
3293 
3294  if (lglActiveColoring()) num |= 1;
3295  if (lglActiveLighting()) num |= 2;
3296  if (lglActiveTexturing()) num |= 4;
3297 
3298  if (lglActiveTexturing() && texid3D_!=0) num += 4;
3299 
3300  if (custom_programs_[num] != 0)
3301  program = custom_programs_[num];
3302  else
3303  program = programs_[num];
3304  }
3305 
3306  return(program);
3307 
3308 #else
3309 
3310  return(0);
3311 
3312 #endif
3313  }
3314 
3316  bool lglActiveColoring() const
3317  {
3318  return(hascolor_ && coloring_ && !disable_coloring_);
3319  }
3320 
3322  bool lglAppliedColoring() const
3323  {
3324  return(hascolor_ && coloring_ && !disable_coloring_ && applied_);
3325  }
3326 
3328  bool lglActiveLighting() const
3329  {
3330  return(hasnormal_ && lighting_ && !disable_lighting_);
3331  }
3332 
3334  bool lglActiveTexturing() const
3335  {
3336  if (!hastexcoord_ || !texturing_ || disable_texturing_)
3337  return(false);
3338 
3339 #ifdef LGL_CORE
3340 
3341  if (lglCustomProgram())
3342  return(true);
3343 
3344 #endif
3345 
3346  if (texid2D_!=0 || texid3D_!=0)
3347  return(true);
3348 
3349  return(false);
3350  }
3351 
3353  void lglColoring(bool on)
3354  {
3355  if (on != coloring_)
3356  {
3357  coloring_ = on;
3358 
3359 #ifdef LGL_CORE
3360 
3361  usedprogram_ = 0;
3362 
3363 #endif
3364  }
3365  }
3366 
3368  bool lglGetColoring() const
3369  {
3370  return(coloring_);
3371  }
3372 
3374  void lglLighting(bool on)
3375  {
3376  if (on != lighting_)
3377  {
3378  lighting_ = on;
3379 
3380 #ifdef LGL_CORE
3381 
3382  usedprogram_ = 0;
3383 
3384 #endif
3385  }
3386  }
3387 
3389  bool lglGetLighting() const
3390  {
3391  return(lighting_);
3392  }
3393 
3395  void lglTexturing(bool on)
3396  {
3397  if (on != texturing_)
3398  {
3399  texturing_ = on;
3400 
3401 #ifdef LGL_CORE
3402 
3403  usedprogram_ = 0;
3404 
3405 #endif
3406  }
3407  }
3408 
3410  bool lglGetTexturing() const
3411  {
3412  return(texturing_);
3413  }
3414 
3416  static void lglDisableColoring(bool off)
3417  {
3418  disable_coloring_ = off;
3419  }
3420 
3422  static void lglDisableLighting(bool off)
3423  {
3424  disable_lighting_ = off;
3425  }
3426 
3428  static void lglDisableTexturing(bool off)
3429  {
3430  disable_texturing_ = off;
3431  }
3432 
3434  unsigned int lglUniform(std::string uniform, bool warn = true)
3435  {
3436 #ifdef LGL_CORE
3437 
3438  lgl_uniform_map_type::iterator i = uniforms_.find(uniform);
3439 
3440  if (i == uniforms_.end())
3441  {
3442  i = uniforms_.insert(std::pair<std::string, unsigned int>(uniform, locations_.size())).first;
3443 
3444  lgl_uniform_struct u = {-1, uniform, lgl_no_type, {0}, warn};
3445  locations_.resize(locations_.size()+1, u);
3446  }
3447 
3448  return(i->second);
3449 
3450 #else
3451 
3452  return(0);
3453 
3454 #endif
3455  }
3456 
3458  unsigned int lglUniformi(std::string uniform, int value, bool warn = true)
3459  {
3460 #ifdef LGL_CORE
3461 
3462  lgl_uniform_map_type::iterator i = uniforms_.find(uniform);
3463 
3464  if (i == uniforms_.end())
3465  {
3466  i = uniforms_.insert(std::pair<std::string, unsigned int>(uniform, locations_.size())).first;
3467 
3468  lgl_uniform_struct u = {-1, uniform, lgl_int_type, {0}, warn};
3469  locations_.resize(locations_.size()+1, u);
3470  }
3471 
3472  lglUniformi(i->second, value, warn);
3473 
3474  return(i->second);
3475 
3476 #else
3477 
3478  return(0);
3479 
3480 #endif
3481  }
3482 
3484  void lglUniformi(unsigned int index, int value, bool warn = true)
3485  {
3486 #ifdef LGL_CORE
3487 
3488  if (index < locations_.size())
3489  {
3490  if (locations_[index].type == lgl_no_type)
3491  {
3492  locations_[index].type = lgl_int_type;
3493  locations_[index].value.int_value = value;
3494  }
3495  else if (locations_[index].type == lgl_int_type)
3496  locations_[index].value.int_value = value;
3497  else
3498  lglError("uniform type mismatch");
3499  }
3500  else
3501  lglError("invalid uniform index");
3502 
3503 #endif
3504  }
3505 
3507  unsigned int lglUniformf(std::string uniform, double value, bool warn = true)
3508  {
3509 #ifdef LGL_CORE
3510 
3511  lgl_uniform_map_type::iterator i = uniforms_.find(uniform);
3512 
3513  if (i == uniforms_.end())
3514  {
3515  i = uniforms_.insert(std::pair<std::string, unsigned int>(uniform, locations_.size())).first;
3516 
3517  lgl_uniform_struct u = {-1, uniform, lgl_float_type, {0}, warn};
3518  locations_.resize(locations_.size()+1, u);
3519  }
3520 
3521  lglUniformf(i->second, value, warn);
3522 
3523  return(i->second);
3524 
3525 #else
3526 
3527  return(0);
3528 
3529 #endif
3530  }
3531 
3533  void lglUniformf(unsigned int index, double value, bool warn = true)
3534  {
3535 #ifdef LGL_CORE
3536 
3537  if (index < locations_.size())
3538  {
3539  if (locations_[index].type == lgl_no_type)
3540  {
3541  locations_[index].type = lgl_float_type;
3542  locations_[index].value.float_value = float(value);
3543  }
3544  else if (locations_[index].type == lgl_float_type)
3545  locations_[index].value.float_value = float(value);
3546  else
3547  lglError("uniform type mismatch");
3548  }
3549  else
3550  lglError("invalid uniform index");
3551 
3552 #endif
3553  }
3554 
3556  unsigned int lglUniformfv(std::string uniform, const vec2f &value, bool warn = true)
3557  {
3558 #ifdef LGL_CORE
3559 
3560  lgl_uniform_map_type::iterator i = uniforms_.find(uniform);
3561 
3562  if (i == uniforms_.end())
3563  {
3564  i = uniforms_.insert(std::pair<std::string, unsigned int>(uniform, locations_.size())).first;
3565 
3566  lgl_uniform_struct u = {-1, uniform, lgl_vec2f_type, {0}, warn};
3567  locations_.resize(locations_.size()+1, u);
3568  }
3569 
3570  lglUniformfv(i->second, value, warn);
3571 
3572  return(i->second);
3573 
3574 #else
3575 
3576  return(0);
3577 
3578 #endif
3579  }
3580 
3582  unsigned int lglUniform2fv(std::string uniform, const float value[2], bool warn = true)
3583  {
3584  return(lglUniformfv(uniform, vec2f(value[0], value[1]), warn));
3585  }
3586 
3588  void lglUniformfv(unsigned int index, const vec2f &value, bool warn = true)
3589  {
3590 #ifdef LGL_CORE
3591 
3592  if (index < locations_.size())
3593  {
3594  if (locations_[index].type == lgl_no_type)
3595  {
3596  locations_[index].type = lgl_vec2f_type;
3597  for (int n=0; n<2; n++)
3598  locations_[index].value.vec2f_value[n] = ((const float *)value)[n];
3599  }
3600  else if (locations_[index].type == lgl_vec2f_type)
3601  for (int n=0; n<2; n++)
3602  locations_[index].value.vec2f_value[n] = ((const float *)value)[n];
3603  else
3604  lglError("uniform type mismatch");
3605  }
3606  else
3607  lglError("invalid uniform index");
3608 
3609 #endif
3610  }
3611 
3612  unsigned int lglUniformfv(std::string uniform, const vec2 &value, bool warn = true)
3613  {return(lglUniformfv(uniform, vec2f(value), warn));}
3614 
3615  void lglUniformfv(unsigned int index, const vec2 &value, bool warn = true)
3616  {lglUniformfv(index, vec2f(value), warn);}
3617 
3619  unsigned int lglUniformfv(std::string uniform, const vec3f &value, bool warn = true)
3620  {
3621 #ifdef LGL_CORE
3622 
3623  lgl_uniform_map_type::iterator i = uniforms_.find(uniform);
3624 
3625  if (i == uniforms_.end())
3626  {
3627  i = uniforms_.insert(std::pair<std::string, unsigned int>(uniform, locations_.size())).first;
3628 
3629  lgl_uniform_struct u = {-1, uniform, lgl_vec3f_type, {0}, warn};
3630  locations_.resize(locations_.size()+1, u);
3631  }
3632 
3633  lglUniformfv(i->second, value, warn);
3634 
3635  return(i->second);
3636 
3637 #else
3638 
3639  return(0);
3640 
3641 #endif
3642  }
3643 
3645  unsigned int lglUniform3fv(std::string uniform, const float value[3], bool warn = true)
3646  {
3647  return(lglUniformfv(uniform, vec3f(value[0], value[1], value[2]), warn));
3648  }
3649 
3651  void lglUniformfv(unsigned int index, const vec3f &value, bool warn = true)
3652  {
3653 #ifdef LGL_CORE
3654 
3655  if (index < locations_.size())
3656  {
3657  if (locations_[index].type == lgl_no_type)
3658  {
3659  locations_[index].type = lgl_vec3f_type;
3660  for (int n=0; n<3; n++)
3661  locations_[index].value.vec3f_value[n] = ((const float *)value)[n];
3662  }
3663  else if (locations_[index].type == lgl_vec3f_type)
3664  for (int n=0; n<3; n++)
3665  locations_[index].value.vec3f_value[n] = ((const float *)value)[n];
3666  else
3667  lglError("uniform type mismatch");
3668  }
3669  else
3670  lglError("invalid uniform index");
3671 
3672 #endif
3673  }
3674 
3675  unsigned int lglUniformfv(std::string uniform, const vec3 &value, bool warn = true)
3676  {return(lglUniformfv(uniform, vec3f(value), warn));}
3677 
3678  void lglUniformfv(unsigned int index, const vec3 &value, bool warn = true)
3679  {lglUniformfv(index, vec3f(value), warn);}
3680 
3682  unsigned int lglUniformfv(std::string uniform, const vec4f &value, bool warn = true)
3683  {
3684 #ifdef LGL_CORE
3685 
3686  lgl_uniform_map_type::iterator i = uniforms_.find(uniform);
3687 
3688  if (i == uniforms_.end())
3689  {
3690  i = uniforms_.insert(std::pair<std::string, unsigned int>(uniform, locations_.size())).first;
3691 
3692  lgl_uniform_struct u = {-1, uniform, lgl_vec4f_type, {0}, warn};
3693  locations_.resize(locations_.size()+1, u);
3694  }
3695 
3696  lglUniformfv(i->second, value, warn);
3697 
3698  return(i->second);
3699 
3700 #else
3701 
3702  return(0);
3703 
3704 #endif
3705  }
3706 
3708  unsigned int lglUniform4fv(std::string uniform, const float value[4], bool warn = true)
3709  {
3710  return(lglUniformfv(uniform, vec4f(value[0], value[1], value[2], value[3]), warn));
3711  }
3712 
3714  void lglUniformfv(unsigned int index, const vec4f &value, bool warn = true)
3715  {
3716 #ifdef LGL_CORE
3717 
3718  if (index < locations_.size())
3719  {
3720  if (locations_[index].type == lgl_no_type)
3721  {
3722  locations_[index].type = lgl_vec4f_type;
3723  for (int n=0; n<4; n++)
3724  locations_[index].value.vec4f_value[n] = ((const float *)value)[n];
3725  }
3726  else if (locations_[index].type == lgl_vec4f_type)
3727  for (int n=0; n<4; n++)
3728  locations_[index].value.vec4f_value[n] = ((const float *)value)[n];
3729  else
3730  lglError("uniform type mismatch");
3731  }
3732  else
3733  lglError("invalid uniform index");
3734 
3735 #endif
3736  }
3737 
3738  unsigned int lglUniformfv(std::string uniform, const vec4 &value, bool warn = true)
3739  {return(lglUniformfv(uniform, vec4f(value), warn));}
3740 
3741  void lglUniformfv(unsigned int index, const vec4 &value, bool warn = true)
3742  {lglUniformfv(index, vec4f(value), warn);}
3743 
3744  unsigned int lglUniformf(std::string uniform, double x, double y, double z, double w = 1, bool warn = true)
3745  {return(lglUniformfv(uniform, vec4(x,y,z,w), warn));}
3746 
3747  void lglUniformf(unsigned int index, double x, double y, double z, double w = 1, bool warn = true)
3748  {lglUniformfv(index, vec4(x,y,z,w), warn);}
3749 
3751  unsigned int lglUniformfv(std::string uniform, const mat2f &value, bool warn = true)
3752  {
3753 #ifdef LGL_CORE
3754 
3755  lgl_uniform_map_type::iterator i = uniforms_.find(uniform);
3756 
3757  if (i == uniforms_.end())
3758  {
3759  i = uniforms_.insert(std::pair<std::string, unsigned int>(uniform, locations_.size())).first;
3760 
3761  lgl_uniform_struct u = {-1, uniform, lgl_mat2f_type, {0}, warn};
3762  locations_.resize(locations_.size()+1, u);
3763  }
3764 
3765  lglUniformfv(i->second, value, warn);
3766 
3767  return(i->second);
3768 
3769 #else
3770 
3771  return(0);
3772 
3773 #endif
3774  }
3775 
3777  unsigned int lglUniformMatrix2fv(std::string uniform, const float value[4], bool warn = true)
3778  {
3779  mat2f matrix;
3780  matrix.fromOpenGL(value);
3781  return(lglUniformfv(uniform, matrix, warn));
3782  }
3783 
3785  void lglUniformfv(unsigned int index, const mat2f &value, bool warn = true)
3786  {
3787 #ifdef LGL_CORE
3788 
3789  if (index < locations_.size())
3790  {
3791  if (locations_[index].type == lgl_no_type)
3792  {
3793  locations_[index].type = lgl_mat2f_type;
3794  for (int n=0; n<4; n++)
3795  locations_[index].value.mat2f_value[n] = ((const float *)value)[n];
3796  }
3797  else if (locations_[index].type == lgl_mat2f_type)
3798  for (int n=0; n<4; n++)
3799  locations_[index].value.mat2f_value[n] = ((const float *)value)[n];
3800  else
3801  lglError("uniform type mismatch");
3802  }
3803  else
3804  lglError("invalid uniform index");
3805 
3806 #endif
3807  }
3808 
3809  unsigned int lglUniformfv(std::string uniform, const mat2 &value, bool warn = true)
3810  {return(lglUniformfv(uniform, mat2f(value), warn));}
3811 
3812  void lglUniformfv(unsigned int index, const mat2 &value, bool warn = true)
3813  {lglUniformfv(index, mat2f(value), warn);}
3814 
3816  unsigned int lglUniformfv(std::string uniform, const mat3f &value, bool warn = true)
3817  {
3818 #ifdef LGL_CORE
3819 
3820  lgl_uniform_map_type::iterator i = uniforms_.find(uniform);
3821 
3822  if (i == uniforms_.end())
3823  {
3824  i = uniforms_.insert(std::pair<std::string, unsigned int>(uniform, locations_.size())).first;
3825 
3826  lgl_uniform_struct u = {-1, uniform, lgl_mat3f_type, {0}, warn};
3827  locations_.resize(locations_.size()+1, u);
3828  }
3829 
3830  lglUniformfv(i->second, value, warn);
3831 
3832  return(i->second);
3833 
3834 #else
3835 
3836  return(0);
3837 
3838 #endif
3839  }
3840 
3842  unsigned int lglUniformMatrix3fv(std::string uniform, const float value[9], bool warn = true)
3843  {
3844  mat3f matrix;
3845  matrix.fromOpenGL(value);
3846  return(lglUniformfv(uniform, matrix, warn));
3847  }
3848 
3850  void lglUniformfv(unsigned int index, const mat3f &value, bool warn = true)
3851  {
3852 #ifdef LGL_CORE
3853 
3854  if (index < locations_.size())
3855  {
3856  if (locations_[index].type == lgl_no_type)
3857  {
3858  locations_[index].type = lgl_mat3f_type;
3859  for (int n=0; n<9; n++)
3860  locations_[index].value.mat3f_value[n] = ((const float *)value)[n];
3861  }
3862  else if (locations_[index].type == lgl_mat3f_type)
3863  for (int n=0; n<9; n++)
3864  locations_[index].value.mat3f_value[n] = ((const float *)value)[n];
3865  else
3866  lglError("uniform type mismatch");
3867  }
3868  else
3869  lglError("invalid uniform index");
3870 
3871 #endif
3872  }
3873 
3874  unsigned int lglUniformfv(std::string uniform, const mat3 &value, bool warn = true)
3875  {return(lglUniformfv(uniform, mat3f(value), warn));}
3876 
3877  void lglUniformfv(unsigned int index, const mat3 &value, bool warn = true)
3878  {lglUniformfv(index, mat3f(value), warn);}
3879 
3881  unsigned int lglUniformfv(std::string uniform, const mat4f &value, bool warn = true)
3882  {
3883 #ifdef LGL_CORE
3884 
3885  lgl_uniform_map_type::iterator i = uniforms_.find(uniform);
3886 
3887  if (i == uniforms_.end())
3888  {
3889  i = uniforms_.insert(std::pair<std::string, unsigned int>(uniform, locations_.size())).first;
3890 
3891  lgl_uniform_struct u = {-1, uniform, lgl_mat4f_type, {0}, warn};
3892  locations_.resize(locations_.size()+1, u);
3893  }
3894 
3895  lglUniformfv(i->second, value, warn);
3896 
3897  return(i->second);
3898 
3899 #else
3900 
3901  return(0);
3902 
3903 #endif
3904  }
3905 
3907  unsigned int lglUniformMatrix4fv(std::string uniform, const float value[16], bool warn = true)
3908  {
3909  mat4f matrix;
3910  matrix.fromOpenGL(value);
3911  return(lglUniformfv(uniform, matrix, warn));
3912  }
3913 
3915  void lglUniformfv(unsigned int index, const mat4f &value, bool warn = true)
3916  {
3917 #ifdef LGL_CORE
3918 
3919  if (index < locations_.size())
3920  {
3921  if (locations_[index].type == lgl_no_type)
3922  {
3923  locations_[index].type = lgl_mat4f_type;
3924  for (int n=0; n<16; n++)
3925  locations_[index].value.mat4f_value[n] = ((const float *)value)[n];
3926  }
3927  else if (locations_[index].type == lgl_mat4f_type)
3928  for (int n=0; n<16; n++)
3929  locations_[index].value.mat4f_value[n] = ((const float *)value)[n];
3930  else
3931  lglError("uniform type mismatch");
3932  }
3933  else
3934  lglError("invalid uniform index");
3935 
3936 #endif
3937  }
3938 
3939  unsigned int lglUniformfv(std::string uniform, const mat4 &value, bool warn = true)
3940  {return(lglUniformfv(uniform, mat4f(value), warn));}
3941 
3942  void lglUniformfv(unsigned int index, const mat4 &value, bool warn = true)
3943  {lglUniformfv(index, mat4f(value), warn);}
3944 
3946  unsigned int lglSampler(std::string sampler, int value = 0, bool warn = true)
3947  {
3948  return(lglUniformi(sampler, value, warn));
3949  }
3950 
3952  void lglSampler(unsigned int index, int value = 0, bool warn = true)
3953  {
3954  lglUniformi(index, value, warn);
3955  }
3956 
3958  unsigned int lglSampler2D(std::string sampler, GLuint texid2D, int value = 0, bool warn = true)
3959  {
3960 #ifdef _WIN32
3961  initWGLprocs();
3962 #endif
3963 
3964  unsigned int index = lglUniformi(sampler, value, warn);
3965 #ifdef GL_ARB_multitexture
3966  if (value != 0) glActiveTexture(GL_TEXTURE0_ARB+value);
3967 #endif
3968  glBindTexture(GL_TEXTURE_2D, texid2D);
3969 #ifdef GL_ARB_multitexture
3970  if (value != 0) glActiveTexture(GL_TEXTURE0_ARB);
3971 #endif
3972  return(index);
3973  }
3974 
3976  void lglSampler2D(unsigned int index, GLuint texid2D, int value = 0, bool warn = true)
3977  {
3978 #ifdef _WIN32
3979  initWGLprocs();
3980 #endif
3981 
3982  lglUniformi(index, value, warn);
3983 #ifdef GL_ARB_multitexture
3984  if (value != 0) glActiveTexture(GL_TEXTURE0_ARB+value);
3985 #endif
3986  glBindTexture(GL_TEXTURE_2D, texid2D);
3987 #ifdef GL_ARB_multitexture
3988  if (value != 0) glActiveTexture(GL_TEXTURE0_ARB);
3989 #endif
3990  }
3991 
3993  unsigned int lglSampler3D(std::string sampler, GLuint texid3D, int value = 0, bool warn = true)
3994  {
3995 #if !defined(LGL_GLES) || defined(LGL_GLES3)
3996 
3997 #ifdef _WIN32
3998  initWGLprocs();
3999 #endif
4000 
4001  unsigned int index = lglUniformi(sampler, value, warn);
4002 #ifdef GL_ARB_multitexture
4003  if (value != 0) glActiveTexture(GL_TEXTURE0_ARB+value);
4004 #endif
4005  glBindTexture(GL_TEXTURE_3D, texid3D);
4006 #ifdef GL_ARB_multitexture
4007  if (value != 0) glActiveTexture(GL_TEXTURE0_ARB);
4008 #endif
4009  return(index);
4010 
4011 #else
4012 
4013  return(0);
4014 
4015 #endif
4016  }
4017 
4019  void lglSampler3D(unsigned int index, GLuint texid3D, int value = 0, bool warn = true)
4020  {
4021 #if !defined(LGL_GLES) || defined(LGL_GLES3)
4022 
4023 #ifdef _WIN32
4024  initWGLprocs();
4025 #endif
4026 
4027  lglUniformi(index, value, warn);
4028 #ifdef GL_ARB_multitexture
4029  if (value != 0) glActiveTexture(GL_TEXTURE0_ARB+value);
4030 #endif
4031  glBindTexture(GL_TEXTURE_3D, texid3D);
4032 #ifdef GL_ARB_multitexture
4033  if (value != 0) glActiveTexture(GL_TEXTURE0_ARB);
4034 #endif
4035 
4036 #endif
4037  }
4038 
4040  void lglCloneUniforms(const lgl *vbo)
4041  {
4042 #ifdef LGL_CORE
4043 
4044  uniforms_ = vbo->uniforms_;
4045  locations_ = vbo->locations_;
4046 
4047 #endif
4048  }
4049 
4051  void lglCopyUniforms(const lgl *vbo, bool warn = false)
4052  {
4053 #ifdef LGL_CORE
4054 
4055  for (typename lgl_uniform_map_type::const_iterator i = vbo->uniforms_.begin(); i != vbo->uniforms_.end(); i++)
4056  {
4057  std::string uniform = i->first;
4058  unsigned int index = i->second;
4059 
4060  switch (vbo->locations_[index].type)
4061  {
4062  case lgl_int_type: lglUniformi(uniform, vbo->locations_[index].value.int_value, warn); break;
4063  case lgl_float_type: lglUniformf(uniform, vbo->locations_[index].value.float_value, warn); break;
4064  case lgl_vec2f_type: lglUniform2fv(uniform, vbo->locations_[index].value.vec2f_value, warn); break;
4065  case lgl_vec3f_type: lglUniform3fv(uniform, vbo->locations_[index].value.vec3f_value, warn); break;
4066  case lgl_vec4f_type: lglUniform4fv(uniform, vbo->locations_[index].value.vec4f_value, warn); break;
4067  case lgl_mat2f_type: lglUniformMatrix2fv(uniform, vbo->locations_[index].value.mat2f_value, warn); break;
4068  case lgl_mat3f_type: lglUniformMatrix3fv(uniform, vbo->locations_[index].value.mat3f_value, warn); break;
4069  case lgl_mat4f_type: lglUniformMatrix4fv(uniform, vbo->locations_[index].value.mat4f_value, warn); break;
4070  case lgl_no_type: if (vbo->locations_[index].warn) lglWarning("copying undefined uniform: " + uniform); break;
4071  }
4072  }
4073 
4074 #endif
4075  }
4076 
4079  {
4080 #ifdef LGL_CORE
4081 
4082  for (typename lgl_uniform_location_type::const_iterator i = locations_.begin(); i != locations_.end(); i++)
4083  {
4084  std::cout << "uniform \"" << i->uniform << "\": ";
4085 
4086  switch (i->type)
4087  {
4088  case lgl_int_type: std::cout << i->value.int_value; break;
4089  case lgl_float_type: std::cout << i->value.float_value; break;
4090  case lgl_vec2f_type: std::cout << vec2f(i->value.vec2f_value[0], i->value.vec2f_value[1]); break;
4091  case lgl_vec3f_type: std::cout << vec3f(i->value.vec3f_value[0], i->value.vec3f_value[1], i->value.vec3f_value[2]); break;
4092  case lgl_vec4f_type: std::cout << vec4f(i->value.vec4f_value[0], i->value.vec4f_value[1], i->value.vec4f_value[2], i->value.vec4f_value[3]); break;
4093  case lgl_mat2f_type: {mat2f m2f; m2f.fromOpenGL(i->value.mat2f_value); std::cout << m2f;} break;
4094  case lgl_mat3f_type: {mat3f m3f; m3f.fromOpenGL(i->value.mat3f_value); std::cout << m3f;} break;
4095  case lgl_mat4f_type: {mat4f m4f; m4f.fromOpenGL(i->value.mat4f_value); std::cout << m4f;} break;
4096  case lgl_no_type: std::cout << "undefined"; break;
4097  }
4098 
4099  std::cout << std::endl;
4100  }
4101 
4102 #endif
4103  }
4104 
4106  void lglCloneProgram(const lgl *vbo)
4107  {
4108 #ifdef LGL_CORE
4109 
4110  program_ = vbo->program_;
4111  uniforms_ = vbo->uniforms_;
4112  locations_ = vbo->locations_;
4113 
4114 #endif
4115  }
4116 
4118  void lglCopyProgram(const lgl *vbo)
4119  {
4120 #ifdef LGL_CORE
4121 
4122  program_ = vbo->program_;
4123  lglCopyUniforms(vbo);
4124 
4125 #endif
4126  }
4127 
4129  void lglLight(vec4f light = vec4f(0,0,1,0), bool camera_light = true,
4130  vec3f ka = vec3f(0.1f), vec3f kd = vec3f(0.7f), vec3f ks = vec3f(0.2f),
4131  vec3f Ia = vec3f(1), vec3f Id = vec3f(1), vec3f Is = vec3f(1),
4132  float exponent = 30, vec3f falloff = vec3f(1,0,0))
4133  {
4134  lglLightVector(light, camera_light);
4135  lglLightParameters(ka, kd, ks, Ia, Id, Is, exponent, falloff);
4136  }
4137 
4139  void lglLightDirection(vec3f light = vec3f(0,0,1), bool camera_light = true)
4140  {
4141  lglLightVector(vec4f(light, 0), camera_light);
4142  }
4143 
4145  void lglLightPosition(vec3f light = vec3f(0,0,0), bool camera_light = true)
4146  {
4147  lglLightVector(vec4f(light, 1), camera_light);
4148  }
4149 
4151  void lglLightVector(vec4f light = vec4f(0,0,1,0), bool camera_light = true)
4152  {
4153  if (camera_light)
4154  light_ = light;
4155  else
4156  {
4157  if (light.w == 0)
4158  {
4159  // directional light vector
4161  light_ = vec4f((mat3(mvit) * light.xyz()).normalize(), 0);
4162  }
4163  else
4164  {
4165  // positional light vector
4166  mat4 mv = lglGetModelViewMatrix();
4167  light_ = mv * light;
4168  }
4169  }
4170 
4171  if (light_.w == 0)
4172  falloff_ = vec3f(1,0,0);
4173  }
4174 
4177  {
4178  return(light_);
4179  }
4180 
4182  void lglLightParameters(vec3f ka = vec3f(0.1f), vec3f kd = vec3f(0.7f), vec3f ks = vec3f(0.2f),
4183  vec3f Ia = vec3f(1), vec3f Id = vec3f(1), vec3f Is = vec3f(1),
4184  float exponent = 30, vec3f falloff = vec3f(1,0,0))
4185  {
4186  ka_ = ka;
4187  kd_ = kd;
4188  ks_ = ks;
4189 
4190  Ia_ = Ia;
4191  Id_ = Id;
4192  Is_ = Is;
4193 
4194  exponent_ = exponent;
4195  falloff_ = falloff;
4196 
4197  if (light_.w == 0)
4198  falloff_ = vec3f(1,0,0);
4199  }
4200 
4203  vec3f &Ia, vec3f &Id, vec3f &Is,
4204  float &exponent, vec3f &falloff) const
4205  {
4206  ka = ka_;
4207  kd = kd_;
4208  ks = ks_;
4209 
4210  Ia = Ia_;
4211  Id = Id_;
4212  Is = Is_;
4213 
4214  exponent = exponent_;
4215  falloff = falloff_;
4216  }
4217 
4219  void lglLightSourceParameters(vec3f Ia = vec3f(1), vec3f Id = vec3f(1), vec3f Is = vec3f(1),
4220  vec3f falloff = vec3f(1,0,0))
4221  {
4222  Ia_ = Ia;
4223  Id_ = Id;
4224  Is_ = Is;
4225 
4226  falloff_ = falloff;
4227 
4228  if (light_.w == 0)
4229  falloff_ = vec3f(1,0,0);
4230  }
4231 
4234  vec3f &falloff) const
4235  {
4236  Ia = Ia_;
4237  Id = Id_;
4238  Is = Is_;
4239 
4240  falloff = falloff_;
4241  }
4242 
4244  void lglMaterialParameters(vec3f ka = vec3f(0.1f), vec3f kd = vec3f(0.7f), vec3f ks = vec3f(0.2f),
4245  float exponent = 30)
4246  {
4247  ka_ = ka;
4248  kd_ = kd;
4249  ks_ = ks;
4250 
4251  exponent_ = exponent;
4252  }
4253 
4256  float &exponent) const
4257  {
4258  ka = ka_;
4259  kd = kd_;
4260  ks = ks_;
4261 
4262  exponent = exponent_;
4263  }
4264 
4266  void lglTexture2D(GLuint texid, bool owner = false)
4267  {
4268  if (texid != texid2D_ && texid_owner_) lglDeleteTexture2D();
4269  if (texid != 0 && texid_owner_) lglDeleteTexture3D();
4270 
4271  texid2D_ = texid;
4272  texid_owner_ = owner;
4273  }
4274 
4276  GLuint lglGetTexture2D() const
4277  {
4278  return(texid2D_);
4279  }
4280 
4282  void lglTexture3D(GLuint texid, bool owner = false)
4283  {
4284  if (texid != texid3D_ && texid_owner_) lglDeleteTexture3D();
4285  if (texid != 0 && texid_owner_) lglDeleteTexture2D();
4286 
4287  texid3D_ = texid;
4288  texid_owner_ = owner;
4289  }
4290 
4292  GLuint lglGetTexture3D() const
4293  {
4294  return(texid3D_);
4295  }
4296 
4298  inline void lglDeleteTexture2D()
4299  {
4300  if (texid2D_ != 0)
4301  {
4302  GLuint GLtexid = texid2D_;
4303  glDeleteTextures(1, &GLtexid);
4304  texid2D_ = 0;
4305  }
4306  }
4307 
4309  inline void lglDeleteTexture3D()
4310  {
4311  if (texid3D_ != 0)
4312  {
4313  GLuint GLtexid = texid3D_;
4314  glDeleteTextures(1, &GLtexid);
4315  texid3D_ = 0;
4316  }
4317  }
4318 
4320  inline void lglDeleteTexture()
4321  {
4324  }
4325 
4327  void lglTexCoordGen(lgl_texgenmode_enum mode = LGL_TEXGEN_LINEAR,
4328  double mix = 0.5)
4329  {
4330  texgen_ = mode;
4331  texgen_mix_ = mix;
4332  }
4333 
4336  {
4337  return(texgen_);
4338  }
4339 
4341  void lglCloneState(const lgl *vbo)
4342  {
4343  vec3f ka, kd, ks;
4344  float exponent;
4345 
4346  lglColoring(vbo->lglGetColoring());
4347 
4348  lglLighting(vbo->lglGetLighting());
4349  vbo->lglGetMaterialParameters(ka, kd, ks, exponent);
4350  lglMaterialParameters(ka, kd, ks, exponent);
4351 
4352  lglTexturing(vbo->lglGetTexturing());
4353  lglTexture2D(vbo->lglGetTexture2D());
4354  lglTexture3D(vbo->lglGetTexture3D());
4355  }
4356 
4358  static void lglInitializeOpenGL(float r=0, float g=0, float b=0, float a=1,
4359  bool ztest = true, bool culling = false)
4360  {
4361  lglClearColor(r,g,b,a);
4362  lglDepthTest(ztest);
4363  lglBackFaceCulling(culling);
4364  }
4365 
4367  static void lglViewport(int ax, int ay, int bx, int by)
4368  {
4369  glViewport(ax, ay, bx, by);
4370  }
4371 
4372  static void lglClearColor(float w, float a=1)
4373  {
4374  glClearColor(w,w,w,a);
4375  }
4376 
4378  static void lglClearColor(float r, float g, float b, float a=1)
4379  {
4380  glClearColor(r,g,b,a);
4381  }
4382 
4384  static void lglClear(GLuint bits = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
4385  {
4386  glClear(bits);
4387  }
4388 
4390  static void lglRGBAWrite(bool r = true, bool g = true, bool b = true, bool a = true)
4391  {
4392  // specify color mask
4393  glColorMask(r?GL_TRUE:GL_FALSE,
4394  g?GL_TRUE:GL_FALSE,
4395  b?GL_TRUE:GL_FALSE,
4396  a?GL_TRUE:GL_FALSE);
4397  }
4398 
4400  static bool lglGetRGBAWrite()
4401  {
4402  GLboolean color_write[4];
4403  glGetBooleanv(GL_DEPTH_WRITEMASK, color_write);
4404  return(color_write[0]!=0 && color_write[1]!=0 && color_write[2]!=0 && color_write[3]!=0);
4405  }
4406 
4408  static void lglZWrite(bool on = true)
4409  {
4410  if (on)
4411  {
4412  // enable Z writing
4413  glDepthMask(GL_TRUE);
4414  }
4415  else
4416  {
4417  // disable Z writing
4418  glDepthMask(GL_FALSE);
4419  }
4420  }
4421 
4423  static bool lglGetZWrite()
4424  {
4425  GLboolean depth_write;
4426  glGetBooleanv(GL_DEPTH_WRITEMASK, &depth_write);
4427  return(depth_write!=0);
4428  }
4429 
4431  static void lglDepthTest(bool on = true)
4432  {
4433  if (on)
4434  {
4435  // enable Z test
4436  glEnable(GL_DEPTH_TEST);
4437  }
4438  else
4439  {
4440  // disable Z test
4441  glDisable(GL_DEPTH_TEST);
4442  }
4443  }
4444 
4446  static bool lglGetDepthTest()
4447  {
4448  GLboolean depth_test;
4449  glGetBooleanv(GL_DEPTH_TEST, &depth_test);
4450  return(depth_test!=0);
4451  }
4452 
4454  static void lglBackFaceCulling(bool on = true)
4455  {
4456  if (on)
4457  {
4458  // enable back-face culling
4459  glFrontFace(GL_CCW); // front faces are defined counter-clockwise
4460  glCullFace(GL_BACK); // cull back faces
4461  glEnable(GL_CULL_FACE); // enable culling
4462  }
4463  else
4464  {
4465  // disable culling
4466  glDisable(GL_CULL_FACE);
4467  }
4468  }
4469 
4472  {
4473  GLboolean cull_face;
4474  glGetBooleanv(GL_CULL_FACE, &cull_face);
4475  return(cull_face!=0);
4476  }
4477 
4479  static void lglBlendMode(lgl_blendmode_enum mode = LGL_BLEND_NONE)
4480  {
4481 #ifdef _WIN32
4482  initWGLprocs();
4483 #endif
4484 
4485  blendmode_ = mode;
4486 
4487  if (mode == LGL_BLEND_NONE)
4488  {
4489  // disable blending
4490  glDisable(GL_BLEND);
4491  }
4492  else if (mode == LGL_BLEND_MULT)
4493  {
4494  // enable multiplicative blending
4495  glBlendFunc(GL_DST_COLOR, GL_ZERO);
4496 #ifdef _WIN32
4497  if (glBlendEquation) glBlendEquation(GL_FUNC_ADD);
4498 #else
4499  glBlendEquation(GL_FUNC_ADD);
4500 #endif
4501  glEnable(GL_BLEND);
4502  }
4503  else if (mode == LGL_BLEND_ALPHA)
4504  {
4505  // enable alpha blending
4506  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
4507 #ifdef _WIN32
4508  if (glBlendEquation) glBlendEquation(GL_FUNC_ADD);
4509 #else
4510  glBlendEquation(GL_FUNC_ADD);
4511 #endif
4512  glEnable(GL_BLEND);
4513  }
4514  else if (mode == LGL_BLEND_ADD)
4515  {
4516  // enable additive blending
4517  glBlendFunc(GL_ONE, GL_ONE);
4518 #ifdef _WIN32
4519  if (glBlendEquation) glBlendEquation(GL_FUNC_ADD);
4520 #else
4521  glBlendEquation(GL_FUNC_ADD);
4522 #endif
4523  glEnable(GL_BLEND);
4524  }
4525  else if (mode == LGL_BLEND_SUB)
4526  {
4527  // enable subtractive blending
4528  glBlendFunc(GL_ONE, GL_ONE);
4529 #ifdef _WIN32
4530  if (glBlendEquation) glBlendEquation(GL_FUNC_REVERSE_SUBTRACT);
4531 #else
4532  glBlendEquation(GL_FUNC_REVERSE_SUBTRACT);
4533 #endif
4534  glEnable(GL_BLEND);
4535  }
4536  else if (mode == LGL_BLEND_MAX)
4537  {
4538  // maximum intensity mode
4539  glBlendFunc(GL_ONE,GL_ONE);
4540 #ifdef _WIN32
4541  if (glBlendEquation) glBlendEquation(GL_MAX);
4542 #else
4543  glBlendEquation(GL_MAX);
4544 #endif
4545  glEnable(GL_BLEND);
4546  }
4547  else if (mode == LGL_BLEND_MIN)
4548  {
4549  // minimum intensity mode
4550  glBlendFunc(GL_ONE,GL_ONE);
4551 #ifdef _WIN32
4552  if (glBlendEquation) glBlendEquation(GL_MIN);
4553 #else
4554  glBlendEquation(GL_MIN);
4555 #endif
4556  glEnable(GL_BLEND);
4557  }
4558  }
4559 
4561  static bool lglGetBlending()
4562  {
4563  GLboolean blend;
4564  glGetBooleanv(GL_BLEND, &blend);
4565  return(blend!=0);
4566  }
4567 
4570  {
4571  return(blendmode_);
4572  }
4573 
4575  static void lglAlphaTest(bool on = false, float value = 0.0f, bool greater = true, bool equal = false)
4576  {
4577  alphavalue_ = value;
4578 
4579 #ifndef LGL_CORE
4580 
4581  if (on)
4582  {
4583  // enable alpha test
4584  if (greater) glAlphaFunc(equal?GL_GEQUAL:GL_GREATER, value);
4585  else glAlphaFunc(equal?GL_LEQUAL:GL_LESS, value);
4586  glEnable(GL_ALPHA_TEST);
4587  }
4588  else
4589  {
4590  // disable alpha test
4591  glDisable(GL_ALPHA_TEST);
4592  }
4593 
4594 #endif
4595 
4596  // setup shader test
4597  if (on)
4598  if (greater)
4599  if (equal)
4600  alphatest_ = vec3f(value, -1, 1); // discard alpha < value
4601  else
4602  alphatest_ = vec3f(value, value, 1); // discard alpha <= value
4603  else
4604  if (equal)
4605  alphatest_ = vec3f(-value, 1, -1); // discard -alpha < -value
4606  else
4607  alphatest_ = vec3f(-value, -value, -1); // discard -alpha <= -value
4608  else
4609  alphatest_ = vec3f(-1,-1,0); // discard none
4610  }
4611 
4613  static bool lglGetAlphaTest()
4614  {
4615 #ifndef LGL_CORE
4616 
4617  GLboolean alpha_test;
4618  glGetBooleanv(GL_ALPHA_TEST, &alpha_test);
4619  return(alpha_test != 0);
4620 
4621 #else
4622 
4623  return(alphatest_.z != 0);
4624 
4625 #endif
4626  }
4627 
4629  static float lglGetAlphaTestValue()
4630  {
4631  return(alphavalue_);
4632  }
4633 
4636  {
4637  return(alphatest_.z > 0);
4638  }
4639 
4641  static bool lglGetAlphaTestEqual()
4642  {
4643  return(alphatest_.x != alphatest_.y);
4644  }
4645 
4647  void lglClipPlane(vec4 equation = vec4(0,0,0,0), unsigned int n = 0, bool camera_plane = false)
4648  {
4649  if (n < LGL_NUM_CLIPPLANES)
4650  {
4651  if (equation != vec4(0,0,0,0))
4652  {
4653  if (clipplane_[n] == vec4(0,0,0,0)) clipping_++;
4654  if (!camera_plane)
4655  {
4657  equation = mvit * equation;
4658  }
4659  clipplane_[n] = equation;
4660  }
4661  else
4662  {
4663  if (clipplane_[n] != vec4(0,0,0,0)) clipping_--;
4664  clipplane_[n] = vec4(0,0,0,0);
4665  }
4666  }
4667  }
4668 
4670  void lglClipPlane(double a, double b, double c, double d, unsigned int n = 0, bool camera_plane = false)
4671  {
4672  lglClipPlane(vec4(a,b,c,d), n, camera_plane);
4673  }
4674 
4676  void lglClipPlane(vec3 point, vec3 normal, unsigned int n = 0, bool camera_plane = false)
4677  {
4678  lglClipPlane(lglGetClipPlaneEquation(point, normal), n, camera_plane);
4679  }
4680 
4682  static bool lglGetClipPlane(unsigned int n = 0)
4683  {
4684  if (n < LGL_NUM_CLIPPLANES)
4685  return(clipplane_[n]!=vec4(0,0,0,0));
4686  else
4687  return(false);
4688  }
4689 
4691  static vec4 lglGetClipPlaneEquation(unsigned int n = 0)
4692  {
4693  if (n < LGL_NUM_CLIPPLANES)
4694  return(clipplane_[n]);
4695  else
4696  return(vec4(0,0,0,0));
4697  }
4698 
4700  static vec4 lglGetClipPlaneEquation(vec3 point, vec3 normal)
4701  {
4702  // normalize clip plane normal
4703  normal = normal.normalize();
4704 
4705  // define clip plane equation via point on plane and normal
4706  return(vec4(normal.x, normal.y, normal.z, -normal.dot(point)));
4707  }
4708 
4710  static void lglFog(float density = 0.0f, vec4f color = vec4f(1))
4711  {
4712  fogdensity_ = density;
4713  fogcolor_ = color;
4714  }
4715 
4717  static bool lglGetFog()
4718  {
4719  return(fogdensity_ > 0.0f);
4720  }
4721 
4723  static float lglGetFogDensity()
4724  {
4725  return(fogdensity_);
4726  }
4727 
4730  {
4731  return(fogcolor_);
4732  }
4733 
4735  static void lglLineWidth(float width = 1.0f)
4736  {
4737  glLineWidth(width);
4738  }
4739 
4741  static float lglGetLineWidth()
4742  {
4743  GLfloat line_width;
4744  glGetFloatv(GL_LINE_WIDTH, &line_width);
4745  return(line_width);
4746  }
4747 
4750  {
4751  polygonmode_ = mode;
4752  }
4753 
4754  static void lglTogglePolygonMode()
4755  {
4756  if (polygonmode_ == LGL_FILL)
4757  polygonmode_ = LGL_LINE;
4758  else if (polygonmode_ == LGL_LINE)
4759  polygonmode_ = LGL_FILL;
4760  }
4761 
4764  {
4765  return(polygonmode_);
4766  }
4767 
4770  {
4771  interlacing_ = mode;
4772  }
4773 
4776  {
4777  switch (mode)
4778  {
4779  case LGL_INTERLACE_NONE: break;
4780  case LGL_INTERLACE_HORIZONTAL_LEFT: mode = LGL_INTERLACE_HORIZONTAL_RIGHT; break;
4781  case LGL_INTERLACE_HORIZONTAL_RIGHT: mode = LGL_INTERLACE_HORIZONTAL_LEFT; break;
4782  case LGL_INTERLACE_VERTICAL_TOP: mode = LGL_INTERLACE_VERTICAL_BOTTOM; break;
4783  case LGL_INTERLACE_VERTICAL_BOTTOM: mode = LGL_INTERLACE_VERTICAL_TOP; break;
4784  }
4785 
4786  lglInterlacingMode(mode);
4787  }
4788 
4791  {
4792  return(interlacing_);
4793  }
4794 
4796  static unsigned char *lglReadRGBPixels(int x, int y, int width, int height)
4797  {
4798 #ifndef LGL_GLES
4799 
4800  unsigned char *pixels;
4801 
4802  glFinish();
4803 
4804  if ((pixels=(unsigned char *)malloc(3*width*height)) == NULL)
4805  {
4806  lglError("insufficient memory");
4807  return(NULL);
4808  }
4809 
4810  glReadBuffer(GL_BACK);
4811  glReadPixels(x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, pixels);
4812 
4813  for (int y=1; y<height/2; y++)
4814  for (int x=1; x<width; x++)
4815  for (int z=0; z<3; z++)
4816  {
4817  unsigned char tmp = pixels[3*(x+y*width)+z];
4818  pixels[3*(x+y*width)+z] = pixels[3*(x+(height-y)*width)+z];
4819  pixels[3*(x+(height-y)*width)+z] = tmp;
4820  }
4821 
4822  return(pixels);
4823 
4824 #endif
4825 
4826  return(NULL);
4827  }
4828 
4830  double lglIntersect(vec3 origin, vec3 direction, mat4 m, double mindist = 0) const
4831  {
4832  double dist = DBL_MAX;
4833 
4834  mat4 mi = m.invert();
4835  vec3 o = mi * vec4(origin);
4836  vec3 d = (mat3(mi) * direction).normalize();
4837 
4838  // check bbox for intersection
4839  if (!glslmath::itest_ray_bbox(o, d, lglGetCenter(), 0.5*lglGetExtent()))
4840  return(dist);
4841 
4842  // check vertex array for intersections
4843  switch (primitive_)
4844  {
4845  case LGL_NONE:
4846  case LGL_LINES:
4847  case LGL_LINE_STRIP:
4848  break;
4849  case LGL_TRIANGLE_FAN:
4850  if (size_ > 2)
4851  {
4852  vec3 v1 = vertices_[0];
4853  vec3 v2 = vertices_[1];
4854  for (int i=2; i<size_; i++)
4855  {
4856  vec3 v3 = vertices_[i];
4857  double td = glslmath::ray_triangle_dist(o, d, v1, v2, v3);
4858  v2 = v3;
4859 
4860  if (td < dist) dist = td;
4861  }
4862  }
4863  break;
4864  case LGL_QUADS:
4865  if (size_ > 3)
4866  {
4867  for (int i=0; i<size_/4; i++)
4868  {
4869  vec3 v1 = vertices_[4*i];
4870  vec3 v2 = vertices_[4*i+1];
4871  vec3 v3 = vertices_[4*i+2];
4872  vec3 v4 = vertices_[4*i+3];
4873  double td1 = glslmath::ray_triangle_dist(o, d, v1, v2, v3);
4874  double td2 = glslmath::ray_triangle_dist(o, d, v1, v3, v4);
4875 
4876  if (td1 < dist) dist = td1;
4877  if (td2 < dist) dist = td2;
4878  }
4879  }
4880  break;
4881  case LGL_QUAD_STRIP:
4882  if (size_ > 3)
4883  {
4884  vec3 v1 = vertices_[0];
4885  vec3 v2 = vertices_[1];
4886  for (int i=2; i+1<size_; i+=2)
4887  {
4888  vec3 v3 = vertices_[i];
4889  vec3 v4 = vertices_[i+1];
4890  double td1 = glslmath::ray_triangle_dist(o, d, v1, v2, v4);
4891  double td2 = glslmath::ray_triangle_dist(o, d, v1, v4, v3);
4892  v1 = v3;
4893  v2 = v4;
4894 
4895  if (td1 < dist) dist = td1;
4896  if (td2 < dist) dist = td2;
4897  }
4898  }
4899  break;
4900  case LGL_TRIANGLE_STRIP:
4901  if (size_ > 2)
4902  {
4903  vec3 v1 = vertices_[0];
4904  vec3 v2 = vertices_[1];
4905  for (int i=2; i<size_; i++)
4906  {
4907  vec3 v3 = vertices_[i];
4908  double td = glslmath::ray_triangle_dist(o, d, v1, v2, v3);
4909  v1 = v2;
4910  v2 = v3;
4911 
4912  if (td < dist) dist = td;
4913  }
4914  }
4915  break;
4916  case LGL_TRIANGLES:
4917  if (size_ > 2)
4918  {
4919  for (int i=0; i<size_/3; i++)
4920  {
4921  vec3 v1 = vertices_[3*i];
4922  vec3 v2 = vertices_[3*i+1];
4923  vec3 v3 = vertices_[3*i+2];
4924  double td = glslmath::ray_triangle_dist(o, d, v1, v2, v3);
4925 
4926  if (td < dist) dist = td;
4927  }
4928  }
4929  break;
4930  }
4931 
4932  // transform hit distance
4933  if (dist != DBL_MAX)
4934  {
4935  vec3 p = m*vec4(o + dist*d);
4936  dist = (p-origin).length();
4937  }
4938 
4939  if (dist < mindist)
4940  dist = DBL_MAX;
4941 
4942  return(dist);
4943  }
4944 
4946  double lglIntersect(vec3 origin, vec3 direction, double mindist = 0) const
4947  {
4948  return(lglIntersect(origin, direction, lglGetModelViewMatrix(), mindist));
4949  }
4950 
4952  static void lglBeginRayCast(vec3 origin, vec3 direction, double mindist = 0)
4953  {
4954  raycast_ = true;
4955  raycast_origin_ = origin;
4956  raycast_direction_ = direction;
4957  raycast_mindist_ = mindist;
4958  raycast_dist_ = DBL_MAX;
4959  raycast_vbo_ = NULL;
4960  }
4961 
4963  static void lglRayCast(lgl *vbo)
4964  {
4965  if (raycast_)
4966  {
4967  double d = vbo->lglIntersect(raycast_origin_, raycast_direction_, raycast_mindist_);
4968 
4969  if (d < raycast_dist_)
4970  {
4971  raycast_dist_ = d;
4972  raycast_vbo_ = vbo;
4973  }
4974  }
4975  }
4976 
4978  static lgl *lglEndRayCast()
4979  {
4980  raycast_ = false;
4981  return(raycast_vbo_);
4982  }
4983 
4985  static double lglGetRayCastDistance()
4986  {
4987  return(raycast_dist_);
4988  }
4989 
4991  static void lglEnableViewCulling(int minsize = 0)
4992  {
4993  cull_ = true;
4994  cull_minsize_ = minsize;
4995  }
4996 
4999  {
5000  cull_ = false;
5001  }
5002 
5007  static void lglBeginExport(void (*callback)(lgl *vbo, void *data), void *data,
5008  mat4 matrix = mat4(1))
5009  {
5010  export_ = callback;
5011  export_data_ = data;
5012  export_matrix_ = matrix;
5013  }
5014 
5016  static void lglExport(lgl *vbo)
5017  {
5018  if (export_)
5019  {
5020  lgl copy;
5021  vbo->lglAppendVerticesTo(&copy);
5022  vec4 c = vbo->lglGetColor();
5023  if (c != vec4(1)) copy.lglApplyColor(c);
5024  mat4 m = vbo->lglGetModelViewMatrix();
5025  if (export_matrix_ != mat4(1)) m = export_matrix_ * m;
5026  else
5027  {
5028  if (lglIsManipApplied()) m = lglGetManip().invert() * m;
5029  if (eye_!=at_ && up_!=vec3(0)) m = mat4::lookat(eye_, at_, up_).invert() * m;
5030  }
5031  copy.lglModel(m);
5032  copy.lglApplyModelMatrix();
5033  export_(&copy, export_data_);
5034  }
5035  }
5036 
5038  static void lglEndExport()
5039  {
5040  export_ = NULL;
5041  }
5042 
5044  static int lglGetGLVersion()
5045  {
5046  return(LGL_OPENGL_VERSION);
5047  }
5048 
5050  static int lglMapGL2GLSLVersion(int glversion)
5051  {
5052  if (glversion < 20) return(0);
5053 
5054  switch (glversion)
5055  {
5056  case 20 : return(11);
5057  case 21 : return(12);
5058  case 30 : return(13);
5059  case 31 : return(14);
5060  case 32 : return(15);
5061  case 33 : return(33);
5062  case 40 : return(40);
5063  case 41 : return(41);
5064  case 42 : return(42);
5065  case 43 : return(43);
5066  case 44 : return(44);
5067  case 45 : return(45);
5068  case 46 : return(46);
5069  default : return(glversion);
5070  }
5071  }
5072 
5074  static int lglGetGLSLVersion()
5075  {
5077  }
5078 
5080  static std::string lglGetRenderer()
5081  {
5082  initializeRenderer();
5083  return(renderer_);
5084  }
5085 
5088  {
5089  initializeRenderer();
5090  return(vendor_);
5091  }
5092 
5094  static std::string lglGetVendorName()
5095  {
5096  initializeRenderer();
5097  switch (vendor_)
5098  {
5099  case LGL_NVIDIA: return("NVIDIA");
5100  case LGL_ATI: return("ATI");
5101  case LGL_INTEL: return("Intel");
5102  default: return("unknown");
5103  }
5104  }
5105 
5107  static std::string lglGetError()
5108  {
5109  if (error_.empty())
5110  {
5111  GLenum error = glGetError();
5112 
5113  if (error != GL_NO_ERROR)
5114  {
5115  if (error == GL_INVALID_ENUM) error_ = "invalid GL enum";
5116  else if (error == GL_INVALID_VALUE) error_ = "invalid GL value";
5117  else if (error == GL_INVALID_OPERATION) error_ = "invalid GL operation";
5118  else error_ = "unknown GL error";
5119 
5120  std::cerr << error_ << std::endl;
5121  }
5122  }
5123 
5124  std::string e = error_;
5125  error_.clear();
5126 
5127  return(e);
5128  }
5129 
5131  static std::string lglGetWarning()
5132  {
5133  std::string w = warning_;
5134  warning_.clear();
5135 
5136  return(w);
5137  }
5138 
5139 protected:
5140 
5141  std::string name_;
5142  bool immediate_;
5143  bool storagetype_;
5144 
5145  vec4 vertex_;
5146  bool copied_;
5147  bool copy_;
5148 
5149  vec4f color_;
5150  vec3f normal_;
5151  vec4f texcoord_;
5152  vec4f attribute_[LGL_NUM_ATTRIBUTES];
5153 
5154  bool hascolor_;
5155  bool hasnormal_;
5156  bool hastexcoord_;
5157  bool hasattribute_[LGL_NUM_ATTRIBUTES];
5158  bool hasattributes_;
5159 
5160  int size_, maxsize_;
5161 
5162  VEC4 *vertices_;
5163  vec4f *verticesf_;
5164  vec4f *colors_;
5165  vec3f *normals_;
5166  vec4f *texcoords_;
5167  vec3f *barycentrics_;
5168  vec4f *attributes_;
5169 
5170  vec3 bboxmin_, bboxmax_;
5171 
5172  lgl_primitive_enum primitive_;
5173  int primitives_;
5174 
5175  bool started_;
5176  bool rearrange_;
5177 
5178  bool modified_;
5179  bool rendered_;
5180  bool applied_;
5181 
5182  bool coloring_;
5183  bool lighting_;
5184  bool texturing_;
5185 
5186  static bool disable_coloring_;
5187  static bool disable_lighting_;
5188  static bool disable_texturing_;
5189 
5190  static std::string renderer_;
5191  static lgl_vendor_enum vendor_;
5192 
5193  static vec4f actual_;
5194  static lgl_matrixmode_enum matrixmode_;
5195 
5196  static std::vector<mat4> projection_matrix_;
5197  static std::vector<mat4> modelview_matrix_;
5198  static std::vector<mat4> texture_matrix_;
5199 
5200  static std::vector<mat4> premodel_matrix_;
5201  static std::vector<bool> premodel_matrix_identity_;
5202  static std::vector<mat3> premodel_matrix_it_;
5203  static std::vector<bool> premodel_matrix_recompute_;
5204 
5205  static std::vector<mat4> pretex_matrix_;
5206  static std::vector<bool> pretex_matrix_identity_;
5207 
5208  static mat4 manip_matrix_;
5209  static bool manip_matrix_identity_;
5210  static bool manip_matrix_apply_;
5211 
5212  mat4 model_matrix_;
5213  bool model_matrix_identity_;
5214 
5215  mat4 tex_matrix_;
5216  bool tex_matrix_identity_;
5217 
5218  static double fovy_, aspect_, nearp_, farp_;
5219  static vec3 eye_, at_, up_;
5220 
5221  static vec4f light_;
5222  vec3f ka_, kd_, ks_;
5223  static vec3f Ia_, Id_, Is_;
5224  float exponent_;
5225  static vec3f falloff_;
5226 
5227  GLuint texid2D_;
5228  GLuint texid3D_;
5229  bool texid_owner_;
5230 
5231  lgl_texgenmode_enum texgen_;
5232  double texgen_mix_;
5233 
5234  static lgl_blendmode_enum blendmode_;
5235 
5236  static float alphavalue_;
5237  static vec3f alphatest_;
5238 
5239  static int clipping_;
5240  static vec4 clipplane_[LGL_NUM_CLIPPLANES];
5241 
5242  static float fogdensity_;
5243  static vec4f fogcolor_;
5244 
5245  static lgl_polygonmode_enum polygonmode_;
5246  static lgl_interlacing_enum interlacing_;
5247 
5248  static bool raycast_;
5249  static vec3 raycast_origin_;
5250  static vec3 raycast_direction_;
5251  static double raycast_mindist_;
5252  static double raycast_dist_;
5253  static lgl *raycast_vbo_;
5254 
5255  static bool cull_;
5256  static double cull_minsize_;
5257 
5258  static void (*export_)(lgl *vbo, void *data);
5259  static void *export_data_;
5260  static mat4 export_matrix_;
5261 
5262  static std::string error_;
5263  static std::string warning_;
5264  static lgl_verbosity_enum verbosity_;
5265 
5266  virtual void init_gl_hook() {}
5267  virtual void exit_gl_hook() {}
5268 
5269  virtual void pre_render_hook() {}
5270  virtual void post_render_hook() {}
5271 
5272 #ifdef LGL_CORE
5273 
5274  GLuint buffers_[LGL_NUM_BUFFERS];
5275  GLuint array_;
5276 
5277  GLuint program_;
5278  GLuint usedprogram_;
5279 
5280  GLint color_loc_;
5281  GLint mv_loc_;
5282  GLint mvp_loc_;
5283  GLint mvit_loc_;
5284  GLint tm_loc_;
5285  GLint light_loc_;
5286  GLint kaIa_loc_, kdId_loc_, ksIs_loc_;
5287  GLint exponent_loc_;
5288  GLint falloff_loc_;
5289  GLint sampler_loc_;
5290  GLint alphatest_loc_;
5291  GLint clipping_loc_;
5292  GLint clipplane_loc_;
5293  GLint fogdensity_loc_;
5294  GLint fogcolor_loc_;
5295  GLint wireframe_loc_;
5296  GLint interlacing_loc_;
5297 
5298  static GLuint programs_[LGL_NUM_SHADERS];
5299  static GLuint custom_programs_[LGL_NUM_SHADERS];
5300 
5301  lgl_uniform_map_type uniforms_;
5302  lgl_uniform_location_type locations_;
5303 
5304 #endif
5305 
5306  bool initGL_;
5307 
5308  static int instances_;
5309  static bool initStaticGL_;
5310 
5311 #ifdef _WIN32
5312 
5313  #undef WGL_MACRO
5314  #define WGL_MACRO(proc,proctype) static PFN##proctype##PROC proc;
5315  #include "glvertex_wgl.h"
5316 
5317 #endif
5318 
5319  void initialize()
5320  {
5321  size_ = maxsize_ = 0;
5322  primitives_ = 0;
5323 
5324  vertices_ = NULL;
5325  verticesf_ = NULL;
5326 
5327  colors_ = NULL;
5328  normals_ = NULL;
5329  texcoords_ = NULL;
5330  barycentrics_ = NULL;
5331  attributes_ = NULL;
5332 
5333  for (unsigned int i=0; i<LGL_NUM_ATTRIBUTES; i++)
5334  {
5335  attribute_[i] = vec4f(0);
5336  hasattribute_[i] = false;
5337  }
5338 
5339  hasattributes_ = false;
5340 
5341  bboxmin_ = bboxmax_ = vec3(NAN);
5342 
5343  primitive_ = LGL_NONE;
5344 
5345  started_ = false;
5346  rearrange_ = false;
5347 
5348  modified_ = false;
5349  rendered_ = false;
5350  applied_ = false;
5351 
5352  coloring_ = true;
5353  lighting_ = true;
5354  texturing_ = true;
5355 
5356  model_matrix_ = mat4(1);
5357  model_matrix_identity_ = true;
5358 
5359  tex_matrix_ = mat4(1);
5360  tex_matrix_identity_ = true;
5361 
5362  ka_ = vec3f(0.1f);
5363  kd_ = vec3f(0.7f);
5364  ks_ = vec3f(0.2f);
5365 
5366  exponent_ = 30;
5367 
5368  texid2D_ = 0;
5369  texid3D_ = 0;
5370 
5371  texgen_ = LGL_TEXGEN_NONE;
5372  texgen_mix_ = 0;
5373 
5374 #ifdef LGL_CORE
5375 
5376  for (int i=0; i<LGL_NUM_BUFFERS; i++)
5377  buffers_[i] = 0;
5378 
5379  program_ = 0;
5380  usedprogram_ = 0;
5381 
5382  color_loc_ = -1;
5383  mv_loc_ = -1;
5384  mvp_loc_ = -1;
5385  mvit_loc_ = -1;
5386  tm_loc_ = -1;
5387  light_loc_ = -1;
5388  kaIa_loc_ = kdId_loc_ = ksIs_loc_ = -1;
5389  exponent_loc_ = -1;
5390  falloff_loc_ = -1;
5391  sampler_loc_ = -1;
5392  alphatest_loc_ = -1;
5393  clipping_loc_ = -1;
5394  clipplane_loc_ = -1;
5395  fogdensity_loc_ = -1;
5396  fogcolor_loc_ = -1;
5397  wireframe_loc_ = -1;
5398  interlacing_loc_ = -1;
5399 
5400 #endif
5401 
5402  initGL_ = false;
5403  }
5404 
5405  static void initializeStatic()
5406  {
5407 #ifdef LGL_CORE
5408 
5409  for (int i=0; i<LGL_NUM_SHADERS; i++)
5410  {
5411  programs_[0] = 0;
5412  custom_programs_[0] = 0;
5413  }
5414 
5415 #endif
5416 
5417  for (int i=0; i<LGL_NUM_CLIPPLANES; i++)
5418  clipplane_[i] = vec4(0,0,0,0);
5419  }
5420 
5421  static void initializeRenderer()
5422  {
5423  if (renderer_ == "")
5424  {
5425  char *renderer = (char *)glGetString(GL_RENDERER);
5426 
5427  if (renderer != NULL)
5428  renderer_ = std::string(renderer);
5429 
5430  char *vendor = (char *)glGetString(GL_VENDOR);
5431 
5432  if (vendor != NULL)
5433  {
5434  if (strstr(vendor,"NVIDIA")!=NULL) vendor_ = LGL_NVIDIA;
5435  else if (strstr(vendor,"ATI")!=NULL) vendor_ = LGL_ATI;
5436  else if (strstr(vendor,"Intel")!=NULL) vendor_ = LGL_INTEL;
5437  }
5438  }
5439  }
5440 
5441  void initializeOpenGL()
5442  {
5443 #ifdef LGL_CORE
5444 
5445  glGenBuffers(LGL_NUM_BUFFERS, buffers_);
5446 
5447 #if defined(LGL_GL3) || defined(LGL_GLES3)
5448 
5449  glGenVertexArrays(1, &array_);
5450 
5451 #endif
5452 
5453 #endif
5454  }
5455 
5456  static void initializeStaticOpenGL()
5457  {
5458  initializeRenderer();
5459 
5460 #ifdef _WIN32
5461  initWGLprocs();
5462 #endif
5463 
5464 #ifdef LGL_CORE
5465 
5466  unsigned int num = LGL_NUM_SHADERS;
5467 
5468  programs_[0] = lglCompileGLSLProgram(lglBasicGLSLVertexShader(false,false,false),lglBasicGLSLFragmentShader(false,false,false,false));
5469  programs_[1] = lglCompileGLSLProgram(lglBasicGLSLVertexShader(true,false,false),lglBasicGLSLFragmentShader(true,false,false,false));
5470  programs_[2] = lglCompileGLSLProgram(lglBasicGLSLVertexShader(false,true,false),lglBasicGLSLFragmentShader(false,true,false,false));
5471  programs_[3] = lglCompileGLSLProgram(lglBasicGLSLVertexShader(true,true,false),lglBasicGLSLFragmentShader(true,true,false,false));
5472  programs_[4] = lglCompileGLSLProgram(lglBasicGLSLVertexShader(false,false,true),lglBasicGLSLFragmentShader(false,false,true,false));
5473  programs_[5] = lglCompileGLSLProgram(lglBasicGLSLVertexShader(true,false,true),lglBasicGLSLFragmentShader(true,false,true,false));
5474  programs_[6] = lglCompileGLSLProgram(lglBasicGLSLVertexShader(false,true,true),lglBasicGLSLFragmentShader(false,true,true,false));
5475  programs_[7] = lglCompileGLSLProgram(lglBasicGLSLVertexShader(true,true,true),lglBasicGLSLFragmentShader(true,true,true,false));
5476 #if !defined(LGL_GLES) || defined(LGL_GLES3)
5477  programs_[8] = lglCompileGLSLProgram(lglBasicGLSLVertexShader(false,false,true),lglBasicGLSLFragmentShader(false,false,true,true));
5478  programs_[9] = lglCompileGLSLProgram(lglBasicGLSLVertexShader(true,false,true),lglBasicGLSLFragmentShader(true,false,true,true));
5479  programs_[10] = lglCompileGLSLProgram(lglBasicGLSLVertexShader(false,true,true),lglBasicGLSLFragmentShader(false,true,true,true));
5480  programs_[11] = lglCompileGLSLProgram(lglBasicGLSLVertexShader(true,true,true),lglBasicGLSLFragmentShader(true,true,true,true));
5481 #else
5482  num -= 4;
5483 #endif
5484 
5485  for (unsigned int i=0; i<num; i++)
5486  if (programs_[i] == 0)
5487  lglFatal("could not compile basic GLSL program");
5488 
5489 #endif
5490  }
5491 
5492  void finalizeOpenGL()
5493  {
5494 #ifdef LGL_CORE
5495 
5496  glDeleteBuffers(LGL_NUM_BUFFERS, buffers_);
5497 
5498 #if defined(LGL_GL3) || defined(LGL_GLES3)
5499 
5500  glDeleteVertexArrays(1, &array_);
5501 
5502 #endif
5503 
5504 #endif
5505  }
5506 
5507  static void finalizeStaticOpenGL()
5508  {
5509 #ifdef LGL_CORE
5510 
5511  for (int i=0; i<8; i++)
5512  lglDeleteGLSLProgram(programs_[i]);
5513 
5514 #endif
5515  }
5516 
5517  void finalize()
5518  {
5519  if (vertices_) free(vertices_);
5520  if (verticesf_) free(verticesf_);
5521 
5522  if (colors_) free(colors_);
5523  if (normals_) free(normals_);
5524  if (texcoords_) free(texcoords_);
5525  if (barycentrics_) free(barycentrics_);
5526  if (attributes_) free(attributes_);
5527 
5528  if (texid_owner_) lglDeleteTexture();
5529  }
5530 
5531  static void finalizeStatic()
5532  {
5533  checkMatrixStacks();
5534 
5535  if (projection_matrix_.size() > 1)
5536  lglError("unbalanced projection matrix stack");
5537 
5538  if (modelview_matrix_.size() > 1)
5539  lglError("unbalanced model-view matrix stack");
5540 
5541  if (premodel_matrix_.size() > 1)
5542  lglError("unbalanced pre-model matrix stack");
5543 
5544  if (texture_matrix_.size() > 1)
5545  lglError("unbalanced texture matrix stack");
5546 
5547  if (pretex_matrix_.size() > 1)
5548  lglError("unbalanced pre-texture matrix stack");
5549  }
5550 
5551  bool checkVertexScope()
5552  {
5553  if (started_)
5554  if (matrixmode_!=LGL_PREMODEL && matrixmode_!=LGL_PRETEX)
5555  {
5556  lglError("missing end operation");
5557  return(false);
5558  }
5559 
5560  return(true);
5561  }
5562 
5563  static bool checkMatrixStacks()
5564  {
5565  if (projection_matrix_.size() == 0)
5566  {
5567  lglError("projection matrix stack underrun");
5568  return(false);
5569  }
5570 
5571  if (modelview_matrix_.size() == 0)
5572  {
5573  lglError("model-view matrix stack underrun");
5574  return(false);
5575  }
5576 
5577  if (premodel_matrix_.size() == 0)
5578  {
5579  lglError("pre-model matrix stack underrun");
5580  return(false);
5581  }
5582 
5583  if (texture_matrix_.size() == 0)
5584  {
5585  lglError("texture matrix stack underrun");
5586  return(false);
5587  }
5588 
5589  if (pretex_matrix_.size() == 0)
5590  {
5591  lglError("pre-texture matrix stack underrun");
5592  return(false);
5593  }
5594 
5595  return(true);
5596  }
5597 
5606  {
5607  float a=0.0f,b=0.0f,c=0.5f,d=0.5f;
5608 
5609  if (mode==LGL_INTERLACE_HORIZONTAL_LEFT) {a=0.5f; c=0.0f;}
5610  else if (mode==LGL_INTERLACE_HORIZONTAL_RIGHT) {a=0.5f; c=0.5f;}
5611  else if (mode==LGL_INTERLACE_VERTICAL_TOP) {b=0.5f; d=0.0f;}
5612  else if (mode==LGL_INTERLACE_VERTICAL_BOTTOM) {b=0.5f; d=0.5f;}
5613 
5614  return(vec4f(a,b,c,d));
5615  }
5616 
5617 #ifdef _WIN32
5618 
5619  static void initWGLprocs()
5620  {
5621  static bool init = false;
5622  if (!init)
5623  {
5624  #undef WGL_MACRO
5625  #define WGL_MACRO(proc,proctype) if ((proc=(PFN##proctype##PROC)wglGetProcAddress(#proc))==NULL) lglWarning(#proc" not supported");
5626  #include "glvertex_wgl.h"
5627  init = true;
5628  }
5629  }
5630 
5631 #endif
5632 
5633 public:
5634 
5635  // wrapped extension function
5636  void lglTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels)
5637  {
5638 #ifdef _WIN32
5639  initWGLprocs();
5640 #endif
5641 
5642  glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels);
5643  }
5644 
5645  // wrapped extension function
5646  void lglTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels)
5647  {
5648 #ifdef _WIN32
5649  initWGLprocs();
5650 #endif
5651 
5652 #if !defined(LGL_GLES) || defined (LGL_GLES3)
5653  glTexImage3D(target, level, internalformat, width, height, depth, border, format, type, pixels);
5654 #endif
5655  }
5656 
5658  static void lglMessage(std::string m)
5659  {
5660  if (verbosity_ >= LGL_VERBOSITY_MESSAGES)
5661  std::cerr << m << std::endl;
5662  }
5663 
5665  static void lglError(std::string e)
5666  {
5667  error_ = e;
5668 
5669  if (verbosity_ >= LGL_VERBOSITY_ERRORS)
5670  std::cerr << e << std::endl;
5671  }
5672 
5674  static void lglWarning(std::string w)
5675  {
5676  warning_ = w;
5677 
5678  if (verbosity_ >= LGL_VERBOSITY_WARNINGS)
5679  std::cerr << w << std::endl;
5680  }
5681 
5683  static void lglFatal(std::string e)
5684  {
5685  lglError(e);
5686  exit(1);
5687  }
5688 
5691  {
5692  verbosity_ = v;
5693  }
5694 
5695  template<class v, const GLenum t>
5696  friend std::ostream& operator << (std::ostream &out, const lgl<v, t> &vbo);
5697 };
5698 
5699 template<class VEC4, const GLenum gl_type> std::string lgl<VEC4, gl_type>::renderer_("");
5700 template<class VEC4, const GLenum gl_type> lgl_vendor_enum lgl<VEC4, gl_type>::vendor_(LGL_UNKNOWN);
5701 
5702 template<class VEC4, const GLenum gl_type> vec4f lgl<VEC4, gl_type>::actual_(1);
5703 template<class VEC4, const GLenum gl_type> lgl_matrixmode_enum lgl<VEC4, gl_type>::matrixmode_(LGL_MODELVIEW);
5704 
5705 template<class VEC4, const GLenum gl_type> bool lgl<VEC4, gl_type>::disable_coloring_(false);
5706 template<class VEC4, const GLenum gl_type> bool lgl<VEC4, gl_type>::disable_lighting_(false);
5707 template<class VEC4, const GLenum gl_type> bool lgl<VEC4, gl_type>::disable_texturing_(false);
5708 
5709 template<class VEC4, const GLenum gl_type> std::vector<mat4> lgl<VEC4, gl_type>::projection_matrix_(1, mat4(1));
5710 template<class VEC4, const GLenum gl_type> std::vector<mat4> lgl<VEC4, gl_type>::modelview_matrix_(1, mat4(1));
5711 template<class VEC4, const GLenum gl_type> std::vector<mat4> lgl<VEC4, gl_type>::texture_matrix_(1, mat4(1));
5712 
5713 template<class VEC4, const GLenum gl_type> std::vector<mat4> lgl<VEC4, gl_type>::premodel_matrix_(1, mat4(1));
5714 template<class VEC4, const GLenum gl_type> std::vector<bool> lgl<VEC4, gl_type>::premodel_matrix_identity_(1, true);
5715 template<class VEC4, const GLenum gl_type> std::vector<mat3> lgl<VEC4, gl_type>::premodel_matrix_it_(1, mat3(1));
5716 template<class VEC4, const GLenum gl_type> std::vector<bool> lgl<VEC4, gl_type>::premodel_matrix_recompute_(1, false);
5717 
5718 template<class VEC4, const GLenum gl_type> std::vector<mat4> lgl<VEC4, gl_type>::pretex_matrix_(1, mat4(1));
5719 template<class VEC4, const GLenum gl_type> std::vector<bool> lgl<VEC4, gl_type>::pretex_matrix_identity_(1, true);
5720 
5721 template<class VEC4, const GLenum gl_type> mat4 lgl<VEC4, gl_type>::manip_matrix_(mat4(1));
5722 template<class VEC4, const GLenum gl_type> bool lgl<VEC4, gl_type>::manip_matrix_identity_(true);
5723 template<class VEC4, const GLenum gl_type> bool lgl<VEC4, gl_type>::manip_matrix_apply_(false);
5724 
5725 template<class VEC4, const GLenum gl_type> double lgl<VEC4, gl_type>::fovy_(0);
5726 template<class VEC4, const GLenum gl_type> double lgl<VEC4, gl_type>::aspect_(0);
5727 template<class VEC4, const GLenum gl_type> double lgl<VEC4, gl_type>::nearp_(0);
5728 template<class VEC4, const GLenum gl_type> double lgl<VEC4, gl_type>::farp_(0);
5729 
5730 template<class VEC4, const GLenum gl_type> vec3 lgl<VEC4, gl_type>::eye_(0);
5731 template<class VEC4, const GLenum gl_type> vec3 lgl<VEC4, gl_type>::at_(0);
5732 template<class VEC4, const GLenum gl_type> vec3 lgl<VEC4, gl_type>::up_(0);
5733 
5734 template<class VEC4, const GLenum gl_type> vec4f lgl<VEC4, gl_type>::light_(0,0,1,0);
5735 template<class VEC4, const GLenum gl_type> vec3f lgl<VEC4, gl_type>::Ia_(1);
5736 template<class VEC4, const GLenum gl_type> vec3f lgl<VEC4, gl_type>::Id_(1);
5737 template<class VEC4, const GLenum gl_type> vec3f lgl<VEC4, gl_type>::Is_(1);
5738 template<class VEC4, const GLenum gl_type> vec3f lgl<VEC4, gl_type>::falloff_(1,0,0);
5739 
5740 template<class VEC4, const GLenum gl_type> lgl_blendmode_enum lgl<VEC4, gl_type>::blendmode_(LGL_BLEND_NONE);
5741 
5742 template<class VEC4, const GLenum gl_type> float lgl<VEC4, gl_type>::alphavalue_(0.0f);
5743 template<class VEC4, const GLenum gl_type> vec3f lgl<VEC4, gl_type>::alphatest_(-1,-1,0);
5744 
5745 template<class VEC4, const GLenum gl_type> int lgl<VEC4, gl_type>::clipping_(0);
5746 template<class VEC4, const GLenum gl_type> vec4 lgl<VEC4, gl_type>::clipplane_[LGL_NUM_CLIPPLANES];
5747 
5748 template<class VEC4, const GLenum gl_type> float lgl<VEC4, gl_type>::fogdensity_(0.0f);
5749 template<class VEC4, const GLenum gl_type> vec4f lgl<VEC4, gl_type>::fogcolor_(1);
5750 
5751 template<class VEC4, const GLenum gl_type> lgl_polygonmode_enum lgl<VEC4, gl_type>::polygonmode_(LGL_FILL);
5752 template<class VEC4, const GLenum gl_type> lgl_interlacing_enum lgl<VEC4, gl_type>::interlacing_(LGL_INTERLACE_NONE);
5753 
5754 template<class VEC4, const GLenum gl_type> std::string lgl<VEC4, gl_type>::error_;
5755 template<class VEC4, const GLenum gl_type> std::string lgl<VEC4, gl_type>::warning_;
5756 template<class VEC4, const GLenum gl_type> lgl_verbosity_enum lgl<VEC4, gl_type>::verbosity_(LGL_VERBOSITY_ERRORS);
5757 
5758 #ifdef LGL_CORE
5759 
5760 template<class VEC4, const GLenum gl_type> GLuint lgl<VEC4, gl_type>::programs_[LGL_NUM_SHADERS];
5761 template<class VEC4, const GLenum gl_type> GLuint lgl<VEC4, gl_type>::custom_programs_[LGL_NUM_SHADERS];
5762 
5763 #endif
5764 
5765 template<class VEC4, const GLenum gl_type> bool lgl<VEC4, gl_type>::raycast_(false);
5766 template<class VEC4, const GLenum gl_type> vec3 lgl<VEC4, gl_type>::raycast_origin_(0);
5767 template<class VEC4, const GLenum gl_type> vec3 lgl<VEC4, gl_type>::raycast_direction_(0);
5768 template<class VEC4, const GLenum gl_type> double lgl<VEC4, gl_type>::raycast_mindist_(DBL_MAX);
5769 template<class VEC4, const GLenum gl_type> double lgl<VEC4, gl_type>::raycast_dist_(DBL_MAX);
5770 template<class VEC4, const GLenum gl_type> lgl<VEC4, gl_type> *lgl<VEC4, gl_type>::raycast_vbo_(NULL);
5771 
5772 template<class VEC4, const GLenum gl_type> bool lgl<VEC4, gl_type>::cull_(false);
5773 template<class VEC4, const GLenum gl_type> double lgl<VEC4, gl_type>::cull_minsize_(0);
5774 
5775 template<class VEC4, const GLenum gl_type> void (*lgl<VEC4, gl_type>::export_)(lgl *vbo, void *data)(NULL);
5776 template<class VEC4, const GLenum gl_type> void *lgl<VEC4, gl_type>::export_data_(NULL);
5777 template<class VEC4, const GLenum gl_type> mat4 lgl<VEC4, gl_type>::export_matrix_(0);
5778 
5779 template<class VEC4, const GLenum gl_type> int lgl<VEC4, gl_type>::instances_(0);
5780 template<class VEC4, const GLenum gl_type> bool lgl<VEC4, gl_type>::initStaticGL_(false);
5781 
5782 #ifdef _WIN32
5783 
5784 #undef WGL_MACRO
5785 #define WGL_MACRO(proc,proctype) template<class VEC4, const GLenum gl_type> PFN##proctype##PROC lgl<VEC4, gl_type>::proc = NULL;
5786 #include "glvertex_wgl.h"
5787 
5788 #endif
5789 
5791 template<class VEC4, const GLenum gl_type>
5792 std::ostream& operator << (std::ostream &out, const lgl<VEC4, gl_type> &vbo)
5793 {
5794  for (unsigned int i=0; i<vbo.size_; i++)
5795  {
5796  if (vbo.storagetype_) out << "vertex #" << i+1 << ": " << vbo.vertices_[i] << std::endl;
5797  else out << "vertex #" << i+1 << ": " << vbo.verticesf_[i] << std::endl;
5798 
5799  if (vbo.hascolor_) out << "color #" << i+1 << ": " << vbo.colors_[i] << std::endl;
5800  if (vbo.hasnormal_) out << "normal #" << i+1 << ": " << vbo.normals_[i] << std::endl;
5801  if (vbo.hastexcoord_) out << "texcoord #" << i+1 << ": " << vbo.texcoords_[i] << std::endl;
5802  }
5803 
5804  return(out);
5805 }
5806 
5807 // LGL vbo storage type
5808 #ifndef LGL_GLES
5809 # define LGL_VEC4 vec4
5810 # define LGL_GL_TYPE GL_DOUBLE
5811 #else
5812 # define LGL_VEC4 vec4f
5813 # define LGL_GL_TYPE GL_FLOAT
5814 #endif
5815 
5816 // LGL vbo container type
5818 
5820 class GL: public LGL_VBO_TYPE
5821 {
5822 public:
5823  GL() : LGL_VBO_TYPE("lgl", true) {}
5824 };
5825 
5827 class lglVBO: public LGL_VBO_TYPE
5828 {
5829 public:
5830  lglVBO(const std::string &name = "", bool storagetype = true)
5831  : LGL_VBO_TYPE(name, false, storagetype) {}
5832 };
5833 
5835 class lglVBOf: public lglVBO
5836 {
5837 public:
5838  lglVBOf(const std::string &name = "")
5839  : lglVBO(name, false) {}
5840 };
5841 
5842 #endif
lgl_vendor_enum
lgl_vendor_enum
graphics hardware vendor
Definition: glvertex_core.h:24
vec3f
3D float vector
Definition: glslmath.h:584
lgl::lglLightPosition
void lglLightPosition(vec3f light=vec3f(0, 0, 0), bool camera_light=true)
set the light position
Definition: glvertex_core.h:4145
lgl::lglMaterialParameters
void lglMaterialParameters(vec3f ka=vec3f(0.1f), vec3f kd=vec3f(0.7f), vec3f ks=vec3f(0.2f), float exponent=30)
set the material parameters
Definition: glvertex_core.h:4244
lgl_polygonmode_enum
lgl_polygonmode_enum
polygon mode enum
Definition: glvertex_core.h:82
lgl::lglDeleteGLSLProgram
static void lglDeleteGLSLProgram(GLuint program)
delete a compiled GLSL program
Definition: glvertex_core.h:3161
lgl::lglGetVertexCoordinates
std::vector< vec4 > lglGetVertexCoordinates() const
return a copy of the vertex coordinates in vbo
Definition: glvertex_core.h:1893
lgl::lglGetTexCoordAttributes
std::vector< vec4f > lglGetTexCoordAttributes() const
return a copy of the texture coordinate attributes in vbo
Definition: glvertex_core.h:1919
lgl::lglGetZWrite
static bool lglGetZWrite()
get the depth write mask
Definition: glvertex_core.h:4423
glvertex_string.h
lgl::lglGetMatrixMode
lgl_matrixmode_enum lglGetMatrixMode() const
get the actual matrix mode
Definition: glvertex_core.h:1987
lgl::lglMultMatrix
void lglMultMatrix(const mat4 &matrix)
multiply a specific matrix in immediate mode fashion
Definition: glvertex_core.h:2044
lgl::lglTranslate
void lglTranslate(double x, double y, double z, double w=1)
translate in immediate mode fashion
Definition: glvertex_core.h:2228
lgl::lglCompileGLSLProgram
static GLuint lglCompileGLSLProgram(std::string vertex_shader, std::string fragment_shader)
compile a GLSL program from a vertex and a fragment shader source
Definition: glvertex_core.h:3007
lgl::lglGetLineWidth
static float lglGetLineWidth()
get the line rasterization width
Definition: glvertex_core.h:4741
lgl::lglProjection
void lglProjection(const mat4 &projection)
set the actual projection matrix
Definition: glvertex_core.h:2363
lgl::lglTex
void lglTex()
reset the vbo texturing matrix
Definition: glvertex_core.h:2577
lgl::lglPlainGLSLVertexShader
static std::string lglPlainGLSLVertexShader()
get the LGL plain GLSL vertex shader
Definition: glvertex_core.h:2673
mat4::transpose
mat4 transpose() const
transpose 4x4 matrix
Definition: glslmath.h:2363
lgl_verbosity_enum
lgl_verbosity_enum
verbosity level enum
Definition: glvertex_core.h:100
lgl::lglDisableLighting
static void lglDisableLighting(bool off)
entirely disable vertex normals
Definition: glvertex_core.h:3422
lgl::lglFog
static void lglFog(float density=0.0f, vec4f color=vec4f(1))
specify the fog parameters as supported by the default GLSL program
Definition: glvertex_core.h:4710
lgl::lglRGBAWrite
static void lglRGBAWrite(bool r=true, bool g=true, bool b=true, bool a=true)
specify the RGBA write mask
Definition: glvertex_core.h:4390
lgl::lglGetLightVector
vec4 lglGetLightVector() const
get the light vector (in camera coordinates)
Definition: glvertex_core.h:4176
lgl::lglGetPrimitiveCount
int lglGetPrimitiveCount() const
get the number of primitives contained in vbo
Definition: glvertex_core.h:1796
lgl_primitive_enum
lgl_primitive_enum
graphics primitive type
Definition: glvertex_core.h:33
lgl::lglGetGLVersion
static int lglGetGLVersion()
get the OpenGL version
Definition: glvertex_core.h:5044
lgl::lglGetInterlacingMode
static lgl_interlacing_enum lglGetInterlacingMode()
get the actual interlacing mode
Definition: glvertex_core.h:4790
lgl::lglMatrixMode
void lglMatrixMode(lgl_matrixmode_enum mode=LGL_MODELVIEW)
determine the actual matrix mode
Definition: glvertex_core.h:1981
lgl::getEye
vec3 getEye() const
get eye point for last lookat transformation
Definition: glvertex_core.h:2336
lgl::lglIntersect
double lglIntersect(vec3 origin, vec3 direction, mat4 m, double mindist=0) const
cast a ray and intersect it with the transformed triangles contained in the vbo
Definition: glvertex_core.h:4830
lgl::lglUniformi
void lglUniformi(unsigned int index, int value, bool warn=true)
specify a uniform for the actual compiled GLSL program (integer, indexed)
Definition: glvertex_core.h:3484
lgl::lglClearColors
void lglClearColors()
clear colors
Definition: glvertex_core.h:1052
lgl::lglUniformfv
unsigned int lglUniformfv(std::string uniform, const mat3f &value, bool warn=true)
specify a uniform for the actual compiled GLSL program (mat3f)
Definition: glvertex_core.h:3816
lgl::lglAlphaTest
static void lglAlphaTest(bool on=false, float value=0.0f, bool greater=true, bool equal=false)
enable or disable alpha testing
Definition: glvertex_core.h:4575
lgl::lglProjection
void lglProjection()
reset the actual projection matrix
Definition: glvertex_core.h:2354
lgl::lglCloneProgram
void lglCloneProgram(const lgl *vbo)
clone GLSL program and uniforms from vbo
Definition: glvertex_core.h:4106
lgl::lglGetInverseModelViewMatrix
mat4 lglGetInverseModelViewMatrix() const
get the inverse of the actual modelview matrix
Definition: glvertex_core.h:2170
lgl::lglExport
static void lglExport(lgl *vbo)
export vbo
Definition: glvertex_core.h:5016
lgl::lglGetTexturing
bool lglGetTexturing() const
check for texturing
Definition: glvertex_core.h:3410
lgl::lglVertexArray
void lglVertexArray(lgl_primitive_enum primitive, unsigned int vertices, const float *vertex_array, const float *color_array, const float *normal_array=NULL, const float *texcoord_array=NULL)
specify a series of vertices and attributes as buffers (and copy them into vbo)
Definition: glvertex_core.h:1005
lgl::lglTexCoordGen
void lglTexCoordGen(lgl_texgenmode_enum mode=LGL_TEXGEN_LINEAR, double mix=0.5)
enable texture coordinate generation
Definition: glvertex_core.h:4327
lgl::lglUniformMatrix2fv
unsigned int lglUniformMatrix2fv(std::string uniform, const float value[4], bool warn=true)
specify a uniform matrix for the actual compiled GLSL program (float[4])
Definition: glvertex_core.h:3777
lgl::lglUniformfv
void lglUniformfv(unsigned int index, const vec3f &value, bool warn=true)
specify a uniform for the actual compiled GLSL program (vec3f, indexed)
Definition: glvertex_core.h:3651
lgl::lglRayCast
static void lglRayCast(lgl *vbo)
cast a ray and intersect it with the transformed triangles contained in the vbo
Definition: glvertex_core.h:4963
lgl::lglGetGLSLVersionString
static std::string lglGetGLSLVersionString()
get GLSL version string
Definition: glvertex_core.h:2658
lgl::lglGetLightSourceParameters
void lglGetLightSourceParameters(vec3f &Ia, vec3f &Id, vec3f &Is, vec3f &falloff) const
get the light source parameters
Definition: glvertex_core.h:4233
mat4::perspective
static mat4 perspective(double fovy, double aspect, double znear, double zfar)
create perspective matrix
Definition: glslmath.h:2712
lgl::lglDepthTest
static void lglDepthTest(bool on=true)
enable or disable depth testing
Definition: glvertex_core.h:4431
lgl::lglCloneUniforms
void lglCloneUniforms(const lgl *vbo)
clone uniforms from vbo
Definition: glvertex_core.h:4040
lgl::lglGetDepthTest
static bool lglGetDepthTest()
check whether or not depth testing is enabled
Definition: glvertex_core.h:4446
lgl::lglColor
void lglColor(float r, float g, float b, float a=1)
specify the color attribute for the next vertex
Definition: glvertex_core.h:838
lgl::lglClear
static void lglClear(GLuint bits=GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
clear the color and depth buffer
Definition: glvertex_core.h:4384
vec3::dot
double dot(const vec3 &v) const
inner product
Definition: glslmath.h:429
lgl::lglUseDefaultProgram
void lglUseDefaultProgram(bool clear=true)
use the default GLSL program which simulates the fixed function OpenGL pipeline
Definition: glvertex_core.h:3202
lgl::lglViewport
static void lglViewport(int ax, int ay, int bx, int by)
set the viewport
Definition: glvertex_core.h:4367
lgl::lglGetInverseTransposeModelMatrix
mat4 lglGetInverseTransposeModelMatrix() const
get the inverse transpose of the vbo modeling matrix
Definition: glvertex_core.h:2545
lgl::lglTexCoord
void lglTexCoord(float s, float t=0, float r=0, float w=1)
specify the texture coordinate attribute for the next vertex
Definition: glvertex_core.h:887
vec3::normalize
vec3 normalize() const
normalize vector to unit length
Definition: glslmath.h:528
lgl::lglUniformfv
unsigned int lglUniformfv(std::string uniform, const mat2f &value, bool warn=true)
specify a uniform for the actual compiled GLSL program (mat2f)
Definition: glvertex_core.h:3751
vec2
2D double vector
Definition: glslmath.h:108
lgl::lglPopMatrix
void lglPopMatrix()
pop the top entry of the matrix stack
Definition: glvertex_core.h:2095
lgl::getAspect
double getAspect()
get aspect parameter for last projection transformation
Definition: glvertex_core.h:2300
lgl::lglCompileGLSLVertexShader
static GLuint lglCompileGLSLVertexShader(std::string shader)
compile GLSL vertex shader
Definition: glvertex_core.h:2847
lgl::lglGetColorAttributes
std::vector< vec4f > lglGetColorAttributes() const
return a copy of the color attributes in vbo
Definition: glvertex_core.h:1901
mat2f
2x2 float matrix
Definition: glslmath.h:1408
GL
LGL API: immediate mode class definition.
Definition: glvertex_core.h:5820
lgl::getNear
double getNear()
get near parameter for last projection transformation
Definition: glvertex_core.h:2306
vec4
4D double vector
Definition: glslmath.h:713
lgl::lglGetLightParameters
void lglGetLightParameters(vec3f &ka, vec3f &kd, vec3f &ks, vec3f &Ia, vec3f &Id, vec3f &Is, float &exponent, vec3f &falloff) const
get the light parameters
Definition: glvertex_core.h:4202
mat4::rotate
static mat4 rotate(double angle, double vx, double vy, double vz)
create rotation matrix
Definition: glslmath.h:2446
lgl::lgl
lgl(const std::string &name="", bool immediate=false, bool storagetype=true)
ctor
Definition: glvertex_core.h:161
lgl::lglGetCenter
vec3 lglGetCenter() const
get the bounding box barycenter of the contained vertices in vbo
Definition: glvertex_core.h:1819
lgl::lglGetVendorName
static std::string lglGetVendorName()
get the vendor name of the graphics hardware
Definition: glvertex_core.h:5094
lgl::lglClipPlane
void lglClipPlane(vec3 point, vec3 normal, unsigned int n=0, bool camera_plane=false)
specify a clip plane by a point on the plane and a plane normal
Definition: glvertex_core.h:4676
lgl::lglTexture3D
void lglTexture3D(GLuint texid, bool owner=false)
bind a 3D texture for the default GLSL program
Definition: glvertex_core.h:4282
lgl::lglCombineGLSLProgram
static std::string lglCombineGLSLProgram(const std::string &vertex_shader, const std::string &fragment_shader)
combine GLSL program
Definition: glvertex_core.h:3064
norm
double norm(const vec2 &v)
get squared vector length
Definition: glslmath.h:225
lgl::lglModelView
void lglModelView()
reset the actual modelview matrix
Definition: glvertex_core.h:2389
lgl::lglGetBoundingBox
void lglGetBoundingBox(vec3 &bboxmin, vec3 &bboxmax) const
get the bounding box of the contained vertices in vbo
Definition: glvertex_core.h:1803
lgl::lglActiveTexturing
bool lglActiveTexturing() const
check for active vertex texture coordinate attributes
Definition: glvertex_core.h:3334
lgl_string::stringReplaceAll
static void stringReplaceAll(std::string &text, const std::string &search, const std::string &with)
replace all occurrences in std::string
Definition: glvertex_string.h:193
lgl::lglGetTextureMatrix
mat4 lglGetTextureMatrix() const
get the actual texture matrix
Definition: glvertex_core.h:2191
lgl::lglEnableViewCulling
static void lglEnableViewCulling(int minsize=0)
enable view culling
Definition: glvertex_core.h:4991
lgl::lglUniform2fv
unsigned int lglUniform2fv(std::string uniform, const float value[2], bool warn=true)
specify a uniform for the actual compiled GLSL program (float[2])
Definition: glvertex_core.h:3582
lgl::lglAppliedColoring
bool lglAppliedColoring() const
check for applied vertex color attributes
Definition: glvertex_core.h:3322
lgl::lglUseProgram
void lglUseProgram(GLuint program, bool clear=true)
use a custom GLSL program
Definition: glvertex_core.h:3178
lgl::lglGetTexture2D
GLuint lglGetTexture2D() const
get the bound 2D texture
Definition: glvertex_core.h:4276
lgl::lglGetTexture3D
GLuint lglGetTexture3D() const
get the bound 3D texture
Definition: glvertex_core.h:4292
lgl::lglDeleteTexture
void lglDeleteTexture()
delete any texture map
Definition: glvertex_core.h:4320
lgl::lglError
static void lglError(std::string e)
generate an error message
Definition: glvertex_core.h:5665
lgl::lglLightVector
void lglLightVector(vec4f light=vec4f(0, 0, 1, 0), bool camera_light=true)
set the light vector
Definition: glvertex_core.h:4151
lgl::lglLookAt
void lglLookAt(double eye_x, double eye_y, double eye_z, double at_x, double at_y, double at_z, double up_x=0, double up_y=1, double up_z=0)
lookat transformation
Definition: glvertex_core.h:2328
lgl::lglGetRayCastDistance
static double lglGetRayCastDistance()
get distance to front-most hit point determined by ray casting
Definition: glvertex_core.h:4985
glslmath.h
lgl::lglUniformfv
void lglUniformfv(unsigned int index, const vec2f &value, bool warn=true)
specify a uniform for the actual compiled GLSL program (vec2f, indexed)
Definition: glvertex_core.h:3588
lgl::lglView
void lglView(double eye_x, double eye_y, double eye_z, double at_x, double at_y, double at_z, double up_x=0, double up_y=1, double up_z=0)
set the actual modelview matrix
Definition: glvertex_core.h:2417
lgl_matrixmode_enum
lgl_matrixmode_enum
matrix mode enum
Definition: glvertex_core.h:46
lgl::lglUniformfv
unsigned int lglUniformfv(std::string uniform, const mat4f &value, bool warn=true)
specify a uniform for the actual compiled GLSL program (mat4f)
Definition: glvertex_core.h:3881
lgl::lglCompileGLSLProgram
static GLuint lglCompileGLSLProgram(std::string shader="")
compile a GLSL program from a combined vertex and fragment shader source
Definition: glvertex_core.h:3112
lgl::lglLightSourceParameters
void lglLightSourceParameters(vec3f Ia=vec3f(1), vec3f Id=vec3f(1), vec3f Is=vec3f(1), vec3f falloff=vec3f(1, 0, 0))
set the light source parameters
Definition: glvertex_core.h:4219
lgl::lglEnd
void lglEnd()
end a series of vertices
Definition: glvertex_core.h:981
mat4f
4x4 float matrix
Definition: glslmath.h:2752
lgl::reset
void reset()
reset all buffers
Definition: glvertex_core.h:708
lgl::lglApplyColor
void lglApplyColor(const vec4f &c)
add a color channel to the vbo
Definition: glvertex_core.h:2626
lgl::lglGetMatrix
mat4 lglGetMatrix() const
get the top entry of the matrix stack
Definition: glvertex_core.h:2123
lgl::lglLoadGLSLProgram
static GLuint lglLoadGLSLProgram(const char *vertex_shader_file, const char *fragment_shader_file)
compile a GLSL program from a vertex and a fragment shader source file
Definition: glvertex_core.h:3040
lgl::lglOrtho
void lglOrtho(double left, double right, double bottom, double top, double nearp=-1, double farp=1)
orthographic projection
Definition: glvertex_core.h:2265
lgl::clear
void clear()
clear all buffers
Definition: glvertex_core.h:737
lgl::lglGetFog
static bool lglGetFog()
check whether or not fogging is enabled
Definition: glvertex_core.h:4717
lgl::getFar
double getFar()
get far parameter for last projection transformation
Definition: glvertex_core.h:2312
lgl::lglGetInverseTransposeManip
static mat4 lglGetInverseTransposeManip()
get the inverse transpose of the manipulator matrix
Definition: glvertex_core.h:2519
lgl::lglReadRGBPixels
static unsigned char * lglReadRGBPixels(int x, int y, int width, int height)
read frame buffer
Definition: glvertex_core.h:4796
lgl_interlacing_enum
lgl_interlacing_enum
interlacing mode enum
Definition: glvertex_core.h:90
lgl::lglGetMaxExtent
double lglGetMaxExtent() const
get the maximum extent of the contained vertices in vbo
Definition: glvertex_core.h:1856
lgl::lglUniformfv
unsigned int lglUniformfv(std::string uniform, const vec4f &value, bool warn=true)
specify a uniform for the actual compiled GLSL program (vec4f)
Definition: glvertex_core.h:3682
length
double length(const vec2 &v)
get vector length
Definition: glslmath.h:221
lgl::lglSampler2D
unsigned int lglSampler2D(std::string sampler, GLuint texid2D, int value=0, bool warn=true)
bind a 2D sampler for the actual compiled GLSL program
Definition: glvertex_core.h:3958
lgl::lglGetRGBAWrite
static bool lglGetRGBAWrite()
get the RGBA write mask
Definition: glvertex_core.h:4400
mat4::frustum
static mat4 frustum(double l, double r, double b, double t, double n, double f)
create frustum matrix
Definition: glslmath.h:2687
lgl::lglRotate
void lglRotate(double angle, double vx, double vy, double vz)
rotate in immediate mode fashion
Definition: glvertex_core.h:2241
lgl::lglPlainGLSLFragmentShader
static std::string lglPlainGLSLFragmentShader()
get the LGL plain GLSL fragment shader
Definition: glvertex_core.h:2680
lgl::lglColoring
void lglColoring(bool on)
enable or disable the vertex color attributes contained in vbo
Definition: glvertex_core.h:3353
lgl::lglClearColor
static void lglClearColor(float r, float g, float b, float a=1)
set the clear color
Definition: glvertex_core.h:4378
lgl::lglRotate
void lglRotate(double angle, const vec3 &v)
rotate in immediate mode fashion
Definition: glvertex_core.h:2234
lgl::lglGetError
static std::string lglGetError()
get a description of the last occured error
Definition: glvertex_core.h:5107
lgl::lglProjection
void lglProjection(double fovy, double aspect, double nearp, double farp)
set the actual projection matrix
Definition: glvertex_core.h:2378
mat2f::fromOpenGL
void fromOpenGL(const float m[4])
convert from 4-element column-major OpenGL matrix
Definition: glslmath.h:1503
lgl::lglPerspective
void lglPerspective(double fovy, double aspect, double nearp, double farp)
perspective projection
Definition: glvertex_core.h:2283
vec2f
2D float vector
Definition: glslmath.h:261
lgl::lglCloneState
void lglCloneState(const lgl *vbo)
clone state from vbo (coloring, lighting and texturing)
Definition: glvertex_core.h:4341
lgl::lglPolygonMode
static void lglPolygonMode(lgl_polygonmode_enum mode)
specify the polygon mode
Definition: glvertex_core.h:4749
lgl::lglLightParameters
void lglLightParameters(vec3f ka=vec3f(0.1f), vec3f kd=vec3f(0.7f), vec3f ks=vec3f(0.2f), vec3f Ia=vec3f(1), vec3f Id=vec3f(1), vec3f Is=vec3f(1), float exponent=30, vec3f falloff=vec3f(1, 0, 0))
set the light parameters
Definition: glvertex_core.h:4182
lgl::lglUniformf
unsigned int lglUniformf(std::string uniform, double value, bool warn=true)
specify a uniform for the actual compiled GLSL program (float)
Definition: glvertex_core.h:3507
lgl::lglScale
void lglScale(const vec4 &c)
scale in immediate mode fashion
Definition: glvertex_core.h:2202
mat3f::fromOpenGL
void fromOpenGL(const float m[9])
convert from 9-element column-major OpenGL matrix
Definition: glslmath.h:2063
lgl::lglUniformi
unsigned int lglUniformi(std::string uniform, int value, bool warn=true)
specify a uniform for the actual compiled GLSL program (integer)
Definition: glvertex_core.h:3458
lgl::lglGetClipPlaneEquation
static vec4 lglGetClipPlaneEquation(vec3 point, vec3 normal)
compute a clip plane equation from a point and a normal
Definition: glvertex_core.h:4700
vec3
3D double vector
Definition: glslmath.h:372
lgl::lglGetNorm
double lglGetNorm() const
get the bounding sphere norm of the contained vertices in vbo
Definition: glvertex_core.h:1844
mat2
2x2 double matrix
Definition: glslmath.h:1130
lgl::lglDeleteTexture3D
void lglDeleteTexture3D()
delete 3D texture map
Definition: glvertex_core.h:4309
lgl::lglManip
static void lglManip(const mat4 &manip)
update the manipulator matrix by multiplying it with a custom matrix
Definition: glvertex_core.h:2449
lgl::lglLinkGLSLProgram
static GLuint lglLinkGLSLProgram(GLuint vertex_shader_id, GLuint fragment_shader_id, GLuint custom_shader_program=0)
link GLSL program
Definition: glvertex_core.h:2939
lgl::lglAttribute
void lglAttribute(float x, float y, float z, float w=1.0f, unsigned int n=0)
specify a custom vertex attribute
Definition: glvertex_core.h:911
lgl::lglZWrite
static void lglZWrite(bool on=true)
specify the depth write mask
Definition: glvertex_core.h:4408
lgl::lglManip
static void lglManip(bool on=true)
enable or disable the manipulator matrix
Definition: glvertex_core.h:2443
lgl::lglUniformMatrix3fv
unsigned int lglUniformMatrix3fv(std::string uniform, const float value[9], bool warn=true)
specify a uniform matrix for the actual compiled GLSL program (float[9])
Definition: glvertex_core.h:3842
mat4
4x4 double matrix
Definition: glslmath.h:2116
lgl::getFovy
double getFovy()
get fovy parameter for last projection transformation
Definition: glvertex_core.h:2294
lgl::lglLoadIdentity
void lglLoadIdentity()
load the identity matrix in immediate mode fashion
Definition: glvertex_core.h:1993
lgl::lglGetInverseTransposeModelViewMatrix
mat4 lglGetInverseTransposeModelViewMatrix() const
get the inverse transpose of the actual modelview matrix
Definition: glvertex_core.h:2177
lgl::lglGetLighting
bool lglGetLighting() const
check for lighting
Definition: glvertex_core.h:3389
lgl::lglComplementaryInterlacingMode
static void lglComplementaryInterlacingMode(lgl_interlacing_enum mode)
specify the complementary interlacing mode
Definition: glvertex_core.h:4775
lgl::lglGetRadius
double lglGetRadius() const
get the bounding sphere radius of the contained vertices in vbo
Definition: glvertex_core.h:1832
lgl::lglBackFaceCulling
static void lglBackFaceCulling(bool on=true)
enable or disable back-face culling
Definition: glvertex_core.h:4454
lgl::lglTexture
void lglTexture(const mat4 &texture)
set the actual texture matrix
Definition: glvertex_core.h:2434
lgl::getName
std::string getName() const
get the vbo name
Definition: glvertex_core.h:203
lgl::lglLoadGLSLProgram
static GLuint lglLoadGLSLProgram(const char *shader_file)
compile a GLSL program from a combined vertex and fragment shader source file
Definition: glvertex_core.h:3127
vec4f
4D float vector
Definition: glslmath.h:961
lgl::lglGetMaterialParameters
void lglGetMaterialParameters(vec3f &ka, vec3f &kd, vec3f &ks, float &exponent) const
get the material parameters
Definition: glvertex_core.h:4255
lgl::lglGetColoring
bool lglGetColoring() const
check for coloring
Definition: glvertex_core.h:3368
lgl::lglBeginRayCast
static void lglBeginRayCast(vec3 origin, vec3 direction, double mindist=0)
begin ray casting in view coordinates
Definition: glvertex_core.h:4952
lgl::lglSupportsGLSL
static bool lglSupportsGLSL()
check for GLSL support
Definition: glvertex_core.h:2648
lgl::lglCopyUniforms
void lglCopyUniforms(const lgl *vbo, bool warn=false)
copy uniforms from vbo
Definition: glvertex_core.h:4051
lgl::lglDisableViewCulling
static void lglDisableViewCulling()
disable view culling
Definition: glvertex_core.h:4998
lgl
LGL core.
Definition: glvertex_core.h:156
lgl::lglMessage
static void lglMessage(std::string m)
generate a status message
Definition: glvertex_core.h:5658
lgl::lglGetBackFaceCulling
static bool lglGetBackFaceCulling()
check whether or not back-face culling is enabled
Definition: glvertex_core.h:4471
lgl::lglGetTexCoordGen
lgl_texgenmode_enum lglGetTexCoordGen()
check whether or not texture coordinate generation is enabled
Definition: glvertex_core.h:4335
lgl::lglProjection
void lglProjection(double left, double right, double bottom, double top, double nearp, double farp)
set the actual projection matrix
Definition: glvertex_core.h:2372
mat4f::fromOpenGL
void fromOpenGL(const float m[16])
convert from 16-element column-major OpenGL matrix
Definition: glslmath.h:2907
lgl_blendmode_enum
lgl_blendmode_enum
blend mode enum
Definition: glvertex_core.h:70
lgl::lglGetBlending
static bool lglGetBlending()
check whether or not blending is enabled
Definition: glvertex_core.h:4561
lgl::lglGetFogColor
static vec4f lglGetFogColor()
get the actual fog color
Definition: glvertex_core.h:4729
lgl::lglUniformf
void lglUniformf(unsigned int index, double value, bool warn=true)
specify a uniform for the actual compiled GLSL program (float, indexed)
Definition: glvertex_core.h:3533
lgl::lglTranslate
void lglTranslate(const vec4 &v)
translate in immediate mode fashion
Definition: glvertex_core.h:2221
lgl::lglGetModelViewProjectionMatrix
mat4 lglGetModelViewProjectionMatrix() const
get the combined modelview and projection matrix
Definition: glvertex_core.h:2184
lgl::lglDeleteGLSLShader
static void lglDeleteGLSLShader(GLuint shader_id)
delete a compiled GLSL shader
Definition: glvertex_core.h:3146
lgl::lglManip
static void lglManip(double focus, double angle, double tilt, double zoom)
update the manipulator matrix by applying a rotation about a focus point and a zoom factor
Definition: glvertex_core.h:2457
lgl::lglCopyProgram
void lglCopyProgram(const lgl *vbo)
copy GLSL program and uniforms from vbo
Definition: glvertex_core.h:4118
lgl::lglGetGLSLVersion
static int lglGetGLSLVersion()
get the GLSL version
Definition: glvertex_core.h:5074
lgl::lglEndExport
static void lglEndExport()
end scene export
Definition: glvertex_core.h:5038
lgl::lglBasicGLSLFragmentShader
static std::string lglBasicGLSLFragmentShader(bool colors=false, bool normals=false, bool texcoords=false, bool tex3D=false)
get the LGL default fragment shader
Definition: glvertex_core.h:2740
lgl::lglCustomProgram
bool lglCustomProgram() const
check whether or not a custom GLSL program is in use
Definition: glvertex_core.h:3269
rotate
mat4 rotate(const mat4 &m, double angle, const vec3 &v)
inline rotate
Definition: glslmath.h:2611
lgl::lglDeleteTexture2D
void lglDeleteTexture2D()
delete 2D texture map
Definition: glvertex_core.h:4298
lgl::lglSampler2D
void lglSampler2D(unsigned int index, GLuint texid2D, int value=0, bool warn=true)
bind a 2D sampler for the actual compiled GLSL program (indexed)
Definition: glvertex_core.h:3976
lgl::lglUniformfv
unsigned int lglUniformfv(std::string uniform, const vec2f &value, bool warn=true)
specify a uniform for the actual compiled GLSL program (vec2f)
Definition: glvertex_core.h:3556
lgl::lglVerbosity
static void lglVerbosity(lgl_verbosity_enum v)
change verbosity level
Definition: glvertex_core.h:5690
lgl::lglBlendMode
static void lglBlendMode(lgl_blendmode_enum mode=LGL_BLEND_NONE)
enable or disable blending
Definition: glvertex_core.h:4479
lgl::lglGetAlphaTestValue
static float lglGetAlphaTestValue()
get the actual alpha test comparison value
Definition: glvertex_core.h:4629
lgl::lglUniformfv
unsigned int lglUniformfv(std::string uniform, const vec3f &value, bool warn=true)
specify a uniform for the actual compiled GLSL program (vec3f)
Definition: glvertex_core.h:3619
lgl::lglApplyTexMatrix
void lglApplyTexMatrix()
apply the vbo texturing matrix to the vbo and reset the matrix
Definition: glvertex_core.h:2603
lgl::lglRender
virtual void lglRender(const lgl *vbo=NULL)
render the series of vertices contained in vbo
Definition: glvertex_core.h:1079
lgl::lglUniformfv
void lglUniformfv(unsigned int index, const mat3f &value, bool warn=true)
specify a uniform matrix for the actual compiled GLSL program (mat3f, indexed)
Definition: glvertex_core.h:3850
lgl::lglInitializeOpenGL
static void lglInitializeOpenGL(float r=0, float g=0, float b=0, float a=1, bool ztest=true, bool culling=false)
initialize the OpenGL state (clear color, depth test, back-face culling)
Definition: glvertex_core.h:4358
lgl::lglCompileGLSLFragmentShader
static GLuint lglCompileGLSLFragmentShader(std::string shader)
compile GLSL fragment shader
Definition: glvertex_core.h:2893
lgl::lglUniform3fv
unsigned int lglUniform3fv(std::string uniform, const float value[3], bool warn=true)
specify a uniform for the actual compiled GLSL program (float[3])
Definition: glvertex_core.h:3645
lgl::lglFatal
static void lglFatal(std::string e)
generate a non-recoverable error
Definition: glvertex_core.h:5683
lgl::lglLighting
void lglLighting(bool on)
enable or disable the vertex normal attributes contained in vbo
Definition: glvertex_core.h:3374
lgl::lglParallel
void lglParallel(const vec3 &p, const vec3 &n, const vec3 &d)
parallel projection
Definition: glvertex_core.h:2277
lgl::lglBeginExport
static void lglBeginExport(void(*callback)(lgl *vbo, void *data), void *data, mat4 matrix=mat4(1))
begin scene export
Definition: glvertex_core.h:5007
lgl::lglRotateZ
void lglRotateZ(double angle)
rotate about z-axis in immediate mode fashion
Definition: glvertex_core.h:2259
lgl::lglGetProjectionMatrix
mat4 lglGetProjectionMatrix() const
get the actual projection matrix
Definition: glvertex_core.h:2140
lgl::lglGetManip
static mat4 lglGetManip()
get the manipulator matrix
Definition: glvertex_core.h:2507
mat4::scale
static mat4 scale(double s, double t, double r, double w=1.0)
create scaling matrix
Definition: glslmath.h:2409
lgl::lglScale
void lglScale(double s, double t, double r, double w=1)
scale in immediate mode fashion
Definition: glvertex_core.h:2209
lgl::lglActiveColoring
bool lglActiveColoring() const
check for active vertex color attributes
Definition: glvertex_core.h:3316
lgl::lglReuseProgram
void lglReuseProgram(GLuint program)
reuse a compiled GLSL program /wo clearing and updating uniforms
Definition: glvertex_core.h:3256
lgl::lglTexture2D
void lglTexture2D(GLuint texid, bool owner=false)
bind a 2D texture for the default GLSL program
Definition: glvertex_core.h:4266
lglVBO
LGL API: vbo class definition.
Definition: glvertex_core.h:5827
lgl::lglVertex
void lglVertex(double x, double y, double z, double w=1)
specify a vertex in immediate mode fashion (and compile it into vbo)
Definition: glvertex_core.h:815
lgl::lglPushMatrix
void lglPushMatrix()
push the top entry of the matrix stack
Definition: glvertex_core.h:2069
lgl::lglLineWidth
static void lglLineWidth(float width=1.0f)
specify the line rasterization width
Definition: glvertex_core.h:4735
lgl::setupStereoMode
vec4f setupStereoMode(lgl_interlacing_enum mode)
interlaced stereo modes:
Definition: glvertex_core.h:5605
mat3
3x3 double matrix
Definition: glslmath.h:1544
lgl::lglUniform4fv
unsigned int lglUniform4fv(std::string uniform, const float value[4], bool warn=true)
specify a uniform for the actual compiled GLSL program (float[4])
Definition: glvertex_core.h:3708
lgl::lglClipPlane
void lglClipPlane(vec4 equation=vec4(0, 0, 0, 0), unsigned int n=0, bool camera_plane=false)
specify a clip plane as supported by the default GLSL program
Definition: glvertex_core.h:4647
lgl::lglUniformfv
void lglUniformfv(unsigned int index, const mat4f &value, bool warn=true)
specify a uniform matrix for the actual compiled GLSL program (mat4f, indexed)
Definition: glvertex_core.h:3915
lgl::lglClearNormals
void lglClearNormals()
clear normals
Definition: glvertex_core.h:1058
lgl::lglManip
static void lglManip(vec2 delta, double zoom=1)
update the manipulator matrix by applying a screen-space delta
Definition: glvertex_core.h:2493
lgl::lglUniform
unsigned int lglUniform(std::string uniform, bool warn=true)
specify a uniform for the actual compiled GLSL program (undefined)
Definition: glvertex_core.h:3434
lgl::lglPlainGLSLProgram
static std::string lglPlainGLSLProgram()
get the combined LGL plain GLSL program
Definition: glvertex_core.h:2687
lgl::lglGetBlendMode
static lgl_blendmode_enum lglGetBlendMode()
get the actual blending mode
Definition: glvertex_core.h:4569
lgl_texgenmode_enum
lgl_texgenmode_enum
texgen mode enum
Definition: glvertex_core.h:56
lgl::lglGetRenderer
static std::string lglGetRenderer()
get the OpenGL renderer
Definition: glvertex_core.h:5080
lgl::lglModel
void lglModel(const mat4 &model)
specify the vbo modeling matrix
Definition: glvertex_core.h:2532
normalize
vec2 normalize(const vec2 &v)
normalization to unit length
Definition: glslmath.h:237
lgl::lglGetMaxAbsCoord
double lglGetMaxAbsCoord() const
get the maximum absolute value of the coordinates in vbo
Definition: glvertex_core.h:1874
lgl::lglGetColor
vec4 lglGetColor() const
get the actual color attribute
Definition: glvertex_core.h:844
lgl::lglFrustum
void lglFrustum(double left, double right, double bottom, double top, double nearp, double farp)
frustum projection
Definition: glvertex_core.h:2271
lgl::lglClearAttributes
void lglClearAttributes()
clear attributes
Definition: glvertex_core.h:1070
lgl::lglTex
void lglTex(const vec4 &scale, const vec4 &offset)
specify the vbo texturing matrix
Definition: glvertex_core.h:2591
lgl::lglGetFogDensity
static float lglGetFogDensity()
get the actual fog density
Definition: glvertex_core.h:4723
lgl::lglBegin
void lglBegin(lgl_primitive_enum primitive)
begin a series of vertices for a particular graphics primitive
Definition: glvertex_core.h:917
lgl::getUp
vec3 getUp() const
get up vector for last lookat transformation
Definition: glvertex_core.h:2348
lgl::lglGetPolygonMode
static lgl_polygonmode_enum lglGetPolygonMode()
get the actual polygon mode
Definition: glvertex_core.h:4763
transpose
mat4 transpose(const mat4 &m)
inline transpose
Definition: glslmath.h:2627
lgl::lglModelView
void lglModelView(const mat4 &modelview)
set the actual modelview matrix
Definition: glvertex_core.h:2398
lglVBOf
LGL API: vbo class definition (storage type: float)
Definition: glvertex_core.h:5835
lgl::lglGetExtent
vec3 lglGetExtent() const
get the bounding box extent of the contained vertices in vbo
Definition: glvertex_core.h:1825
lgl::lglTexture
void lglTexture()
reset the actual texture matrix
Definition: glvertex_core.h:2425
lgl::lglResetManip
static void lglResetManip()
reset the manipulator matrix
Definition: glvertex_core.h:2499
lgl::lglTex
void lglTex(const mat4 &tex)
specify the vbo texturing matrix
Definition: glvertex_core.h:2584
lgl::lglRotateX
void lglRotateX(double angle)
rotate about x-axis in immediate mode fashion
Definition: glvertex_core.h:2247
lgl::lglView
void lglView(const vec3 &eye, const vec3 &at, const vec3 &up=vec3(0, 1, 0))
set the actual modelview matrix
Definition: glvertex_core.h:2407
scale
mat4 scale(const mat4 &m, const vec4 &c)
inline scale
Definition: glslmath.h:2591
lgl::lglGetVendor
static lgl_vendor_enum lglGetVendor()
get the OpenGL vendor
Definition: glvertex_core.h:5087
glvertex_io.h
lgl::lglModel
void lglModel()
reset the vbo modeling matrix
Definition: glvertex_core.h:2525
mat3f
3x3 float matrix
Definition: glslmath.h:1939
lgl::lglSampler3D
void lglSampler3D(unsigned int index, GLuint texid3D, int value=0, bool warn=true)
bind a 3D sampler for the actual compiled GLSL program (indexed)
Definition: glvertex_core.h:4019
lgl::lglApplyModelMatrix
void lglApplyModelMatrix()
apply the vbo modeling matrix to the vbo and reset the matrix
Definition: glvertex_core.h:2551
lgl::lglClipPlane
void lglClipPlane(double a, double b, double c, double d, unsigned int n=0, bool camera_plane=false)
specify a clip plane as supported by the default GLSL program
Definition: glvertex_core.h:4670
lgl::lglGetModelMatrix
mat4 lglGetModelMatrix() const
get the vbo modeling matrix
Definition: glvertex_core.h:2539
lgl::lglGetVertexCount
int lglGetVertexCount() const
get the number of vertices contained in vbo
Definition: glvertex_core.h:1790
lgl::lglGetTexMatrix
mat4 lglGetTexMatrix() const
get the vbo texturing matrix
Definition: glvertex_core.h:2597
lgl::lglUniformfv
void lglUniformfv(unsigned int index, const vec4f &value, bool warn=true)
specify a uniform for the actual compiled GLSL program (vec4f, indexed)
Definition: glvertex_core.h:3714
lgl::lglIsManipApplied
static bool lglIsManipApplied()
is the manipulator matrix applied?
Definition: glvertex_core.h:2513
mat4::invert
mat4 invert() const
invert 4x4 matrix
Definition: glslmath.h:2371
lgl::lglDisableColoring
static void lglDisableColoring(bool off)
entirely disable vertex colors
Definition: glvertex_core.h:3416
lgl::lglGetActiveProgram
GLuint lglGetActiveProgram() const
get the actual GLSL program in use
Definition: glvertex_core.h:3282
lgl::lglManip
static void lglManip(double dx, double dy, double zoom=1)
update the manipulator matrix by applying a screen-space delta
Definition: glvertex_core.h:2465
lgl::lglGetAlphaTestEqual
static bool lglGetAlphaTestEqual()
get the actual alpha test equality mode
Definition: glvertex_core.h:4641
lgl::lglGetVertexMode
lgl_primitive_enum lglGetVertexMode() const
get the primitive mode of vertices contained in vbo
Definition: glvertex_core.h:1784
lgl::lglGetBoundingSphere
double lglGetBoundingSphere(vec3 &center) const
get the bounding sphere of the contained vertices in vbo
Definition: glvertex_core.h:1812
lgl::lglSampler
unsigned int lglSampler(std::string sampler, int value=0, bool warn=true)
specify a uniform sampler for the actual compiled GLSL program
Definition: glvertex_core.h:3946
lgl::lglLoadMatrix
void lglLoadMatrix(const mat4 &matrix)
load a specific matrix in immediate mode fashion
Definition: glvertex_core.h:2019
mat4::lookat
static mat4 lookat(const vec3 &eye, const vec3 &center, const vec3 &up=vec3(0, 1, 0))
create lookat matrix
Definition: glslmath.h:2731
lgl::lglGetAlphaTest
static bool lglGetAlphaTest()
check whether or not alpha testing is enabled
Definition: glvertex_core.h:4613
lgl::lglAppendVerticesTo
void lglAppendVerticesTo(lgl *vbo) const
append a copy of the vertices and attributes in vbo to another vbo
Definition: glvertex_core.h:1928
lgl::lglSampler3D
unsigned int lglSampler3D(std::string sampler, GLuint texid3D, int value=0, bool warn=true)
bind a 3D sampler for the actual compiled GLSL program
Definition: glvertex_core.h:3993
lgl::lglEndRayCast
static lgl * lglEndRayCast()
end ray casting
Definition: glvertex_core.h:4978
mat4::translate
static mat4 translate(double x, double y, double z)
create translation matrix
Definition: glslmath.h:2427
operator<<
std::ostream & operator<<(std::ostream &out, const lgl< VEC4, gl_type > &vbo)
output operator
Definition: glvertex_core.h:5792
lgl::getLookAt
vec3 getLookAt() const
get lookat point for last lookat transformation
Definition: glvertex_core.h:2342
lgl::lglTexturing
void lglTexturing(bool on)
enable or disable the vertex texture coordinate attributes contained in vbo
Definition: glvertex_core.h:3395
lgl::lglLookAt
void lglLookAt(const vec3 &eye, const vec3 &at, const vec3 &up=vec3(0, 1, 0))
lookat transformation
Definition: glvertex_core.h:2318
lgl::lglGetNormalAttributes
std::vector< vec3f > lglGetNormalAttributes() const
return a copy of the normal attributes in vbo
Definition: glvertex_core.h:1910
lgl::lglSampler
void lglSampler(unsigned int index, int value=0, bool warn=true)
specify a uniform sampler for the actual compiled GLSL program (indexed)
Definition: glvertex_core.h:3952
lgl::lglClearTexCoords
void lglClearTexCoords()
clear texture coordinates
Definition: glvertex_core.h:1064
lgl::lglGetAlphaTestGreater
static bool lglGetAlphaTestGreater()
get the actual alpha test comparison mode
Definition: glvertex_core.h:4635
lgl::lglDisableTexturing
static void lglDisableTexturing(bool off)
entirely disable texture coordinates
Definition: glvertex_core.h:3428
lgl::lglSplitGLSLProgram
static bool lglSplitGLSLProgram(std::string shader, std::string &vertex_shader, std::string &fragment_shader)
split GLSL program
Definition: glvertex_core.h:3070
lgl::lglGetClipPlaneEquation
static vec4 lglGetClipPlaneEquation(unsigned int n=0)
get the actual clip plane equation
Definition: glvertex_core.h:4691
mat4::parallel
static mat4 parallel(const vec3 &p, const vec3 &n, const vec3 &d)
create parallel projection matrix
Definition: glslmath.h:2698
lgl::lglWarning
static void lglWarning(std::string w)
generate a warning message
Definition: glvertex_core.h:5674
lgl::lglGetClipPlane
static bool lglGetClipPlane(unsigned int n=0)
check whether or not a clip plane is enabled
Definition: glvertex_core.h:4682
lgl::lglReplaceDefaultProgram
void lglReplaceDefaultProgram(GLuint program, bool colors=false, bool normals=true, bool texcoords=false, bool tex3D=false)
replace default GLSL program
Definition: glvertex_core.h:3222
lgl::lglInterlacingMode
static void lglInterlacingMode(lgl_interlacing_enum mode)
specify the interlacing mode
Definition: glvertex_core.h:4769
lgl::setName
void setName(std::string name="")
set the vbo name
Definition: glvertex_core.h:209
lgl::lglUniformfv
void lglUniformfv(unsigned int index, const mat2f &value, bool warn=true)
specify a uniform matrix for the actual compiled GLSL program (mat2f, indexed)
Definition: glvertex_core.h:3785
lgl::lglLightDirection
void lglLightDirection(vec3f light=vec3f(0, 0, 1), bool camera_light=true)
set the light direction
Definition: glvertex_core.h:4139
lgl::lglActiveLighting
bool lglActiveLighting() const
check for active vertex normal attributes
Definition: glvertex_core.h:3328
lgl::lglRotateY
void lglRotateY(double angle)
rotate about y-axis in immediate mode fashion
Definition: glvertex_core.h:2253
lgl::lglScale
void lglScale(double s, double w=1)
scale in immediate mode fashion
Definition: glvertex_core.h:2215
lgl::lglInterleavedVertexArray
void lglInterleavedVertexArray(lgl_primitive_enum primitive, const float *interleaved_array, unsigned int vertices, int colors=0, int normals=0, int texcoords=0)
specify a series of vertices as interleaved buffer (and copy it into vbo)
Definition: glvertex_core.h:1027
lgl::lglGetWarning
static std::string lglGetWarning()
get a description of the last occured warning
Definition: glvertex_core.h:5131
lgl::lglBasicGLSLVertexShader
static std::string lglBasicGLSLVertexShader(bool colors=false, bool normals=false, bool texcoords=false)
get the LGL default vertex shader
Definition: glvertex_core.h:2693
lgl::lglPrintUniforms
void lglPrintUniforms()
print GLSL uniforms
Definition: glvertex_core.h:4078
mat4::ortho
static mat4 ortho(double l, double r, double b, double t, double n=-1, double f=1)
create orthographic matrix
Definition: glslmath.h:2677
lgl::lglMapGL2GLSLVersion
static int lglMapGL2GLSLVersion(int glversion)
map gl version to glsl version
Definition: glvertex_core.h:5050
lgl::lglGetProgram
GLuint lglGetProgram() const
get the actual custom GLSL program in use
Definition: glvertex_core.h:3242
mix
vec2 mix(const vec2 &a, const vec2 &b, double w)
linear interpolation (GLSL-style)
Definition: glslmath.h:249
lgl::lglLight
void lglLight(vec4f light=vec4f(0, 0, 1, 0), bool camera_light=true, vec3f ka=vec3f(0.1f), vec3f kd=vec3f(0.7f), vec3f ks=vec3f(0.2f), vec3f Ia=vec3f(1), vec3f Id=vec3f(1), vec3f Is=vec3f(1), float exponent=30, vec3f falloff=vec3f(1, 0, 0))
specify the lighting parameters as supported by the default GLSL program
Definition: glvertex_core.h:4129
lgl::lglNormal
void lglNormal(float x, float y, float z)
specify the normal attribute for the next vertex
Definition: glvertex_core.h:867
lgl::lglIntersect
double lglIntersect(vec3 origin, vec3 direction, double mindist=0) const
cast a ray and intersect it with the transformed triangles contained in the vbo
Definition: glvertex_core.h:4946
lgl::lglGetModelViewMatrix
mat4 lglGetModelViewMatrix() const
get the actual modelview matrix
Definition: glvertex_core.h:2151
lgl::lglUniformMatrix4fv
unsigned int lglUniformMatrix4fv(std::string uniform, const float value[16], bool warn=true)
specify a uniform matrix for the actual compiled GLSL program (float[16])
Definition: glvertex_core.h:3907