ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/libgender/material.h
Revision: 1.7
Committed: Thu Oct 21 21:30:34 2004 UTC (21 years, 11 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.6: +2 -4 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.6 ref (type &d)
35 root 1.5 {
36     d.refcnt_inc ();
37 root 1.6 p = &d;
38     }
39    
40     ref (const ref &r)
41     {
42     r.p->refcnt_inc ();
43     p = r.p;
44 root 1.5 }
45    
46 root 1.6 template<class type2>
47     ref (const ref<type2> &r)
48 root 1.5 {
49 root 1.6 r.p->refcnt_inc ();
50 root 1.5 p = r.p;
51     }
52    
53 root 1.6 ~ref ()
54 root 1.5 {
55     p->refcnt_dec ();
56     }
57    
58 root 1.6 ref &operator =(type &d)
59 root 1.5 {
60 root 1.6 d.refcnt_inc ();
61     p->refcnt_dec ();
62     p = &d;
63     return *this;
64 root 1.5 }
65    
66 root 1.6 type *operator ->() { return p; }
67     const type *operator ->() const { return p; }
68 root 1.5
69 root 1.6 operator type &() { return *p; }
70     operator const type &() const { return *p; }
71 root 1.5
72 root 1.6 template<class type2>
73     bool operator ==(const ref<type2> b) const
74 root 1.5 {
75 root 1.6 return (void *)p == (void *)b.p;
76 root 1.5 }
77     };
78    
79 root 1.6 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 root 1.5 typedef ref<struct var_i> var;
86 root 1.6 typedef ref<struct uniform_i> uniform;
87 root 1.5
88     struct shader_builder
89     {
90     struct shader_program *prog;
91 root 1.6 vector<uniform> refs; // uniform parameters
92     vector<var> temps; // temporary variables
93     vector<var> streams; // varying inputs & outputs
94 root 1.5 vector<var> samplers; // textures
95    
96 root 1.6 ostringstream source;
97 root 1.5
98     template<typename type>
99     shader_builder &operator <<(const type &t)
100     {
101 root 1.6 source << t;
102 root 1.5 return *this;
103     }
104     };
105    
106 root 1.6 struct fragment_i : refcounted
107 root 1.5 {
108     virtual void build (shader_builder &b) = 0;
109     };
110    
111 root 1.6 typedef ref<fragment_i> fragment;
112    
113     struct var_i : fragment_i
114 root 1.5 {
115     static int next_name;
116    
117     CGparameter param;
118     int name;
119 root 1.6 const char *typestr;
120 root 1.5
121     void build (shader_builder &b);
122 root 1.7 virtual void build_decl (ostringstream &b);
123 root 1.5
124 root 1.6 var_i (CGtype cgtype, const char *typestr);
125 root 1.5 ~var_i ();
126     };
127    
128 root 1.6 struct uniform_i : var_i
129 root 1.5 {
130 root 1.6 bool dirty;
131 root 1.5
132     virtual void update () = 0;
133    
134 root 1.6 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 root 1.5 };
138    
139 root 1.6 template<int dimension, typename gltype, CGtype cgtype, const char *strtype, void (*upd)(CGparameter, const gltype *)>
140     struct uniform2_i : uniform_i
141 root 1.5 {
142     gltype data[dimension];
143    
144     void update ()
145     {
146     if (dirty)
147     {
148 root 1.6 upd (param, data);
149 root 1.5 dirty = false;
150     }
151     }
152    
153 root 1.6 uniform2_i () : uniform_i (cgtype, strtype) { }
154 root 1.5 };
155    
156 root 1.6 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 root 1.5 {
159     };
160    
161 root 1.6 struct uniform_1f_i : uniform_f_i<1, str_float, cgGLSetParameter1fv> {
162 root 1.5 void operator =(GLfloat v)
163     {
164     data[0] = v;
165     dirty = true;
166     }
167     };
168    
169 root 1.6 struct uniform_2f_i : uniform_f_i<2, str_float2, cgGLSetParameter2fv> { };
170 root 1.5
171 root 1.6 struct uniform_3f_i : uniform_f_i<3, str_float3, cgGLSetParameter3fv> {
172 root 1.5 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 root 1.6 struct uniform_4f_i : uniform_f_i<4, str_float4, cgGLSetParameter4fv> {
182 root 1.5 void operator =(const gl::matrix &m)
183     {
184     memcpy (data, m.data, 16 * sizeof (GLfloat));
185     dirty = true;
186     }
187     };
188    
189 root 1.6 struct uniform_matrix_f_i : uniform_f_i<16, str_float4x4, cgGLSetMatrixParameterfc> { };
190 root 1.5
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 root 1.6 struct stream_i : var_i
198 root 1.5 {
199     char binding[16];
200    
201 root 1.6 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 root 1.5
215     void set (GLsizei stride, GLvoid *ptr)
216     {
217     cgGLSetParameterPointer (param, dimension, gltype, stride, ptr);
218     }
219     };
220    
221 root 1.6 template<int dimension, const char *strtype>
222     struct varying_f_i : varying_i<dimension, GL_FLOAT, CG_FLOAT, strtype>
223 root 1.5 {
224 root 1.6 varying_f_i (const char *binding) : varying_i<dimension, GL_FLOAT, CG_FLOAT, strtype> (binding) { }
225 root 1.5
226     void set (const gl::vertex_buffer_object &vb, GLint offset)
227     {
228 root 1.6 varying_i<dimension, GL_FLOAT, CG_FLOAT, strtype>::set (gl::format_stride (vb.format), (GLvoid *)(long)offset);
229 root 1.5 }
230     };
231    
232 root 1.6 struct varying_1f_i : varying_f_i<1, str_float>
233 root 1.5 {
234 root 1.6 varying_1f_i (const char *binding) : varying_f_i<1, str_float> (binding) { }
235 root 1.5 };
236    
237 root 1.6 struct varying_2f_i : varying_f_i<2, str_float2>
238 root 1.5 {
239 root 1.6 varying_2f_i (const char *binding) : varying_f_i<2, str_float2> (binding) { }
240 root 1.5
241     void set_t (const gl::vertex_buffer_object &vb)
242     {
243     set (vb, gl::format_offset_t (vb.format));
244     }
245     };
246    
247 root 1.6 struct varying_3f_i : varying_f_i<3, str_float3>
248 root 1.5 {
249 root 1.6 varying_3f_i (const char *binding) : varying_f_i<3, str_float3> (binding) { }
250 root 1.5
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 root 1.6 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 root 1.5 {
359 root 1.6 temp_ref ()
360 root 1.7 : ref<temporary_i> (*new temporary_i (cgtype, strtype))
361 root 1.6 {
362     }
363 root 1.5 };
364    
365 root 1.6 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 root 1.5
371     template<CGtype cgtype>
372     struct sampler_i : var_i
373     {
374     sampler_i () : var_i (cgtype) { }
375     };
376    
377 root 1.6 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 root 1.5 {
415 root 1.6 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 root 1.5 };
425 root 1.6
426     struct fragment_program : shader_program
427     {
428     fragment_program () : shader_program (false) { }
429     };
430    
431     void debdebdebdebug ();//D
432 root 1.5 }
433 root 1.3
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 root 1.1 struct material
452     {
453 root 1.2 virtual void begin () = 0;
454     virtual void end () = 0;
455 root 1.1 virtual ~material ();
456     };
457    
458     struct simple_material : material
459     {
460     colour diffuse, specular, emission;
461     GLfloat shininess;
462    
463 root 1.2 void begin ();
464     void end ();
465 root 1.1
466     simple_material ()
467     : diffuse(1, 0, 1, 1)
468     , specular(1, 0, 1, 1)
469     , emission(1, 0, 1, 1)
470     , shininess(1.)
471     {
472     }
473     };
474    
475 root 1.3 struct texture
476     {
477     SDL_Surface *image;
478     GLuint texture_pxls;
479     GLfloat texcoord[4];
480    
481     GLuint load_texture (SDL_Surface *surface, GLfloat *texcoord);
482    
483     texture(const char *f)
484     {
485     image = IMG_Load (f);
486    
487     if (!image)
488     throw (texture_execption ("Couldn't load " + (string) f + ": " + (string) IMG_GetError ()));
489    
490     texture_pxls = load_texture (image, (GLfloat*)&texcoord);
491     if (texture_pxls == 0)
492     throw (texture_execption ("Couldn't make GL Texture, failed to create new RGB SWSurface"));
493     }
494     };
495    
496     extern CGcontext cgc;
497    
498 root 1.6 struct xshader
499 root 1.3 {
500     CGprogram vsh, fsh;
501     CGparameter lightpos;
502     // mv, mvp
503     CGprofile vsh_profile, fsh_profile;
504 root 1.4 CGparameter g_Texture; // the texture parameter
505 root 1.3
506     void check_cg_error (void)
507     {
508     CGerror err = cgGetError ();
509    
510     if (err != CG_NO_ERROR)
511     {
512     printf("CG error: %s\n", cgGetErrorString (err));
513     exit(1);
514     }
515     }
516 root 1.6 xshader (const char *vshp, const char *fshp)
517 root 1.3 {
518     vsh_profile = CG_PROFILE_ARBVP1;
519     //if (cgGLIsProfileSupported (CG_PROFILE_VP30)) vsh_profile = CG_PROFILE_VP30;
520     //if (cgGLIsProfileSupported (CG_PROFILE_VP40)) vsh_profile = CG_PROFILE_VP40;
521     fsh_profile = CG_PROFILE_ARBFP1;
522     //if (cgGLIsProfileSupported (CG_PROFILE_FP30)) fsh_profile = CG_PROFILE_FP30;
523     //if (cgGLIsProfileSupported (CG_PROFILE_FP40)) fsh_profile = CG_PROFILE_FP40;
524    
525     vsh = cgCreateProgramFromFile (cgc, CG_SOURCE, vshp, vsh_profile, 0, 0);
526     check_cg_error ();
527     cgGLLoadProgram (vsh);
528     check_cg_error ();
529    
530     fsh = cgCreateProgramFromFile (cgc, CG_SOURCE, fshp, fsh_profile, 0, 0);
531     check_cg_error ();
532     cgGLLoadProgram (fsh);
533     check_cg_error ();
534    
535 root 1.4 cgGLBindProgram (vsh);
536     cgGLBindProgram (fsh);
537 root 1.3
538     // mv = cgGetNamedParameter (vsh, "WorldProj");
539     // mvp = cgGetNamedParameter (vsh, "WorldViewProj");
540 root 1.4 //lightpos = cgGetNamedParameter (vsh, "LightPos");
541     //cgGLSetParameter4f (lightpos, 10, 10, 0, 1); //camera.p.x, camera.p.y, camera.p.z, 1);
542    
543     check_cg_error ();
544 root 1.3 }
545     };
546    
547 root 1.6 struct osama_material : material, texture, xshader {
548 root 1.3 osama_material ()
549 root 1.6 : xshader ("vsh.cg", "fsh.cg"), texture ("textures/osama.jpg")
550 root 1.3 {
551     g_Texture = cgGetNamedParameter(fsh, "Texture"); // the texture cg-warper ;)
552 root 1.4 cgGLSetTextureParameter(g_Texture, texture_pxls); // Bind the texture number 999 to g_Texture
553 root 1.3 }
554    
555     void begin ();
556     void end ();
557    
558     };
559    
560     void init_shaders ();
561 root 1.1 #endif
562    
563