ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/libgender/material.h
Revision: 1.5
Committed: Thu Oct 21 15:46:38 2004 UTC (21 years, 11 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.4: +268 -0 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     template<class data> friend class ref;
21     int refcnt;
22     void refcnt_inc () { refcnt++; }
23     void refcnt_dec () { if (!--refcnt) delete this; };
24     public:
25     refcounted () : refcnt(0) { }
26     virtual ~refcounted ();
27     };
28    
29     template<class data>
30     class ref
31     {
32     data *p;
33    
34     public:
35     ref (const data &d)
36     {
37     d.refcnt_inc ();
38     p = &v;
39     }
40    
41     ref (const ref<data> &r)
42     {
43     r.refcnt_inc ();
44     p = r.p;
45     }
46    
47     ref &operator =(const data &d)
48     {
49     d.refcnt_inc ();
50     p->refcnt_dec ();
51     p = &r;
52     return *this;
53     }
54    
55     ref &operator =(const ref r)
56     {
57     return *this = *r->p;
58     }
59    
60     ref operator &() { return *this; }
61     const ref operator &() const { return *this; }
62    
63     ref *operator ->() { return p; }
64     const ref *operator ->() const { return p; }
65    
66     bool operator ==(const ref b)
67     {
68     return p == b->p;
69     }
70     };
71    
72     typedef ref<struct var_i> var;
73     typedef ref<struct updateable_i> updateable;
74    
75     struct shader_builder
76     {
77     struct shader_program *prog;
78     vector<updateable> refs; // uniform parameters
79     vector<var> inputs; // varying inputs
80     vector<var> outputs; // varying outputs
81     vector<var> samplers; // textures
82    
83     ostringstream fragment;
84    
85     template<typename type>
86     shader_builder &operator <<(const type &t)
87     {
88     fragment << t;
89     return *this;
90     }
91     };
92    
93     struct fragment
94     {
95     virtual void build (shader_builder &b) = 0;
96     };
97    
98     struct var_i : fragment
99     {
100     static int next_name;
101    
102     CGparameter param;
103     int name;
104    
105     void build (shader_builder &b);
106     void build_decl (shader_builder &b);
107    
108     var_i (CGtype cgtype);
109     ~var_i ();
110     };
111    
112     inline ostringstream &operator <<(ostringstream &os, const var_i &v)
113     {
114     os << ' ' << v.name << ' ';
115     return os;
116     }
117    
118     struct updateable_i : var_i
119     {
120     virtual void update () = 0;
121    
122     updateable_i (CGtype cgtype) : var_i (cgtype) { }
123     };
124    
125     template<int dimension, typename gltype, CGtype cgtype, void (*update)(CGparameter, const gltype *)>
126     struct uniform_i : updateable_i
127     {
128     gltype data[dimension];
129     bool dirty;
130    
131     void update ()
132     {
133     if (dirty)
134     {
135     update (param, data);
136     dirty = false;
137     }
138     }
139    
140     uniform_i () : var_i (cgtype) { }
141     };
142    
143     template<int dimension, void (*update)(CGparameter, const GLfloat *)>
144     struct uniform_f_i : uniform_i<dimension, GLfloat, CG_FLOAT, update>
145     {
146     };
147    
148     struct uniform_1f_i : uniform_f_i<1, cgGLSetParameter1fv> {
149     void operator =(GLfloat v)
150     {
151     data[0] = v;
152     dirty = true;
153     }
154     };
155    
156     struct uniform_2f_i : uniform_f_i<2, cgGLSetParameter2fv> { };
157    
158     struct uniform_3f_i : uniform_f_i<3, cgGLSetParameter3fv> {
159     void operator =(const vec3 &v)
160     {
161     data[0] = v.x;
162     data[1] = v.y;
163     data[2] = v.z;
164     dirty = true;
165     }
166     };
167    
168     struct uniform_4f_i : uniform_f_i<4, cgGLSetParameter4fv> {
169     void operator =(const gl::matrix &m)
170     {
171     memcpy (data, m.data, 16 * sizeof (GLfloat));
172     dirty = true;
173     }
174     };
175    
176     struct uniform_matrix_f_i : uniform_f_i<16, cgGLSetMatrixParameterfc> { };
177    
178     typedef ref<uniform_1f_i> uniform_1f;
179     typedef ref<uniform_2f_i> uniform_2f;
180     typedef ref<uniform_3f_i> uniform_3f;
181     typedef ref<uniform_4f_i> uniform_4f;
182     typedef ref<uniform_matrix_f_i> uniform_matrix_f;
183    
184     template<int dimension, GLenum gltype, CGtype cgtype>
185     struct varying_i : var_i
186     {
187     char binding[16];
188    
189     varying_i (const char *binding);
190    
191     void set (GLsizei stride, GLvoid *ptr)
192     {
193     cgGLSetParameterPointer (param, dimension, gltype, stride, ptr);
194     }
195     };
196    
197     template<int dimension>
198     struct varying_f_i : varying_i<dimension, GL_FLOAT, CG_FLOAT>
199     {
200     varying_f_i (const char *binding) : varying_i<dimension, GL_FLOAT, CG_FLOAT> (binding) { }
201    
202     void set (const gl::vertex_buffer_object &vb, GLint offset)
203     {
204     varying_i<dimension, GL_FLOAT, CG_FLOAT>::set (gl::format_stride (vb.format), (GLvoid *)(long)offset);
205     }
206     };
207    
208     struct varying_1f_i : varying_f_i<1>
209     {
210     varying_1f_i (const char *binding) : varying_f_i<1> (binding) { }
211     };
212    
213     struct varying_2f_i : varying_f_i<2>
214     {
215     varying_2f_i (const char *binding) : varying_f_i<2> (binding) { }
216    
217     void set_t (const gl::vertex_buffer_object &vb)
218     {
219     set (vb, gl::format_offset_t (vb.format));
220     }
221     };
222    
223     struct varying_3f_i : varying_f_i<3>
224     {
225     varying_3f_i (const char *binding) : varying_f_i<3> (binding) { }
226    
227     void set_p (const gl::vertex_buffer_object &vb)
228     {
229     set (vb, gl::format_offset_p (vb.format));
230     }
231    
232     void set_n (const gl::vertex_buffer_object &vb)
233     {
234     set (vb, gl::format_offset_n (vb.format));
235     }
236     };
237    
238     struct varying_4f_i : varying_f_i<4>
239     {
240     varying_4f_i (const char *binding) : varying_f_i<4> (binding) { }
241     };
242    
243     typedef ref<varying_1f_i> varying_1f;
244     typedef ref<varying_2f_i> varying_2f;
245     typedef ref<varying_3f_i> varying_3f;
246     typedef ref<varying_4f_i> varying_4f;
247    
248     extern varying_3f_i position_3f;
249     extern varying_3f_i normal_3f;
250     extern varying_3f_i color0_3f;
251     extern varying_3f_i color1_3f;
252     extern varying_2f_i texcoord0_2f;
253     extern varying_2f_i texcoord1_2f;
254     extern varying_2f_i texcoord2_2f;
255     extern varying_2f_i texcoord3_2f;
256     extern varying_2f_i texcoord4_2f;
257     extern varying_2f_i texcoord5_2f;
258     extern varying_2f_i texcoord6_2f;
259     extern varying_2f_i texcoord7_2f;
260     extern varying_1f_i attr6_1f, attr7_1f;
261     extern varying_2f_i attr6_2f, attr7_2f;
262     extern varying_3f_i attr6_3f, attr7_3f;
263    
264     template<CGtype cgtype>
265     struct sampler_i : var_i
266     {
267     sampler_i () : var_i (cgtype) { }
268     };
269    
270     struct shader_program
271     {
272     };
273     }
274 root 1.3
275     struct texture_execption
276     {
277     texture_execption (string s) : msg(s) { }
278     string msg;
279     };
280    
281     inline int power_of_two (int input)
282     {
283     int value = 1;
284    
285     while (value < input)
286     {
287     value <<= 1;
288     }
289     return value;
290     }
291    
292    
293    
294 root 1.1 struct material
295     {
296 root 1.2 virtual void begin () = 0;
297     virtual void end () = 0;
298 root 1.1 virtual ~material ();
299     };
300    
301     struct simple_material : material
302     {
303     colour diffuse, specular, emission;
304     GLfloat shininess;
305    
306 root 1.2 void begin ();
307     void end ();
308 root 1.1
309     simple_material ()
310     : diffuse(1, 0, 1, 1)
311     , specular(1, 0, 1, 1)
312     , emission(1, 0, 1, 1)
313     , shininess(1.)
314     {
315     }
316     };
317    
318 root 1.3 struct texture
319     {
320     SDL_Surface *image;
321     GLuint texture_pxls;
322     GLfloat texcoord[4];
323    
324     GLuint load_texture (SDL_Surface *surface, GLfloat *texcoord);
325    
326     texture(const char *f)
327     {
328     image = IMG_Load (f);
329    
330     if (!image)
331     throw (texture_execption ("Couldn't load " + (string) f + ": " + (string) IMG_GetError ()));
332    
333     texture_pxls = load_texture (image, (GLfloat*)&texcoord);
334     if (texture_pxls == 0)
335     throw (texture_execption ("Couldn't make GL Texture, failed to create new RGB SWSurface"));
336     }
337     };
338    
339     extern CGcontext cgc;
340    
341     struct shader
342     {
343     CGprogram vsh, fsh;
344     CGparameter lightpos;
345     // mv, mvp
346     CGprofile vsh_profile, fsh_profile;
347 root 1.4 CGparameter g_Texture; // the texture parameter
348 root 1.3
349     void check_cg_error (void)
350     {
351     CGerror err = cgGetError ();
352    
353     if (err != CG_NO_ERROR)
354     {
355     printf("CG error: %s\n", cgGetErrorString (err));
356     exit(1);
357     }
358     }
359     shader (const char *vshp, const char *fshp)
360     {
361     vsh_profile = CG_PROFILE_ARBVP1;
362     //if (cgGLIsProfileSupported (CG_PROFILE_VP30)) vsh_profile = CG_PROFILE_VP30;
363     //if (cgGLIsProfileSupported (CG_PROFILE_VP40)) vsh_profile = CG_PROFILE_VP40;
364     fsh_profile = CG_PROFILE_ARBFP1;
365     //if (cgGLIsProfileSupported (CG_PROFILE_FP30)) fsh_profile = CG_PROFILE_FP30;
366     //if (cgGLIsProfileSupported (CG_PROFILE_FP40)) fsh_profile = CG_PROFILE_FP40;
367    
368     vsh = cgCreateProgramFromFile (cgc, CG_SOURCE, vshp, vsh_profile, 0, 0);
369     check_cg_error ();
370     cgGLLoadProgram (vsh);
371     check_cg_error ();
372    
373     fsh = cgCreateProgramFromFile (cgc, CG_SOURCE, fshp, fsh_profile, 0, 0);
374     check_cg_error ();
375     cgGLLoadProgram (fsh);
376     check_cg_error ();
377    
378 root 1.4 cgGLBindProgram (vsh);
379     cgGLBindProgram (fsh);
380 root 1.3
381     // mv = cgGetNamedParameter (vsh, "WorldProj");
382     // mvp = cgGetNamedParameter (vsh, "WorldViewProj");
383 root 1.4 //lightpos = cgGetNamedParameter (vsh, "LightPos");
384     //cgGLSetParameter4f (lightpos, 10, 10, 0, 1); //camera.p.x, camera.p.y, camera.p.z, 1);
385    
386     check_cg_error ();
387 root 1.3 }
388     };
389    
390     struct osama_material : material, texture, shader {
391     osama_material ()
392 root 1.4 : shader ("vsh.cg", "fsh.cg"), texture ("textures/osama.jpg")
393 root 1.3 {
394     g_Texture = cgGetNamedParameter(fsh, "Texture"); // the texture cg-warper ;)
395 root 1.4 cgGLSetTextureParameter(g_Texture, texture_pxls); // Bind the texture number 999 to g_Texture
396 root 1.3 }
397    
398     void begin ();
399     void end ();
400    
401     };
402    
403     void init_shaders ();
404 root 1.1 #endif
405    
406