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

Comparing libgender/shader.C (file contents):
Revision 1.12 by root, Sun Oct 24 02:13:43 2004 UTC vs.
Revision 1.32 by root, Wed Jan 25 22:48:02 2006 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines