ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/libgender/shader.h
Revision: 1.24
Committed: Mon Nov 1 22:23:38 2004 UTC (21 years, 11 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.23: +156 -130 lines
Log Message:
*** empty log message ***

File Contents

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