ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/libgender/shader.C
Revision: 1.32
Committed: Wed Jan 25 22:48:02 2006 UTC (18 years, 4 months ago) by root
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 1.31: +4 -3 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 root 1.12 #include <cassert>
2    
3 root 1.1 #include "shader.h"
4     #include "shader_vars.h"
5    
6 root 1.17 #include <sstream>
7     #include <iomanip>
8    
9 root 1.18 namespace shader {
10 root 1.17
11 root 1.18 using namespace std;
12 root 1.1
13     refcounted::~refcounted ()
14     {
15     if (refcnt)
16     abort ();
17     }
18    
19 root 1.26 void refcounted::refcnt_destroy () const
20 root 1.6 {
21     if (!--refcnt)
22     delete this; // quite a bit of code...
23     }
24    
25 root 1.1 const char str_float [] = "float";
26     const char str_vec2 [] = "vec2";
27     const char str_vec3 [] = "vec3";
28     const char str_vec4 [] = "vec4";
29     const char str_mat2 [] = "mat2";
30     const char str_mat3 [] = "mat3";
31     const char str_mat4 [] = "mat4";
32    
33     const char str_sampler_1d [] = "sampler1D";
34     const char str_sampler_1d_shadow [] = "sampler1DShadow";
35     const char str_sampler_2d [] = "sampler2D";
36     const char str_sampler_2d_shadow [] = "sampler2DShadow";
37     const char str_sampler_2d_rect [] = "sampler2DRect";
38     const char str_sampler_2d_rect_shadow [] = "sampler2DRectShadow";
39     const char str_sampler_3d [] = "sampler3D";
40     const char str_sampler_3d_rect [] = "sampler3DRect";
41     const char str_sampler_cube [] = "samplerCube";
42    
43     unsigned int var_i::next_id = 0;
44    
45 root 1.26 var_i::var_i (const char *domainstr, const char *typestr)
46     : domainstr (domainstr), typestr (typestr)
47 root 1.1 {
48     }
49    
50     var_i::~var_i ()
51     {
52     }
53    
54 root 1.24 #if 0
55 root 1.4 stream_i::stream_i (const char *strtype)
56     : var_i (strtype)
57     {
58 root 1.19 sprintf (name, "V%d", ++next_id);
59 root 1.4 }
60 root 1.24 #endif
61 root 1.4
62 root 1.1 temporary_i::temporary_i (const char *strtype)
63 root 1.26 : var_i (0, strtype)
64 root 1.1 {
65 root 1.19 sprintf (name, "T%d", ++next_id);
66 root 1.1 }
67    
68 root 1.24 varying_i::varying_i (const char *strtype)
69 root 1.26 : var_i ("varying", strtype)
70 root 1.24 {
71     sprintf (name, "V%d", ++next_id);
72     }
73    
74 root 1.1 uniform_i::uniform_i (const char *strtype)
75 root 1.26 : var_i ("uniform", strtype)
76 root 1.1 {
77 root 1.19 sprintf (name, "U%d", ++next_id);
78 root 1.1 }
79    
80     ////////////////////////////////////////////////////////////////////////////
81    
82 root 1.26 void var_i::operator ()() const
83 root 1.1 {
84 root 1.28 shader_builder::cur->code << name;
85 root 1.1
86 root 1.28 if (shader_builder::cur->first (this))
87 root 1.26 {
88     if (domainstr)
89 root 1.28 shader_builder::cur->global << domainstr << ' ' << typestr << ' ' << name << ";\n";
90 root 1.26 else
91 root 1.28 shader_builder::cur->local << " " << typestr << ' ' << name << ";\n";
92 root 1.26 }
93 root 1.1 }
94    
95     ////////////////////////////////////////////////////////////////////////////
96    
97 root 1.20 int texture_units::unit_count = 8;
98 root 1.21 int texture_units::units[8] = { 7, 6, 5, 4, 3, 2, 1, 0 };
99 root 1.20
100 root 1.1 shader_object_i *cur = 0;
101    
102     shader_object_i::shader_object_i (GLenum type)
103     : type (type)
104     {
105     id = glCreateShaderObjectARB (type);
106 root 1.12 assert (id);
107 root 1.1 }
108    
109     shader_object_i::~shader_object_i ()
110     {
111     glDeleteObjectARB (id);
112     }
113    
114 root 1.17 static string linify (const string &s)
115     {
116     ostringstream o;
117    
118     int b = 0, e;
119     int l = 1;
120     do {
121     o << setw (3) << l << ": ";
122     e = s.find ('\n', b);
123     if (e == string::npos)
124     e = s.size ();
125    
126     o << s.substr (b, e - b + 1);
127     b = e + 1;
128     l++;
129     } while (b < s.size ());
130    
131     return o.str ();
132     }
133    
134 root 1.19 ////////////////////////////////////////////////////////////////////////////
135    
136     GLint uniform_i::location ()
137     {
138 root 1.27 assert (program_object_i::cur);
139 root 1.19
140 root 1.27 GLint &rid = program_object_i::cur->uloc[this];
141 root 1.19
142     if (!rid)
143 root 1.27 rid = glGetUniformLocationARB (program_object_i::cur->id, name);
144 root 1.19
145     return rid;
146     }
147    
148 root 1.28 program_object_i *program_object_i::cur;
149 root 1.27
150     program_object_i::program_object_i ()
151 root 1.12 {
152     id = glCreateProgramObjectARB ();
153     assert (id);
154     }
155    
156 root 1.27 program_object_i::~program_object_i ()
157 root 1.12 {
158     glDeleteProgramsARB (1, &id);
159     }
160    
161 root 1.27 void program_object_i::link ()
162 root 1.12 {
163     glLinkProgramARB (id);
164    
165     GLint linked;
166     glGetObjectParameterivARB (id, GL_OBJECT_LINK_STATUS_ARB, &linked);
167    
168     if (!linked)
169     {
170     char infolog[8192];
171     glGetInfoLogARB (id, 8192, NULL, infolog);
172     printf ("LINK-INFOLOG<%s>\n", infolog);
173 root 1.1 abort ();
174     }
175 root 1.19
176     uloc.clear ();
177 root 1.22 }
178    
179 root 1.27 void program_object_i::enable ()
180 root 1.22 {
181 root 1.30 if (this != cur)
182     {
183     glUseProgramObjectARB (id);
184     //TODO: set samplers here?
185     cur = this;
186     }
187 root 1.22 }
188    
189 root 1.27 void program_object_i::disable ()
190 root 1.22 {
191 root 1.30 //TODO: clear samplers here?
192 root 1.22 glUseProgramObjectARB (0);
193     cur = 0;
194 root 1.1 }
195    
196 root 1.29 static map<string, program_object> progcache;
197    
198     program_object get_program (const string &vsh, const string &fsh)
199     {
200     string idx = vsh + "\0" + fsh;
201    
202     map<string, program_object>::iterator i = progcache.find (idx);
203    
204     if (i != progcache.end ())
205     return i->second;
206    
207     program_object p;
208    
209 root 1.31 if (vsh.size ())
210     {
211     vertex_shader sh;
212     p->attach (sh);
213     sh->compile (vsh);
214     }
215    
216     if (fsh.size ())
217     {
218     fragment_shader sh;
219     p->attach (sh);
220     sh->compile (fsh);
221     }
222    
223 root 1.29 p->link ();
224    
225     progcache.insert (pair<string, program_object> (idx, p));
226    
227     return p;
228     }
229    
230 root 1.26 const sl_expr< sl_string<60> > sl_convert< ::vec2 >::convert (const ::vec2 &v)
231 root 1.6 {
232     sl_string<60> s;
233 root 1.32 sprintf (s.str, "vec2 (%e, %e)", v.x, v.y);
234 root 1.6 return s;
235     }
236    
237 root 1.26 const sl_expr< sl_string<80> > sl_convert< ::vec3 >::convert (const ::vec3 &v)
238 root 1.6 {
239     sl_string<80> s;
240 root 1.32 sprintf (s.str, "vec3 (%e, %e, %e)", v.x, v.y, v.z);
241 root 1.6 return s;
242     }
243    
244 root 1.26 const sl_expr< sl_string<100> > sl_convert< ::vec4 >::convert (const ::vec4 &v)
245 root 1.6 {
246     sl_string<100> s;
247 root 1.32 sprintf (s.str, "vec4 (%e, %e, %e, %e)", v.x, v.y, v.z, v.w);
248 root 1.6 return s;
249     }
250    
251 root 1.28 shader_builder *shader_builder::cur = 0;
252 root 1.5
253 root 1.28 bool shader_builder::first (const void *p)
254     {
255     if (seen.find (p) == seen.end ())
256     {
257     seen.insert (p);
258     return true;
259     }
260 root 1.26
261 root 1.28 return false;
262     }
263 root 1.26
264 root 1.28 void shader_builder::start ()
265     {
266     cur = new shader_builder;
267 root 1.32 cur->code << scientific;
268 root 1.5 }
269    
270 root 1.28 string shader_builder::stop ()
271 root 1.1 {
272 root 1.28 ostringstream os;
273 root 1.20
274 root 1.28 os << cur->global.str ()
275     << "\nvoid main (void)\n"
276     << "{\n"
277     << cur->local.str ()
278     << "\n"
279     << cur->code.str ()
280     << "}\n";
281 root 1.23
282 root 1.28 delete cur;
283     cur = 0;
284 root 1.1
285 root 1.28 return os.str ();
286     }
287 root 1.1
288 root 1.28 void shader_object_i::compile (const string &source)
289     {
290     const char *sptr = source.data ();
291     const int slen = source.size ();
292 root 1.1
293 root 1.28 printf ("%s\n", linify (source).c_str ());
294     glShaderSourceARB (id, 1, &sptr, &slen);
295     glCompileShaderARB (id);
296 root 1.1
297 root 1.28 GLint compiled;
298     glGetObjectParameterivARB (id, GL_OBJECT_COMPILE_STATUS_ARB, &compiled);
299 root 1.10
300 root 1.28 if (!compiled)
301     {
302     char infolog[8192];
303     glGetInfoLogARB (id, 8192, NULL, infolog);
304     printf ("%s\n", linify (source).c_str ());
305     printf ("%s\n", infolog);
306     abort ();
307     }
308 root 1.1 }
309    
310     }
311