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

# 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.6 void refcounted::refcnt_dec () const
20     {
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     var_i::var_i (const char *typestr)
46     : typestr (typestr)
47     {
48     }
49    
50     var_i::~var_i ()
51     {
52     }
53    
54 root 1.4 stream_i::stream_i (const char *strtype)
55     : var_i (strtype)
56     {
57 root 1.19 sprintf (name, "V%d", ++next_id);
58 root 1.4 }
59    
60 root 1.1 temporary_i::temporary_i (const char *strtype)
61     : var_i (strtype)
62     {
63 root 1.19 sprintf (name, "T%d", ++next_id);
64 root 1.1 }
65    
66     uniform_i::uniform_i (const char *strtype)
67 root 1.19 : var_i (strtype)
68 root 1.1 {
69 root 1.19 sprintf (name, "U%d", ++next_id);
70 root 1.1 }
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 root 1.16 void gluvar_i::build (shader_builder &b)
97 root 1.1 {
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 root 1.22 #if 0
119 root 1.1 if (find (b.streams.begin (), b.streams.end (), var (*this)) == b.streams.end ())
120     b.streams.push_back (*this);
121 root 1.22 #endif
122 root 1.1 }
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 root 1.20 int texture_units::unit_count = 8;
160 root 1.21 int texture_units::units[8] = { 7, 6, 5, 4, 3, 2, 1, 0 };
161 root 1.20
162 root 1.1 shader_object_i *cur = 0;
163    
164     shader_object_i::shader_object_i (GLenum type)
165     : type (type)
166     {
167     id = glCreateShaderObjectARB (type);
168 root 1.12 assert (id);
169 root 1.1 }
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 root 1.22 #if 0
200 root 1.1 // 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 root 1.22 #endif
208 root 1.1
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 root 1.17 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 root 1.1 void shader_object_i::compile ()
246     {
247     string src = source ();
248     const char *sptr = src.data ();
249     const int slen = src.size ();
250    
251 root 1.17 printf ("%s\n", linify (src).c_str ());
252 root 1.1 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 root 1.17 printf ("%s\n", linify (src).c_str ());
263     printf ("%s\n", infolog);
264 root 1.12 abort ();
265     }
266     }
267    
268 root 1.19 ////////////////////////////////////////////////////////////////////////////
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 root 1.12 program_object::program_object ()
285     {
286     id = glCreateProgramObjectARB ();
287     assert (id);
288 root 1.15
289     glAttachObjectARB (id, vsh->id);
290     glAttachObjectARB (id, fsh->id);
291 root 1.12 }
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 root 1.1 abort ();
311     }
312 root 1.19
313     uloc.clear ();
314 root 1.22 }
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 root 1.1 }
329    
330 root 1.7 void sl_func0::begin () const
331     {
332     cur->append_string (name_par);
333     }
334    
335 root 1.8 void sl_func0::comma () const
336     {
337 root 1.23 cur->append (compile::str_comma);
338 root 1.8 }
339    
340 root 1.7 void sl_func0::end () const
341     {
342 root 1.23 compile::str_rpar ();
343 root 1.7 }
344    
345 root 1.6 void sl_float::operator ()() const
346     {
347     char s[20];
348     sprintf (s, "%g", c);
349     cur->append_string (s);
350     }
351    
352 root 1.9 const sl_convert< ::vec2 >::T sl_convert< ::vec2 >::convert (const ::vec2 &v)
353 root 1.6 {
354     sl_string<60> s;
355     sprintf (s.str, "vec2 (%g, %g)", v.x, v.y);
356     return s;
357     }
358    
359 root 1.9 const sl_convert< ::vec3 >::T sl_convert< ::vec3 >::convert (const ::vec3 &v)
360 root 1.6 {
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 root 1.9 const sl_convert< ::vec4 >::T sl_convert< ::vec4 >::convert (const ::vec4 &v)
367 root 1.6 {
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 root 1.23 namespace compile {
374 root 1.5
375 root 1.23 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 root 1.1
414 root 1.23 *str++ = 0;
415     }
416 root 1.5 }
417    
418 root 1.1 void debdebdebdebug ()//D
419     {
420 root 1.20 return;
421    
422 root 1.23 using namespace compile;
423    
424 root 1.1 vertex_shader vsh;
425    
426     vsh->start ();
427    
428     temp_4f lightpos;
429 root 1.18 temp_4f wpos;
430 root 1.1
431 root 1.13 lightpos = vec4 (0, 10, 0, 1);
432 root 1.23 wpos = model_view_matrix * vin.vertex;
433     vout.position = vin.vertex * model_view_matrix_inverse;
434 root 1.7 vout.tex_coord[0] = vin.tex_coord[0];
435 root 1.18 vout.tex_coord[1] = normalize (lightpos - wpos);
436     vout.tex_coord[2] = normalize (wpos);
437 root 1.23 //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 root 1.1
440     vsh->end ();
441 root 1.13 vsh->compile ();
442 root 1.10
443     fragment_shader fsh;
444    
445     fsh->start ();
446    
447 root 1.11 xyz (fout.frag_color) = noise3 (x (fin.frag_coord) * y (fin.frag_coord));
448    
449 root 1.10 temp_1f spec_expon;
450     spec_expon = 200;
451    
452     fsh->end ();
453     fsh->compile ();
454    
455 root 1.11 //abort ();
456 root 1.1 }
457    
458     }
459