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