ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/libgender/shader.C
Revision: 1.24
Committed: Mon Nov 1 20:11:35 2004 UTC (19 years, 7 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.23: +21 -3 lines
Log Message:
*** empty log message ***

File Contents

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