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