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, 1 month 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

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: rglmat.c,v 3.6 2003/11/14 17:22:06 schorsch Exp $";
3 #endif
4 /*
5 * Routines for Radiance -> OpenGL materials.
6 */
7
8 #include "copyright.h"
9
10 #include "radogl.h"
11
12 int domats = 1; /* are we doing materials? */
13
14 extern lut_free_t freemtl;
15
16 LUTAB mtab = LU_SINIT(free,freemtl);
17
18
19 void
20 rgl_matclear(void) /* clean up materials */
21 {
22 lu_done(&mtab);
23 domats = 1;
24 }
25
26
27 MATREC *
28 getmatp( /* find material record for modifier name */
29 char *nam
30 )
31 {
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 int
43 o_default( /* default object is non-material modifier */
44 register OBJREC *o
45 )
46 {
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 freemtl(lup->data);
62 if ((lup->data = o->os) != NULL) /* make material reference */
63 ((MATREC *)lup->data)->nlinks++;
64 return(0);
65 memerr:
66 error(SYSTEM, "out of memory in o_default");
67 return(0);
68 }
69
70
71 int
72 o_unsupported( /* unsupported object primitive */
73 OBJREC *o
74 )
75 {
76 objerror(o, WARNING, "unsupported type");
77 return(0);
78 }
79
80
81 MATREC *
82 newmaterial( /* get an entry for a new material */
83 char *nam
84 )
85 {
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 freemtl(lup->data);
97 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 return NULL; /* pro forma return */
105 }
106
107
108 void
109 freemtl(void *p) /* free a material */
110 {
111 register MATREC *mp = (MATREC *)p;
112
113 if (!--mp->nlinks)
114 free((void *)mp);
115 }
116
117
118 int
119 m_normal( /* compute normal material parameters */
120 register OBJREC *o
121 )
122 {
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 return(0);
149 }
150
151
152 int
153 m_aniso( /* anisotropic material */
154 register OBJREC *o
155 )
156 {
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 return(0);
183 }
184
185
186 int
187 m_glass( /* glass material (hopeless) */
188 OBJREC *o
189 )
190 {
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 return(0);
199 }
200
201
202 int
203 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 return(0);
227 }
228
229
230 int
231 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 return(0);
248 }
249
250
251 int
252 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 return(0);
278 }
279
280
281 int
282 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 return(0);
296 }
297
298
299 int
300 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 return(0);
311 }