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