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

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines