ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/libgender/shader.h
Revision: 1.20
Committed: Fri Oct 29 23:19:08 2004 UTC (19 years, 7 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.19: +2 -21 lines
Log Message:
*** empty log message ***

File Contents

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