ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/libgender/material.h
Revision: 1.9
Committed: Fri Oct 22 00:16:08 2004 UTC (21 years, 11 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.8: +86 -58 lines
Log Message:
*** empty log message ***

File Contents

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