ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/libgender/shader.C
Revision: 1.18
Committed: Thu Oct 28 17:00:46 2004 UTC (19 years, 8 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.17: +6 -8 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 //param = cgCreateParameter (cg_context, cgtype);
49 }
50
51 var_i::~var_i ()
52 {
53 //cgDestroyParameter (param);
54 }
55
56 stream_i::stream_i (const char *strtype)
57 : var_i (strtype)
58 {
59 sprintf (name, "V%lx_%d", ((long)this >> 4) & 0xfff, ++next_id);
60 }
61
62 temporary_i::temporary_i (const char *strtype)
63 : var_i (strtype)
64 {
65 sprintf (name, "T%lx_%d", ((long)this >> 4) & 0xfff, ++next_id);
66 }
67
68 uniform_i::uniform_i (const char *strtype)
69 : var_i (strtype), dirty (true)
70 {
71 sprintf (name, "U%lx_%d", ((long)this >> 4) & 0xfff, ++next_id);
72 }
73
74 fragment_string_i::~fragment_string_i ()
75 {
76 free (str);
77 }
78
79 ////////////////////////////////////////////////////////////////////////////
80
81 void var_i::build_decl (ostringstream &b)
82 {
83 b << typestr << ' ' << name;
84 }
85
86 void uniform_i::build_decl (ostringstream &b)
87 {
88 b << "uniform " << typestr << ' ' << name;
89 }
90
91 void stream_i::build_decl (ostringstream &b)
92 {
93 b << typestr << ' ' << name;
94 }
95
96 ////////////////////////////////////////////////////////////////////////////
97
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 shader_object_i *cur = 0;
160
161 shader_object_i::shader_object_i (GLenum type)
162 : type (type)
163 {
164 id = glCreateShaderObjectARB (type);
165 assert (id);
166 }
167
168 shader_object_i::~shader_object_i ()
169 {
170 glDeleteObjectARB (id);
171 }
172
173 void shader_object_i::start ()
174 {
175 clear ();
176 cur = this;
177 }
178
179 void shader_object_i::stop ()
180 {
181 cur = 0;
182 }
183
184 string shader_object_i::source ()
185 {
186 shader_builder b;
187 build (b);
188 ostringstream os;
189
190 for (vector<uniform>::iterator i = b.refs.begin (); i != b.refs.end (); i++)
191 {
192 (*i)->build_decl (os);
193 os << ";\n";
194 }
195
196 // not neccessary right now, as GLSL is rich on predefinitions
197 for (vector<var>::iterator i = b.streams.begin (); i != b.streams.end (); i++)
198 {
199 os << "attribute ";
200 (*i)->build_decl (os);
201 os << ";\n";
202 }
203
204 os << "\nvoid main (void)\n{\n";
205
206 for (vector<var>::iterator i = b.temps.begin (); i != b.temps.end (); i++)
207 {
208 os << " ";
209 (*i)->build_decl (os);
210 os << ";\n";
211 }
212
213 os << "\n";
214 os << b.source.str ();
215 os << "}\n";
216
217 return os.str ();
218 }
219
220 static string linify (const string &s)
221 {
222 ostringstream o;
223
224 int b = 0, e;
225 int l = 1;
226 do {
227 o << setw (3) << l << ": ";
228 e = s.find ('\n', b);
229 if (e == string::npos)
230 e = s.size ();
231
232 o << s.substr (b, e - b + 1);
233 b = e + 1;
234 l++;
235 } while (b < s.size ());
236
237 return o.str ();
238 }
239
240 void shader_object_i::compile ()
241 {
242 string src = source ();
243 const char *sptr = src.data ();
244 const int slen = src.size ();
245
246 printf ("%s\n", linify (src).c_str ());
247 glShaderSourceARB (id, 1, &sptr, &slen);
248 glCompileShaderARB (id);
249
250 GLint compiled;
251 glGetObjectParameterivARB (id, GL_OBJECT_COMPILE_STATUS_ARB, &compiled);
252
253 if (!compiled)
254 {
255 char infolog[8192];
256 glGetInfoLogARB (id, 8192, NULL, infolog);
257 printf ("%s\n", linify (src).c_str ());
258 printf ("%s\n", infolog);
259 abort ();
260 }
261 }
262
263 program_object::program_object ()
264 {
265 id = glCreateProgramObjectARB ();
266 assert (id);
267
268 glAttachObjectARB (id, vsh->id);
269 glAttachObjectARB (id, fsh->id);
270 }
271
272 program_object::~program_object ()
273 {
274 glDeleteProgramsARB (1, &id);
275 }
276
277 void program_object::link ()
278 {
279 glLinkProgramARB (id);
280
281 GLint linked;
282 glGetObjectParameterivARB (id, GL_OBJECT_LINK_STATUS_ARB, &linked);
283
284 if (!linked)
285 {
286 char infolog[8192];
287 glGetInfoLogARB (id, 8192, NULL, infolog);
288 printf ("LINK-INFOLOG<%s>\n", infolog);
289 abort ();
290 }
291 }
292
293 void sl_func0::begin () const
294 {
295 cur->append_string (name_par);
296 }
297
298 void sl_func0::comma () const
299 {
300 cur->append (str_comma);
301 }
302
303 void sl_func0::end () const
304 {
305 str_rpar ();
306 }
307
308 void sl_float::operator ()() const
309 {
310 char s[20];
311 sprintf (s, "%g", c);
312 cur->append_string (s);
313 }
314
315 const sl_convert< ::vec2 >::T sl_convert< ::vec2 >::convert (const ::vec2 &v)
316 {
317 sl_string<60> s;
318 sprintf (s.str, "vec2 (%g, %g)", v.x, v.y);
319 return s;
320 }
321
322 const sl_convert< ::vec3 >::T sl_convert< ::vec3 >::convert (const ::vec3 &v)
323 {
324 sl_string<80> s;
325 sprintf (s.str, "vec3 (%g, %g, %g)", v.x, v.y, v.z);
326 return s;
327 }
328
329 const sl_convert< ::vec4 >::T sl_convert< ::vec4 >::convert (const ::vec4 &v)
330 {
331 sl_string<100> s;
332 sprintf (s.str, "vec4 (%g, %g, %g, %g)", v.x, v.y, v.z, v.w);
333 return s;
334 }
335
336 const fragment_const_string str_2sp (" ");
337 const fragment_const_string str_equal (" = ");
338 const fragment_const_string str_comma (", ");
339 const fragment_const_string str_endl (";\n");
340
341 const sl_append_const_string str_plus (" + ");
342 const sl_append_const_string str_minus (" - ");
343 const sl_append_const_string str_mul (" * ");
344 const sl_append_const_string str_div (" / ");
345 const sl_append_const_string str_mod (" % ");
346
347 const sl_append_const_string str_lpar ("(");
348 const sl_append_const_string str_rpar (")");
349
350 void swizzle_mask (sl_string<7> &s, int mask)
351 {
352 static const char channel[4] = { 'x', 'y', 'z', 'w' };
353
354 char *str = s.str;
355
356 *str++ = ')';
357 *str++ = '.';
358
359 while (mask)
360 {
361 int c = mask % 5;
362 mask /= 5;
363
364 if (c)
365 *str++ = channel[c - 1];
366 }
367
368 *str++ = 0;
369 }
370
371
372 void debdebdebdebug ()//D
373 {
374 vertex_shader vsh;
375
376 vsh->start ();
377
378 temp_4f lightpos;
379 temp_4f wpos;
380
381 lightpos = vec4 (0, 10, 0, 1);
382 wpos = gl.model_view_matrix * vin.vertex;
383 vout.position = vin.vertex * gl.model_view_matrix_inverse;
384 vout.tex_coord[0] = vin.tex_coord[0];
385 vout.tex_coord[1] = normalize (lightpos - wpos);
386 vout.tex_coord[2] = normalize (wpos);
387 //vout.tex_coord[3] = normalize (xyz (gl.model_view_matrix_inverse_transpose) * vin.normal);
388 //vout.tex_coord[4] = normalize (xyz (gl.projection_matrix_inverse_transpose) - wpos);
389
390 vsh->end ();
391 vsh->compile ();
392
393 fragment_shader fsh;
394
395 fsh->start ();
396
397 xyz (fout.frag_color) = noise3 (x (fin.frag_coord) * y (fin.frag_coord));
398
399 temp_1f spec_expon;
400 spec_expon = 200;
401
402 fsh->end ();
403 fsh->compile ();
404
405 //abort ();
406 }
407
408 }
409