ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/libgender/shader.C
Revision: 1.21
Committed: Fri Oct 29 22:32:49 2004 UTC (19 years, 7 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.20: +1 -7 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 (find (b.streams.begin (), b.streams.end (), var (*this)) == b.streams.end ())
119 b.streams.push_back (*this);
120 }
121
122 void temporary_i::build (shader_builder &b)
123 {
124 var_i::build (b);
125
126 if (find (b.temps.begin (), b.temps.end (), var (*this)) == b.temps.end ())
127 b.temps.push_back (*this);
128 }
129
130 void fragment_vector_i::build (shader_builder &b)
131 {
132 for (vector<fragment>::iterator i = begin (); i != end (); i++)
133 (*i)->build (b);
134 }
135
136 void fragment_const_string_i::build (shader_builder &b)
137 {
138 b << str;
139 }
140
141 void fragment_string_i::build (shader_builder &b)
142 {
143 b << str;
144 }
145
146 #if 0
147 void statement_i::build (shader_builder &b)
148 {
149 b << " ";
150 fragment_vector_i::build (b);
151 b << ";\n";
152 }
153 #endif
154
155 ////////////////////////////////////////////////////////////////////////////
156
157 int texture_units::unit_count = 8;
158 int texture_units::units[8] = { 7, 6, 5, 4, 3, 2, 1, 0 };
159
160 shader_object_i *cur = 0;
161
162 shader_object_i::shader_object_i (GLenum type)
163 : type (type)
164 {
165 id = glCreateShaderObjectARB (type);
166 assert (id);
167 }
168
169 shader_object_i::~shader_object_i ()
170 {
171 glDeleteObjectARB (id);
172 }
173
174 void shader_object_i::start ()
175 {
176 clear ();
177 cur = this;
178 }
179
180 void shader_object_i::stop ()
181 {
182 cur = 0;
183 }
184
185 string shader_object_i::source ()
186 {
187 shader_builder b;
188 build (b);
189 ostringstream os;
190
191 for (vector<uniform>::iterator i = b.refs.begin (); i != b.refs.end (); i++)
192 {
193 (*i)->build_decl (os);
194 os << ";\n";
195 }
196
197 // not neccessary right now, as GLSL is rich on predefinitions
198 for (vector<var>::iterator i = b.streams.begin (); i != b.streams.end (); i++)
199 {
200 os << "attribute ";
201 (*i)->build_decl (os);
202 os << ";\n";
203 }
204
205 os << "\nvoid main (void)\n{\n";
206
207 for (vector<var>::iterator i = b.temps.begin (); i != b.temps.end (); i++)
208 {
209 os << " ";
210 (*i)->build_decl (os);
211 os << ";\n";
212 }
213
214 os << "\n";
215 os << b.source.str ();
216 os << "}\n";
217
218 return os.str ();
219 }
220
221 static string linify (const string &s)
222 {
223 ostringstream o;
224
225 int b = 0, e;
226 int l = 1;
227 do {
228 o << setw (3) << l << ": ";
229 e = s.find ('\n', b);
230 if (e == string::npos)
231 e = s.size ();
232
233 o << s.substr (b, e - b + 1);
234 b = e + 1;
235 l++;
236 } while (b < s.size ());
237
238 return o.str ();
239 }
240
241 void shader_object_i::compile ()
242 {
243 string src = source ();
244 const char *sptr = src.data ();
245 const int slen = src.size ();
246
247 printf ("%s\n", linify (src).c_str ());
248 glShaderSourceARB (id, 1, &sptr, &slen);
249 glCompileShaderARB (id);
250
251 GLint compiled;
252 glGetObjectParameterivARB (id, GL_OBJECT_COMPILE_STATUS_ARB, &compiled);
253
254 if (!compiled)
255 {
256 char infolog[8192];
257 glGetInfoLogARB (id, 8192, NULL, infolog);
258 printf ("%s\n", linify (src).c_str ());
259 printf ("%s\n", infolog);
260 abort ();
261 }
262 }
263
264 ////////////////////////////////////////////////////////////////////////////
265
266 program_object *program_object::cur = 0;
267
268 GLint uniform_i::location ()
269 {
270 assert (program_object::cur);
271
272 GLint &rid = program_object::cur->uloc[this];
273
274 if (!rid)
275 rid = glGetUniformLocationARB (program_object::cur->id, name);
276
277 return rid;
278 }
279
280 program_object::program_object ()
281 {
282 id = glCreateProgramObjectARB ();
283 assert (id);
284
285 glAttachObjectARB (id, vsh->id);
286 glAttachObjectARB (id, fsh->id);
287 }
288
289 program_object::~program_object ()
290 {
291 glDeleteProgramsARB (1, &id);
292 }
293
294 void program_object::link ()
295 {
296 glLinkProgramARB (id);
297
298 GLint linked;
299 glGetObjectParameterivARB (id, GL_OBJECT_LINK_STATUS_ARB, &linked);
300
301 if (!linked)
302 {
303 char infolog[8192];
304 glGetInfoLogARB (id, 8192, NULL, infolog);
305 printf ("LINK-INFOLOG<%s>\n", infolog);
306 abort ();
307 }
308
309 uloc.clear ();
310 }
311
312 void sl_func0::begin () const
313 {
314 cur->append_string (name_par);
315 }
316
317 void sl_func0::comma () const
318 {
319 cur->append (str_comma);
320 }
321
322 void sl_func0::end () const
323 {
324 str_rpar ();
325 }
326
327 void sl_float::operator ()() const
328 {
329 char s[20];
330 sprintf (s, "%g", c);
331 cur->append_string (s);
332 }
333
334 const sl_convert< ::vec2 >::T sl_convert< ::vec2 >::convert (const ::vec2 &v)
335 {
336 sl_string<60> s;
337 sprintf (s.str, "vec2 (%g, %g)", v.x, v.y);
338 return s;
339 }
340
341 const sl_convert< ::vec3 >::T sl_convert< ::vec3 >::convert (const ::vec3 &v)
342 {
343 sl_string<80> s;
344 sprintf (s.str, "vec3 (%g, %g, %g)", v.x, v.y, v.z);
345 return s;
346 }
347
348 const sl_convert< ::vec4 >::T sl_convert< ::vec4 >::convert (const ::vec4 &v)
349 {
350 sl_string<100> s;
351 sprintf (s.str, "vec4 (%g, %g, %g, %g)", v.x, v.y, v.z, v.w);
352 return s;
353 }
354
355 const fragment_const_string str_2sp (" ");
356 const fragment_const_string str_equal (" = ");
357 const fragment_const_string str_comma (", ");
358 const fragment_const_string str_endl (";\n");
359
360 const sl_append_const_string str_plus (" + ");
361 const sl_append_const_string str_minus (" - ");
362 const sl_append_const_string str_mul (" * ");
363 const sl_append_const_string str_div (" / ");
364 const sl_append_const_string str_mod (" % ");
365
366 const sl_append_const_string str_lpar ("(");
367 const sl_append_const_string str_rpar (")");
368
369 void swizzle_mask (sl_string<7> &s, int mask)
370 {
371 static const char channel[4] = { 'x', 'y', 'z', 'w' };
372
373 char *str = s.str;
374
375 *str++ = ')';
376 *str++ = '.';
377
378 while (mask)
379 {
380 int c = mask % 5;
381 mask /= 5;
382
383 if (c)
384 *str++ = channel[c - 1];
385 }
386
387 *str++ = 0;
388 }
389
390
391 void debdebdebdebug ()//D
392 {
393 return;
394
395 vertex_shader vsh;
396
397 vsh->start ();
398
399 temp_4f lightpos;
400 temp_4f wpos;
401
402 lightpos = vec4 (0, 10, 0, 1);
403 wpos = gl.model_view_matrix * vin.vertex;
404 vout.position = vin.vertex * gl.model_view_matrix_inverse;
405 vout.tex_coord[0] = vin.tex_coord[0];
406 vout.tex_coord[1] = normalize (lightpos - wpos);
407 vout.tex_coord[2] = normalize (wpos);
408 //vout.tex_coord[3] = normalize (xyz (gl.model_view_matrix_inverse_transpose) * vin.normal);
409 //vout.tex_coord[4] = normalize (xyz (gl.projection_matrix_inverse_transpose) - wpos);
410
411 vsh->end ();
412 vsh->compile ();
413
414 fragment_shader fsh;
415
416 fsh->start ();
417
418 xyz (fout.frag_color) = noise3 (x (fin.frag_coord) * y (fin.frag_coord));
419
420 temp_1f spec_expon;
421 spec_expon = 200;
422
423 fsh->end ();
424 fsh->compile ();
425
426 //abort ();
427 }
428
429 }
430