ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/libgender/material.h
Revision: 1.6
Committed: Thu Oct 21 21:20:09 2004 UTC (19 years, 7 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.5: +252 -93 lines
Log Message:
*** empty log message ***

File Contents

# Content
1 #ifndef MATERIAL_H
2 #define MATERIAL_H
3
4 #include <vector>
5 #include <string>
6 #include <sstream>
7
8 #include "opengl.h"
9
10 #include "util.h"
11
12 namespace shader {
13
14 using namespace std;
15
16 const int NAMELEN = 16;
17
18 class refcounted
19 {
20 template<class type> friend class ref;
21 mutable int refcnt;
22 void refcnt_inc () const { refcnt++; }
23 void refcnt_dec () const { if (!--refcnt) delete this; };
24 public:
25 refcounted () : refcnt(0) { }
26 virtual ~refcounted ();
27 };
28
29 template<class type>
30 struct ref
31 {
32 type *p;
33
34 ref (type &d)
35 {
36 d.refcnt_inc ();
37 p = &d;
38 }
39
40 ref (const ref &r)
41 {
42 r.p->refcnt_inc ();
43 p = r.p;
44 }
45
46 template<class type2>
47 ref (const ref<type2> &r)
48 {
49 r.p->refcnt_inc ();
50 p = r.p;
51 }
52
53 ~ref ()
54 {
55 p->refcnt_dec ();
56 }
57
58 ref &operator =(type &d)
59 {
60 d.refcnt_inc ();
61 p->refcnt_dec ();
62 p = &d;
63 return *this;
64 }
65
66 type *operator ->() { return p; }
67 const type *operator ->() const { return p; }
68
69 operator type &() { return *p; }
70 operator const type &() const { return *p; }
71
72 template<class type2>
73 bool operator ==(const ref<type2> b) const
74 {
75 return (void *)p == (void *)b.p;
76 }
77 };
78
79 extern const char str_float [];
80 extern const char str_float2 [];
81 extern const char str_float3 [];
82 extern const char str_float4 [];
83 extern const char str_float4x4 [];
84
85 typedef ref<struct var_i> var;
86 typedef ref<struct uniform_i> uniform;
87
88 struct shader_builder
89 {
90 struct shader_program *prog;
91 vector<uniform> refs; // uniform parameters
92 vector<var> temps; // temporary variables
93 vector<var> streams; // varying inputs & outputs
94 vector<var> samplers; // textures
95
96 ostringstream source;
97
98 template<typename type>
99 shader_builder &operator <<(const type &t)
100 {
101 source << t;
102 return *this;
103 }
104 };
105
106 struct fragment_i : refcounted
107 {
108 virtual void build (shader_builder &b) = 0;
109 };
110
111 typedef ref<fragment_i> fragment;
112
113 struct var_i : fragment_i
114 {
115 static int next_name;
116
117 CGparameter param;
118 int name;
119 const char *typestr;
120
121 void build (shader_builder &b);
122 virtual void build_decl (ostringstream &b) = 0;
123
124 var_i (CGtype cgtype, const char *typestr);
125 ~var_i ();
126 };
127
128 struct uniform_i : var_i
129 {
130 bool dirty;
131
132 virtual void update () = 0;
133
134 void build (shader_builder &b);
135 void build_decl (ostringstream &b);
136 uniform_i (CGtype cgtype, const char *strtype) : var_i (cgtype, strtype), dirty (true) { }
137 };
138
139 template<int dimension, typename gltype, CGtype cgtype, const char *strtype, void (*upd)(CGparameter, const gltype *)>
140 struct uniform2_i : uniform_i
141 {
142 gltype data[dimension];
143
144 void update ()
145 {
146 if (dirty)
147 {
148 upd (param, data);
149 dirty = false;
150 }
151 }
152
153 uniform2_i () : uniform_i (cgtype, strtype) { }
154 };
155
156 template<int dimension, const char *strtype, void (*update)(CGparameter, const GLfloat *)>
157 struct uniform_f_i : uniform2_i<dimension, GLfloat, CG_FLOAT, strtype, update>
158 {
159 };
160
161 struct uniform_1f_i : uniform_f_i<1, str_float, cgGLSetParameter1fv> {
162 void operator =(GLfloat v)
163 {
164 data[0] = v;
165 dirty = true;
166 }
167 };
168
169 struct uniform_2f_i : uniform_f_i<2, str_float2, cgGLSetParameter2fv> { };
170
171 struct uniform_3f_i : uniform_f_i<3, str_float3, cgGLSetParameter3fv> {
172 void operator =(const vec3 &v)
173 {
174 data[0] = v.x;
175 data[1] = v.y;
176 data[2] = v.z;
177 dirty = true;
178 }
179 };
180
181 struct uniform_4f_i : uniform_f_i<4, str_float4, cgGLSetParameter4fv> {
182 void operator =(const gl::matrix &m)
183 {
184 memcpy (data, m.data, 16 * sizeof (GLfloat));
185 dirty = true;
186 }
187 };
188
189 struct uniform_matrix_f_i : uniform_f_i<16, str_float4x4, cgGLSetMatrixParameterfc> { };
190
191 typedef ref<uniform_1f_i> uniform_1f;
192 typedef ref<uniform_2f_i> uniform_2f;
193 typedef ref<uniform_3f_i> uniform_3f;
194 typedef ref<uniform_4f_i> uniform_4f;
195 typedef ref<uniform_matrix_f_i> uniform_matrix_f;
196
197 struct stream_i : var_i
198 {
199 char binding[16];
200
201 void build (shader_builder &b);
202 void build_decl (ostringstream &b);
203 stream_i (CGtype type, const char *strtype) : var_i (type, strtype) { }
204 };
205
206 template<int dimension, GLenum gltype, CGtype cgtype, const char *strtype>
207 struct varying_i : stream_i
208 {
209 varying_i (const char *binding)
210 : stream_i (cgtype, strtype)
211 {
212 strcpy (this->binding, binding);
213 }
214
215 void set (GLsizei stride, GLvoid *ptr)
216 {
217 cgGLSetParameterPointer (param, dimension, gltype, stride, ptr);
218 }
219 };
220
221 template<int dimension, const char *strtype>
222 struct varying_f_i : varying_i<dimension, GL_FLOAT, CG_FLOAT, strtype>
223 {
224 varying_f_i (const char *binding) : varying_i<dimension, GL_FLOAT, CG_FLOAT, strtype> (binding) { }
225
226 void set (const gl::vertex_buffer_object &vb, GLint offset)
227 {
228 varying_i<dimension, GL_FLOAT, CG_FLOAT, strtype>::set (gl::format_stride (vb.format), (GLvoid *)(long)offset);
229 }
230 };
231
232 struct varying_1f_i : varying_f_i<1, str_float>
233 {
234 varying_1f_i (const char *binding) : varying_f_i<1, str_float> (binding) { }
235 };
236
237 struct varying_2f_i : varying_f_i<2, str_float2>
238 {
239 varying_2f_i (const char *binding) : varying_f_i<2, str_float2> (binding) { }
240
241 void set_t (const gl::vertex_buffer_object &vb)
242 {
243 set (vb, gl::format_offset_t (vb.format));
244 }
245 };
246
247 struct varying_3f_i : varying_f_i<3, str_float3>
248 {
249 varying_3f_i (const char *binding) : varying_f_i<3, str_float3> (binding) { }
250
251 void set_p (const gl::vertex_buffer_object &vb)
252 {
253 set (vb, gl::format_offset_p (vb.format));
254 }
255
256 void set_n (const gl::vertex_buffer_object &vb)
257 {
258 set (vb, gl::format_offset_n (vb.format));
259 }
260 };
261
262 struct varying_4f_i : varying_f_i<4, str_float4>
263 {
264 varying_4f_i (const char *binding) : varying_f_i<4, str_float4> (binding) { }
265 };
266
267 template<class class_i>
268 struct ref_varying : ref<class_i>
269 {
270 ref_varying (const char *binding)
271 : ref<class_i> (*new class_i (binding))
272 {
273 }
274 };
275
276 typedef ref_varying<varying_1f_i> varying_1f;
277 typedef ref_varying<varying_2f_i> varying_2f;
278 typedef ref_varying<varying_3f_i> varying_3f;
279 typedef ref_varying<varying_4f_i> varying_4f;
280
281 extern struct vin
282 {
283 static varying_3f position_3f;
284 static varying_4f position_4f;
285 static varying_3f normal_3f;
286 static varying_4f normal_4f;
287 static varying_3f color0_3f;
288 static varying_4f color0_4f;
289 static varying_3f color1_3f;
290 static varying_4f color1_4f;
291 static varying_1f psize_1f;
292 static varying_1f attr6_1f, attr7_1f;
293 static varying_2f attr6_2f, attr7_2f;
294 static varying_3f attr6_3f, attr7_3f;
295 static varying_4f attr6_4f, attr7_4f;
296 static varying_2f texcoord0_2f;
297 static varying_4f texcoord0_4f;
298 static varying_2f texcoord1_2f;
299 static varying_4f texcoord1_4f;
300 static varying_2f texcoord2_2f;
301 static varying_4f texcoord2_4f;
302 static varying_2f texcoord3_2f;
303 static varying_4f texcoord3_4f;
304 static varying_2f texcoord4_2f;
305 static varying_4f texcoord4_4f;
306 static varying_2f texcoord5_2f;
307 static varying_4f texcoord5_4f;
308 static varying_2f texcoord6_2f;
309 static varying_4f texcoord6_4f;
310 static varying_2f texcoord7_2f;
311 static varying_4f texcoord7_4f;
312
313 bool is (const var &r);
314 } vin;
315
316 extern struct fin
317 {
318 static varying_4f position_4f;
319 static varying_4f color0_4f;
320 static varying_4f color1_4f;
321 static varying_4f texcoord0_4f;
322 static varying_4f texcoord1_4f;
323 static varying_4f texcoord2_4f;
324 static varying_4f texcoord3_4f;
325 static varying_4f texcoord4_4f;
326 static varying_4f texcoord5_4f;
327 static varying_4f texcoord6_4f;
328 static varying_4f texcoord7_4f;
329
330 bool is (const var &r);
331 } fin;
332
333 extern struct fin &vout;
334
335 extern struct fout
336 {
337 static varying_4f color0_4f;
338 static varying_3f color0_3f;
339 static varying_4f color1_4f;
340 static varying_3f color1_3f;
341 static varying_1f depth_1f;
342
343 bool is (const var &r);
344 } fout;
345
346 // predefined globals
347 extern uniform_matrix_f_i mvp, mv, proj;
348
349 struct temporary_i : var_i
350 {
351 void build (shader_builder &b);
352
353 temporary_i (CGtype cgtype, const char *strtype) : var_i (cgtype, strtype) { };
354 };
355
356 template<CGtype cgtype, const char *strtype>
357 struct temp_ref : ref<temporary_i>
358 {
359 temp_ref ()
360 : ref<temporary_i> (new temporary_i (cgtype, strtype))
361 {
362 }
363 };
364
365 typedef temp_ref<CG_FLOAT, str_float > temp_1f;
366 typedef temp_ref<CG_FLOAT, str_float2 > temp_2f;
367 typedef temp_ref<CG_FLOAT, str_float3 > temp_3f;
368 typedef temp_ref<CG_FLOAT, str_float4 > temp_4f;
369 typedef temp_ref<CG_FLOAT, str_float4x4> temp_matrix_f;
370
371 template<CGtype cgtype>
372 struct sampler_i : var_i
373 {
374 sampler_i () : var_i (cgtype) { }
375 };
376
377 struct fragment_const_string_i : fragment_i
378 {
379 const char *str;
380
381 void build (shader_builder &b);
382
383 fragment_const_string_i (const char *str) : str(str) { }
384 };
385
386 struct fragment_vector_i : fragment_i, vector<fragment>
387 {
388 void build (shader_builder &b);
389
390 template<class fragment_i>
391 fragment_vector_i &operator <<(ref<fragment_i> &f)
392 {
393 push_back (f);
394 return *this;
395 }
396
397 template<class fragment_i>
398 fragment_vector_i &operator <<(fragment_i &f)
399 {
400 push_back (f);
401 return *this;
402 }
403
404 fragment_vector_i &operator <<(const char *s)
405 {
406 push_back (*new fragment_const_string_i (s));
407 return *this;
408 }
409 };
410
411 typedef ref<fragment_vector_i> fragment_vector;
412
413 struct shader_program : fragment_vector_i
414 {
415 bool is_vertex;
416 void print ();
417
418 shader_program (bool is_vertex) : is_vertex(is_vertex) { }
419 };
420
421 struct vertex_program : shader_program
422 {
423 vertex_program () : shader_program (true) { }
424 };
425
426 struct fragment_program : shader_program
427 {
428 fragment_program () : shader_program (false) { }
429 };
430
431 void debdebdebdebug ();//D
432 }
433
434 struct texture_execption
435 {
436 texture_execption (string s) : msg(s) { }
437 string msg;
438 };
439
440 inline int power_of_two (int input)
441 {
442 int value = 1;
443
444 while (value < input)
445 {
446 value <<= 1;
447 }
448 return value;
449 }
450
451
452
453 struct material
454 {
455 virtual void begin () = 0;
456 virtual void end () = 0;
457 virtual ~material ();
458 };
459
460 struct simple_material : material
461 {
462 colour diffuse, specular, emission;
463 GLfloat shininess;
464
465 void begin ();
466 void end ();
467
468 simple_material ()
469 : diffuse(1, 0, 1, 1)
470 , specular(1, 0, 1, 1)
471 , emission(1, 0, 1, 1)
472 , shininess(1.)
473 {
474 }
475 };
476
477 struct texture
478 {
479 SDL_Surface *image;
480 GLuint texture_pxls;
481 GLfloat texcoord[4];
482
483 GLuint load_texture (SDL_Surface *surface, GLfloat *texcoord);
484
485 texture(const char *f)
486 {
487 image = IMG_Load (f);
488
489 if (!image)
490 throw (texture_execption ("Couldn't load " + (string) f + ": " + (string) IMG_GetError ()));
491
492 texture_pxls = load_texture (image, (GLfloat*)&texcoord);
493 if (texture_pxls == 0)
494 throw (texture_execption ("Couldn't make GL Texture, failed to create new RGB SWSurface"));
495 }
496 };
497
498 extern CGcontext cgc;
499
500 struct xshader
501 {
502 CGprogram vsh, fsh;
503 CGparameter lightpos;
504 // mv, mvp
505 CGprofile vsh_profile, fsh_profile;
506 CGparameter g_Texture; // the texture parameter
507
508 void check_cg_error (void)
509 {
510 CGerror err = cgGetError ();
511
512 if (err != CG_NO_ERROR)
513 {
514 printf("CG error: %s\n", cgGetErrorString (err));
515 exit(1);
516 }
517 }
518 xshader (const char *vshp, const char *fshp)
519 {
520 vsh_profile = CG_PROFILE_ARBVP1;
521 //if (cgGLIsProfileSupported (CG_PROFILE_VP30)) vsh_profile = CG_PROFILE_VP30;
522 //if (cgGLIsProfileSupported (CG_PROFILE_VP40)) vsh_profile = CG_PROFILE_VP40;
523 fsh_profile = CG_PROFILE_ARBFP1;
524 //if (cgGLIsProfileSupported (CG_PROFILE_FP30)) fsh_profile = CG_PROFILE_FP30;
525 //if (cgGLIsProfileSupported (CG_PROFILE_FP40)) fsh_profile = CG_PROFILE_FP40;
526
527 vsh = cgCreateProgramFromFile (cgc, CG_SOURCE, vshp, vsh_profile, 0, 0);
528 check_cg_error ();
529 cgGLLoadProgram (vsh);
530 check_cg_error ();
531
532 fsh = cgCreateProgramFromFile (cgc, CG_SOURCE, fshp, fsh_profile, 0, 0);
533 check_cg_error ();
534 cgGLLoadProgram (fsh);
535 check_cg_error ();
536
537 cgGLBindProgram (vsh);
538 cgGLBindProgram (fsh);
539
540 // mv = cgGetNamedParameter (vsh, "WorldProj");
541 // mvp = cgGetNamedParameter (vsh, "WorldViewProj");
542 //lightpos = cgGetNamedParameter (vsh, "LightPos");
543 //cgGLSetParameter4f (lightpos, 10, 10, 0, 1); //camera.p.x, camera.p.y, camera.p.z, 1);
544
545 check_cg_error ();
546 }
547 };
548
549 struct osama_material : material, texture, xshader {
550 osama_material ()
551 : xshader ("vsh.cg", "fsh.cg"), texture ("textures/osama.jpg")
552 {
553 g_Texture = cgGetNamedParameter(fsh, "Texture"); // the texture cg-warper ;)
554 cgGLSetTextureParameter(g_Texture, texture_pxls); // Bind the texture number 999 to g_Texture
555 }
556
557 void begin ();
558 void end ();
559
560 };
561
562 void init_shaders ();
563 #endif
564
565