ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/rglmat.c
Revision: 3.7
Committed: Fri Feb 18 00:40:25 2011 UTC (13 years, 2 months ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad5R4, rad5R2, rad4R2P2, rad5R0, rad5R1, rad4R2, rad4R1, rad4R2P1, rad5R3, HEAD
Changes since 3.6: +26 -18 lines
Log Message:
Major code reorg, moving mgflib to common and introducing BSDF material

File Contents

# User Rev Content
1 gwlarson 3.1 #ifndef lint
2 greg 3.7 static const char RCSid[] = "$Id: rglmat.c,v 3.6 2003/11/14 17:22:06 schorsch Exp $";
3 gwlarson 3.1 #endif
4     /*
5     * Routines for Radiance -> OpenGL materials.
6     */
7    
8 greg 3.3 #include "copyright.h"
9 greg 3.2
10 gwlarson 3.1 #include "radogl.h"
11    
12     int domats = 1; /* are we doing materials? */
13    
14 greg 3.7 extern lut_free_t freemtl;
15    
16 gwlarson 3.1 LUTAB mtab = LU_SINIT(free,freemtl);
17    
18    
19 greg 3.2 void
20 greg 3.7 rgl_matclear(void) /* clean up materials */
21 gwlarson 3.1 {
22     lu_done(&mtab);
23     domats = 1;
24     }
25    
26    
27     MATREC *
28 greg 3.7 getmatp( /* find material record for modifier name */
29     char *nam
30     )
31 gwlarson 3.1 {
32     register LUENT *lup;
33    
34     if (nam == NULL)
35     return(NULL);
36     if ((lup = lu_find(&mtab, nam)) == NULL)
37     return(NULL);
38     return((MATREC *)lup->data);
39     }
40    
41    
42 greg 3.2 int
43 greg 3.7 o_default( /* default object is non-material modifier */
44     register OBJREC *o
45     )
46 gwlarson 3.1 {
47     register LUENT *lup;
48     #ifdef DEBUG
49     if (o->otype >= 0 && !ismodifier(o->otype))
50     error(CONSISTENCY, "o_default handed non-modifier");
51     #endif
52     /* find name in lookup table */
53     if ((lup = lu_find(&mtab, o->oname)) == NULL)
54     goto memerr;
55     if (lup->key == NULL) { /* new entry? */
56     lup->key = (char *)malloc(strlen(o->oname)+1);
57     if (lup->key == NULL)
58     goto memerr;
59     strcpy(lup->key, o->oname);
60     } else if (lup->data != NULL)
61 greg 3.5 freemtl(lup->data);
62 gwlarson 3.1 if ((lup->data = o->os) != NULL) /* make material reference */
63     ((MATREC *)lup->data)->nlinks++;
64 greg 3.4 return(0);
65 gwlarson 3.1 memerr:
66     error(SYSTEM, "out of memory in o_default");
67 greg 3.4 return(0);
68     }
69    
70    
71     int
72 greg 3.7 o_unsupported( /* unsupported object primitive */
73     OBJREC *o
74     )
75 greg 3.4 {
76     objerror(o, WARNING, "unsupported type");
77     return(0);
78 gwlarson 3.1 }
79    
80    
81     MATREC *
82 greg 3.7 newmaterial( /* get an entry for a new material */
83     char *nam
84     )
85 gwlarson 3.1 {
86     register LUENT *lup;
87     /* look it up (assign entry) */
88     if ((lup = lu_find(&mtab, nam)) == NULL)
89     goto memerr;
90     if (lup->key == NULL) { /* new entry? */
91     lup->key = (char *)malloc(strlen(nam)+1);
92     if (lup->key == NULL)
93     goto memerr;
94     strcpy(lup->key, nam);
95     } else if (lup->data != NULL)
96 greg 3.5 freemtl(lup->data);
97 gwlarson 3.1 lup->data = (char *)malloc(sizeof(MATREC));
98     if (lup->data == NULL)
99     goto memerr;
100     ((MATREC *)lup->data)->nlinks = 1;
101     return((MATREC *)lup->data);
102     memerr:
103     error(SYSTEM, "out of memory in newmaterial");
104 schorsch 3.6 return NULL; /* pro forma return */
105 gwlarson 3.1 }
106    
107    
108 greg 3.2 void
109 greg 3.7 freemtl(void *p) /* free a material */
110 gwlarson 3.1 {
111 greg 3.5 register MATREC *mp = (MATREC *)p;
112    
113 gwlarson 3.1 if (!--mp->nlinks)
114 greg 3.2 free((void *)mp);
115 gwlarson 3.1 }
116    
117    
118 greg 3.2 int
119 greg 3.7 m_normal( /* compute normal material parameters */
120     register OBJREC *o
121     )
122 gwlarson 3.1 {
123     register MATREC *m;
124     /* check arguments */
125     if (o->oargs.nfargs != (o->otype == MAT_TRANS ? 7 : 5))
126     objerror(o, USER, "bad # of real arguments");
127     /* allocate/insert material */
128     m = newmaterial(o->oname);
129     /* assign parameters */
130     setcolor(m->u.m.ambdiff, o->oargs.farg[0],
131     o->oargs.farg[1], o->oargs.farg[2]);
132     if ((m->type = o->otype) == MAT_METAL)
133     copycolor(m->u.m.specular, m->u.m.ambdiff);
134     else
135     setcolor(m->u.m.specular, 1., 1., 1.);
136     scalecolor(m->u.m.specular, o->oargs.farg[3]);
137     scalecolor(m->u.m.ambdiff, 1.-o->oargs.farg[3]);
138     if (m->type == MAT_TRANS) {
139     scalecolor(m->u.m.specular, 1.-o->oargs.farg[5]);
140     scalecolor(m->u.m.ambdiff, 1.-o->oargs.farg[5]);
141     }
142     if (o->oargs.farg[4] <= FTINY)
143     m->u.m.specexp = MAXSPECEXP;
144     else
145     m->u.m.specexp = 2./(o->oargs.farg[4]*o->oargs.farg[4]);
146     if (m->u.m.specexp > MAXSPECEXP)
147     m->u.m.specexp = MAXSPECEXP;
148 greg 3.4 return(0);
149 gwlarson 3.1 }
150    
151    
152 greg 3.2 int
153 greg 3.7 m_aniso( /* anisotropic material */
154     register OBJREC *o
155     )
156 gwlarson 3.1 {
157     register MATREC *m;
158     /* check arguments */
159     if (o->oargs.nfargs < (o->otype == MAT_TRANS2 ? 8 : 6))
160     objerror(o, USER, "bad # of real arguments");
161     /* allocate/insert material */
162     m = newmaterial(o->oname);
163     /* assign parameters */
164     setcolor(m->u.m.ambdiff, o->oargs.farg[0],
165     o->oargs.farg[1], o->oargs.farg[2]);
166     if ((m->type = o->otype) == MAT_METAL2)
167     copycolor(m->u.m.specular, m->u.m.ambdiff);
168     else
169     setcolor(m->u.m.specular, 1., 1., 1.);
170     scalecolor(m->u.m.specular, o->oargs.farg[3]);
171     scalecolor(m->u.m.ambdiff, 1.-o->oargs.farg[3]);
172     if (m->type == MAT_TRANS2) {
173     scalecolor(m->u.m.specular, 1.-o->oargs.farg[6]);
174     scalecolor(m->u.m.ambdiff, 1.-o->oargs.farg[6]);
175     }
176     if (o->oargs.farg[4]*o->oargs.farg[5] <= FTINY*FTINY)
177     m->u.m.specexp = MAXSPECEXP;
178     else
179     m->u.m.specexp = 2./(o->oargs.farg[4]*o->oargs.farg[5]);
180     if (m->u.m.specexp > MAXSPECEXP)
181     m->u.m.specexp = MAXSPECEXP;
182 greg 3.4 return(0);
183 gwlarson 3.1 }
184    
185    
186 greg 3.2 int
187 greg 3.7 m_glass( /* glass material (hopeless) */
188     OBJREC *o
189     )
190 gwlarson 3.1 {
191     register MATREC *m;
192    
193     m = newmaterial(o->oname);
194     m->type = o->otype;
195     setcolor(m->u.m.ambdiff, 0., 0., 0.);
196     setcolor(m->u.m.specular, .08, .08, .08);
197     m->u.m.specexp = MAXSPECEXP;
198 greg 3.4 return(0);
199 gwlarson 3.1 }
200    
201    
202 greg 3.2 int
203 gwlarson 3.1 m_brdf(o) /* convert functional material */
204     register OBJREC *o;
205     {
206     register MATREC *m;
207     /* check arguments */
208     if (o->oargs.nfargs < (o->otype == MAT_TFUNC ? 6 : 4))
209     objerror(o, USER, "bad # of real arguments");
210     /* allocate/insert material */
211     m = newmaterial(o->oname);
212     /* assign parameters */
213     setcolor(m->u.m.ambdiff, o->oargs.farg[0],
214     o->oargs.farg[1], o->oargs.farg[2]);
215     if ((m->type = o->otype) == MAT_MFUNC)
216     copycolor(m->u.m.specular, m->u.m.ambdiff);
217     else
218     setcolor(m->u.m.specular, 1., 1., 1.);
219     scalecolor(m->u.m.specular, o->oargs.farg[3]);
220     scalecolor(m->u.m.ambdiff, 1.-o->oargs.farg[3]);
221     if (m->type == MAT_TFUNC) {
222     scalecolor(m->u.m.specular, 1.-o->oargs.farg[4]);
223     scalecolor(m->u.m.ambdiff, 1.-o->oargs.farg[4]);
224     }
225     m->u.m.specexp = UNKSPECEXP;
226 greg 3.4 return(0);
227 gwlarson 3.1 }
228    
229    
230 greg 3.2 int
231 gwlarson 3.1 m_brdf2(o) /* convert advanced functional material */
232     register OBJREC *o;
233     {
234     register MATREC *m;
235    
236     if (o->oargs.nfargs < 9)
237     objerror(o, USER, "bad # of real arguments");
238     m = newmaterial(o->oname);
239     m->type = o->otype;
240     /* assign average diffuse front+back */
241     setcolor(m->u.m.ambdiff, (o->oargs.farg[0]+o->oargs.farg[3])*.5,
242     (o->oargs.farg[1]+o->oargs.farg[4])*.5,
243     (o->oargs.farg[2]+o->oargs.farg[5])*.5);
244     /* guess the rest */
245     setcolor(m->u.m.specular, .1, .1, .1);
246     m->u.m.specexp = UNKSPECEXP;
247 greg 3.4 return(0);
248 gwlarson 3.1 }
249    
250    
251 greg 3.2 int
252 gwlarson 3.1 m_light(o) /* convert light type */
253     register OBJREC *o;
254     {
255     FVECT v;
256     register MATREC *m;
257    
258     if (o->oargs.nfargs < (o->otype == MAT_SPOT ? 7 : 3))
259     objerror(o, USER, "bad # of real arguments");
260     m = newmaterial(o->oname);
261     setcolor(m->u.l.emission, o->oargs.farg[0],
262     o->oargs.farg[1], o->oargs.farg[2]);
263     if ((m->type = o->otype) == MAT_SPOT) {
264     if ((m->u.l.spotang = o->oargs.farg[3]/2.) > 90.)
265     m->u.l.spotang = 180.;
266     v[0] = o->oargs.farg[4];
267     v[1] = o->oargs.farg[5];
268     v[2] = o->oargs.farg[6];
269     if (normalize(v) == 0.)
270     objerror(o, USER, "illegal direction");
271     VCOPY(m->u.l.spotdir, v);
272     } else {
273     m->u.l.spotang = 180.;
274     m->u.l.spotdir[0] = m->u.l.spotdir[1] = 0.;
275     m->u.l.spotdir[2] = -1.;
276     }
277 greg 3.4 return(0);
278 gwlarson 3.1 }
279    
280    
281 greg 3.2 int
282 gwlarson 3.1 m_mirror(o) /* convert mirror type */
283     register OBJREC *o;
284     {
285     register MATREC *m;
286    
287     if (o->oargs.nfargs != 3)
288     objerror(o, USER, "bad # real arguments");
289     m = newmaterial(o->oname);
290     m->type = o->otype;
291     setcolor(m->u.m.ambdiff, 0., 0., 0.);
292     setcolor(m->u.m.specular, o->oargs.farg[0],
293     o->oargs.farg[1], o->oargs.farg[2]);
294     m->u.m.specexp = MAXSPECEXP;
295 greg 3.4 return(0);
296 gwlarson 3.1 }
297    
298    
299 greg 3.2 int
300 gwlarson 3.1 m_prism(o) /* convert prism type */
301     register OBJREC *o;
302     {
303     register MATREC *m;
304     /* can't really deal with this type */
305     m = newmaterial(o->oname);
306     m->type = o->otype;
307     setcolor(m->u.m.ambdiff, 0.2, 0.2, 0.2);
308     setcolor(m->u.m.specular, 0.1, 0.1, 0.1);
309     m->u.m.specexp = UNKSPECEXP;
310 greg 3.4 return(0);
311 gwlarson 3.1 }