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