ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/libgender/shader.h
(Generate patch)

Comparing libgender/shader.h (file contents):
Revision 1.24 by root, Mon Nov 1 22:23:38 2004 UTC vs.
Revision 1.25 by root, Tue Nov 2 02:59:33 2004 UTC

1#ifndef SHADER_H 1#ifndef SHADER_H
2#define SHADER_H 2#define SHADER_H
3 3
4#include <cassert> 4#include <cassert>
5 5
6#include <set>
6#include <map> 7#include <map>
7#include <sstream> 8#include <sstream>
8 9
9#include "opengl.h" 10#include "opengl.h"
10#include "util.h" 11#include "util.h"
13 14
14 using namespace std; 15 using namespace std;
15 16
16 const int NAMELEN = 32; 17 const int NAMELEN = 32;
17 18
19 namespace compile {
20 struct shader_builder
21 {
22 set<const void *> seen;
23
24 ostringstream global;
25 ostringstream local;
26 ostringstream code;
27
28 bool first (const void *p);
29 };
30
31 extern shader_builder *cur;
32 }
33
18 template<class T> 34 template<class T>
19 struct sl_expr { 35 struct sl_expr {
20 const T t; 36 const T &t;
21 sl_expr (const T &t) : t(t) { } 37 sl_expr (const T &t) : t(t) { }
22 void operator ()() const { t (); } 38 void operator ()() const { t (); }
23 template<typename expr> 39 template<typename expr>
24 const sl_expr &operator =(const expr &e) const; 40 const sl_expr &operator =(const expr &e) const;
25 }; 41 };
50 66
51 struct sl_func0 67 struct sl_func0
52 { 68 {
53 const char *name_par; 69 const char *name_par;
54 sl_func0 (const char *name_par) : name_par(name_par) { } 70 sl_func0 (const char *name_par) : name_par(name_par) { }
71
55 void begin () const; 72 void begin () const
73 {
74 compile::cur->code << name_par;
75 }
76
56 void comma () const; 77 void comma () const
78 {
79 compile::cur->code << ", ";
80 }
81
57 void end () const; 82 void end () const
83 {
84 compile::cur->code << ")";
85 }
86
58 void operator ()() const 87 void operator ()() const
59 { 88 {
60 begin (); 89 begin ();
61 end (); 90 end ();
62 } 91 }
95 }; 124 };
96 125
97 class refcounted 126 class refcounted
98 { 127 {
99 template<class type> friend class ref; 128 template<class type> friend class ref;
100 mutable int refcnt; 129 mutable unsigned int refcnt;
101 void refcnt_inc () const { refcnt++; } 130 void refcnt_inc () const { refcnt++; }
131 void refcnt_dec () const { if (!--refcnt) refcnt_destroy (); }
102 void refcnt_dec () const; 132 void refcnt_destroy () const;
103 public: 133 public:
104 refcounted () : refcnt(0) { } 134 refcounted () : refcnt(0) { }
105 virtual ~refcounted (); 135 virtual ~refcounted ();
106 }; 136 };
107 137
207 extern const char str_sampler_cube []; 237 extern const char str_sampler_cube [];
208 238
209 typedef ref<struct var_i> var; 239 typedef ref<struct var_i> var;
210 typedef ref<struct uniform_i> uniform; 240 typedef ref<struct uniform_i> uniform;
211 241
212 struct shader_builder
213 {
214 vector<var> refs; // uniform/varying parameters
215 vector<var> temps; // temporary variables
216
217 ostringstream source;
218
219 template<typename type>
220 shader_builder &operator <<(const type &t)
221 {
222 source << t;
223 return *this;
224 }
225 };
226
227 struct fragment_i : refcounted 242 struct fragment_i : refcounted
228 { 243 {
229 virtual void build (shader_builder &b) = 0;
230 }; 244 };
231 245
232 typedef ref<fragment_i> fragment; 246 typedef ref<fragment_i> fragment;
233 247
234 struct lvalue_i : fragment_i 248 struct lvalue_i : fragment_i
237 251
238 // a simple predeclared variable with unspecified type 252 // a simple predeclared variable with unspecified type
239 struct gluvar_i : lvalue_i 253 struct gluvar_i : lvalue_i
240 { 254 {
241 const char *name; 255 const char *name;
242 void build (shader_builder &b); 256
257 void operator ()() const
258 {
259 compile::cur->code << name;
260 }
261
243 gluvar_i (const char *name) : name (name) { } 262 gluvar_i (const char *name) : name (name) { }
244 }; 263 };
245 264
246 typedef auto_lvalue_ref1<gluvar_i, const char *> gluvar; 265 typedef auto_lvalue_ref1<gluvar_i, const char *> gluvar;
247 266
248 struct var_i : lvalue_i 267 struct var_i : lvalue_i
249 { 268 {
250 static unsigned int next_id; 269 static unsigned int next_id;
251 270
252 char name[NAMELEN]; 271 char name[NAMELEN];
272 const char *domainstr;
253 const char *typestr; 273 const char *typestr;
254 274
255 void build (shader_builder &b); 275 void operator ()() const;
256 virtual void build_decl (ostringstream &b); 276
257 277 var_i (const char *domainstr, const char *typestr);
258 var_i (const char *typestr);
259 ~var_i (); 278 ~var_i ();
260 }; 279 };
261 280
262 struct uniform_i : var_i 281 struct uniform_i : var_i
263 { 282 {
264 void build (shader_builder &b);
265 void build_decl (ostringstream &b);
266
267 GLint location (); 283 GLint location ();
268 284
269 uniform_i (const char *strtype); 285 uniform_i (const char *strtype);
270 }; 286 };
271 287
396#if 0 412#if 0
397 // to be used for attributes 413 // to be used for attributes
398 414
399 struct stream_i : var_i 415 struct stream_i : var_i
400 { 416 {
401 void build (shader_builder &b);
402 void build_decl (ostringstream &b);
403 stream_i (const char *strtype); 417 stream_i (const char *strtype);
404 }; 418 };
405 419
406 template<int dimension, GLenum gltype, const char *strtype> 420 template<int dimension, GLenum gltype, const char *strtype>
407 struct varying_i : stream_i 421 struct varying_i : stream_i
458 typedef var_ref<varying_4f_i> varying_4f; 472 typedef var_ref<varying_4f_i> varying_4f;
459#endif 473#endif
460 474
461 struct varying_i : var_i 475 struct varying_i : var_i
462 { 476 {
463 void build_decl (ostringstream &b);
464 void build (shader_builder &b);
465 varying_i (const char *strtype); 477 varying_i (const char *strtype);
466 }; 478 };
467 479
468 struct temporary_i : var_i 480 struct temporary_i : var_i
469 { 481 {
470 void build (shader_builder &b);
471 temporary_i (const char *strtype); 482 temporary_i (const char *strtype);
472 }; 483 };
473 484
474 template<const char *strtype, class var_i> 485 template<const char *strtype, class var_i>
475 struct glnvar_ref : ref<var_i> 486 struct glnvar_ref : ref<var_i>
640 typedef sampler_ref<sampler_2d_rect_shadow_i> sampler_2d_rect_shadow; 651 typedef sampler_ref<sampler_2d_rect_shadow_i> sampler_2d_rect_shadow;
641 typedef sampler_ref<sampler_3d_i> sampler_3d; 652 typedef sampler_ref<sampler_3d_i> sampler_3d;
642 typedef sampler_ref<sampler_3d_rect_i> sampler_3d_rect; 653 typedef sampler_ref<sampler_3d_rect_i> sampler_3d_rect;
643 typedef sampler_ref<sampler_cube_i> sampler_cube; 654 typedef sampler_ref<sampler_cube_i> sampler_cube;
644 655
645 struct fragment_const_string_i : fragment_i
646 {
647 const char *str;
648
649 void build (shader_builder &b);
650
651 fragment_const_string_i (const char *str) : str(str) { }
652 };
653
654 typedef auto_ref1<fragment_const_string_i, const char *> fragment_const_string;
655
656 struct fragment_string_i : fragment_i
657 {
658 char *str;
659
660 void build (shader_builder &b);
661
662 fragment_string_i (const char *str) : str (strdup (str)) { }
663 ~fragment_string_i ();
664 };
665
666 struct fragment_vector_i : fragment_i, vector<fragment>
667 {
668 void build (shader_builder &b);
669
670 template<class fragment_i>
671 void append (const ref<fragment_i> &f)
672 {
673 push_back (f);
674 }
675
676 template<class expr>
677 void append (const sl_expr<expr> &e)
678 {
679 e ();
680 }
681
682 void append_const (const char *s)
683 {
684 push_back (*new fragment_const_string_i (s));
685 }
686
687 void append_string (const char *s)
688 {
689 push_back (*new fragment_string_i (s));
690 }
691 };
692
693 typedef ref<fragment_vector_i> fragment_vector;
694
695 struct shader_object_i : fragment_vector_i 656 struct shader_object_i : refcounted
696 { 657 {
697 GLenum type; 658 GLenum type;
698 GLuint id; // GLhandleARB, but 2.0 will use uint 659 GLuint id; // GLhandleARB, but 2.0 will use uint
699 660
700 string source ();
701 void compile ();
702 void start (); 661 void start ();
703 void stop (); 662 void stop ();
704 663
705 shader_object_i (GLenum type); 664 shader_object_i (GLenum type);
706 ~shader_object_i (); 665 ~shader_object_i ();
707 }; 666 };
708 667
709 extern shader_object_i *cur; // record actions to this shader
710
711 template<GLenum type> 668 template<GLenum type>
712 struct shader_object : ref<shader_object_i> 669 struct shader_object : ref<shader_object_i>
713 { 670 {
714 shader_object () 671 shader_object ()
715 : ref<shader_object_i> (*new shader_object_i (type)) 672 : ref<shader_object_i> (*new shader_object_i (type))
738 695
739 void enable (); 696 void enable ();
740 void disable (); 697 void disable ();
741 }; 698 };
742 699
743 template<typename T>
744 struct sl_append
745 {
746 T t;
747
748 sl_append (const T &t) : t(t) { }
749
750 void operator ()() const
751 {
752 cur->push_back (t);
753 }
754 };
755
756 template<int length> 700 template<int length>
757 struct sl_string 701 struct sl_string
758 { 702 {
759 char str[length]; 703 char str[length];
760 704
761 void operator ()() const 705 void operator ()() const
762 { 706 {
763 cur->push_back (*new fragment_string_i (str)); 707 compile::cur->code << str;
764 } 708 }
765 }; 709 };
766 710
767 struct sl_float 711 struct sl_float
768 { 712 {
769 const GLfloat c; 713 const GLfloat c;
770 714
771 sl_float (GLfloat c) : c(c) { } 715 sl_float (GLfloat c) : c(c) { }
772 716
773 void operator ()() const; 717 void operator ()() const
718 {
719 compile::cur->code << c;
720 }
774 }; 721 };
775 722
776 template<class A, class B> 723 template<class A, class B>
777 inline sl_expr< sl_concat2<A, B> > 724 inline sl_expr< sl_concat2<A, B> >
778 concat (const A &a, const B &b) 725 concat (const A &a, const B &b)
838 }; 785 };
839 786
840 template<> 787 template<>
841 struct sl_convert<vec2> 788 struct sl_convert<vec2>
842 { 789 {
843 typedef sl_expr< sl_string<60> > T;
844 static const T convert (const vec2 &v); 790 static const sl_expr< sl_string<60> > convert (const vec2 &v);
845 }; 791 };
846 792
847 template<> 793 template<>
848 struct sl_convert<vec3> 794 struct sl_convert<vec3>
849 { 795 {
850 typedef sl_expr< sl_string<80> > T;
851 static const T convert (const vec3 &v); 796 static const sl_expr< sl_string<80> > convert (const vec3 &v);
852 }; 797 };
853 798
854 template<> 799 template<>
855 struct sl_convert<vec4> 800 struct sl_convert<vec4>
856 { 801 {
857 typedef sl_expr< sl_string<100> > T;
858 static const T convert (const vec4 &v); 802 static const sl_expr< sl_string<100> > convert (const vec4 &v);
859 }; 803 };
860 804
861 template<> 805 template<>
862 template<class V> 806 template<class var_i>
863 struct sl_convert< var_ref<V> > 807 struct sl_convert< var_ref<var_i> >
864 { 808 {
865 typedef sl_expr< sl_append< var_ref<V> > > T; 809 typedef sl_expr< var_i > T;
866 static inline const T convert (const var_ref<V> &v) 810 static inline const T convert (const var_ref<var_i> &v)
867 { 811 {
868 return sl_append< var_ref<V> > (v); 812 return T (*&v);
869 } 813 }
870 }; 814 };
871 815
872 template<> 816 template<>
873 struct sl_convert<gluvar> 817 template<class gluvar_i>
818 struct sl_convert< auto_lvalue_ref1<gluvar_i, const char *> >
874 { 819 {
875 typedef sl_expr< sl_append<gluvar> > T; 820 typedef sl_expr< gluvar_i > T;
876 static inline const T convert (const gluvar &v) 821 static inline const T convert (const auto_lvalue_ref1<gluvar_i, const char *> &v)
877 { 822 {
878 return sl_append<gluvar> (v); 823 return T (*&v);
879 } 824 }
880 }; 825 };
881 826
882 template<> 827 template<>
883 template<const char *strtype, class var_i> 828 template<const char *strtype, class var_i>
884 struct sl_convert< glnvar_ref<strtype, var_i> > 829 struct sl_convert< glnvar_ref<strtype, var_i> >
885 { 830 {
886 typedef sl_expr< sl_append< glnvar_ref<strtype, var_i> > > T; 831 typedef sl_expr< var_i > T;
887 static inline const T convert (const glnvar_ref<strtype, var_i> &v) 832 static inline const T convert (const glnvar_ref<strtype, var_i> &v)
888 { 833 {
889 return sl_expr< sl_append< glnvar_ref<strtype, var_i> > >( 834 return T (*&v);
890 sl_append< glnvar_ref<strtype, var_i> > (v)
891 );
892 } 835 }
893 }; 836 };
894 837
895 template<> 838 template<>
896 template<class sampler_i> 839 template<class sampler_i>
897 struct sl_convert< sampler_ref<sampler_i> > 840 struct sl_convert< sampler_ref<sampler_i> >
898 { 841 {
899 typedef sl_expr< sl_append< sampler_ref<sampler_i> > > T; 842 typedef sl_expr< sampler_i > T;
900 static inline const T convert (const sampler_ref<sampler_i> &v) 843 static inline const T convert (const sampler_ref<sampler_i> &v)
901 { 844 {
902 return sl_append< sampler_ref<sampler_i> > (v); 845 return T (*&v);
903 } 846 }
904 }; 847 };
905 848
906 namespace compile { 849 namespace compile {
907 extern const fragment_const_string str_2sp;
908 extern const fragment_const_string str_equal;
909 extern const fragment_const_string str_comma;
910 extern const fragment_const_string str_endl;
911
912 template<class fragment, typename expr> 850 template<class lvalue, typename expr>
913 inline void sl_assign (const fragment &f, const expr &e) 851 inline void sl_assign (const lvalue &l, const expr &e)
914 { 852 {
915 cur->append (str_2sp); 853 compile::cur->code << " ";
916 cur->append (f); 854 sl_convert<lvalue>::convert (l) ();
917 cur->append (str_equal); 855 compile::cur->code << " = ";
918 sl_convert<expr>::convert (e) (); 856 sl_convert<expr>::convert (e) ();
919 cur->append (str_endl); 857 compile::cur->code << ";\n";
920 } 858 }
921 } 859 }
922 860
923 template<class type> 861 template<class type>
924 template<typename expr> 862 template<typename expr>
949 inline const glnvar_ref<strtype, var_i> &glnvar_ref<strtype, var_i>::operator =(const expr &e) const 887 inline const glnvar_ref<strtype, var_i> &glnvar_ref<strtype, var_i>::operator =(const expr &e) const
950 { 888 {
951 compile::sl_assign (*this, e); 889 compile::sl_assign (*this, e);
952 return *this; 890 return *this;
953 } 891 }
954
955 struct sl_append_const_string
956 {
957 fragment_const_string str;
958 sl_append_const_string (const char *s)
959 : str (s)
960 { }
961
962 void operator ()() const
963 {
964 cur->push_back (str);
965 }
966 };
967 892
968 namespace compile { 893 namespace compile {
969 using namespace shader; 894 using namespace shader;
970 895
971 template<typename T> 896 template<typename T>
987 { 912 {
988 const A a; const char *b; const C c; 913 const A a; const char *b; const C c;
989 sl_binop (const A &a, const char *b, const C &c) : a(a), b(b), c(c) { } 914 sl_binop (const A &a, const char *b, const C &c) : a(a), b(b), c(c) { }
990 void operator ()() const 915 void operator ()() const
991 { 916 {
992 shader::cur->append_const ("("); 917 compile::cur->code << "(";
993 a (); 918 a ();
994 shader::cur->append_const (b); 919 compile::cur->code << b;
995 c (); 920 c ();
996 shader::cur->append_const (")"); 921 compile::cur->code << ")";
997 } 922 }
998 }; 923 };
999 924
1000 template<class A, class B, class C> 925 template<class A, class B, class C>
1001 struct sl_ternary 926 struct sl_ternary
1002 { 927 {
1003 const A a; const B b; const C c; 928 const A a; const B b; const C c;
1004 sl_ternary (const A &a, const B &b, const C &c) : a(a), b(b), c(c) { } 929 sl_ternary (const A &a, const B &b, const C &c) : a(a), b(b), c(c) { }
1005 void operator ()() const 930 void operator ()() const
1006 { 931 {
1007 shader::cur->append_const ("("); 932 compile::cur->code << "(";
1008 a (); 933 a ();
1009 shader::cur->append_const (") ? ("); 934 compile::cur->code << ") ? (";
1010 b (); 935 b ();
1011 shader::cur->append_const (") : ("); 936 compile::cur->code << ") : (";
1012 c (); 937 c ();
1013 shader::cur->append_const (")"); 938 compile::cur->code << ")";
1014 } 939 }
1015 }; 940 };
1016 941
1017# define SHADER_BINOP(op) \ 942# define SHADER_BINOP(op) \
1018 template<typename A, typename B> \ 943 template<typename A, typename B> \
1045 const A a; 970 const A a;
1046 const char *swizzle; 971 const char *swizzle;
1047 sl_swizzle (const A &a, const char *swizzle) : a(a), swizzle(swizzle) { } 972 sl_swizzle (const A &a, const char *swizzle) : a(a), swizzle(swizzle) { }
1048 void operator ()() const 973 void operator ()() const
1049 { 974 {
1050 shader::cur->append_const ("("); 975 compile::cur->code << "(";
1051 a (); 976 a ();
1052 shader::cur->append_const (")."); 977 compile::cur->code << ")." << swizzle;
1053 shader::cur->append_const (swizzle);
1054 } 978 }
1055 }; 979 };
1056 980
1057# define SHADER_SWIZZLE_OP(type) \ 981# define SHADER_SWIZZLE_OP(type) \
1058 template<typename T> \ 982 template<typename T> \

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines