ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/libgender/shader.h
Revision: 1.28
Committed: Wed Nov 3 03:35:13 2004 UTC (19 years, 7 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.27: +8 -0 lines
Log Message:
*** empty log message ***

File Contents

# Content
1 #ifndef SHADER_H
2 #define SHADER_H
3
4 #include <cassert>
5
6 #include <string>
7 #include <set>
8 #include <map>
9 #include <sstream>
10
11 #include "opengl.h"
12 #include "util.h"
13
14 namespace shader {
15
16 using namespace std;
17
18 const int NAMELEN = 32;
19
20 struct shader_builder
21 {
22 static struct shader_builder *cur;
23
24 set<const void *> seen;
25
26 ostringstream global;
27 ostringstream local;
28 ostringstream code;
29
30 bool first (const void *p);
31
32 static void start ();
33 static string stop ();
34 };
35
36 template<class T>
37 struct sl_expr {
38 const T &t;
39 sl_expr (const T &t) : t(t) { }
40 void operator ()() const { t (); }
41 template<typename expr>
42 const sl_expr &operator =(const expr &e) const;
43 };
44
45 template<class A, class B>
46 struct sl_concat2
47 {
48 const A a; const B b;
49 sl_concat2 (const A &a, const B &b) : a(a), b(b) { }
50 void operator ()() const { a (); b (); }
51 };
52
53 template<class A, class B, class C>
54 struct sl_concat3
55 {
56 const A a; const B b; const C c;
57 sl_concat3 (const A &a, const B &b, const C &c) : a(a), b(b), c(c) { }
58 void operator ()() const { a (); b (); c (); }
59 };
60
61 template<class A, class B, class C, class D>
62 struct sl_concat4
63 {
64 const A a; const B b; const C c; const D d;
65 sl_concat4 (const A &a, const B &b, const C &c, const D &d) : a(a), b(b), c(c), d(d) { }
66 void operator ()() const { a (); b (); c (); d(); }
67 };
68
69 struct sl_func0
70 {
71 const char *name_par;
72 sl_func0 (const char *name_par) : name_par(name_par) { }
73
74 void begin () const
75 {
76 shader_builder::cur->code << name_par;
77 }
78
79 void comma () const
80 {
81 shader_builder::cur->code << ", ";
82 }
83
84 void end () const
85 {
86 shader_builder::cur->code << ")";
87 }
88
89 void operator ()() const
90 {
91 begin ();
92 end ();
93 }
94 };
95
96 template<class A>
97 struct sl_func1 : sl_func0
98 {
99 const A a;
100 sl_func1 (const char *name, const A &a) : sl_func0(name), a(a) { }
101 void operator ()() const { begin (); a (); end (); }
102 };
103
104 template<class A, class B>
105 struct sl_func2 : sl_func0
106 {
107 const A a; const B b;
108 sl_func2 (const char *name, const A &a, const B &b) : sl_func0(name), a(a), b(b) { }
109 void operator ()() const { begin (); a (); comma (); b (); end (); }
110 };
111
112 template<class A, class B, class C>
113 struct sl_func3 : sl_func0
114 {
115 const A a; const B b; const C c;
116 sl_func3 (const char *name, const A &a, const B &b, const C &c) : sl_func0(name), a(a), b(b), c(c) { }
117 void operator ()() const { begin (); a (); comma (); b (); comma (); c (); end (); }
118 };
119
120 template<class A, class B, class C, class D>
121 struct sl_func4 : sl_func0
122 {
123 const A a; const B b; const C c; const D d;
124 sl_func4 (const char *name, const A &a, const B &b, const C &c, const D &d) : sl_func0(name), a(a), b(b), c(c), d(d) { }
125 void operator ()() const { begin (); a (); comma (); b (); comma (); c (); comma (); d(); end (); }
126 };
127
128 class refcounted
129 {
130 template<class type> friend class ref;
131 mutable unsigned int refcnt;
132 void refcnt_inc () const { refcnt++; }
133 void refcnt_dec () const { if (!--refcnt) refcnt_destroy (); }
134 void refcnt_destroy () const;
135 public:
136 refcounted () : refcnt(0) { }
137 virtual ~refcounted ();
138 };
139
140 template<class type>
141 struct ref
142 {
143 type *p;
144
145 ref ()
146 {
147 p = new type;
148 p->refcnt_inc ();
149 }
150
151 ref (type &d)
152 {
153 d.refcnt_inc ();
154 p = &d;
155 }
156
157 ref (const ref &r)
158 {
159 r.p->refcnt_inc ();
160 p = r.p;
161 }
162
163 template<class type2>
164 ref (const ref<type2> &r)
165 {
166 r.p->refcnt_inc ();
167 p = r.p;
168 }
169
170 ~ref ()
171 {
172 p->refcnt_dec ();
173 }
174
175 ref &operator =(type &d)
176 {
177 d.refcnt_inc ();
178 p->refcnt_dec ();
179 p = &d;
180 return *this;
181 }
182
183 type *operator ->() const { return p; }
184
185 operator type &() const { return *p; }
186
187 template<class type2>
188 bool operator ==(const ref<type2> b) const
189 {
190 return (void *)p == (void *)b.p;
191 }
192 };
193
194 // ref with auto-construct
195 template<class type>
196 struct auto_ref0 : ref<type>
197 {
198 auto_ref0 () : ref<type> (*new type ()) { }
199 };
200
201 template<class type, typename arg1>
202 struct auto_ref1 : ref<type>
203 {
204 auto_ref1 (arg1 a) : ref<type> (*new type (a)) { }
205 };
206
207 template<class type>
208 struct auto_lvalue_ref0 : ref<type>
209 {
210 auto_lvalue_ref0 () : ref<type> (*new type ()) { }
211 template<typename expr>
212 const auto_lvalue_ref0 &operator =(const expr &e) const;
213 };
214
215 template<class type, typename arg1>
216 struct auto_lvalue_ref1 : ref<type>
217 {
218 auto_lvalue_ref1 (arg1 a) : ref<type> (*new type (a)) { }
219 template<class expr>
220 const auto_lvalue_ref1 &operator =(const expr &e) const;
221 };
222
223 extern const char str_float [];
224 extern const char str_vec2 [];
225 extern const char str_vec3 [];
226 extern const char str_vec4 [];
227 extern const char str_mat2 [];
228 extern const char str_mat3 [];
229 extern const char str_mat4 [];
230
231 extern const char str_sampler_1d [];
232 extern const char str_sampler_1d_shadow [];
233 extern const char str_sampler_2d [];
234 extern const char str_sampler_2d_shadow [];
235 extern const char str_sampler_2d_rect [];
236 extern const char str_sampler_2d_rect_shadow [];
237 extern const char str_sampler_3d [];
238 extern const char str_sampler_3d_rect [];
239 extern const char str_sampler_cube [];
240
241 typedef ref<struct var_i> var;
242 typedef ref<struct uniform_i> uniform;
243
244 struct fragment_i : refcounted
245 {
246 };
247
248 typedef ref<fragment_i> fragment;
249
250 struct lvalue_i : fragment_i
251 {
252 };
253
254 // a simple predeclared variable with unspecified type
255 struct gluvar_i : lvalue_i
256 {
257 const char *name;
258
259 void operator ()() const
260 {
261 shader_builder::cur->code << name;
262 }
263
264 gluvar_i (const char *name) : name (name) { }
265 };
266
267 typedef auto_lvalue_ref1<gluvar_i, const char *> gluvar;
268
269 struct var_i : lvalue_i
270 {
271 static unsigned int next_id;
272
273 char name[NAMELEN];
274 const char *domainstr;
275 const char *typestr;
276
277 void operator ()() const;
278
279 var_i (const char *domainstr, const char *typestr);
280 ~var_i ();
281 };
282
283 struct uniform_i : var_i
284 {
285 GLint location ();
286
287 uniform_i (const char *strtype);
288 };
289
290 template<int dimension, typename gltype, const char *strtype>
291 struct uniform2_i : uniform_i
292 {
293 gltype data[dimension];
294
295 uniform2_i () : uniform_i (strtype) { }
296 };
297
298 template<int dimension, const char *strtype>
299 struct uniform_f_i : uniform2_i<dimension, GLfloat, strtype>
300 {
301 };
302
303 struct uniform_1f_i : uniform_f_i<1, str_float> {
304 void set (GLfloat v)
305 {
306 data[0] = v;
307
308 GLint loc = location ();
309 if (loc >= 0) // workaround for buggy drivers
310 glUniform1fvARB (loc, 1, data);
311 }
312 };
313
314 struct uniform_2f_i : uniform_f_i<2, str_vec2> {
315 void set (GLfloat x, GLfloat y)
316 {
317 data[0] = x;
318 data[1] = y;
319
320 GLint loc = location ();
321 if (loc >= 0) // workaround for buggy drivers
322 glUniform2fvARB (loc, 1, data);
323 }
324
325 void set (const vec2 &v) { set (v.x, v.y); }
326 };
327
328 struct uniform_3f_i : uniform_f_i<3, str_vec3> {
329 void set (GLfloat x, GLfloat y, GLfloat z)
330 {
331 data[0] = x;
332 data[1] = y;
333 data[2] = z;
334
335 GLint loc = location ();
336 if (loc >= 0) // workaround for buggy drivers
337 glUniform3fvARB (loc, 1, data);
338 }
339
340 void set (const vec3 &v) { set (v.x, v.y, v.z); }
341 };
342
343 struct uniform_4f_i : uniform_f_i<4, str_vec4> {
344 void set (GLfloat x, GLfloat y, GLfloat z, GLfloat w)
345 {
346 data[0] = x;
347 data[1] = y;
348 data[2] = z;
349 data[3] = w;
350
351 GLint loc = location ();
352 if (loc >= 0) // workaround for buggy drivers
353 glUniform4fvARB (loc, 1, data);
354 }
355
356 void set (const vec4 &v) { set (v.x, v.y, v.z, v.w); }
357 };
358
359 struct uniform_matrix_2f_i : uniform_f_i< 4, str_mat2>
360 {
361 void set (const GLfloat d[4])
362 {
363 memcpy (data, d, 4 * sizeof (GLfloat));
364
365 GLint loc = location ();
366 if (loc >= 0) // workaround for buggy drivers
367 glUniformMatrix2fvARB (loc, 1, 0, data);
368 }
369 };
370
371 struct uniform_matrix_3f_i : uniform_f_i< 9, str_mat3>
372 {
373 void set (const GLfloat d[9])
374 {
375 memcpy (data, d, 9 * sizeof (GLfloat));
376
377 GLint loc = location ();
378 if (loc >= 0) // workaround for buggy drivers
379 glUniformMatrix3fvARB (loc, 1, 0, data);
380 }
381 };
382
383 struct uniform_matrix_4f_i : uniform_f_i<16, str_mat4>
384 {
385 void set (const gl::matrix &m)
386 {
387 memcpy (data, m.data, 16 * sizeof (GLfloat));
388
389 GLint loc = location ();
390 if (loc >= 0) // workaround for buggy drivers
391 glUniformMatrix4fvARB (loc, 1, 0, data);
392 }
393 };
394
395 template<class var_i>
396 struct var_ref : ref<var_i>
397 {
398 var_ref (const char *glname = 0)
399 : ref<var_i> (*new var_i)
400 {
401 if (glname)
402 strcpy ((*this)->name, glname);
403 }
404 };
405
406 typedef var_ref<uniform_1f_i> uniform_1f;
407 typedef var_ref<uniform_2f_i> uniform_2f;
408 typedef var_ref<uniform_3f_i> uniform_3f;
409 typedef var_ref<uniform_4f_i> uniform_4f;
410 typedef var_ref<uniform_matrix_2f_i> uniform_matrix_2f;
411 typedef var_ref<uniform_matrix_3f_i> uniform_matrix_3f;
412 typedef var_ref<uniform_matrix_4f_i> uniform_matrix_4f;
413
414 #if 0
415 // to be used for attributes
416
417 struct stream_i : var_i
418 {
419 stream_i (const char *strtype);
420 };
421
422 template<int dimension, GLenum gltype, const char *strtype>
423 struct varying_i : stream_i
424 {
425 varying_i () : stream_i (strtype) { }
426
427 void set (GLsizei stride, GLvoid *ptr)
428 {
429 //cgGLSetParameterPointer (param, dimension, gltype, stride, ptr);
430 }
431 };
432
433 template<int dimension, const char *strtype>
434 struct varying_f_i : varying_i<dimension, GL_FLOAT, strtype>
435 {
436 void set (const gl::vertex_buffer &vb, GLint offset)
437 {
438 varying_i<dimension, GL_FLOAT, strtype>::set (gl::format_stride (vb.format), (GLvoid *)(long)offset);
439 }
440 };
441
442 struct varying_1f_i : varying_f_i<1, str_float>
443 {
444 };
445
446 struct varying_2f_i : varying_f_i<2, str_vec2>
447 {
448 void set_t (const gl::vertex_buffer &vb)
449 {
450 set (vb, gl::format_offset_t (vb.format));
451 }
452 };
453
454 struct varying_3f_i : varying_f_i<3, str_vec3>
455 {
456 void set_p (const gl::vertex_buffer &vb)
457 {
458 set (vb, gl::format_offset_p (vb.format));
459 }
460
461 void set_n (const gl::vertex_buffer &vb)
462 {
463 set (vb, gl::format_offset_n (vb.format));
464 }
465 };
466
467 struct varying_4f_i : varying_f_i<4, str_vec4>
468 {
469 };
470
471 typedef var_ref<varying_1f_i> varying_1f;
472 typedef var_ref<varying_2f_i> varying_2f;
473 typedef var_ref<varying_3f_i> varying_3f;
474 typedef var_ref<varying_4f_i> varying_4f;
475 #endif
476
477 struct varying_i : var_i
478 {
479 varying_i (const char *strtype);
480 };
481
482 struct temporary_i : var_i
483 {
484 temporary_i (const char *strtype);
485 };
486
487 template<const char *strtype, class var_i>
488 struct glnvar_ref : ref<var_i>
489 {
490 glnvar_ref ()
491 : ref<var_i> (*new var_i (strtype))
492 {
493 }
494
495 #if 0
496 template<typename expr>
497 glnvar_ref (const sl_expr<expr> &e)
498 : ref<var_i> (*new var_i (strtype))
499 {
500 (*this) = e;
501 }
502 #endif
503
504 template<typename expr>
505 const glnvar_ref &operator =(const expr &e) const;
506 };
507
508 typedef glnvar_ref<str_float, temporary_i> temp_1f;
509 typedef glnvar_ref<str_vec2, temporary_i> temp_2f;
510 typedef glnvar_ref<str_vec3, temporary_i> temp_3f;
511 typedef glnvar_ref<str_vec4, temporary_i> temp_4f;
512 typedef glnvar_ref<str_mat2, temporary_i> temp_matrix_2f;
513 typedef glnvar_ref<str_mat3, temporary_i> temp_matrix_3f;
514 typedef glnvar_ref<str_mat4, temporary_i> temp_matrix_4f;
515
516 typedef glnvar_ref<str_float, varying_i> varying_1f;
517 typedef glnvar_ref<str_vec2, varying_i> varying_2f;
518 typedef glnvar_ref<str_vec3, varying_i> varying_3f;
519 typedef glnvar_ref<str_vec4, varying_i> varying_4f;
520 typedef glnvar_ref<str_mat2, varying_i> varying_matrix_2f;
521 typedef glnvar_ref<str_mat3, varying_i> varying_matrix_3f;
522 typedef glnvar_ref<str_mat4, varying_i> varying_matrix_4f;
523
524 struct texture_units
525 {
526 static int units[8];
527 static int unit_count;
528
529 static GLenum get_texture_unit ()
530 {
531 assert (unit_count);
532 return units[--unit_count];
533 }
534
535 static void put_texture_unit (GLenum unit)
536 {
537 assert (unit_count < 8);
538 units[unit_count++] = unit;
539 }
540 };
541
542 template<GLenum gltype, const char *strtype>
543 struct sampler_i : uniform_i, texture_units
544 {
545 int unit;
546 GLuint name;
547
548 void enable ()
549 {
550 #if DEBUG
551 assert (unit < 0);
552 #endif
553 GLint loc = location ();
554
555 if (loc >= 0)
556 {
557 unit = get_texture_unit ();
558 glActiveTexture (GL_TEXTURE0 + unit);
559 glBindTexture (gltype, name);
560 glUniform1iARB (loc, unit);
561 }
562 }
563
564 void disable ()
565 {
566 if (unit >= 0)
567 {
568 put_texture_unit (unit);
569 unit = -1;
570 }
571 }
572
573 template<class bufferclass, class vectype>
574 void set (const gl::vertex_buffer &vb, const vectype bufferclass::*vp)
575 {
576 glTexCoordPointer (
577 vector_traits<vectype>::dimension (),
578 gl::type_traits<typename vector_traits<vectype>::basetype>::glenum (),
579 sizeof (bufferclass),
580 (GLvoid)(char bufferclass::*)vp
581 );
582 }
583
584 sampler_i (GLuint texture)
585 : uniform_i (strtype)
586 , name (texture)
587 #if DEBUG
588 , unit (-1)
589 #endif
590 {
591 }
592 };
593
594 struct sampler_1d_i : sampler_i<GL_TEXTURE_1D, str_sampler_1d>
595 {
596 sampler_1d_i (GLuint texture) : sampler_i<GL_TEXTURE_1D, str_sampler_1d> (texture) { }
597 };
598
599 struct sampler_1d_shadow_i : sampler_i<GL_TEXTURE_1D, str_sampler_1d_shadow>
600 {
601 sampler_1d_shadow_i (GLuint texture) : sampler_i<GL_TEXTURE_1D, str_sampler_1d_shadow> (texture) { }
602 };
603
604 struct sampler_2d_i : sampler_i<GL_TEXTURE_2D, str_sampler_2d>
605 {
606 sampler_2d_i (GLuint texture) : sampler_i<GL_TEXTURE_2D, str_sampler_2d> (texture) { }
607 };
608
609 struct sampler_2d_shadow_i : sampler_i<GL_TEXTURE_2D, str_sampler_2d_shadow>
610 {
611 sampler_2d_shadow_i (GLuint texture) : sampler_i<GL_TEXTURE_2D, str_sampler_2d_shadow> (texture) { }
612 };
613
614 struct sampler_2d_rect_i : sampler_i<GL_TEXTURE_2D, str_sampler_2d_rect>
615 {
616 sampler_2d_rect_i (GLuint texture) : sampler_i<GL_TEXTURE_2D, str_sampler_2d_rect> (texture) { }
617 };
618
619 struct sampler_2d_rect_shadow_i : sampler_i<GL_TEXTURE_2D, str_sampler_2d_rect_shadow>
620 {
621 sampler_2d_rect_shadow_i (GLuint texture) : sampler_i<GL_TEXTURE_2D, str_sampler_2d_rect_shadow> (texture) { }
622 };
623
624 struct sampler_3d_i : sampler_i<GL_TEXTURE_3D, str_sampler_3d>
625 {
626 sampler_3d_i (GLuint texture) : sampler_i<GL_TEXTURE_3D, str_sampler_3d> (texture) { }
627 };
628
629 struct sampler_3d_rect_i : sampler_i<GL_TEXTURE_3D, str_sampler_3d_rect>
630 {
631 sampler_3d_rect_i (GLuint texture) : sampler_i<GL_TEXTURE_3D, str_sampler_3d_rect> (texture) { }
632 };
633
634 struct sampler_cube_i : sampler_i<GL_TEXTURE_CUBE_MAP, str_sampler_cube>
635 {
636 sampler_cube_i (GLuint texture) : sampler_i<GL_TEXTURE_CUBE_MAP, str_sampler_cube> (texture) { }
637 };
638
639 template<class sampler_i>
640 struct sampler_ref : auto_ref1<sampler_i, GLuint>
641 {
642 sampler_ref (GLuint texture)
643 : auto_ref1<sampler_i, GLuint> (texture)
644 {
645 }
646 };
647
648 typedef sampler_ref<sampler_1d_i> sampler_1d;
649 typedef sampler_ref<sampler_1d_shadow_i> sampler_1d_shadow;
650 typedef sampler_ref<sampler_2d_i> sampler_2d;
651 typedef sampler_ref<sampler_2d_shadow_i> sampler_2d_shadow;
652 typedef sampler_ref<sampler_2d_rect_i> sampler_2d_rect;
653 typedef sampler_ref<sampler_2d_rect_shadow_i> sampler_2d_rect_shadow;
654 typedef sampler_ref<sampler_3d_i> sampler_3d;
655 typedef sampler_ref<sampler_3d_rect_i> sampler_3d_rect;
656 typedef sampler_ref<sampler_cube_i> sampler_cube;
657
658 struct shader_object_i : refcounted
659 {
660 GLenum type;
661 GLuint id; // GLhandleARB, but 2.0 will use uint
662
663 void compile (const string &source);
664
665 shader_object_i (GLenum type);
666 ~shader_object_i ();
667 };
668
669 template<GLenum type>
670 struct shader_object : ref<shader_object_i>
671 {
672 shader_object ()
673 : ref<shader_object_i> (*new shader_object_i (type))
674 {
675 }
676 };
677
678 typedef shader_object<GL_VERTEX_SHADER_ARB> vertex_shader;
679 typedef shader_object<GL_FRAGMENT_SHADER_ARB> fragment_shader;
680
681 struct program_object_i : refcounted
682 {
683 static struct program_object_i *cur; // currently bound program
684
685 GLuint id;
686
687 vertex_shader vsh;
688 fragment_shader fsh;
689
690 map<uniform_i *,GLint> uloc; // uniform location
691
692 program_object_i ();
693 ~program_object_i ();
694
695 void link ();
696
697 void enable ();
698 void disable ();
699 };
700
701 typedef auto_ref0<program_object_i> program_object;
702
703 // create a new program or return a cached one
704 program_object get_program (const string &vsh, const string &fsh);
705
706 template<int length>
707 struct sl_string
708 {
709 char str[length];
710
711 void operator ()() const
712 {
713 shader_builder::cur->code << str;
714 }
715 };
716
717 struct sl_float
718 {
719 const GLfloat c;
720
721 sl_float (GLfloat c) : c(c) { }
722
723 void operator ()() const
724 {
725 shader_builder::cur->code << c;
726 }
727 };
728
729 template<class A, class B>
730 inline sl_expr< sl_concat2<A, B> >
731 concat (const A &a, const B &b)
732 {
733 typedef sl_concat2<A, B> expr;
734 return sl_expr<expr> (expr (a, b));
735 }
736
737 template<class A, class B, class C>
738 inline sl_expr< sl_concat3<A, B, C> >
739 concat (const A &a, const B &b, const C &c)
740 {
741 typedef sl_concat3<A, B, C> expr;
742 return sl_expr<expr> (expr (a, b, c));
743 }
744
745 template<class A, class B, class C, class D>
746 inline sl_expr< sl_concat4<A, B, C, D> >
747 concat (const A &a, const B &b, const C &c, const D &d)
748 {
749 typedef sl_concat4<A, B, C, D> expr;
750 return sl_expr<expr> (expr (a, b, c, d));
751 }
752
753 template<typename expr>
754 struct sl_convert
755 {
756 typedef sl_expr<expr> T;
757 static inline const T &convert (const T &e)
758 {
759 return e;
760 }
761 };
762
763 template<>
764 struct sl_convert<GLfloat>
765 {
766 typedef sl_expr<sl_float> T;
767 static inline const T convert (GLfloat f)
768 {
769 return sl_float (f);
770 }
771 };
772
773 template<>
774 struct sl_convert<GLdouble>
775 {
776 typedef sl_expr<sl_float> T;
777 static inline const T convert (GLdouble d)
778 {
779 return sl_float (d);
780 }
781 };
782
783 template<>
784 struct sl_convert<GLint>
785 {
786 typedef sl_expr<sl_float> T;
787 static inline const T convert (GLint i)
788 {
789 return sl_float (i);
790 }
791 };
792
793 template<>
794 struct sl_convert<vec2>
795 {
796 static const sl_expr< sl_string<60> > convert (const vec2 &v);
797 };
798
799 template<>
800 struct sl_convert<vec3>
801 {
802 static const sl_expr< sl_string<80> > convert (const vec3 &v);
803 };
804
805 template<>
806 struct sl_convert<vec4>
807 {
808 static const sl_expr< sl_string<100> > convert (const vec4 &v);
809 };
810
811 template<>
812 template<class var_i>
813 struct sl_convert< var_ref<var_i> >
814 {
815 typedef sl_expr< var_i > T;
816 static inline const T convert (const var_ref<var_i> &v)
817 {
818 return T (*&v);
819 }
820 };
821
822 template<>
823 template<class gluvar_i>
824 struct sl_convert< auto_lvalue_ref1<gluvar_i, const char *> >
825 {
826 typedef sl_expr< gluvar_i > T;
827 static inline const T convert (const auto_lvalue_ref1<gluvar_i, const char *> &v)
828 {
829 return T (*&v);
830 }
831 };
832
833 template<>
834 template<const char *strtype, class var_i>
835 struct sl_convert< glnvar_ref<strtype, var_i> >
836 {
837 typedef sl_expr< var_i > T;
838 static inline const T convert (const glnvar_ref<strtype, var_i> &v)
839 {
840 return T (*&v);
841 }
842 };
843
844 template<>
845 template<class sampler_i>
846 struct sl_convert< sampler_ref<sampler_i> >
847 {
848 typedef sl_expr< sampler_i > T;
849 static inline const T convert (const sampler_ref<sampler_i> &v)
850 {
851 return T (*&v);
852 }
853 };
854
855 template<class lvalue, typename expr>
856 inline void sl_assign (const lvalue &l, const expr &e)
857 {
858 shader_builder::cur->code << " ";
859 sl_convert<lvalue>::convert (l) ();
860 shader_builder::cur->code << " = ";
861 sl_convert<expr>::convert (e) ();
862 shader_builder::cur->code << ";\n";
863 }
864
865 template<class type>
866 template<typename expr>
867 inline const auto_lvalue_ref0<type> &auto_lvalue_ref0<type>::operator =(const expr &e) const
868 {
869 sl_assign (*this, e);
870 return *this;
871 }
872
873 template<class type, typename arg1>
874 template<typename expr>
875 inline const auto_lvalue_ref1<type,arg1> &auto_lvalue_ref1<type,arg1>::operator =(const expr &e) const
876 {
877 sl_assign (*this, e);
878 return *this;
879 }
880
881 template<class T>
882 template<typename expr>
883 inline const sl_expr<T> &sl_expr<T>::operator =(const expr &e) const
884 {
885 sl_assign (*this, e);
886 return *this;
887 }
888
889 template<const char *strtype, class var_i>
890 template<typename expr>
891 inline const glnvar_ref<strtype, var_i> &glnvar_ref<strtype, var_i>::operator =(const expr &e) const
892 {
893 sl_assign (*this, e);
894 return *this;
895 }
896
897 namespace compile {
898 using namespace shader;
899
900 template<typename T>
901 inline const sl_expr< sl_func1<typename sl_convert<T>::T> >
902 operator +(const T &t)
903 {
904 return sl_func1<typename sl_convert<T>::T> ("+(", sl_convert<T>::convert (t));
905 }
906
907 template<typename T>
908 inline const sl_expr< sl_func1<typename sl_convert<T>::T> >
909 operator -(const T &t)
910 {
911 return sl_func1<typename sl_convert<T>::T> ("-(", sl_convert<T>::convert (t));
912 }
913
914 template<class A, class C>
915 struct sl_binop
916 {
917 const A a; const char *b; const C c;
918 sl_binop (const A &a, const char *b, const C &c) : a(a), b(b), c(c) { }
919 void operator ()() const
920 {
921 shader_builder::cur->code << "(";
922 a ();
923 shader_builder::cur->code << b;
924 c ();
925 shader_builder::cur->code << ")";
926 }
927 };
928
929 template<class A, class B, class C>
930 struct sl_ternary
931 {
932 const A a; const B b; const C c;
933 sl_ternary (const A &a, const B &b, const C &c) : a(a), b(b), c(c) { }
934 void operator ()() const
935 {
936 shader_builder::cur->code << "(";
937 a ();
938 shader_builder::cur->code << ") ? (";
939 b ();
940 shader_builder::cur->code << ") : (";
941 c ();
942 shader_builder::cur->code << ")";
943 }
944 };
945
946 # define SHADER_BINOP(op) \
947 template<typename A, typename B> \
948 inline const sl_expr< sl_binop< typename sl_convert<A>::T, \
949 typename sl_convert<B>::T > > \
950 operator op(const A &a, const B &b) \
951 { \
952 return sl_binop< typename sl_convert<A>::T, typename sl_convert<B>::T > \
953 (sl_convert<A>::convert (a), " " # op " ", sl_convert<B>::convert (b)); \
954 }
955
956 SHADER_BINOP (+);
957 SHADER_BINOP (-);
958 SHADER_BINOP (*);
959 SHADER_BINOP (/);
960 SHADER_BINOP (%);
961
962 SHADER_BINOP (<);
963 SHADER_BINOP (<=);
964 SHADER_BINOP (==);
965 SHADER_BINOP (!=);
966 SHADER_BINOP (>=);
967 SHADER_BINOP (>);
968
969 # undef SHADER_BINOP
970
971 template<class A>
972 struct sl_swizzle
973 {
974 const A a;
975 const char *swizzle;
976 sl_swizzle (const A &a, const char *swizzle) : a(a), swizzle(swizzle) { }
977 void operator ()() const
978 {
979 shader_builder::cur->code << "(";
980 a ();
981 shader_builder::cur->code << ")." << swizzle;
982 }
983 };
984
985 # define SHADER_SWIZZLE_OP(type) \
986 template<typename T> \
987 inline const sl_expr< sl_swizzle<typename sl_convert<T>::T> > \
988 type (const T &t) \
989 { \
990 return sl_swizzle<typename sl_convert<T>::T> (sl_convert<T>::convert (t), #type); \
991 }
992
993 // brute force is lovely, ain't it?
994 SHADER_SWIZZLE_OP (x ) SHADER_SWIZZLE_OP (xx ) SHADER_SWIZZLE_OP (xxx ) SHADER_SWIZZLE_OP (xxxx)
995 SHADER_SWIZZLE_OP (xxxy) SHADER_SWIZZLE_OP (xxxz) SHADER_SWIZZLE_OP (xxxw) SHADER_SWIZZLE_OP (xxy )
996 SHADER_SWIZZLE_OP (xxyx) SHADER_SWIZZLE_OP (xxyy) SHADER_SWIZZLE_OP (xxyz) SHADER_SWIZZLE_OP (xxyw)
997 SHADER_SWIZZLE_OP (xxz ) SHADER_SWIZZLE_OP (xxzx) SHADER_SWIZZLE_OP (xxzy) SHADER_SWIZZLE_OP (xxzz)
998 SHADER_SWIZZLE_OP (xxzw) SHADER_SWIZZLE_OP (xxw ) SHADER_SWIZZLE_OP (xxwx) SHADER_SWIZZLE_OP (xxwy)
999 SHADER_SWIZZLE_OP (xxwz) SHADER_SWIZZLE_OP (xxww) SHADER_SWIZZLE_OP (xy ) SHADER_SWIZZLE_OP (xyx )
1000 SHADER_SWIZZLE_OP (xyxx) SHADER_SWIZZLE_OP (xyxy) SHADER_SWIZZLE_OP (xyxz) SHADER_SWIZZLE_OP (xyxw)
1001 SHADER_SWIZZLE_OP (xyy ) SHADER_SWIZZLE_OP (xyyx) SHADER_SWIZZLE_OP (xyyy) SHADER_SWIZZLE_OP (xyyz)
1002 SHADER_SWIZZLE_OP (xyyw) SHADER_SWIZZLE_OP (xyz ) SHADER_SWIZZLE_OP (xyzx) SHADER_SWIZZLE_OP (xyzy)
1003 SHADER_SWIZZLE_OP (xyzz) SHADER_SWIZZLE_OP (xyzw) SHADER_SWIZZLE_OP (xyw ) SHADER_SWIZZLE_OP (xywx)
1004 SHADER_SWIZZLE_OP (xywy) SHADER_SWIZZLE_OP (xywz) SHADER_SWIZZLE_OP (xyww) SHADER_SWIZZLE_OP (xz )
1005 SHADER_SWIZZLE_OP (xzx ) SHADER_SWIZZLE_OP (xzxx) SHADER_SWIZZLE_OP (xzxy) SHADER_SWIZZLE_OP (xzxz)
1006 SHADER_SWIZZLE_OP (xzxw) SHADER_SWIZZLE_OP (xzy ) SHADER_SWIZZLE_OP (xzyx) SHADER_SWIZZLE_OP (xzyy)
1007 SHADER_SWIZZLE_OP (xzyz) SHADER_SWIZZLE_OP (xzyw) SHADER_SWIZZLE_OP (xzz ) SHADER_SWIZZLE_OP (xzzx)
1008 SHADER_SWIZZLE_OP (xzzy) SHADER_SWIZZLE_OP (xzzz) SHADER_SWIZZLE_OP (xzzw) SHADER_SWIZZLE_OP (xzw )
1009 SHADER_SWIZZLE_OP (xzwx) SHADER_SWIZZLE_OP (xzwy) SHADER_SWIZZLE_OP (xzwz) SHADER_SWIZZLE_OP (xzww)
1010 SHADER_SWIZZLE_OP (xw ) SHADER_SWIZZLE_OP (xwx ) SHADER_SWIZZLE_OP (xwxx) SHADER_SWIZZLE_OP (xwxy)
1011 SHADER_SWIZZLE_OP (xwxz) SHADER_SWIZZLE_OP (xwxw) SHADER_SWIZZLE_OP (xwy ) SHADER_SWIZZLE_OP (xwyx)
1012 SHADER_SWIZZLE_OP (xwyy) SHADER_SWIZZLE_OP (xwyz) SHADER_SWIZZLE_OP (xwyw) SHADER_SWIZZLE_OP (xwz )
1013 SHADER_SWIZZLE_OP (xwzx) SHADER_SWIZZLE_OP (xwzy) SHADER_SWIZZLE_OP (xwzz) SHADER_SWIZZLE_OP (xwzw)
1014 SHADER_SWIZZLE_OP (xww ) SHADER_SWIZZLE_OP (xwwx) SHADER_SWIZZLE_OP (xwwy) SHADER_SWIZZLE_OP (xwwz)
1015 SHADER_SWIZZLE_OP (xwww) SHADER_SWIZZLE_OP (y ) SHADER_SWIZZLE_OP (yx ) SHADER_SWIZZLE_OP (yxx )
1016 SHADER_SWIZZLE_OP (yxxx) SHADER_SWIZZLE_OP (yxxy) SHADER_SWIZZLE_OP (yxxz) SHADER_SWIZZLE_OP (yxxw)
1017 SHADER_SWIZZLE_OP (yxy ) SHADER_SWIZZLE_OP (yxyx) SHADER_SWIZZLE_OP (yxyy) SHADER_SWIZZLE_OP (yxyz)
1018 SHADER_SWIZZLE_OP (yxyw) SHADER_SWIZZLE_OP (yxz ) SHADER_SWIZZLE_OP (yxzx) SHADER_SWIZZLE_OP (yxzy)
1019 SHADER_SWIZZLE_OP (yxzz) SHADER_SWIZZLE_OP (yxzw) SHADER_SWIZZLE_OP (yxw ) SHADER_SWIZZLE_OP (yxwx)
1020 SHADER_SWIZZLE_OP (yxwy) SHADER_SWIZZLE_OP (yxwz) SHADER_SWIZZLE_OP (yxww) SHADER_SWIZZLE_OP (yy )
1021 SHADER_SWIZZLE_OP (yyx ) SHADER_SWIZZLE_OP (yyxx) SHADER_SWIZZLE_OP (yyxy) SHADER_SWIZZLE_OP (yyxz)
1022 SHADER_SWIZZLE_OP (yyxw) SHADER_SWIZZLE_OP (yyy ) SHADER_SWIZZLE_OP (yyyx) SHADER_SWIZZLE_OP (yyyy)
1023 SHADER_SWIZZLE_OP (yyyz) SHADER_SWIZZLE_OP (yyyw) SHADER_SWIZZLE_OP (yyz ) SHADER_SWIZZLE_OP (yyzx)
1024 SHADER_SWIZZLE_OP (yyzy) SHADER_SWIZZLE_OP (yyzz) SHADER_SWIZZLE_OP (yyzw) SHADER_SWIZZLE_OP (yyw )
1025 SHADER_SWIZZLE_OP (yywx) SHADER_SWIZZLE_OP (yywy) SHADER_SWIZZLE_OP (yywz) SHADER_SWIZZLE_OP (yyww)
1026 SHADER_SWIZZLE_OP (yz ) SHADER_SWIZZLE_OP (yzx ) SHADER_SWIZZLE_OP (yzxx) SHADER_SWIZZLE_OP (yzxy)
1027 SHADER_SWIZZLE_OP (yzxz) SHADER_SWIZZLE_OP (yzxw) SHADER_SWIZZLE_OP (yzy ) SHADER_SWIZZLE_OP (yzyx)
1028 SHADER_SWIZZLE_OP (yzyy) SHADER_SWIZZLE_OP (yzyz) SHADER_SWIZZLE_OP (yzyw) SHADER_SWIZZLE_OP (yzz )
1029 SHADER_SWIZZLE_OP (yzzx) SHADER_SWIZZLE_OP (yzzy) SHADER_SWIZZLE_OP (yzzz) SHADER_SWIZZLE_OP (yzzw)
1030 SHADER_SWIZZLE_OP (yzw ) SHADER_SWIZZLE_OP (yzwx) SHADER_SWIZZLE_OP (yzwy) SHADER_SWIZZLE_OP (yzwz)
1031 SHADER_SWIZZLE_OP (yzww) SHADER_SWIZZLE_OP (yw ) SHADER_SWIZZLE_OP (ywx ) SHADER_SWIZZLE_OP (ywxx)
1032 SHADER_SWIZZLE_OP (ywxy) SHADER_SWIZZLE_OP (ywxz) SHADER_SWIZZLE_OP (ywxw) SHADER_SWIZZLE_OP (ywy )
1033 SHADER_SWIZZLE_OP (ywyx) SHADER_SWIZZLE_OP (ywyy) SHADER_SWIZZLE_OP (ywyz) SHADER_SWIZZLE_OP (ywyw)
1034 SHADER_SWIZZLE_OP (ywz ) SHADER_SWIZZLE_OP (ywzx) SHADER_SWIZZLE_OP (ywzy) SHADER_SWIZZLE_OP (ywzz)
1035 SHADER_SWIZZLE_OP (ywzw) SHADER_SWIZZLE_OP (yww ) SHADER_SWIZZLE_OP (ywwx) SHADER_SWIZZLE_OP (ywwy)
1036 SHADER_SWIZZLE_OP (ywwz) SHADER_SWIZZLE_OP (ywww) SHADER_SWIZZLE_OP (z ) SHADER_SWIZZLE_OP (zx )
1037 SHADER_SWIZZLE_OP (zxx ) SHADER_SWIZZLE_OP (zxxx) SHADER_SWIZZLE_OP (zxxy) SHADER_SWIZZLE_OP (zxxz)
1038 SHADER_SWIZZLE_OP (zxxw) SHADER_SWIZZLE_OP (zxy ) SHADER_SWIZZLE_OP (zxyx) SHADER_SWIZZLE_OP (zxyy)
1039 SHADER_SWIZZLE_OP (zxyz) SHADER_SWIZZLE_OP (zxyw) SHADER_SWIZZLE_OP (zxz ) SHADER_SWIZZLE_OP (zxzx)
1040 SHADER_SWIZZLE_OP (zxzy) SHADER_SWIZZLE_OP (zxzz) SHADER_SWIZZLE_OP (zxzw) SHADER_SWIZZLE_OP (zxw )
1041 SHADER_SWIZZLE_OP (zxwx) SHADER_SWIZZLE_OP (zxwy) SHADER_SWIZZLE_OP (zxwz) SHADER_SWIZZLE_OP (zxww)
1042 SHADER_SWIZZLE_OP (zy ) SHADER_SWIZZLE_OP (zyx ) SHADER_SWIZZLE_OP (zyxx) SHADER_SWIZZLE_OP (zyxy)
1043 SHADER_SWIZZLE_OP (zyxz) SHADER_SWIZZLE_OP (zyxw) SHADER_SWIZZLE_OP (zyy ) SHADER_SWIZZLE_OP (zyyx)
1044 SHADER_SWIZZLE_OP (zyyy) SHADER_SWIZZLE_OP (zyyz) SHADER_SWIZZLE_OP (zyyw) SHADER_SWIZZLE_OP (zyz )
1045 SHADER_SWIZZLE_OP (zyzx) SHADER_SWIZZLE_OP (zyzy) SHADER_SWIZZLE_OP (zyzz) SHADER_SWIZZLE_OP (zyzw)
1046 SHADER_SWIZZLE_OP (zyw ) SHADER_SWIZZLE_OP (zywx) SHADER_SWIZZLE_OP (zywy) SHADER_SWIZZLE_OP (zywz)
1047 SHADER_SWIZZLE_OP (zyww) SHADER_SWIZZLE_OP (zz ) SHADER_SWIZZLE_OP (zzx ) SHADER_SWIZZLE_OP (zzxx)
1048 SHADER_SWIZZLE_OP (zzxy) SHADER_SWIZZLE_OP (zzxz) SHADER_SWIZZLE_OP (zzxw) SHADER_SWIZZLE_OP (zzy )
1049 SHADER_SWIZZLE_OP (zzyx) SHADER_SWIZZLE_OP (zzyy) SHADER_SWIZZLE_OP (zzyz) SHADER_SWIZZLE_OP (zzyw)
1050 SHADER_SWIZZLE_OP (zzz ) SHADER_SWIZZLE_OP (zzzx) SHADER_SWIZZLE_OP (zzzy) SHADER_SWIZZLE_OP (zzzz)
1051 SHADER_SWIZZLE_OP (zzzw) SHADER_SWIZZLE_OP (zzw ) SHADER_SWIZZLE_OP (zzwx) SHADER_SWIZZLE_OP (zzwy)
1052 SHADER_SWIZZLE_OP (zzwz) SHADER_SWIZZLE_OP (zzww) SHADER_SWIZZLE_OP (zw ) SHADER_SWIZZLE_OP (zwx )
1053 SHADER_SWIZZLE_OP (zwxx) SHADER_SWIZZLE_OP (zwxy) SHADER_SWIZZLE_OP (zwxz) SHADER_SWIZZLE_OP (zwxw)
1054 SHADER_SWIZZLE_OP (zwy ) SHADER_SWIZZLE_OP (zwyx) SHADER_SWIZZLE_OP (zwyy) SHADER_SWIZZLE_OP (zwyz)
1055 SHADER_SWIZZLE_OP (zwyw) SHADER_SWIZZLE_OP (zwz ) SHADER_SWIZZLE_OP (zwzx) SHADER_SWIZZLE_OP (zwzy)
1056 SHADER_SWIZZLE_OP (zwzz) SHADER_SWIZZLE_OP (zwzw) SHADER_SWIZZLE_OP (zww ) SHADER_SWIZZLE_OP (zwwx)
1057 SHADER_SWIZZLE_OP (zwwy) SHADER_SWIZZLE_OP (zwwz) SHADER_SWIZZLE_OP (zwww) SHADER_SWIZZLE_OP (w )
1058 SHADER_SWIZZLE_OP (wx ) SHADER_SWIZZLE_OP (wxx ) SHADER_SWIZZLE_OP (wxxx) SHADER_SWIZZLE_OP (wxxy)
1059 SHADER_SWIZZLE_OP (wxxz) SHADER_SWIZZLE_OP (wxxw) SHADER_SWIZZLE_OP (wxy ) SHADER_SWIZZLE_OP (wxyx)
1060 SHADER_SWIZZLE_OP (wxyy) SHADER_SWIZZLE_OP (wxyz) SHADER_SWIZZLE_OP (wxyw) SHADER_SWIZZLE_OP (wxz )
1061 SHADER_SWIZZLE_OP (wxzx) SHADER_SWIZZLE_OP (wxzy) SHADER_SWIZZLE_OP (wxzz) SHADER_SWIZZLE_OP (wxzw)
1062 SHADER_SWIZZLE_OP (wxw ) SHADER_SWIZZLE_OP (wxwx) SHADER_SWIZZLE_OP (wxwy) SHADER_SWIZZLE_OP (wxwz)
1063 SHADER_SWIZZLE_OP (wxww) SHADER_SWIZZLE_OP (wy ) SHADER_SWIZZLE_OP (wyx ) SHADER_SWIZZLE_OP (wyxx)
1064 SHADER_SWIZZLE_OP (wyxy) SHADER_SWIZZLE_OP (wyxz) SHADER_SWIZZLE_OP (wyxw) SHADER_SWIZZLE_OP (wyy )
1065 SHADER_SWIZZLE_OP (wyyx) SHADER_SWIZZLE_OP (wyyy) SHADER_SWIZZLE_OP (wyyz) SHADER_SWIZZLE_OP (wyyw)
1066 SHADER_SWIZZLE_OP (wyz ) SHADER_SWIZZLE_OP (wyzx) SHADER_SWIZZLE_OP (wyzy) SHADER_SWIZZLE_OP (wyzz)
1067 SHADER_SWIZZLE_OP (wyzw) SHADER_SWIZZLE_OP (wyw ) SHADER_SWIZZLE_OP (wywx) SHADER_SWIZZLE_OP (wywy)
1068 SHADER_SWIZZLE_OP (wywz) SHADER_SWIZZLE_OP (wyww) SHADER_SWIZZLE_OP (wz ) SHADER_SWIZZLE_OP (wzx )
1069 SHADER_SWIZZLE_OP (wzxx) SHADER_SWIZZLE_OP (wzxy) SHADER_SWIZZLE_OP (wzxz) SHADER_SWIZZLE_OP (wzxw)
1070 SHADER_SWIZZLE_OP (wzy ) SHADER_SWIZZLE_OP (wzyx) SHADER_SWIZZLE_OP (wzyy) SHADER_SWIZZLE_OP (wzyz)
1071 SHADER_SWIZZLE_OP (wzyw) SHADER_SWIZZLE_OP (wzz ) SHADER_SWIZZLE_OP (wzzx) SHADER_SWIZZLE_OP (wzzy)
1072 SHADER_SWIZZLE_OP (wzzz) SHADER_SWIZZLE_OP (wzzw) SHADER_SWIZZLE_OP (wzw ) SHADER_SWIZZLE_OP (wzwx)
1073 SHADER_SWIZZLE_OP (wzwy) SHADER_SWIZZLE_OP (wzwz) SHADER_SWIZZLE_OP (wzww) SHADER_SWIZZLE_OP (ww )
1074 SHADER_SWIZZLE_OP (wwx ) SHADER_SWIZZLE_OP (wwxx) SHADER_SWIZZLE_OP (wwxy) SHADER_SWIZZLE_OP (wwxz)
1075 SHADER_SWIZZLE_OP (wwxw) SHADER_SWIZZLE_OP (wwy ) SHADER_SWIZZLE_OP (wwyx) SHADER_SWIZZLE_OP (wwyy)
1076 SHADER_SWIZZLE_OP (wwyz) SHADER_SWIZZLE_OP (wwyw) SHADER_SWIZZLE_OP (wwz ) SHADER_SWIZZLE_OP (wwzx)
1077 SHADER_SWIZZLE_OP (wwzy) SHADER_SWIZZLE_OP (wwzz) SHADER_SWIZZLE_OP (wwzw) SHADER_SWIZZLE_OP (www )
1078 SHADER_SWIZZLE_OP (wwwx) SHADER_SWIZZLE_OP (wwwy) SHADER_SWIZZLE_OP (wwwz) SHADER_SWIZZLE_OP (wwww)
1079
1080 # undef SHADER_SWIZZLE_OP
1081
1082 # define SHADER_FUNC0_(name, glname) \
1083 template<typename A> \
1084 inline const sl_expr<sl_func0> \
1085 name () \
1086 { \
1087 return sl_func0 (#glname " ("); \
1088 }
1089
1090 # define SHADER_FUNC0(name) SHADER_FUNC0_(name,name)
1091
1092 # define SHADER_FUNC1_(name, glname) \
1093 template<typename A> \
1094 inline const sl_expr< sl_func1<typename sl_convert<A>::T> > \
1095 name (const A &a) \
1096 { \
1097 return sl_func1<typename sl_convert<A>::T> (#glname " (", sl_convert<A>::convert (a));\
1098 }
1099
1100 # define SHADER_FUNC1(name) SHADER_FUNC1_(name,name)
1101
1102 # define SHADER_FUNC2_(name, glname) \
1103 template<typename A, typename B> \
1104 inline const sl_expr< sl_func2<typename sl_convert<A>::T, typename sl_convert<B>::T> > \
1105 name (const A &a, const B &b) \
1106 { \
1107 return sl_func2<typename sl_convert<A>::T, typename sl_convert<B>::T> (#glname " (", sl_convert<A>::convert (a), sl_convert<B>::convert (b));\
1108 }
1109
1110 # define SHADER_FUNC2(name) SHADER_FUNC2_(name,name)
1111
1112 # define SHADER_FUNC3_(name, glname) \
1113 template<typename A, typename B, typename C> \
1114 inline const sl_expr< sl_func3<typename sl_convert<A>::T, typename sl_convert<B>::T, typename sl_convert<C>::T> > \
1115 name (const A &a, const B &b, const C &c) \
1116 { \
1117 return sl_func3<typename sl_convert<A>::T, typename sl_convert<B>::T, typename sl_convert<C>::T> (#glname " (", sl_convert<A>::convert (a), sl_convert<B>::convert (b), sl_convert<C>::convert (c));\
1118 }
1119
1120 # define SHADER_FUNC3(name) SHADER_FUNC3_(name,name)
1121
1122 # define SHADER_FUNC4_(name, glname) \
1123 template<typename A, typename B, typename C, typename D> \
1124 inline const sl_expr< sl_func4<typename sl_convert<A>::T, typename sl_convert<B>::T, typename sl_convert<C>::T, typename sl_convert<D>::T > > \
1125 name (const A &a, const B &b, const C &c, const D &d) \
1126 { \
1127 return sl_func4<typename sl_convert<A>::T, typename sl_convert<B>::T, typename sl_convert<C>::T, typename sl_convert<D>::T> (#glname " (", sl_convert<A>::convert (a), sl_convert<B>::convert (b), sl_convert<C>::convert (c), sl_convert<D>::convert (d));\
1128 }
1129
1130 # define SHADER_FUNC4(name) SHADER_FUNC4_(name,name)
1131
1132 SHADER_FUNC1 (abs)
1133 SHADER_FUNC1 (acos)
1134 SHADER_FUNC1 (all)
1135 SHADER_FUNC1 (any)
1136 SHADER_FUNC1 (asin)
1137 SHADER_FUNC1 (atan)
1138 SHADER_FUNC2 (atan)
1139 SHADER_FUNC1 (ceil)
1140 SHADER_FUNC3 (clamp)
1141 SHADER_FUNC1 (cos)
1142 SHADER_FUNC2 (cross)
1143 SHADER_FUNC1 (dFdx)
1144 SHADER_FUNC1 (dFdy)
1145 SHADER_FUNC1 (degrees)
1146 SHADER_FUNC2 (distance)
1147 SHADER_FUNC2 (dot)
1148 SHADER_FUNC2_(equal, equal)
1149 SHADER_FUNC1 (exp)
1150 SHADER_FUNC1 (exp2)
1151 SHADER_FUNC3 (faceforward)
1152 SHADER_FUNC1 (floor)
1153 SHADER_FUNC1 (fract)
1154 SHADER_FUNC0 (ftransform)
1155 SHADER_FUNC1 (fwidth)
1156 SHADER_FUNC2_(greater_than_equal, greaterThanEqual)
1157 SHADER_FUNC2_(greater_then, greaterThan)
1158 SHADER_FUNC1 (inversesqrt)
1159 SHADER_FUNC1 (length)
1160 SHADER_FUNC2_(less_than, lessThan)
1161 SHADER_FUNC2_(less_than_equal, lessThanEqual)
1162 SHADER_FUNC1 (log)
1163 SHADER_FUNC1 (log2)
1164 SHADER_FUNC2_(matrix_comp_mult, matrixCompMult)
1165 SHADER_FUNC2 (max)
1166 SHADER_FUNC2 (min)
1167 SHADER_FUNC3 (mix)
1168 SHADER_FUNC2 (mod)
1169 SHADER_FUNC1 (noise1)
1170 SHADER_FUNC1 (noise2)
1171 SHADER_FUNC1 (noise3)
1172 SHADER_FUNC1 (noise4)
1173 SHADER_FUNC1 (normalize)
1174 SHADER_FUNC1 (gl_not) // TODO
1175 SHADER_FUNC2_(notequal, notEqual)
1176 SHADER_FUNC2 (pow)
1177 SHADER_FUNC1 (radians)
1178 SHADER_FUNC2 (reflect)
1179 SHADER_FUNC3 (refract)
1180 SHADER_FUNC2_(shadow_1d, shadow1D)
1181 SHADER_FUNC3_(shadow_1d, shadow1D)
1182 SHADER_FUNC3_(shadow_1d_lod, shadow1DLod)
1183 SHADER_FUNC2_(shadow_1d_proj, shadow1DProj)
1184 SHADER_FUNC3_(shadow_1d_proj, shadow1DProj)
1185 SHADER_FUNC3_(shadow_1d_proj_lod, shadow1DProjLod)
1186 SHADER_FUNC2_(shadow_2d, shadow2D)
1187 SHADER_FUNC3_(shadow_2d, shadow2D)
1188 SHADER_FUNC3_(shadow_2d_lod, shadow2DLod)
1189 SHADER_FUNC2_(shadow_2d_proj, shadow2DProj)
1190 SHADER_FUNC3_(shadow_2d_proj, shadow2DProj)
1191 SHADER_FUNC3_(shadow_2d_proj_lod, shadow2DProjLod)
1192 SHADER_FUNC1 (sign)
1193 SHADER_FUNC1 (sin)
1194 SHADER_FUNC3 (smoothstep)
1195 SHADER_FUNC1 (sqrt)
1196 SHADER_FUNC2 (step)
1197 SHADER_FUNC1 (tan)
1198 SHADER_FUNC2_(texture_1d, texture1D)
1199 SHADER_FUNC3_(texture_1d, texture1D)
1200 SHADER_FUNC3_(texture_1d_lod, texture1DLod)
1201 SHADER_FUNC2_(texture_1d_proj, texture1DProj)
1202 SHADER_FUNC3_(texture_1d_proj, texture1DProj)
1203 SHADER_FUNC3_(texture_1d_proj_lod, texture1DProjLod)
1204 SHADER_FUNC2_(texture_2d, texture2D)
1205 SHADER_FUNC3_(texture_2d, texture2D)
1206 SHADER_FUNC3_(texture_2d_lod, texture2DLod)
1207 SHADER_FUNC2_(texture_2d_proj, texture2DProj)
1208 SHADER_FUNC3_(texture_2d_proj, texture2DProj)
1209 SHADER_FUNC3_(texture_2d_proj_lod, texture2DProjLod)
1210 SHADER_FUNC2_(texture_3d, texture3D)
1211 SHADER_FUNC3_(texture_3d, texture3D)
1212 SHADER_FUNC3_(texture_3d_lod, texture3DLod)
1213 SHADER_FUNC2_(texture_3d_proj, texture3DProj)
1214 SHADER_FUNC3_(texture_3d_proj, texture3DProj)
1215 SHADER_FUNC3_(texture_3d_proj_lod, texture3DProjLod)
1216 SHADER_FUNC2_(texture_cube, textureCube)
1217 SHADER_FUNC3_(texture_cube, textureCube)
1218 SHADER_FUNC3_(texture_cude_lod, textureCubeLod)
1219 SHADER_FUNC1 (vec2) SHADER_FUNC2 (vec2)
1220 SHADER_FUNC1 (vec3) SHADER_FUNC2 (vec3) SHADER_FUNC3 (vec3)
1221 SHADER_FUNC1 (vec4) SHADER_FUNC2 (vec4) SHADER_FUNC3 (vec4) SHADER_FUNC4 (vec4)
1222 // floatx is out extension
1223 SHADER_FUNC1 (float2) SHADER_FUNC2 (float2)
1224 SHADER_FUNC1 (float3) SHADER_FUNC2 (float3) SHADER_FUNC3 (float3)
1225 SHADER_FUNC1 (float4) SHADER_FUNC2 (float4) SHADER_FUNC3 (float4) SHADER_FUNC4 (float4)
1226 SHADER_FUNC1 (mat2) SHADER_FUNC2 (mat2)
1227 SHADER_FUNC1 (mat3) SHADER_FUNC2 (mat3) SHADER_FUNC3 (mat3)
1228 SHADER_FUNC1 (mat4) SHADER_FUNC2 (mat4) SHADER_FUNC3 (mat4) SHADER_FUNC4 (mat4)
1229
1230 # undef SHADER_FUNC0
1231 # undef SHADER_FUNC0_
1232 # undef SHADER_FUNC1
1233 # undef SHADER_FUNC1_
1234 # undef SHADER_FUNC2
1235 # undef SHADER_FUNC2_
1236 # undef SHADER_FUNC3
1237 # undef SHADER_FUNC3_
1238 # undef SHADER_FUNC4
1239 # undef SHADER_FUNC5_
1240 }
1241
1242 #if 0
1243 template<typename A, typename B, typename C>
1244 inline const sl_expr< sl_ternary<typename sl_convert<A>::T, typename sl_convert<B>::T, typename sl_convert<C>::T> >
1245 ifelse (const A &a, const B &b, const C &c)
1246 {
1247 return sl_ternary<typename sl_convert<A>::T, typename sl_convert<B>::T, typename sl_convert<C>::T>
1248 (sl_convert<A>::convert (a), sl_convert<B>::convert (b), sl_convert<C>::convert (c));
1249 }
1250 #endif
1251
1252 }
1253
1254 #endif
1255
1256 #include "shader_vars.h"
1257
1258