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

# Content
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 template<typename expr>
21 const sl_expr &operator =(const expr &e) const;
22 };
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 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 class refcounted
94 {
95 template<class type> friend class ref;
96 mutable int refcnt;
97 void refcnt_inc () const { refcnt++; }
98 void refcnt_dec () const;
99 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 template<class var_i>
327 struct var_ref : ref<var_i>
328 {
329 var_ref (const char *glname = 0)
330 : ref<var_i> (*new var_i)
331 {
332 if (glname)
333 strcpy ((*this)->name, glname);
334 }
335 };
336
337 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
345 struct stream_i : var_i
346 {
347 void build (shader_builder &b);
348 void build_decl (ostringstream &b);
349 stream_i (const char *strtype);
350 };
351
352 template<int dimension, GLenum gltype, const char *strtype>
353 struct varying_i : stream_i
354 {
355 varying_i () : stream_i (strtype) { }
356
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 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
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 template<class expr>
542 void append (const sl_expr<expr> &e)
543 {
544 e ();
545 }
546
547 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 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 void operator ()() const;
632 };
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 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 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 struct sl_convert<vec3>
707 {
708 typedef sl_expr< sl_string<80> > T;
709 static const T convert (const vec3 &v);
710 };
711
712 template<>
713 struct sl_convert<vec4>
714 {
715 typedef sl_expr< sl_string<100> > T;
716 static const T convert (const vec4 &v);
717 };
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 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 template<class fragment, typename expr>
758 inline void sl_assign (const fragment &f, const expr &e)
759 {
760 cur->append (str_2sp);
761 cur->append (f);
762 cur->append (str_equal);
763 sl_convert<expr>::convert (e) ();
764 cur->append (str_endl);
765 }
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 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 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 void swizzle_mask (sl_string<7> &s, int mask);
831
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 void debdebdebdebug ();//D
948 }
949
950 #endif
951