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

Comparing libgender/shader.C (file contents):
Revision 1.23 by root, Sat Oct 30 00:17:28 2004 UTC vs.
Revision 1.31 by root, Fri Nov 5 19:55:15 2004 UTC

14 { 14 {
15 if (refcnt) 15 if (refcnt)
16 abort (); 16 abort ();
17 } 17 }
18 18
19 void refcounted::refcnt_dec () const 19 void refcounted::refcnt_destroy () const
20 { 20 {
21 if (!--refcnt) 21 if (!--refcnt)
22 delete this; // quite a bit of code... 22 delete this; // quite a bit of code...
23 } 23 }
24 24
40 const char str_sampler_3d_rect [] = "sampler3DRect"; 40 const char str_sampler_3d_rect [] = "sampler3DRect";
41 const char str_sampler_cube [] = "samplerCube"; 41 const char str_sampler_cube [] = "samplerCube";
42 42
43 unsigned int var_i::next_id = 0; 43 unsigned int var_i::next_id = 0;
44 44
45 var_i::var_i (const char *typestr) 45 var_i::var_i (const char *domainstr, const char *typestr)
46 : typestr (typestr) 46 : domainstr (domainstr), typestr (typestr)
47 { 47 {
48 } 48 }
49 49
50 var_i::~var_i () 50 var_i::~var_i ()
51 { 51 {
52 } 52 }
53 53
54#if 0
54 stream_i::stream_i (const char *strtype) 55 stream_i::stream_i (const char *strtype)
55 : var_i (strtype) 56 : var_i (strtype)
56 { 57 {
57 sprintf (name, "V%d", ++next_id); 58 sprintf (name, "V%d", ++next_id);
58 } 59 }
60#endif
59 61
60 temporary_i::temporary_i (const char *strtype) 62 temporary_i::temporary_i (const char *strtype)
61 : var_i (strtype) 63 : var_i (0, strtype)
62 { 64 {
63 sprintf (name, "T%d", ++next_id); 65 sprintf (name, "T%d", ++next_id);
64 } 66 }
65 67
68 varying_i::varying_i (const char *strtype)
69 : var_i ("varying", strtype)
70 {
71 sprintf (name, "V%d", ++next_id);
72 }
73
66 uniform_i::uniform_i (const char *strtype) 74 uniform_i::uniform_i (const char *strtype)
67 : var_i (strtype) 75 : var_i ("uniform", strtype)
68 { 76 {
69 sprintf (name, "U%d", ++next_id); 77 sprintf (name, "U%d", ++next_id);
70 } 78 }
71 79
72 fragment_string_i::~fragment_string_i ()
73 {
74 free (str);
75 }
76
77 //////////////////////////////////////////////////////////////////////////// 80 ////////////////////////////////////////////////////////////////////////////
78 81
79 void var_i::build_decl (ostringstream &b) 82 void var_i::operator ()() const
80 { 83 {
81 b << typestr << ' ' << name; 84 shader_builder::cur->code << name;
82 }
83 85
84 void uniform_i::build_decl (ostringstream &b) 86 if (shader_builder::cur->first (this))
85 { 87 {
86 b << "uniform " << typestr << ' ' << name; 88 if (domainstr)
89 shader_builder::cur->global << domainstr << ' ' << typestr << ' ' << name << ";\n";
90 else
91 shader_builder::cur->local << " " << typestr << ' ' << name << ";\n";
92 }
87 } 93 }
88
89 void stream_i::build_decl (ostringstream &b)
90 {
91 b << typestr << ' ' << name;
92 }
93
94 ////////////////////////////////////////////////////////////////////////////
95
96 void gluvar_i::build (shader_builder &b)
97 {
98 b << name;
99 }
100
101 void var_i::build (shader_builder &b)
102 {
103 b << name;
104 }
105
106 void uniform_i::build (shader_builder &b)
107 {
108 var_i::build (b);
109
110 if (find (b.refs.begin (), b.refs.end (), uniform (*this)) == b.refs.end ())
111 b.refs.push_back (*this);
112 }
113
114 void stream_i::build (shader_builder &b)
115 {
116 var_i::build (b);
117
118#if 0
119 if (find (b.streams.begin (), b.streams.end (), var (*this)) == b.streams.end ())
120 b.streams.push_back (*this);
121#endif
122 }
123
124 void temporary_i::build (shader_builder &b)
125 {
126 var_i::build (b);
127
128 if (find (b.temps.begin (), b.temps.end (), var (*this)) == b.temps.end ())
129 b.temps.push_back (*this);
130 }
131
132 void fragment_vector_i::build (shader_builder &b)
133 {
134 for (vector<fragment>::iterator i = begin (); i != end (); i++)
135 (*i)->build (b);
136 }
137
138 void fragment_const_string_i::build (shader_builder &b)
139 {
140 b << str;
141 }
142
143 void fragment_string_i::build (shader_builder &b)
144 {
145 b << str;
146 }
147
148#if 0
149 void statement_i::build (shader_builder &b)
150 {
151 b << " ";
152 fragment_vector_i::build (b);
153 b << ";\n";
154 }
155#endif
156 94
157 //////////////////////////////////////////////////////////////////////////// 95 ////////////////////////////////////////////////////////////////////////////
158 96
159 int texture_units::unit_count = 8; 97 int texture_units::unit_count = 8;
160 int texture_units::units[8] = { 7, 6, 5, 4, 3, 2, 1, 0 }; 98 int texture_units::units[8] = { 7, 6, 5, 4, 3, 2, 1, 0 };
169 } 107 }
170 108
171 shader_object_i::~shader_object_i () 109 shader_object_i::~shader_object_i ()
172 { 110 {
173 glDeleteObjectARB (id); 111 glDeleteObjectARB (id);
174 }
175
176 void shader_object_i::start ()
177 {
178 clear ();
179 cur = this;
180 }
181
182 void shader_object_i::stop ()
183 {
184 cur = 0;
185 }
186
187 string shader_object_i::source ()
188 {
189 shader_builder b;
190 build (b);
191 ostringstream os;
192
193 for (vector<uniform>::iterator i = b.refs.begin (); i != b.refs.end (); i++)
194 {
195 (*i)->build_decl (os);
196 os << ";\n";
197 }
198
199#if 0
200 // not neccessary right now, as GLSL is rich on predefinitions
201 for (vector<var>::iterator i = b.streams.begin (); i != b.streams.end (); i++)
202 {
203 os << "attribute ";
204 (*i)->build_decl (os);
205 os << ";\n";
206 }
207#endif
208
209 os << "\nvoid main (void)\n{\n";
210
211 for (vector<var>::iterator i = b.temps.begin (); i != b.temps.end (); i++)
212 {
213 os << " ";
214 (*i)->build_decl (os);
215 os << ";\n";
216 }
217
218 os << "\n";
219 os << b.source.str ();
220 os << "}\n";
221
222 return os.str ();
223 } 112 }
224 113
225 static string linify (const string &s) 114 static string linify (const string &s)
226 { 115 {
227 ostringstream o; 116 ostringstream o;
240 } while (b < s.size ()); 129 } while (b < s.size ());
241 130
242 return o.str (); 131 return o.str ();
243 } 132 }
244 133
245 void shader_object_i::compile ()
246 {
247 string src = source ();
248 const char *sptr = src.data ();
249 const int slen = src.size ();
250
251 printf ("%s\n", linify (src).c_str ());
252 glShaderSourceARB (id, 1, &sptr, &slen);
253 glCompileShaderARB (id);
254
255 GLint compiled;
256 glGetObjectParameterivARB (id, GL_OBJECT_COMPILE_STATUS_ARB, &compiled);
257
258 if (!compiled)
259 {
260 char infolog[8192];
261 glGetInfoLogARB (id, 8192, NULL, infolog);
262 printf ("%s\n", linify (src).c_str ());
263 printf ("%s\n", infolog);
264 abort ();
265 }
266 }
267
268 //////////////////////////////////////////////////////////////////////////// 134 ////////////////////////////////////////////////////////////////////////////
269 135
270 program_object *program_object::cur = 0;
271
272 GLint uniform_i::location () 136 GLint uniform_i::location ()
273 { 137 {
274 assert (program_object::cur); 138 assert (program_object_i::cur);
275 139
276 GLint &rid = program_object::cur->uloc[this]; 140 GLint &rid = program_object_i::cur->uloc[this];
277 141
278 if (!rid) 142 if (!rid)
279 rid = glGetUniformLocationARB (program_object::cur->id, name); 143 rid = glGetUniformLocationARB (program_object_i::cur->id, name);
280 144
281 return rid; 145 return rid;
282 } 146 }
283 147
148 program_object_i *program_object_i::cur;
149
284 program_object::program_object () 150 program_object_i::program_object_i ()
285 { 151 {
286 id = glCreateProgramObjectARB (); 152 id = glCreateProgramObjectARB ();
287 assert (id); 153 assert (id);
288
289 glAttachObjectARB (id, vsh->id);
290 glAttachObjectARB (id, fsh->id);
291 } 154 }
292 155
293 program_object::~program_object () 156 program_object_i::~program_object_i ()
294 { 157 {
295 glDeleteProgramsARB (1, &id); 158 glDeleteProgramsARB (1, &id);
296 } 159 }
297 160
298 void program_object::link () 161 void program_object_i::link ()
299 { 162 {
300 glLinkProgramARB (id); 163 glLinkProgramARB (id);
301 164
302 GLint linked; 165 GLint linked;
303 glGetObjectParameterivARB (id, GL_OBJECT_LINK_STATUS_ARB, &linked); 166 glGetObjectParameterivARB (id, GL_OBJECT_LINK_STATUS_ARB, &linked);
311 } 174 }
312 175
313 uloc.clear (); 176 uloc.clear ();
314 } 177 }
315 178
316 void program_object::enable () 179 void program_object_i::enable ()
317 { 180 {
181 if (this != cur)
182 {
318 glUseProgramObjectARB (id); 183 glUseProgramObjectARB (id);
319 //TODO: set samplers here 184 //TODO: set samplers here?
320 cur = this; 185 cur = this;
186 }
321 } 187 }
322 188
323 void program_object::disable () 189 void program_object_i::disable ()
324 { 190 {
325 //TODO: clear samplers here 191 //TODO: clear samplers here?
326 glUseProgramObjectARB (0); 192 glUseProgramObjectARB (0);
327 cur = 0; 193 cur = 0;
328 } 194 }
329 195
330 void sl_func0::begin () const 196 static map<string, program_object> progcache;
331 {
332 cur->append_string (name_par);
333 }
334 197
335 void sl_func0::comma () const 198 program_object get_program (const string &vsh, const string &fsh)
336 { 199 {
337 cur->append (compile::str_comma); 200 string idx = vsh + "\0" + fsh;
338 }
339 201
340 void sl_func0::end () const 202 map<string, program_object>::iterator i = progcache.find (idx);
341 {
342 compile::str_rpar ();
343 }
344 203
345 void sl_float::operator ()() const 204 if (i != progcache.end ())
346 { 205 return i->second;
347 char s[20];
348 sprintf (s, "%g", c);
349 cur->append_string (s);
350 }
351 206
352 const sl_convert< ::vec2 >::T sl_convert< ::vec2 >::convert (const ::vec2 &v) 207 program_object p;
208
209 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 p->link ();
224
225 progcache.insert (pair<string, program_object> (idx, p));
226
227 return p;
228 }
229
230 const sl_expr< sl_string<60> > sl_convert< ::vec2 >::convert (const ::vec2 &v)
353 { 231 {
354 sl_string<60> s; 232 sl_string<60> s;
355 sprintf (s.str, "vec2 (%g, %g)", v.x, v.y); 233 sprintf (s.str, "vec2 (%g, %g)", v.x, v.y);
356 return s; 234 return s;
357 } 235 }
358 236
359 const sl_convert< ::vec3 >::T sl_convert< ::vec3 >::convert (const ::vec3 &v) 237 const sl_expr< sl_string<80> > sl_convert< ::vec3 >::convert (const ::vec3 &v)
360 { 238 {
361 sl_string<80> s; 239 sl_string<80> s;
362 sprintf (s.str, "vec3 (%g, %g, %g)", v.x, v.y, v.z); 240 sprintf (s.str, "vec3 (%g, %g, %g)", v.x, v.y, v.z);
363 return s; 241 return s;
364 } 242 }
365 243
366 const sl_convert< ::vec4 >::T sl_convert< ::vec4 >::convert (const ::vec4 &v) 244 const sl_expr< sl_string<100> > sl_convert< ::vec4 >::convert (const ::vec4 &v)
367 { 245 {
368 sl_string<100> s; 246 sl_string<100> s;
369 sprintf (s.str, "vec4 (%g, %g, %g, %g)", v.x, v.y, v.z, v.w); 247 sprintf (s.str, "vec4 (%g, %g, %g, %g)", v.x, v.y, v.z, v.w);
370 return s; 248 return s;
371 } 249 }
372 250
373 namespace compile { 251 shader_builder *shader_builder::cur = 0;
374 252
375 const fragment_const_string str_2sp (" "); 253 bool shader_builder::first (const void *p)
376 const fragment_const_string str_equal (" = ");
377 const fragment_const_string str_comma (", ");
378 const fragment_const_string str_endl (";\n");
379
380 const sl_append_const_string str_plus (" + ");
381 const sl_append_const_string str_minus (" - ");
382 const sl_append_const_string str_mul (" * ");
383 const sl_append_const_string str_div (" / ");
384 const sl_append_const_string str_mod (" % ");
385
386 const sl_append_const_string str_lt (" < ");
387 const sl_append_const_string str_lte (" <= ");
388 const sl_append_const_string str_eq (" == ");
389 const sl_append_const_string str_ne (" != ");
390 const sl_append_const_string str_gte (" >= ");
391 const sl_append_const_string str_gt (" > ");
392
393 const sl_append_const_string str_lpar ("(");
394 const sl_append_const_string str_rpar (")");
395
396 void swizzle_mask (sl_string<7> &s, int mask)
397 { 254 {
398 static const char channel[4] = { 'x', 'y', 'z', 'w' }; 255 if (seen.find (p) == seen.end ())
399
400 char *str = s.str;
401
402 *str++ = ')';
403 *str++ = '.';
404
405 while (mask)
406 { 256 {
407 int c = mask % 5; 257 seen.insert (p);
408 mask /= 5; 258 return true;
409
410 if (c)
411 *str++ = channel[c - 1];
412 } 259 }
413 260
414 *str++ = 0; 261 return false;
262 }
263
264 void shader_builder::start ()
265 {
266 cur = new shader_builder;
267 }
268
269 string shader_builder::stop ()
270 {
271 ostringstream os;
272
273 os << cur->global.str ()
274 << "\nvoid main (void)\n"
275 << "{\n"
276 << cur->local.str ()
277 << "\n"
278 << cur->code.str ()
279 << "}\n";
280
281 delete cur;
282 cur = 0;
283
284 return os.str ();
285 }
286
287 void shader_object_i::compile (const string &source)
288 {
289 const char *sptr = source.data ();
290 const int slen = source.size ();
291
292 printf ("%s\n", linify (source).c_str ());
293 glShaderSourceARB (id, 1, &sptr, &slen);
294 glCompileShaderARB (id);
295
296 GLint compiled;
297 glGetObjectParameterivARB (id, GL_OBJECT_COMPILE_STATUS_ARB, &compiled);
298
299 if (!compiled)
300 {
301 char infolog[8192];
302 glGetInfoLogARB (id, 8192, NULL, infolog);
303 printf ("%s\n", linify (source).c_str ());
304 printf ("%s\n", infolog);
305 abort ();
415 } 306 }
416 }
417
418 void debdebdebdebug ()//D
419 {
420 return;
421
422 using namespace compile;
423
424 vertex_shader vsh;
425
426 vsh->start ();
427
428 temp_4f lightpos;
429 temp_4f wpos;
430
431 lightpos = vec4 (0, 10, 0, 1);
432 wpos = model_view_matrix * vin.vertex;
433 vout.position = vin.vertex * model_view_matrix_inverse;
434 vout.tex_coord[0] = vin.tex_coord[0];
435 vout.tex_coord[1] = normalize (lightpos - wpos);
436 vout.tex_coord[2] = normalize (wpos);
437 //vout.tex_coord[3] = normalize (xyz (model_view_matrix_inverse_transpose) * vin.normal);
438 //vout.tex_coord[4] = normalize (xyz (projection_matrix_inverse_transpose) - wpos);
439
440 vsh->end ();
441 vsh->compile ();
442
443 fragment_shader fsh;
444
445 fsh->start ();
446
447 xyz (fout.frag_color) = noise3 (x (fin.frag_coord) * y (fin.frag_coord));
448
449 temp_1f spec_expon;
450 spec_expon = 200;
451
452 fsh->end ();
453 fsh->compile ();
454
455 //abort ();
456 } 307 }
457 308
458} 309}
459 310

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines