ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/libgender/shader.h
Revision: 1.6
Committed: Sat Oct 23 23:36:45 2004 UTC (19 years, 7 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.5: +129 -22 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 root 1.1 #ifndef SHADER_H
2     #define SHADER_H
3    
4     #include <sstream>
5    
6     #include "opengl.h"
7     #include "util.h"
8    
9     namespace shader {
10    
11     using namespace std;
12    
13     const int NAMELEN = 32;
14    
15     template<class T>
16     struct sl_expr {
17     const T t;
18     sl_expr (const T &t) : t(t) { }
19     void operator ()() const { t (); }
20 root 1.5 template<typename expr>
21     const sl_expr &operator =(const expr &e) const;
22 root 1.1 };
23    
24     template<class A, class B>
25     struct sl_concat2
26     {
27     const A a; const B b;
28     sl_concat2 (const A &a, const B &b) : a(a), b(b) { }
29     void operator ()() const { a (); b (); }
30     };
31    
32     template<class A, class B, class C>
33     struct sl_concat3
34     {
35     const A a; const B b; const C c;
36     sl_concat3 (const A &a, const B &b, const C &c) : a(a), b(b), c(c) { }
37     void operator ()() const { a (); b (); c (); }
38     };
39    
40     template<class A, class B, class C, class D>
41     struct sl_concat4
42     {
43     const A a; const B b; const C c; const D d;
44     sl_concat4 (const A &a, const B &b, const C &c, const D &d) : a(a), b(b), c(c), d(d) { }
45     void operator ()() const { a (); b (); c (); d(); }
46     };
47    
48     class refcounted
49     {
50     template<class type> friend class ref;
51     mutable int refcnt;
52     void refcnt_inc () const { refcnt++; }
53 root 1.6 void refcnt_dec () const;
54 root 1.1 public:
55     refcounted () : refcnt(0) { }
56     virtual ~refcounted ();
57     };
58    
59     template<class type>
60     struct ref
61     {
62     type *p;
63    
64     ref ()
65     {
66     p = new type;
67     p->refcnt_inc ();
68     }
69    
70     ref (type &d)
71     {
72     d.refcnt_inc ();
73     p = &d;
74     }
75    
76     ref (const ref &r)
77     {
78     r.p->refcnt_inc ();
79     p = r.p;
80     }
81    
82     template<class type2>
83     ref (const ref<type2> &r)
84     {
85     r.p->refcnt_inc ();
86     p = r.p;
87     }
88    
89     ~ref ()
90     {
91     p->refcnt_dec ();
92     }
93    
94     ref &operator =(type &d)
95     {
96     d.refcnt_inc ();
97     p->refcnt_dec ();
98     p = &d;
99     return *this;
100     }
101    
102     type *operator ->() const { return p; }
103    
104     operator type &() const { return *p; }
105    
106     template<class type2>
107     bool operator ==(const ref<type2> b) const
108     {
109     return (void *)p == (void *)b.p;
110     }
111     };
112    
113     // ref with auto-construct
114     template<class type>
115     struct auto_ref0 : ref<type>
116     {
117     auto_ref0 () : ref<type> (*new type ()) { }
118     };
119    
120     template<class type, typename arg1>
121     struct auto_ref1 : ref<type>
122     {
123     auto_ref1 (arg1 a) : ref<type> (*new type (a)) { }
124     };
125    
126     template<class type>
127     struct auto_lvalue_ref0 : ref<type>
128     {
129     auto_lvalue_ref0 () : ref<type> (*new type ()) { }
130     template<typename expr>
131     const auto_lvalue_ref0 &operator =(const expr &e) const;
132     };
133    
134     template<class type, typename arg1>
135     struct auto_lvalue_ref1 : ref<type>
136     {
137     auto_lvalue_ref1 (arg1 a) : ref<type> (*new type (a)) { }
138     template<class expr>
139     const auto_lvalue_ref1 &operator =(const expr &e) const;
140     };
141    
142     extern const char str_float [];
143     extern const char str_vec2 [];
144     extern const char str_vec3 [];
145     extern const char str_vec4 [];
146     extern const char str_mat2 [];
147     extern const char str_mat3 [];
148     extern const char str_mat4 [];
149    
150     extern const char str_sampler_1d [];
151     extern const char str_sampler_1d_shadow [];
152     extern const char str_sampler_2d [];
153     extern const char str_sampler_2d_shadow [];
154     extern const char str_sampler_2d_rect [];
155     extern const char str_sampler_2d_rect_shadow [];
156     extern const char str_sampler_3d [];
157     extern const char str_sampler_3d_rect [];
158     extern const char str_sampler_cube [];
159    
160     typedef ref<struct var_i> var;
161     typedef ref<struct uniform_i> uniform;
162    
163     struct shader_builder
164     {
165     vector<uniform> refs; // uniform parameters
166     vector<var> temps; // temporary variables
167     vector<var> streams; // varying inputs & outputs
168    
169     ostringstream source;
170    
171     template<typename type>
172     shader_builder &operator <<(const type &t)
173     {
174     source << t;
175     return *this;
176     }
177     };
178    
179     struct fragment_i : refcounted
180     {
181     virtual void build (shader_builder &b) = 0;
182     };
183    
184     typedef ref<fragment_i> fragment;
185    
186     struct lvalue_i : fragment_i
187     {
188     };
189    
190     // a simple predeclared variable with unspecified type
191     struct glvar_i : lvalue_i
192     {
193     const char *name;
194     void build (shader_builder &b);
195     glvar_i (const char *name) : name (name) { }
196     };
197    
198     typedef auto_lvalue_ref1<glvar_i, const char *> glvar;
199    
200     struct var_i : lvalue_i
201     {
202     static unsigned int next_id;
203    
204     char name[NAMELEN];
205     const char *typestr;
206    
207     void build (shader_builder &b);
208     virtual void build_decl (ostringstream &b);
209    
210     var_i (const char *typestr);
211     ~var_i ();
212     };
213    
214     struct uniform_i : var_i
215     {
216     bool dirty;
217    
218     virtual void update () = 0;
219    
220     void build (shader_builder &b);
221     void build_decl (ostringstream &b);
222     uniform_i (const char *strtype);
223     };
224    
225     template<int dimension, typename gltype, const char *strtype, void (*upd)(CGparameter, const gltype *)>
226     struct uniform2_i : uniform_i
227     {
228     gltype data[dimension];
229    
230     void update ()
231     {
232     if (dirty)
233     {
234     //upd (param, data);
235     dirty = false;
236     }
237     }
238    
239     uniform2_i () : uniform_i (strtype) { }
240     };
241    
242     template<int dimension, const char *strtype, void (*update)(CGparameter, const GLfloat *)>
243     struct uniform_f_i : uniform2_i<dimension, GLfloat, strtype, update>
244     {
245     };
246    
247     struct uniform_1f_i : uniform_f_i<1, str_float, cgGLSetParameter1fv> {
248     void operator =(GLfloat v)
249     {
250     data[0] = v;
251     dirty = true;
252     }
253     };
254    
255     struct uniform_2f_i : uniform_f_i<2, str_vec2, cgGLSetParameter2fv> { };
256    
257     struct uniform_3f_i : uniform_f_i<3, str_vec3, cgGLSetParameter3fv> {
258     void operator =(const vec3 &v)
259     {
260     data[0] = v.x;
261     data[1] = v.y;
262     data[2] = v.z;
263     dirty = true;
264     }
265     };
266    
267     struct uniform_4f_i : uniform_f_i<4, str_vec4, cgGLSetParameter4fv> {
268     #if 0
269     void operator =(const gl::matrix &m)
270     {
271     memcpy (data, m.data, 16 * sizeof (GLfloat));
272     dirty = true;
273     }
274     #endif
275     };
276    
277     struct uniform_matrix_2f_i : uniform_f_i< 4, str_mat2, cgGLSetMatrixParameterfc> { };
278     struct uniform_matrix_3f_i : uniform_f_i< 9, str_mat3, cgGLSetMatrixParameterfc> { };
279     struct uniform_matrix_4f_i : uniform_f_i<16, str_mat4, cgGLSetMatrixParameterfc> { };
280    
281 root 1.2 template<class var_i>
282     struct var_ref : ref<var_i>
283 root 1.1 {
284 root 1.2 var_ref (const char *glname = 0)
285     : ref<var_i> (*new var_i)
286 root 1.1 {
287     if (glname)
288     strcpy ((*this)->name, glname);
289     }
290     };
291    
292 root 1.2 typedef var_ref<uniform_1f_i> uniform_1f;
293     typedef var_ref<uniform_2f_i> uniform_2f;
294     typedef var_ref<uniform_3f_i> uniform_3f;
295     typedef var_ref<uniform_4f_i> uniform_4f;
296     typedef var_ref<uniform_matrix_2f_i> uniform_matrix_2f;
297     typedef var_ref<uniform_matrix_3f_i> uniform_matrix_3f;
298     typedef var_ref<uniform_matrix_4f_i> uniform_matrix_4f;
299 root 1.1
300     struct stream_i : var_i
301     {
302     void build (shader_builder &b);
303     void build_decl (ostringstream &b);
304 root 1.4 stream_i (const char *strtype);
305 root 1.1 };
306    
307     template<int dimension, GLenum gltype, const char *strtype>
308     struct varying_i : stream_i
309     {
310 root 1.4 varying_i () : stream_i (strtype) { }
311 root 1.1
312     void set (GLsizei stride, GLvoid *ptr)
313     {
314     //cgGLSetParameterPointer (param, dimension, gltype, stride, ptr);
315     }
316     };
317    
318     template<int dimension, const char *strtype>
319     struct varying_f_i : varying_i<dimension, GL_FLOAT, strtype>
320     {
321     void set (const gl::vertex_buffer_object &vb, GLint offset)
322     {
323     varying_i<dimension, GL_FLOAT, strtype>::set (gl::format_stride (vb.format), (GLvoid *)(long)offset);
324     }
325     };
326    
327     struct varying_1f_i : varying_f_i<1, str_float>
328     {
329     };
330    
331     struct varying_2f_i : varying_f_i<2, str_vec2>
332     {
333     void set_t (const gl::vertex_buffer_object &vb)
334     {
335     set (vb, gl::format_offset_t (vb.format));
336     }
337     };
338    
339     struct varying_3f_i : varying_f_i<3, str_vec3>
340     {
341     void set_p (const gl::vertex_buffer_object &vb)
342     {
343     set (vb, gl::format_offset_p (vb.format));
344     }
345    
346     void set_n (const gl::vertex_buffer_object &vb)
347     {
348     set (vb, gl::format_offset_n (vb.format));
349     }
350     };
351    
352     struct varying_4f_i : varying_f_i<4, str_vec4>
353     {
354     };
355    
356 root 1.2 typedef var_ref<varying_1f_i> varying_1f;
357     typedef var_ref<varying_2f_i> varying_2f;
358     typedef var_ref<varying_3f_i> varying_3f;
359     typedef var_ref<varying_4f_i> varying_4f;
360 root 1.1
361     struct temporary_i : var_i
362     {
363     void build (shader_builder &b);
364    
365     temporary_i (const char *strtype);
366     };
367    
368     template<const char *strtype>
369     struct temp_ref : ref<temporary_i>
370     {
371     temp_ref ()
372     : ref<temporary_i> (*new temporary_i (strtype))
373     {
374     }
375    
376     template<typename expr>
377     const temp_ref &operator =(const expr &e) const;
378     };
379    
380     typedef temp_ref<str_float> temp_1f;
381     typedef temp_ref<str_vec2> temp_2f;
382     typedef temp_ref<str_vec3> temp_3f;
383     typedef temp_ref<str_vec4> temp_4f;
384     typedef temp_ref<str_mat2> temp_matrix_2f;
385     typedef temp_ref<str_mat3> temp_matrix_3f;
386     typedef temp_ref<str_mat4> temp_matrix_4f;
387    
388     template<GLenum gltype, const char *strtype>
389     struct sampler_i : uniform_i
390     {
391     GLuint texture;
392    
393     void update ()
394     {
395     if (dirty)
396     {
397     //cgGLSetTextureParameter (param, texture);
398     dirty = false;
399     }
400     }
401    
402     void begin ()
403     {
404     cgGLEnableTextureParameter (texture);
405     }
406    
407     sampler_i (GLuint texturename) : uniform_i (strtype), texture (texturename) { }
408     };
409    
410     struct sampler_1d_i : sampler_i<CG_SAMPLER1D, str_sampler_1d>
411     {
412     sampler_1d_i (GLuint texturename) : sampler_i<CG_SAMPLER1D, str_sampler_1d> (texturename) { }
413     };
414    
415     struct sampler_1d_shadow_i : sampler_i<CG_SAMPLER1D, str_sampler_1d_shadow>
416     {
417     sampler_1d_shadow_i (GLuint texturename) : sampler_i<CG_SAMPLER1D, str_sampler_1d_shadow> (texturename) { }
418     };
419    
420     struct sampler_2d_i : sampler_i<CG_SAMPLER2D, str_sampler_2d>
421     {
422     sampler_2d_i (GLuint texturename) : sampler_i<CG_SAMPLER2D, str_sampler_2d> (texturename) { }
423     };
424    
425     struct sampler_2d_shadow_i : sampler_i<CG_SAMPLER2D, str_sampler_2d_shadow>
426     {
427     sampler_2d_shadow_i (GLuint texturename) : sampler_i<CG_SAMPLER2D, str_sampler_2d_shadow> (texturename) { }
428     };
429    
430     struct sampler_2d_rect_i : sampler_i<CG_SAMPLERRECT, str_sampler_2d_rect>
431     {
432     sampler_2d_rect_i (GLuint texturename) : sampler_i<CG_SAMPLERRECT, str_sampler_2d_rect> (texturename) { }
433     };
434    
435     struct sampler_2d_rect_shadow_i : sampler_i<CG_SAMPLERRECT, str_sampler_2d_rect_shadow>
436     {
437     sampler_2d_rect_shadow_i (GLuint texturename) : sampler_i<CG_SAMPLERRECT, str_sampler_2d_rect_shadow> (texturename) { }
438     };
439    
440     struct sampler_3d_i : sampler_i<CG_SAMPLER3D, str_sampler_3d>
441     {
442     sampler_3d_i (GLuint texturename) : sampler_i<CG_SAMPLER3D, str_sampler_3d> (texturename) { }
443     };
444    
445     struct sampler_3d_rect_i : sampler_i<CG_SAMPLER3D, str_sampler_3d_rect>
446     {
447     sampler_3d_rect_i (GLuint texturename) : sampler_i<CG_SAMPLER3D, str_sampler_3d_rect> (texturename) { }
448     };
449    
450     struct sampler_cube_i : sampler_i<CG_SAMPLERCUBE, str_sampler_cube>
451     {
452     sampler_cube_i (GLuint texturename) : sampler_i<CG_SAMPLERCUBE, str_sampler_cube> (texturename) { }
453     };
454    
455     typedef auto_ref1<sampler_1d_i, GLuint> sampler_1d;
456     typedef auto_ref1<sampler_1d_shadow_i, GLuint> sampler_1d_shadow;
457     typedef auto_ref1<sampler_2d_i, GLuint> sampler_2d;
458     typedef auto_ref1<sampler_2d_shadow_i, GLuint> sampler_2d_shadow;
459     typedef auto_ref1<sampler_2d_rect_i, GLuint> sampler_2d_rect;
460     typedef auto_ref1<sampler_2d_rect_shadow_i, GLuint> sampler_2d_rect_shadow;
461     typedef auto_ref1<sampler_3d_i, GLuint> sampler_3d;
462     typedef auto_ref1<sampler_3d_rect_i, GLuint> sampler_3d_rect;
463     typedef auto_ref1<sampler_cube_i, GLuint> sampler_cube;
464    
465     struct fragment_const_string_i : fragment_i
466     {
467     const char *str;
468    
469     void build (shader_builder &b);
470    
471     fragment_const_string_i (const char *str) : str(str) { }
472     };
473    
474     typedef auto_ref1<fragment_const_string_i, const char *> fragment_const_string;
475    
476     struct fragment_string_i : fragment_i
477     {
478     char *str;
479    
480     void build (shader_builder &b);
481    
482     fragment_string_i (const char *str) : str (strdup (str)) { }
483     ~fragment_string_i ();
484     };
485    
486     struct fragment_vector_i : fragment_i, vector<fragment>
487     {
488     void build (shader_builder &b);
489    
490     template<class fragment_i>
491     void append (const ref<fragment_i> &f)
492     {
493     push_back (f);
494     }
495    
496 root 1.5 template<class expr>
497     void append (const sl_expr<expr> &e)
498     {
499     e ();
500     }
501    
502 root 1.1 void append_const (const char *s)
503     {
504     push_back (*new fragment_const_string_i (s));
505     }
506    
507     void append_string (const char *s)
508     {
509     push_back (*new fragment_string_i (s));
510     }
511    
512     #if 0
513     fragment_vector_i &operator <<(statement_i &f)
514     {
515     push_back (*new fragment_const_string_i (" "));
516    
517     for (vector<fragment>::iterator i = f.begin (); i != f.end (); i++)
518     push_back (*i);
519    
520     push_back (*new fragment_const_string_i (";\n"));
521     return *this;
522     }
523     #endif
524     };
525    
526     typedef ref<fragment_vector_i> fragment_vector;
527    
528     struct shader_object_i : fragment_vector_i
529     {
530     GLenum type;
531     GLuint id; // GLhandleARB, but 2.0 will use uint
532    
533     string source ();
534     void compile ();
535     void start ();
536     void stop ();
537    
538     shader_object_i (GLenum type);
539     ~shader_object_i ();
540     };
541    
542     extern shader_object_i *cur; // record actions to this shader
543    
544     template<GLenum type>
545     struct shader_object : ref<shader_object_i>
546     {
547     shader_object ()
548     : ref<shader_object_i> (*new shader_object_i (type))
549     {
550     }
551     };
552    
553     typedef shader_object<GL_VERTEX_SHADER_ARB> vertex_shader;
554     typedef shader_object<GL_FRAGMENT_SHADER_ARB> fragment_shader;
555    
556 root 1.3 template<typename T>
557     struct sl_append
558     {
559     T t;
560    
561     sl_append (const T &t) : t(t) { }
562    
563     void operator ()() const
564     {
565     cur->push_back (t);
566     }
567     };
568    
569     template<int length>
570     struct sl_string
571     {
572     char str[length];
573    
574     void operator ()() const
575     {
576     cur->push_back (*new fragment_string_i (str));
577     }
578     };
579    
580     struct sl_float
581     {
582     const GLfloat c;
583    
584     sl_float (GLfloat c) : c(c) { }
585    
586 root 1.6 void operator ()() const;
587 root 1.3 };
588    
589     template<class A, class B>
590     inline sl_expr< sl_concat2<A, B> >
591     concat (const A &a, const B &b)
592     {
593     typedef sl_concat2<A, B> expr;
594     return sl_expr<expr> (expr (a, b));
595     }
596    
597     template<class A, class B, class C>
598     inline sl_expr< sl_concat3<A, B, C> >
599     concat (const A &a, const B &b, const C &c)
600     {
601     typedef sl_concat3<A, B, C> expr;
602     return sl_expr<expr> (expr (a, b, c));
603     }
604    
605     template<class A, class B, class C, class D>
606     inline sl_expr< sl_concat4<A, B, C, D> >
607     concat (const A &a, const B &b, const C &c, const D &d)
608     {
609     typedef sl_concat4<A, B, C, D> expr;
610     return sl_expr<expr> (expr (a, b, c, d));
611     }
612    
613     template<typename expr>
614     struct sl_convert
615     {
616     typedef sl_expr<expr> T;
617     static inline const T &convert (const T &e)
618     {
619     return e;
620     }
621     };
622    
623     template<>
624     struct sl_convert<GLfloat>
625     {
626     typedef sl_expr<sl_float> T;
627     static inline const T convert (GLfloat f)
628     {
629     return sl_float (f);
630     }
631     };
632    
633     template<>
634 root 1.5 struct sl_convert<GLdouble>
635     {
636     typedef sl_expr<sl_float> T;
637     static inline const T convert (GLdouble d)
638     {
639     return sl_float (d);
640     }
641     };
642    
643     template<>
644     struct sl_convert<GLint>
645     {
646     typedef sl_expr<sl_float> T;
647     static inline const T convert (GLint i)
648     {
649     return sl_float (i);
650     }
651     };
652    
653     template<>
654 root 1.6 struct sl_convert<vec2>
655     {
656     typedef sl_expr< sl_string<60> > T;
657     static const T convert (const vec2 &v);
658     };
659    
660     template<>
661 root 1.3 struct sl_convert<vec3>
662     {
663 root 1.6 typedef sl_expr< sl_string<80> > T;
664     static const T convert (const vec3 &v);
665 root 1.3 };
666    
667     template<>
668     struct sl_convert<vec4>
669     {
670 root 1.6 typedef sl_expr< sl_string<100> > T;
671     static const T convert (const vec4 &v);
672 root 1.3 };
673    
674     template<>
675     template<class V>
676     struct sl_convert< var_ref<V> >
677     {
678     typedef sl_expr< sl_append< var_ref<V> > > T;
679     static inline const T convert (const var_ref<V> &v)
680     {
681     return sl_append< var_ref<V> > (v);
682     }
683     };
684    
685     template<>
686     struct sl_convert<glvar>
687     {
688     typedef sl_expr< sl_append<glvar> > T;
689     static inline const T convert (const glvar &v)
690     {
691     return sl_append<glvar> (v);
692     }
693     };
694    
695     template<>
696     template<const char *strtype>
697     struct sl_convert< temp_ref<strtype> >
698     {
699     typedef sl_expr< sl_append< temp_ref<strtype> > > T;
700     static inline const T convert (const temp_ref<strtype> &v)
701     {
702     return sl_expr< sl_append< temp_ref<strtype> > >(
703     sl_append< temp_ref<strtype> > (v)
704     );
705     }
706     };
707    
708 root 1.5 extern const fragment_const_string str_2sp;
709     extern const fragment_const_string str_equal;
710     extern const fragment_const_string str_endl;
711    
712 root 1.3 template<class fragment, typename expr>
713     inline void sl_assign (const fragment &f, const expr &e)
714     {
715 root 1.5 cur->append (str_2sp);
716 root 1.3 cur->append (f);
717 root 1.5 cur->append (str_equal);
718 root 1.3 sl_convert<expr>::convert (e) ();
719 root 1.5 cur->append (str_endl);
720 root 1.3 }
721    
722     template<class type>
723     template<typename expr>
724     inline const auto_lvalue_ref0<type> &auto_lvalue_ref0<type>::operator =(const expr &e) const
725     {
726     sl_assign (*this, e);
727     return *this;
728     }
729    
730     template<class type, typename arg1>
731     template<typename expr>
732     inline const auto_lvalue_ref1<type,arg1> &auto_lvalue_ref1<type,arg1>::operator =(const expr &e) const
733     {
734     sl_assign (*this, e);
735     return *this;
736     }
737    
738 root 1.5 template<class T>
739     template<typename expr>
740     inline const sl_expr<T> &sl_expr<T>::operator =(const expr &e) const
741     {
742     sl_assign (*this, e);
743     return *this;
744     }
745    
746 root 1.3 template<const char *strtype>
747     template<typename expr>
748     inline const temp_ref<strtype> &temp_ref<strtype>::operator =(const expr &e) const
749     {
750     sl_assign (*this, e);
751     return *this;
752     }
753    
754     struct sl_append_const_string
755     {
756     fragment_const_string str;
757     sl_append_const_string (const char *s)
758     : str (s)
759     { }
760    
761     void operator ()() const
762     {
763     cur->push_back (str);
764     }
765     };
766    
767     # define SHADER_BINOP(op, str) \
768     extern const sl_append_const_string str_ ## str; \
769     template<typename A, typename B> \
770     inline const sl_expr< sl_concat3< typename sl_convert<A>::T, \
771     sl_append_const_string, \
772     typename sl_convert<B>::T > > \
773     operator op(const A &a, const B &b) \
774     { \
775     return concat (sl_convert<A>::convert (a), str_ ## str, sl_convert<B>::convert (b)); \
776     }
777    
778     SHADER_BINOP (+, plus);
779     SHADER_BINOP (-, minus);
780     SHADER_BINOP (*, mul);
781     SHADER_BINOP (/, div);
782    
783     # undef SHADER_BINOP
784    
785 root 1.5 void swizzle_mask (sl_string<7> &s, int mask);
786 root 1.6
787     extern const sl_append_const_string str_lpar;
788     extern const sl_append_const_string str_rpar;
789    
790     template<typename T>
791     inline const sl_expr< sl_concat3< sl_append_const_string,
792     typename sl_convert<T>::T,
793     sl_string<7>
794     > >
795     swizzle (const T &t, int a, int b = 0, int c = 0, int d = 0)
796     {
797     sl_string<7> s;
798     swizzle_mask (s, ((d * 5 + c) * 5 + b) * 5 + a);
799     return concat (str_lpar, sl_convert<T>::convert (t), s);
800     }
801    
802     # define SHADER_SWIZZLE_OP(abcd,type) \
803     template<typename T> \
804     inline const sl_expr< sl_concat3< sl_append_const_string, \
805     typename sl_convert<T>::T, \
806     sl_string<7> \
807     > > \
808     type (const T &t) \
809     { \
810     return swizzle (t, (abcd / 1000) % 5, (abcd / 100) % 5, (abcd / 10) % 5, (abcd / 1) % 5); \
811     }
812    
813     // brute force is lovely, ain't it?
814     SHADER_SWIZZLE_OP (1 , x ) SHADER_SWIZZLE_OP (11 , xx ) SHADER_SWIZZLE_OP (111 , xxx ) SHADER_SWIZZLE_OP (1111, xxxx)
815     SHADER_SWIZZLE_OP (1112, xxxy) SHADER_SWIZZLE_OP (1113, xxxz) SHADER_SWIZZLE_OP (1114, xxxw) SHADER_SWIZZLE_OP (112 , xxy )
816     SHADER_SWIZZLE_OP (1121, xxyx) SHADER_SWIZZLE_OP (1122, xxyy) SHADER_SWIZZLE_OP (1123, xxyz) SHADER_SWIZZLE_OP (1124, xxyw)
817     SHADER_SWIZZLE_OP (113 , xxz ) SHADER_SWIZZLE_OP (1131, xxzx) SHADER_SWIZZLE_OP (1132, xxzy) SHADER_SWIZZLE_OP (1133, xxzz)
818     SHADER_SWIZZLE_OP (1134, xxzw) SHADER_SWIZZLE_OP (114 , xxw ) SHADER_SWIZZLE_OP (1141, xxwx) SHADER_SWIZZLE_OP (1142, xxwy)
819     SHADER_SWIZZLE_OP (1143, xxwz) SHADER_SWIZZLE_OP (1144, xxww) SHADER_SWIZZLE_OP (12 , xy ) SHADER_SWIZZLE_OP (121 , xyx )
820     SHADER_SWIZZLE_OP (1211, xyxx) SHADER_SWIZZLE_OP (1212, xyxy) SHADER_SWIZZLE_OP (1213, xyxz) SHADER_SWIZZLE_OP (1214, xyxw)
821     SHADER_SWIZZLE_OP (122 , xyy ) SHADER_SWIZZLE_OP (1221, xyyx) SHADER_SWIZZLE_OP (1222, xyyy) SHADER_SWIZZLE_OP (1223, xyyz)
822     SHADER_SWIZZLE_OP (1224, xyyw) SHADER_SWIZZLE_OP (123 , xyz ) SHADER_SWIZZLE_OP (1231, xyzx) SHADER_SWIZZLE_OP (1232, xyzy)
823     SHADER_SWIZZLE_OP (1233, xyzz) SHADER_SWIZZLE_OP (1234, xyzw) SHADER_SWIZZLE_OP (124 , xyw ) SHADER_SWIZZLE_OP (1241, xywx)
824     SHADER_SWIZZLE_OP (1242, xywy) SHADER_SWIZZLE_OP (1243, xywz) SHADER_SWIZZLE_OP (1244, xyww) SHADER_SWIZZLE_OP (13 , xz )
825     SHADER_SWIZZLE_OP (131 , xzx ) SHADER_SWIZZLE_OP (1311, xzxx) SHADER_SWIZZLE_OP (1312, xzxy) SHADER_SWIZZLE_OP (1313, xzxz)
826     SHADER_SWIZZLE_OP (1314, xzxw) SHADER_SWIZZLE_OP (132 , xzy ) SHADER_SWIZZLE_OP (1321, xzyx) SHADER_SWIZZLE_OP (1322, xzyy)
827     SHADER_SWIZZLE_OP (1323, xzyz) SHADER_SWIZZLE_OP (1324, xzyw) SHADER_SWIZZLE_OP (133 , xzz ) SHADER_SWIZZLE_OP (1331, xzzx)
828     SHADER_SWIZZLE_OP (1332, xzzy) SHADER_SWIZZLE_OP (1333, xzzz) SHADER_SWIZZLE_OP (1334, xzzw) SHADER_SWIZZLE_OP (134 , xzw )
829     SHADER_SWIZZLE_OP (1341, xzwx) SHADER_SWIZZLE_OP (1342, xzwy) SHADER_SWIZZLE_OP (1343, xzwz) SHADER_SWIZZLE_OP (1344, xzww)
830     SHADER_SWIZZLE_OP (14 , xw ) SHADER_SWIZZLE_OP (141 , xwx ) SHADER_SWIZZLE_OP (1411, xwxx) SHADER_SWIZZLE_OP (1412, xwxy)
831     SHADER_SWIZZLE_OP (1413, xwxz) SHADER_SWIZZLE_OP (1414, xwxw) SHADER_SWIZZLE_OP (142 , xwy ) SHADER_SWIZZLE_OP (1421, xwyx)
832     SHADER_SWIZZLE_OP (1422, xwyy) SHADER_SWIZZLE_OP (1423, xwyz) SHADER_SWIZZLE_OP (1424, xwyw) SHADER_SWIZZLE_OP (143 , xwz )
833     SHADER_SWIZZLE_OP (1431, xwzx) SHADER_SWIZZLE_OP (1432, xwzy) SHADER_SWIZZLE_OP (1433, xwzz) SHADER_SWIZZLE_OP (1434, xwzw)
834     SHADER_SWIZZLE_OP (144 , xww ) SHADER_SWIZZLE_OP (1441, xwwx) SHADER_SWIZZLE_OP (1442, xwwy) SHADER_SWIZZLE_OP (1443, xwwz)
835     SHADER_SWIZZLE_OP (1444, xwww) SHADER_SWIZZLE_OP (2 , y ) SHADER_SWIZZLE_OP (21 , yx ) SHADER_SWIZZLE_OP (211 , yxx )
836     SHADER_SWIZZLE_OP (2111, yxxx) SHADER_SWIZZLE_OP (2112, yxxy) SHADER_SWIZZLE_OP (2113, yxxz) SHADER_SWIZZLE_OP (2114, yxxw)
837     SHADER_SWIZZLE_OP (212 , yxy ) SHADER_SWIZZLE_OP (2121, yxyx) SHADER_SWIZZLE_OP (2122, yxyy) SHADER_SWIZZLE_OP (2123, yxyz)
838     SHADER_SWIZZLE_OP (2124, yxyw) SHADER_SWIZZLE_OP (213 , yxz ) SHADER_SWIZZLE_OP (2131, yxzx) SHADER_SWIZZLE_OP (2132, yxzy)
839     SHADER_SWIZZLE_OP (2133, yxzz) SHADER_SWIZZLE_OP (2134, yxzw) SHADER_SWIZZLE_OP (214 , yxw ) SHADER_SWIZZLE_OP (2141, yxwx)
840     SHADER_SWIZZLE_OP (2142, yxwy) SHADER_SWIZZLE_OP (2143, yxwz) SHADER_SWIZZLE_OP (2144, yxww) SHADER_SWIZZLE_OP (22 , yy )
841     SHADER_SWIZZLE_OP (221 , yyx ) SHADER_SWIZZLE_OP (2211, yyxx) SHADER_SWIZZLE_OP (2212, yyxy) SHADER_SWIZZLE_OP (2213, yyxz)
842     SHADER_SWIZZLE_OP (2214, yyxw) SHADER_SWIZZLE_OP (222 , yyy ) SHADER_SWIZZLE_OP (2221, yyyx) SHADER_SWIZZLE_OP (2222, yyyy)
843     SHADER_SWIZZLE_OP (2223, yyyz) SHADER_SWIZZLE_OP (2224, yyyw) SHADER_SWIZZLE_OP (223 , yyz ) SHADER_SWIZZLE_OP (2231, yyzx)
844     SHADER_SWIZZLE_OP (2232, yyzy) SHADER_SWIZZLE_OP (2233, yyzz) SHADER_SWIZZLE_OP (2234, yyzw) SHADER_SWIZZLE_OP (224 , yyw )
845     SHADER_SWIZZLE_OP (2241, yywx) SHADER_SWIZZLE_OP (2242, yywy) SHADER_SWIZZLE_OP (2243, yywz) SHADER_SWIZZLE_OP (2244, yyww)
846     SHADER_SWIZZLE_OP (23 , yz ) SHADER_SWIZZLE_OP (231 , yzx ) SHADER_SWIZZLE_OP (2311, yzxx) SHADER_SWIZZLE_OP (2312, yzxy)
847     SHADER_SWIZZLE_OP (2313, yzxz) SHADER_SWIZZLE_OP (2314, yzxw) SHADER_SWIZZLE_OP (232 , yzy ) SHADER_SWIZZLE_OP (2321, yzyx)
848     SHADER_SWIZZLE_OP (2322, yzyy) SHADER_SWIZZLE_OP (2323, yzyz) SHADER_SWIZZLE_OP (2324, yzyw) SHADER_SWIZZLE_OP (233 , yzz )
849     SHADER_SWIZZLE_OP (2331, yzzx) SHADER_SWIZZLE_OP (2332, yzzy) SHADER_SWIZZLE_OP (2333, yzzz) SHADER_SWIZZLE_OP (2334, yzzw)
850     SHADER_SWIZZLE_OP (234 , yzw ) SHADER_SWIZZLE_OP (2341, yzwx) SHADER_SWIZZLE_OP (2342, yzwy) SHADER_SWIZZLE_OP (2343, yzwz)
851     SHADER_SWIZZLE_OP (2344, yzww) SHADER_SWIZZLE_OP (24 , yw ) SHADER_SWIZZLE_OP (241 , ywx ) SHADER_SWIZZLE_OP (2411, ywxx)
852     SHADER_SWIZZLE_OP (2412, ywxy) SHADER_SWIZZLE_OP (2413, ywxz) SHADER_SWIZZLE_OP (2414, ywxw) SHADER_SWIZZLE_OP (242 , ywy )
853     SHADER_SWIZZLE_OP (2421, ywyx) SHADER_SWIZZLE_OP (2422, ywyy) SHADER_SWIZZLE_OP (2423, ywyz) SHADER_SWIZZLE_OP (2424, ywyw)
854     SHADER_SWIZZLE_OP (243 , ywz ) SHADER_SWIZZLE_OP (2431, ywzx) SHADER_SWIZZLE_OP (2432, ywzy) SHADER_SWIZZLE_OP (2433, ywzz)
855     SHADER_SWIZZLE_OP (2434, ywzw) SHADER_SWIZZLE_OP (244 , yww ) SHADER_SWIZZLE_OP (2441, ywwx) SHADER_SWIZZLE_OP (2442, ywwy)
856     SHADER_SWIZZLE_OP (2443, ywwz) SHADER_SWIZZLE_OP (2444, ywww) SHADER_SWIZZLE_OP (3 , z ) SHADER_SWIZZLE_OP (31 , zx )
857     SHADER_SWIZZLE_OP (311 , zxx ) SHADER_SWIZZLE_OP (3111, zxxx) SHADER_SWIZZLE_OP (3112, zxxy) SHADER_SWIZZLE_OP (3113, zxxz)
858     SHADER_SWIZZLE_OP (3114, zxxw) SHADER_SWIZZLE_OP (312 , zxy ) SHADER_SWIZZLE_OP (3121, zxyx) SHADER_SWIZZLE_OP (3122, zxyy)
859     SHADER_SWIZZLE_OP (3123, zxyz) SHADER_SWIZZLE_OP (3124, zxyw) SHADER_SWIZZLE_OP (313 , zxz ) SHADER_SWIZZLE_OP (3131, zxzx)
860     SHADER_SWIZZLE_OP (3132, zxzy) SHADER_SWIZZLE_OP (3133, zxzz) SHADER_SWIZZLE_OP (3134, zxzw) SHADER_SWIZZLE_OP (314 , zxw )
861     SHADER_SWIZZLE_OP (3141, zxwx) SHADER_SWIZZLE_OP (3142, zxwy) SHADER_SWIZZLE_OP (3143, zxwz) SHADER_SWIZZLE_OP (3144, zxww)
862     SHADER_SWIZZLE_OP (32 , zy ) SHADER_SWIZZLE_OP (321 , zyx ) SHADER_SWIZZLE_OP (3211, zyxx) SHADER_SWIZZLE_OP (3212, zyxy)
863     SHADER_SWIZZLE_OP (3213, zyxz) SHADER_SWIZZLE_OP (3214, zyxw) SHADER_SWIZZLE_OP (322 , zyy ) SHADER_SWIZZLE_OP (3221, zyyx)
864     SHADER_SWIZZLE_OP (3222, zyyy) SHADER_SWIZZLE_OP (3223, zyyz) SHADER_SWIZZLE_OP (3224, zyyw) SHADER_SWIZZLE_OP (323 , zyz )
865     SHADER_SWIZZLE_OP (3231, zyzx) SHADER_SWIZZLE_OP (3232, zyzy) SHADER_SWIZZLE_OP (3233, zyzz) SHADER_SWIZZLE_OP (3234, zyzw)
866     SHADER_SWIZZLE_OP (324 , zyw ) SHADER_SWIZZLE_OP (3241, zywx) SHADER_SWIZZLE_OP (3242, zywy) SHADER_SWIZZLE_OP (3243, zywz)
867     SHADER_SWIZZLE_OP (3244, zyww) SHADER_SWIZZLE_OP (33 , zz ) SHADER_SWIZZLE_OP (331 , zzx ) SHADER_SWIZZLE_OP (3311, zzxx)
868     SHADER_SWIZZLE_OP (3312, zzxy) SHADER_SWIZZLE_OP (3313, zzxz) SHADER_SWIZZLE_OP (3314, zzxw) SHADER_SWIZZLE_OP (332 , zzy )
869     SHADER_SWIZZLE_OP (3321, zzyx) SHADER_SWIZZLE_OP (3322, zzyy) SHADER_SWIZZLE_OP (3323, zzyz) SHADER_SWIZZLE_OP (3324, zzyw)
870     SHADER_SWIZZLE_OP (333 , zzz ) SHADER_SWIZZLE_OP (3331, zzzx) SHADER_SWIZZLE_OP (3332, zzzy) SHADER_SWIZZLE_OP (3333, zzzz)
871     SHADER_SWIZZLE_OP (3334, zzzw) SHADER_SWIZZLE_OP (334 , zzw ) SHADER_SWIZZLE_OP (3341, zzwx) SHADER_SWIZZLE_OP (3342, zzwy)
872     SHADER_SWIZZLE_OP (3343, zzwz) SHADER_SWIZZLE_OP (3344, zzww) SHADER_SWIZZLE_OP (34 , zw ) SHADER_SWIZZLE_OP (341 , zwx )
873     SHADER_SWIZZLE_OP (3411, zwxx) SHADER_SWIZZLE_OP (3412, zwxy) SHADER_SWIZZLE_OP (3413, zwxz) SHADER_SWIZZLE_OP (3414, zwxw)
874     SHADER_SWIZZLE_OP (342 , zwy ) SHADER_SWIZZLE_OP (3421, zwyx) SHADER_SWIZZLE_OP (3422, zwyy) SHADER_SWIZZLE_OP (3423, zwyz)
875     SHADER_SWIZZLE_OP (3424, zwyw) SHADER_SWIZZLE_OP (343 , zwz ) SHADER_SWIZZLE_OP (3431, zwzx) SHADER_SWIZZLE_OP (3432, zwzy)
876     SHADER_SWIZZLE_OP (3433, zwzz) SHADER_SWIZZLE_OP (3434, zwzw) SHADER_SWIZZLE_OP (344 , zww ) SHADER_SWIZZLE_OP (3441, zwwx)
877     SHADER_SWIZZLE_OP (3442, zwwy) SHADER_SWIZZLE_OP (3443, zwwz) SHADER_SWIZZLE_OP (3444, zwww) SHADER_SWIZZLE_OP (4 , w )
878     SHADER_SWIZZLE_OP (41 , wx ) SHADER_SWIZZLE_OP (411 , wxx ) SHADER_SWIZZLE_OP (4111, wxxx) SHADER_SWIZZLE_OP (4112, wxxy)
879     SHADER_SWIZZLE_OP (4113, wxxz) SHADER_SWIZZLE_OP (4114, wxxw) SHADER_SWIZZLE_OP (412 , wxy ) SHADER_SWIZZLE_OP (4121, wxyx)
880     SHADER_SWIZZLE_OP (4122, wxyy) SHADER_SWIZZLE_OP (4123, wxyz) SHADER_SWIZZLE_OP (4124, wxyw) SHADER_SWIZZLE_OP (413 , wxz )
881     SHADER_SWIZZLE_OP (4131, wxzx) SHADER_SWIZZLE_OP (4132, wxzy) SHADER_SWIZZLE_OP (4133, wxzz) SHADER_SWIZZLE_OP (4134, wxzw)
882     SHADER_SWIZZLE_OP (414 , wxw ) SHADER_SWIZZLE_OP (4141, wxwx) SHADER_SWIZZLE_OP (4142, wxwy) SHADER_SWIZZLE_OP (4143, wxwz)
883     SHADER_SWIZZLE_OP (4144, wxww) SHADER_SWIZZLE_OP (42 , wy ) SHADER_SWIZZLE_OP (421 , wyx ) SHADER_SWIZZLE_OP (4211, wyxx)
884     SHADER_SWIZZLE_OP (4212, wyxy) SHADER_SWIZZLE_OP (4213, wyxz) SHADER_SWIZZLE_OP (4214, wyxw) SHADER_SWIZZLE_OP (422 , wyy )
885     SHADER_SWIZZLE_OP (4221, wyyx) SHADER_SWIZZLE_OP (4222, wyyy) SHADER_SWIZZLE_OP (4223, wyyz) SHADER_SWIZZLE_OP (4224, wyyw)
886     SHADER_SWIZZLE_OP (423 , wyz ) SHADER_SWIZZLE_OP (4231, wyzx) SHADER_SWIZZLE_OP (4232, wyzy) SHADER_SWIZZLE_OP (4233, wyzz)
887     SHADER_SWIZZLE_OP (4234, wyzw) SHADER_SWIZZLE_OP (424 , wyw ) SHADER_SWIZZLE_OP (4241, wywx) SHADER_SWIZZLE_OP (4242, wywy)
888     SHADER_SWIZZLE_OP (4243, wywz) SHADER_SWIZZLE_OP (4244, wyww) SHADER_SWIZZLE_OP (43 , wz ) SHADER_SWIZZLE_OP (431 , wzx )
889     SHADER_SWIZZLE_OP (4311, wzxx) SHADER_SWIZZLE_OP (4312, wzxy) SHADER_SWIZZLE_OP (4313, wzxz) SHADER_SWIZZLE_OP (4314, wzxw)
890     SHADER_SWIZZLE_OP (432 , wzy ) SHADER_SWIZZLE_OP (4321, wzyx) SHADER_SWIZZLE_OP (4322, wzyy) SHADER_SWIZZLE_OP (4323, wzyz)
891     SHADER_SWIZZLE_OP (4324, wzyw) SHADER_SWIZZLE_OP (433 , wzz ) SHADER_SWIZZLE_OP (4331, wzzx) SHADER_SWIZZLE_OP (4332, wzzy)
892     SHADER_SWIZZLE_OP (4333, wzzz) SHADER_SWIZZLE_OP (4334, wzzw) SHADER_SWIZZLE_OP (434 , wzw ) SHADER_SWIZZLE_OP (4341, wzwx)
893     SHADER_SWIZZLE_OP (4342, wzwy) SHADER_SWIZZLE_OP (4343, wzwz) SHADER_SWIZZLE_OP (4344, wzww) SHADER_SWIZZLE_OP (44 , ww )
894     SHADER_SWIZZLE_OP (441 , wwx ) SHADER_SWIZZLE_OP (4411, wwxx) SHADER_SWIZZLE_OP (4412, wwxy) SHADER_SWIZZLE_OP (4413, wwxz)
895     SHADER_SWIZZLE_OP (4414, wwxw) SHADER_SWIZZLE_OP (442 , wwy ) SHADER_SWIZZLE_OP (4421, wwyx) SHADER_SWIZZLE_OP (4422, wwyy)
896     SHADER_SWIZZLE_OP (4423, wwyz) SHADER_SWIZZLE_OP (4424, wwyw) SHADER_SWIZZLE_OP (443 , wwz ) SHADER_SWIZZLE_OP (4431, wwzx)
897     SHADER_SWIZZLE_OP (4432, wwzy) SHADER_SWIZZLE_OP (4433, wwzz) SHADER_SWIZZLE_OP (4434, wwzw) SHADER_SWIZZLE_OP (444 , www )
898     SHADER_SWIZZLE_OP (4441, wwwx) SHADER_SWIZZLE_OP (4442, wwwy) SHADER_SWIZZLE_OP (4443, wwwz) SHADER_SWIZZLE_OP (4444, wwww)
899    
900     # undef SHADER_SWIZZLE_OP
901    
902 root 1.1 void debdebdebdebug ();//D
903     }
904    
905     #endif
906