ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/libgender/material.h
Revision: 1.8
Committed: Thu Oct 21 22:28:42 2004 UTC (19 years, 7 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.7: +77 -29 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.6 extern const char str_float [];
86     extern const char str_float2 [];
87     extern const char str_float3 [];
88     extern const char str_float4 [];
89     extern const char str_float4x4 [];
90    
91 root 1.8 extern const char str_sampler1d [];
92     extern const char str_sampler2d [];
93     extern const char str_sampler3d [];
94     extern const char str_samplerCUBE [];
95     extern const char str_samplerRECT [];
96    
97 root 1.5 typedef ref<struct var_i> var;
98 root 1.6 typedef ref<struct uniform_i> uniform;
99 root 1.5
100     struct shader_builder
101     {
102     struct shader_program *prog;
103 root 1.6 vector<uniform> refs; // uniform parameters
104     vector<var> temps; // temporary variables
105     vector<var> streams; // varying inputs & outputs
106 root 1.5
107 root 1.6 ostringstream source;
108 root 1.5
109     template<typename type>
110     shader_builder &operator <<(const type &t)
111     {
112 root 1.6 source << t;
113 root 1.5 return *this;
114     }
115     };
116    
117 root 1.6 struct fragment_i : refcounted
118 root 1.5 {
119     virtual void build (shader_builder &b) = 0;
120     };
121    
122 root 1.6 typedef ref<fragment_i> fragment;
123    
124     struct var_i : fragment_i
125 root 1.5 {
126     static int next_name;
127    
128     CGparameter param;
129     int name;
130 root 1.6 const char *typestr;
131 root 1.5
132     void build (shader_builder &b);
133 root 1.7 virtual void build_decl (ostringstream &b);
134 root 1.5
135 root 1.6 var_i (CGtype cgtype, const char *typestr);
136 root 1.5 ~var_i ();
137     };
138    
139 root 1.6 struct uniform_i : var_i
140 root 1.5 {
141 root 1.6 bool dirty;
142 root 1.5
143     virtual void update () = 0;
144    
145 root 1.6 void build (shader_builder &b);
146     void build_decl (ostringstream &b);
147     uniform_i (CGtype cgtype, const char *strtype) : var_i (cgtype, strtype), dirty (true) { }
148 root 1.5 };
149    
150 root 1.6 template<int dimension, typename gltype, CGtype cgtype, const char *strtype, void (*upd)(CGparameter, const gltype *)>
151     struct uniform2_i : uniform_i
152 root 1.5 {
153     gltype data[dimension];
154    
155     void update ()
156     {
157     if (dirty)
158     {
159 root 1.6 upd (param, data);
160 root 1.5 dirty = false;
161     }
162     }
163    
164 root 1.6 uniform2_i () : uniform_i (cgtype, strtype) { }
165 root 1.5 };
166    
167 root 1.6 template<int dimension, const char *strtype, void (*update)(CGparameter, const GLfloat *)>
168     struct uniform_f_i : uniform2_i<dimension, GLfloat, CG_FLOAT, strtype, update>
169 root 1.5 {
170     };
171    
172 root 1.6 struct uniform_1f_i : uniform_f_i<1, str_float, cgGLSetParameter1fv> {
173 root 1.5 void operator =(GLfloat v)
174     {
175     data[0] = v;
176     dirty = true;
177     }
178     };
179    
180 root 1.6 struct uniform_2f_i : uniform_f_i<2, str_float2, cgGLSetParameter2fv> { };
181 root 1.5
182 root 1.6 struct uniform_3f_i : uniform_f_i<3, str_float3, cgGLSetParameter3fv> {
183 root 1.5 void operator =(const vec3 &v)
184     {
185     data[0] = v.x;
186     data[1] = v.y;
187     data[2] = v.z;
188     dirty = true;
189     }
190     };
191    
192 root 1.6 struct uniform_4f_i : uniform_f_i<4, str_float4, cgGLSetParameter4fv> {
193 root 1.5 void operator =(const gl::matrix &m)
194     {
195     memcpy (data, m.data, 16 * sizeof (GLfloat));
196     dirty = true;
197     }
198     };
199    
200 root 1.6 struct uniform_matrix_f_i : uniform_f_i<16, str_float4x4, cgGLSetMatrixParameterfc> { };
201 root 1.5
202     typedef ref<uniform_1f_i> uniform_1f;
203     typedef ref<uniform_2f_i> uniform_2f;
204     typedef ref<uniform_3f_i> uniform_3f;
205     typedef ref<uniform_4f_i> uniform_4f;
206     typedef ref<uniform_matrix_f_i> uniform_matrix_f;
207    
208 root 1.6 struct stream_i : var_i
209 root 1.5 {
210     char binding[16];
211    
212 root 1.6 void build (shader_builder &b);
213     void build_decl (ostringstream &b);
214     stream_i (CGtype type, const char *strtype) : var_i (type, strtype) { }
215     };
216    
217     template<int dimension, GLenum gltype, CGtype cgtype, const char *strtype>
218     struct varying_i : stream_i
219     {
220     varying_i (const char *binding)
221     : stream_i (cgtype, strtype)
222     {
223     strcpy (this->binding, binding);
224     }
225 root 1.5
226     void set (GLsizei stride, GLvoid *ptr)
227     {
228     cgGLSetParameterPointer (param, dimension, gltype, stride, ptr);
229     }
230     };
231    
232 root 1.6 template<int dimension, const char *strtype>
233     struct varying_f_i : varying_i<dimension, GL_FLOAT, CG_FLOAT, strtype>
234 root 1.5 {
235 root 1.6 varying_f_i (const char *binding) : varying_i<dimension, GL_FLOAT, CG_FLOAT, strtype> (binding) { }
236 root 1.5
237     void set (const gl::vertex_buffer_object &vb, GLint offset)
238     {
239 root 1.6 varying_i<dimension, GL_FLOAT, CG_FLOAT, strtype>::set (gl::format_stride (vb.format), (GLvoid *)(long)offset);
240 root 1.5 }
241     };
242    
243 root 1.6 struct varying_1f_i : varying_f_i<1, str_float>
244 root 1.5 {
245 root 1.6 varying_1f_i (const char *binding) : varying_f_i<1, str_float> (binding) { }
246 root 1.5 };
247    
248 root 1.6 struct varying_2f_i : varying_f_i<2, str_float2>
249 root 1.5 {
250 root 1.6 varying_2f_i (const char *binding) : varying_f_i<2, str_float2> (binding) { }
251 root 1.5
252     void set_t (const gl::vertex_buffer_object &vb)
253     {
254     set (vb, gl::format_offset_t (vb.format));
255     }
256     };
257    
258 root 1.6 struct varying_3f_i : varying_f_i<3, str_float3>
259 root 1.5 {
260 root 1.6 varying_3f_i (const char *binding) : varying_f_i<3, str_float3> (binding) { }
261 root 1.5
262     void set_p (const gl::vertex_buffer_object &vb)
263     {
264     set (vb, gl::format_offset_p (vb.format));
265     }
266    
267     void set_n (const gl::vertex_buffer_object &vb)
268     {
269     set (vb, gl::format_offset_n (vb.format));
270     }
271     };
272    
273 root 1.6 struct varying_4f_i : varying_f_i<4, str_float4>
274     {
275     varying_4f_i (const char *binding) : varying_f_i<4, str_float4> (binding) { }
276     };
277    
278     template<class class_i>
279     struct ref_varying : ref<class_i>
280     {
281     ref_varying (const char *binding)
282     : ref<class_i> (*new class_i (binding))
283     {
284     }
285     };
286    
287     typedef ref_varying<varying_1f_i> varying_1f;
288     typedef ref_varying<varying_2f_i> varying_2f;
289     typedef ref_varying<varying_3f_i> varying_3f;
290     typedef ref_varying<varying_4f_i> varying_4f;
291    
292     extern struct vin
293     {
294     static varying_3f position_3f;
295     static varying_4f position_4f;
296     static varying_3f normal_3f;
297     static varying_4f normal_4f;
298     static varying_3f color0_3f;
299     static varying_4f color0_4f;
300     static varying_3f color1_3f;
301     static varying_4f color1_4f;
302     static varying_1f psize_1f;
303     static varying_1f attr6_1f, attr7_1f;
304     static varying_2f attr6_2f, attr7_2f;
305     static varying_3f attr6_3f, attr7_3f;
306     static varying_4f attr6_4f, attr7_4f;
307 root 1.8 static varying_1f texcoord_1f[8];
308     static varying_2f texcoord_2f[8];
309     static varying_3f texcoord_3f[8];
310     static varying_4f texcoord_4f[8];
311 root 1.6
312     bool is (const var &r);
313     } vin;
314    
315     extern struct fin
316     {
317     static varying_4f position_4f;
318     static varying_4f color0_4f;
319     static varying_4f color1_4f;
320 root 1.8 static varying_4f texcoord_4f[8];
321 root 1.6
322     bool is (const var &r);
323     } fin;
324    
325     extern struct fin &vout;
326    
327     extern struct fout
328     {
329     static varying_4f color0_4f;
330     static varying_3f color0_3f;
331     static varying_4f color1_4f;
332     static varying_3f color1_3f;
333     static varying_1f depth_1f;
334    
335     bool is (const var &r);
336     } fout;
337    
338     // predefined globals
339 root 1.8 extern uniform_matrix_f mvp, mv, proj;
340 root 1.6
341     struct temporary_i : var_i
342     {
343     void build (shader_builder &b);
344    
345     temporary_i (CGtype cgtype, const char *strtype) : var_i (cgtype, strtype) { };
346     };
347    
348     template<CGtype cgtype, const char *strtype>
349     struct temp_ref : ref<temporary_i>
350 root 1.5 {
351 root 1.6 temp_ref ()
352 root 1.7 : ref<temporary_i> (*new temporary_i (cgtype, strtype))
353 root 1.6 {
354     }
355 root 1.5 };
356    
357 root 1.6 typedef temp_ref<CG_FLOAT, str_float > temp_1f;
358     typedef temp_ref<CG_FLOAT, str_float2 > temp_2f;
359     typedef temp_ref<CG_FLOAT, str_float3 > temp_3f;
360     typedef temp_ref<CG_FLOAT, str_float4 > temp_4f;
361     typedef temp_ref<CG_FLOAT, str_float4x4> temp_matrix_f;
362 root 1.5
363 root 1.8 template<CGtype cgtype, const char *strtype>
364     struct sampler_i : uniform_i
365     {
366     GLuint texture;
367    
368     void update ()
369     {
370     if (dirty)
371     {
372     cgGLSetTextureParameter (param, texture);
373     dirty = false;
374     }
375     }
376    
377     void begin ()
378     {
379     cgGLEnableTextureParameter (texture);
380     }
381    
382     sampler_i (GLuint texturename) : uniform_i (cgtype, strtype), texture (texturename) { }
383     };
384    
385     struct sampler1d_i : sampler_i<CG_SAMPLER1D, str_sampler1d>
386     {
387     sampler1d_i (GLuint texturename) : sampler_i<CG_SAMPLER1D, str_sampler1d> (texturename) { }
388     };
389    
390     struct sampler2d_i : sampler_i<CG_SAMPLER2D, str_sampler2d>
391     {
392     sampler2d_i (GLuint texturename) : sampler_i<CG_SAMPLER2D, str_sampler2d> (texturename) { }
393     };
394    
395     struct sampler3d_i : sampler_i<CG_SAMPLER3D, str_sampler3d>
396     {
397     sampler3d_i (GLuint texturename) : sampler_i<CG_SAMPLER3D, str_sampler3d> (texturename) { }
398     };
399    
400     struct samplerCUBE_i : sampler_i<CG_SAMPLERCUBE, str_samplerCUBE>
401 root 1.5 {
402 root 1.8 samplerCUBE_i (GLuint texturename) : sampler_i<CG_SAMPLERCUBE, str_samplerCUBE> (texturename) { }
403 root 1.5 };
404 root 1.8
405     struct samplerRECT_i : sampler_i<CG_SAMPLERRECT, str_samplerRECT>
406     {
407     samplerRECT_i (GLuint texturename) : sampler_i<CG_SAMPLERRECT, str_samplerRECT> (texturename) { }
408     };
409    
410     template<class sampler_i>
411     struct sampler_ref : ref<sampler_i>
412     {
413     sampler_ref (GLuint texturename)
414     : ref<sampler_i> (*new sampler_i (texturename))
415     {
416     }
417     };
418    
419     typedef sampler_ref<sampler1d_i> sampler1d;
420     typedef sampler_ref<sampler2d_i> sampler2d;
421     typedef sampler_ref<sampler3d_i> sampler3d;
422     typedef sampler_ref<samplerCUBE_i> samplerCUBE;
423     typedef sampler_ref<samplerRECT_i> samplerRECT;
424 root 1.5
425 root 1.6 struct fragment_const_string_i : fragment_i
426     {
427     const char *str;
428    
429     void build (shader_builder &b);
430    
431     fragment_const_string_i (const char *str) : str(str) { }
432     };
433    
434     struct fragment_vector_i : fragment_i, vector<fragment>
435     {
436     void build (shader_builder &b);
437    
438     template<class fragment_i>
439     fragment_vector_i &operator <<(ref<fragment_i> &f)
440     {
441     push_back (f);
442     return *this;
443     }
444    
445     template<class fragment_i>
446     fragment_vector_i &operator <<(fragment_i &f)
447     {
448     push_back (f);
449     return *this;
450     }
451    
452     fragment_vector_i &operator <<(const char *s)
453     {
454     push_back (*new fragment_const_string_i (s));
455     return *this;
456     }
457     };
458    
459     typedef ref<fragment_vector_i> fragment_vector;
460    
461     struct shader_program : fragment_vector_i
462 root 1.5 {
463 root 1.6 bool is_vertex;
464     void print ();
465    
466     shader_program (bool is_vertex) : is_vertex(is_vertex) { }
467     };
468    
469     struct vertex_program : shader_program
470     {
471     vertex_program () : shader_program (true) { }
472 root 1.5 };
473 root 1.6
474     struct fragment_program : shader_program
475     {
476     fragment_program () : shader_program (false) { }
477     };
478    
479     void debdebdebdebug ();//D
480 root 1.5 }
481 root 1.3
482     struct texture_execption
483     {
484     texture_execption (string s) : msg(s) { }
485     string msg;
486     };
487    
488     inline int power_of_two (int input)
489     {
490     int value = 1;
491    
492     while (value < input)
493     {
494     value <<= 1;
495     }
496     return value;
497     }
498    
499 root 1.1 struct material
500     {
501 root 1.2 virtual void begin () = 0;
502     virtual void end () = 0;
503 root 1.1 virtual ~material ();
504     };
505    
506     struct simple_material : material
507     {
508     colour diffuse, specular, emission;
509     GLfloat shininess;
510    
511 root 1.2 void begin ();
512     void end ();
513 root 1.1
514     simple_material ()
515     : diffuse(1, 0, 1, 1)
516     , specular(1, 0, 1, 1)
517     , emission(1, 0, 1, 1)
518     , shininess(1.)
519     {
520     }
521     };
522    
523 root 1.3 struct texture
524     {
525     SDL_Surface *image;
526     GLuint texture_pxls;
527     GLfloat texcoord[4];
528    
529     GLuint load_texture (SDL_Surface *surface, GLfloat *texcoord);
530    
531     texture(const char *f)
532     {
533     image = IMG_Load (f);
534    
535     if (!image)
536     throw (texture_execption ("Couldn't load " + (string) f + ": " + (string) IMG_GetError ()));
537    
538     texture_pxls = load_texture (image, (GLfloat*)&texcoord);
539     if (texture_pxls == 0)
540     throw (texture_execption ("Couldn't make GL Texture, failed to create new RGB SWSurface"));
541     }
542     };
543    
544     extern CGcontext cgc;
545    
546 root 1.6 struct xshader
547 root 1.3 {
548     CGprogram vsh, fsh;
549     CGparameter lightpos;
550     // mv, mvp
551     CGprofile vsh_profile, fsh_profile;
552 root 1.4 CGparameter g_Texture; // the texture parameter
553 root 1.3
554     void check_cg_error (void)
555     {
556     CGerror err = cgGetError ();
557    
558     if (err != CG_NO_ERROR)
559     {
560     printf("CG error: %s\n", cgGetErrorString (err));
561     exit(1);
562     }
563     }
564 root 1.6 xshader (const char *vshp, const char *fshp)
565 root 1.3 {
566     vsh_profile = CG_PROFILE_ARBVP1;
567     //if (cgGLIsProfileSupported (CG_PROFILE_VP30)) vsh_profile = CG_PROFILE_VP30;
568     //if (cgGLIsProfileSupported (CG_PROFILE_VP40)) vsh_profile = CG_PROFILE_VP40;
569     fsh_profile = CG_PROFILE_ARBFP1;
570     //if (cgGLIsProfileSupported (CG_PROFILE_FP30)) fsh_profile = CG_PROFILE_FP30;
571     //if (cgGLIsProfileSupported (CG_PROFILE_FP40)) fsh_profile = CG_PROFILE_FP40;
572    
573     vsh = cgCreateProgramFromFile (cgc, CG_SOURCE, vshp, vsh_profile, 0, 0);
574     check_cg_error ();
575     cgGLLoadProgram (vsh);
576     check_cg_error ();
577    
578     fsh = cgCreateProgramFromFile (cgc, CG_SOURCE, fshp, fsh_profile, 0, 0);
579     check_cg_error ();
580     cgGLLoadProgram (fsh);
581     check_cg_error ();
582    
583 root 1.4 cgGLBindProgram (vsh);
584     cgGLBindProgram (fsh);
585 root 1.3
586     // mv = cgGetNamedParameter (vsh, "WorldProj");
587     // mvp = cgGetNamedParameter (vsh, "WorldViewProj");
588 root 1.4 //lightpos = cgGetNamedParameter (vsh, "LightPos");
589     //cgGLSetParameter4f (lightpos, 10, 10, 0, 1); //camera.p.x, camera.p.y, camera.p.z, 1);
590    
591     check_cg_error ();
592 root 1.3 }
593     };
594    
595 root 1.6 struct osama_material : material, texture, xshader {
596 root 1.3 osama_material ()
597 root 1.6 : xshader ("vsh.cg", "fsh.cg"), texture ("textures/osama.jpg")
598 root 1.3 {
599     g_Texture = cgGetNamedParameter(fsh, "Texture"); // the texture cg-warper ;)
600 root 1.4 cgGLSetTextureParameter(g_Texture, texture_pxls); // Bind the texture number 999 to g_Texture
601 root 1.3 }
602    
603     void begin ();
604     void end ();
605    
606     };
607    
608     void init_shaders ();
609 root 1.1 #endif
610    
611