ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/rglmat.c
Revision: 3.2
Committed: Sat Feb 22 02:07:22 2003 UTC (21 years, 2 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 3.1: +72 -9 lines
Log Message:
Changes and check-in for 3.5 release
Includes new source files and modifications not recorded for many years
See ray/doc/notes/ReleaseNotes for notes between 3.1 and 3.5 release

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id$";
3 #endif
4 /*
5 * Routines for Radiance -> OpenGL materials.
6 */
7
8 /* ====================================================================
9 * The Radiance Software License, Version 1.0
10 *
11 * Copyright (c) 1990 - 2002 The Regents of the University of California,
12 * through Lawrence Berkeley National Laboratory. All rights reserved.
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions
16 * are met:
17 *
18 * 1. Redistributions of source code must retain the above copyright
19 * notice, this list of conditions and the following disclaimer.
20 *
21 * 2. Redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in
23 * the documentation and/or other materials provided with the
24 * distribution.
25 *
26 * 3. The end-user documentation included with the redistribution,
27 * if any, must include the following acknowledgment:
28 * "This product includes Radiance software
29 * (http://radsite.lbl.gov/)
30 * developed by the Lawrence Berkeley National Laboratory
31 * (http://www.lbl.gov/)."
32 * Alternately, this acknowledgment may appear in the software itself,
33 * if and wherever such third-party acknowledgments normally appear.
34 *
35 * 4. The names "Radiance," "Lawrence Berkeley National Laboratory"
36 * and "The Regents of the University of California" must
37 * not be used to endorse or promote products derived from this
38 * software without prior written permission. For written
39 * permission, please contact [email protected].
40 *
41 * 5. Products derived from this software may not be called "Radiance",
42 * nor may "Radiance" appear in their name, without prior written
43 * permission of Lawrence Berkeley National Laboratory.
44 *
45 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
46 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
47 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
48 * DISCLAIMED. IN NO EVENT SHALL Lawrence Berkeley National Laboratory OR
49 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
50 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
51 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
52 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
53 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
54 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
55 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
56 * SUCH DAMAGE.
57 * ====================================================================
58 *
59 * This software consists of voluntary contributions made by many
60 * individuals on behalf of Lawrence Berkeley National Laboratory. For more
61 * information on Lawrence Berkeley National Laboratory, please see
62 * <http://www.lbl.gov/>.
63 */
64
65 #include "radogl.h"
66
67 int domats = 1; /* are we doing materials? */
68
69 LUTAB mtab = LU_SINIT(free,freemtl);
70
71
72 void
73 rgl_matclear() /* clean up materials */
74 {
75 lu_done(&mtab);
76 domats = 1;
77 }
78
79
80 MATREC *
81 getmatp(nam) /* find material record for modifier name */
82 char *nam;
83 {
84 register LUENT *lup;
85
86 if (nam == NULL)
87 return(NULL);
88 if ((lup = lu_find(&mtab, nam)) == NULL)
89 return(NULL);
90 return((MATREC *)lup->data);
91 }
92
93
94 int
95 o_default(o) /* default object is non-material modifier */
96 register OBJREC *o;
97 {
98 register LUENT *lup;
99 #ifdef DEBUG
100 if (o->otype >= 0 && !ismodifier(o->otype))
101 error(CONSISTENCY, "o_default handed non-modifier");
102 #endif
103 /* find name in lookup table */
104 if ((lup = lu_find(&mtab, o->oname)) == NULL)
105 goto memerr;
106 if (lup->key == NULL) { /* new entry? */
107 lup->key = (char *)malloc(strlen(o->oname)+1);
108 if (lup->key == NULL)
109 goto memerr;
110 strcpy(lup->key, o->oname);
111 } else if (lup->data != NULL)
112 freemtl((MATREC *)lup->data);
113 if ((lup->data = o->os) != NULL) /* make material reference */
114 ((MATREC *)lup->data)->nlinks++;
115 return;
116 memerr:
117 error(SYSTEM, "out of memory in o_default");
118 }
119
120
121 MATREC *
122 newmaterial(nam) /* get an entry for a new material */
123 char *nam;
124 {
125 register LUENT *lup;
126 /* look it up (assign entry) */
127 if ((lup = lu_find(&mtab, nam)) == NULL)
128 goto memerr;
129 if (lup->key == NULL) { /* new entry? */
130 lup->key = (char *)malloc(strlen(nam)+1);
131 if (lup->key == NULL)
132 goto memerr;
133 strcpy(lup->key, nam);
134 } else if (lup->data != NULL)
135 freemtl((MATREC *)lup->data);
136 lup->data = (char *)malloc(sizeof(MATREC));
137 if (lup->data == NULL)
138 goto memerr;
139 ((MATREC *)lup->data)->nlinks = 1;
140 return((MATREC *)lup->data);
141 memerr:
142 error(SYSTEM, "out of memory in newmaterial");
143 }
144
145
146 void
147 freemtl(mp) /* free a material */
148 register MATREC *mp;
149 {
150 if (!--mp->nlinks)
151 free((void *)mp);
152 }
153
154
155 int
156 m_normal(o) /* compute normal material parameters */
157 register OBJREC *o;
158 {
159 register MATREC *m;
160 /* check arguments */
161 if (o->oargs.nfargs != (o->otype == MAT_TRANS ? 7 : 5))
162 objerror(o, USER, "bad # of real arguments");
163 /* allocate/insert material */
164 m = newmaterial(o->oname);
165 /* assign parameters */
166 setcolor(m->u.m.ambdiff, o->oargs.farg[0],
167 o->oargs.farg[1], o->oargs.farg[2]);
168 if ((m->type = o->otype) == MAT_METAL)
169 copycolor(m->u.m.specular, m->u.m.ambdiff);
170 else
171 setcolor(m->u.m.specular, 1., 1., 1.);
172 scalecolor(m->u.m.specular, o->oargs.farg[3]);
173 scalecolor(m->u.m.ambdiff, 1.-o->oargs.farg[3]);
174 if (m->type == MAT_TRANS) {
175 scalecolor(m->u.m.specular, 1.-o->oargs.farg[5]);
176 scalecolor(m->u.m.ambdiff, 1.-o->oargs.farg[5]);
177 }
178 if (o->oargs.farg[4] <= FTINY)
179 m->u.m.specexp = MAXSPECEXP;
180 else
181 m->u.m.specexp = 2./(o->oargs.farg[4]*o->oargs.farg[4]);
182 if (m->u.m.specexp > MAXSPECEXP)
183 m->u.m.specexp = MAXSPECEXP;
184 }
185
186
187 int
188 m_aniso(o) /* anisotropic material */
189 register OBJREC *o;
190 {
191 register MATREC *m;
192 /* check arguments */
193 if (o->oargs.nfargs < (o->otype == MAT_TRANS2 ? 8 : 6))
194 objerror(o, USER, "bad # of real arguments");
195 /* allocate/insert material */
196 m = newmaterial(o->oname);
197 /* assign parameters */
198 setcolor(m->u.m.ambdiff, o->oargs.farg[0],
199 o->oargs.farg[1], o->oargs.farg[2]);
200 if ((m->type = o->otype) == MAT_METAL2)
201 copycolor(m->u.m.specular, m->u.m.ambdiff);
202 else
203 setcolor(m->u.m.specular, 1., 1., 1.);
204 scalecolor(m->u.m.specular, o->oargs.farg[3]);
205 scalecolor(m->u.m.ambdiff, 1.-o->oargs.farg[3]);
206 if (m->type == MAT_TRANS2) {
207 scalecolor(m->u.m.specular, 1.-o->oargs.farg[6]);
208 scalecolor(m->u.m.ambdiff, 1.-o->oargs.farg[6]);
209 }
210 if (o->oargs.farg[4]*o->oargs.farg[5] <= FTINY*FTINY)
211 m->u.m.specexp = MAXSPECEXP;
212 else
213 m->u.m.specexp = 2./(o->oargs.farg[4]*o->oargs.farg[5]);
214 if (m->u.m.specexp > MAXSPECEXP)
215 m->u.m.specexp = MAXSPECEXP;
216 }
217
218
219 int
220 m_glass(o) /* glass material (hopeless) */
221 OBJREC *o;
222 {
223 register MATREC *m;
224
225 m = newmaterial(o->oname);
226 m->type = o->otype;
227 setcolor(m->u.m.ambdiff, 0., 0., 0.);
228 setcolor(m->u.m.specular, .08, .08, .08);
229 m->u.m.specexp = MAXSPECEXP;
230 }
231
232
233 int
234 m_brdf(o) /* convert functional material */
235 register OBJREC *o;
236 {
237 register MATREC *m;
238 /* check arguments */
239 if (o->oargs.nfargs < (o->otype == MAT_TFUNC ? 6 : 4))
240 objerror(o, USER, "bad # of real arguments");
241 /* allocate/insert material */
242 m = newmaterial(o->oname);
243 /* assign parameters */
244 setcolor(m->u.m.ambdiff, o->oargs.farg[0],
245 o->oargs.farg[1], o->oargs.farg[2]);
246 if ((m->type = o->otype) == MAT_MFUNC)
247 copycolor(m->u.m.specular, m->u.m.ambdiff);
248 else
249 setcolor(m->u.m.specular, 1., 1., 1.);
250 scalecolor(m->u.m.specular, o->oargs.farg[3]);
251 scalecolor(m->u.m.ambdiff, 1.-o->oargs.farg[3]);
252 if (m->type == MAT_TFUNC) {
253 scalecolor(m->u.m.specular, 1.-o->oargs.farg[4]);
254 scalecolor(m->u.m.ambdiff, 1.-o->oargs.farg[4]);
255 }
256 m->u.m.specexp = UNKSPECEXP;
257 }
258
259
260 int
261 m_brdf2(o) /* convert advanced functional material */
262 register OBJREC *o;
263 {
264 register MATREC *m;
265
266 if (o->oargs.nfargs < 9)
267 objerror(o, USER, "bad # of real arguments");
268 m = newmaterial(o->oname);
269 m->type = o->otype;
270 /* assign average diffuse front+back */
271 setcolor(m->u.m.ambdiff, (o->oargs.farg[0]+o->oargs.farg[3])*.5,
272 (o->oargs.farg[1]+o->oargs.farg[4])*.5,
273 (o->oargs.farg[2]+o->oargs.farg[5])*.5);
274 /* guess the rest */
275 setcolor(m->u.m.specular, .1, .1, .1);
276 m->u.m.specexp = UNKSPECEXP;
277 }
278
279
280 int
281 m_light(o) /* convert light type */
282 register OBJREC *o;
283 {
284 FVECT v;
285 register MATREC *m;
286
287 if (o->oargs.nfargs < (o->otype == MAT_SPOT ? 7 : 3))
288 objerror(o, USER, "bad # of real arguments");
289 m = newmaterial(o->oname);
290 setcolor(m->u.l.emission, o->oargs.farg[0],
291 o->oargs.farg[1], o->oargs.farg[2]);
292 if ((m->type = o->otype) == MAT_SPOT) {
293 if ((m->u.l.spotang = o->oargs.farg[3]/2.) > 90.)
294 m->u.l.spotang = 180.;
295 v[0] = o->oargs.farg[4];
296 v[1] = o->oargs.farg[5];
297 v[2] = o->oargs.farg[6];
298 if (normalize(v) == 0.)
299 objerror(o, USER, "illegal direction");
300 VCOPY(m->u.l.spotdir, v);
301 } else {
302 m->u.l.spotang = 180.;
303 m->u.l.spotdir[0] = m->u.l.spotdir[1] = 0.;
304 m->u.l.spotdir[2] = -1.;
305 }
306 }
307
308
309 int
310 m_mirror(o) /* convert mirror type */
311 register OBJREC *o;
312 {
313 register MATREC *m;
314
315 if (o->oargs.nfargs != 3)
316 objerror(o, USER, "bad # real arguments");
317 m = newmaterial(o->oname);
318 m->type = o->otype;
319 setcolor(m->u.m.ambdiff, 0., 0., 0.);
320 setcolor(m->u.m.specular, o->oargs.farg[0],
321 o->oargs.farg[1], o->oargs.farg[2]);
322 m->u.m.specexp = MAXSPECEXP;
323 }
324
325
326 int
327 m_prism(o) /* convert prism type */
328 register OBJREC *o;
329 {
330 register MATREC *m;
331 /* can't really deal with this type */
332 m = newmaterial(o->oname);
333 m->type = o->otype;
334 setcolor(m->u.m.ambdiff, 0.2, 0.2, 0.2);
335 setcolor(m->u.m.specular, 0.1, 0.1, 0.1);
336 m->u.m.specexp = UNKSPECEXP;
337 }