ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/libgender/shader.C
Revision: 1.23
Committed: Sat Oct 30 00:17:28 2004 UTC (19 years, 7 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.22: +49 -38 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 stream_i::stream_i (const char *strtype)
55 : var_i (strtype)
56 {
57 sprintf (name, "V%d", ++next_id);
58 }
59
60 temporary_i::temporary_i (const char *strtype)
61 : var_i (strtype)
62 {
63 sprintf (name, "T%d", ++next_id);
64 }
65
66 uniform_i::uniform_i (const char *strtype)
67 : var_i (strtype)
68 {
69 sprintf (name, "U%d", ++next_id);
70 }
71
72 fragment_string_i::~fragment_string_i ()
73 {
74 free (str);
75 }
76
77 ////////////////////////////////////////////////////////////////////////////
78
79 void var_i::build_decl (ostringstream &b)
80 {
81 b << typestr << ' ' << name;
82 }
83
84 void uniform_i::build_decl (ostringstream &b)
85 {
86 b << "uniform " << typestr << ' ' << name;
87 }
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
157 ////////////////////////////////////////////////////////////////////////////
158
159 int texture_units::unit_count = 8;
160 int texture_units::units[8] = { 7, 6, 5, 4, 3, 2, 1, 0 };
161
162 shader_object_i *cur = 0;
163
164 shader_object_i::shader_object_i (GLenum type)
165 : type (type)
166 {
167 id = glCreateShaderObjectARB (type);
168 assert (id);
169 }
170
171 shader_object_i::~shader_object_i ()
172 {
173 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 }
224
225 static string linify (const string &s)
226 {
227 ostringstream o;
228
229 int b = 0, e;
230 int l = 1;
231 do {
232 o << setw (3) << l << ": ";
233 e = s.find ('\n', b);
234 if (e == string::npos)
235 e = s.size ();
236
237 o << s.substr (b, e - b + 1);
238 b = e + 1;
239 l++;
240 } while (b < s.size ());
241
242 return o.str ();
243 }
244
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 ////////////////////////////////////////////////////////////////////////////
269
270 program_object *program_object::cur = 0;
271
272 GLint uniform_i::location ()
273 {
274 assert (program_object::cur);
275
276 GLint &rid = program_object::cur->uloc[this];
277
278 if (!rid)
279 rid = glGetUniformLocationARB (program_object::cur->id, name);
280
281 return rid;
282 }
283
284 program_object::program_object ()
285 {
286 id = glCreateProgramObjectARB ();
287 assert (id);
288
289 glAttachObjectARB (id, vsh->id);
290 glAttachObjectARB (id, fsh->id);
291 }
292
293 program_object::~program_object ()
294 {
295 glDeleteProgramsARB (1, &id);
296 }
297
298 void program_object::link ()
299 {
300 glLinkProgramARB (id);
301
302 GLint linked;
303 glGetObjectParameterivARB (id, GL_OBJECT_LINK_STATUS_ARB, &linked);
304
305 if (!linked)
306 {
307 char infolog[8192];
308 glGetInfoLogARB (id, 8192, NULL, infolog);
309 printf ("LINK-INFOLOG<%s>\n", infolog);
310 abort ();
311 }
312
313 uloc.clear ();
314 }
315
316 void program_object::enable ()
317 {
318 glUseProgramObjectARB (id);
319 //TODO: set samplers here
320 cur = this;
321 }
322
323 void program_object::disable ()
324 {
325 //TODO: clear samplers here
326 glUseProgramObjectARB (0);
327 cur = 0;
328 }
329
330 void sl_func0::begin () const
331 {
332 cur->append_string (name_par);
333 }
334
335 void sl_func0::comma () const
336 {
337 cur->append (compile::str_comma);
338 }
339
340 void sl_func0::end () const
341 {
342 compile::str_rpar ();
343 }
344
345 void sl_float::operator ()() const
346 {
347 char s[20];
348 sprintf (s, "%g", c);
349 cur->append_string (s);
350 }
351
352 const sl_convert< ::vec2 >::T sl_convert< ::vec2 >::convert (const ::vec2 &v)
353 {
354 sl_string<60> s;
355 sprintf (s.str, "vec2 (%g, %g)", v.x, v.y);
356 return s;
357 }
358
359 const sl_convert< ::vec3 >::T sl_convert< ::vec3 >::convert (const ::vec3 &v)
360 {
361 sl_string<80> s;
362 sprintf (s.str, "vec3 (%g, %g, %g)", v.x, v.y, v.z);
363 return s;
364 }
365
366 const sl_convert< ::vec4 >::T sl_convert< ::vec4 >::convert (const ::vec4 &v)
367 {
368 sl_string<100> s;
369 sprintf (s.str, "vec4 (%g, %g, %g, %g)", v.x, v.y, v.z, v.w);
370 return s;
371 }
372
373 namespace compile {
374
375 const fragment_const_string str_2sp (" ");
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 {
398 static const char channel[4] = { 'x', 'y', 'z', 'w' };
399
400 char *str = s.str;
401
402 *str++ = ')';
403 *str++ = '.';
404
405 while (mask)
406 {
407 int c = mask % 5;
408 mask /= 5;
409
410 if (c)
411 *str++ = channel[c - 1];
412 }
413
414 *str++ = 0;
415 }
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 }
457
458 }
459