ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/rglsrc.c
Revision: 3.3
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.2: +66 -8 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 handling OpenGL light sources
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 double expval = 0.; /* global exposure value */
68
69 COLOR ambval = {0.2, 0.2, 0.2}; /* global ambient value */
70
71 int dolights = MAXLIGHTS; /* do how many more light sources? */
72
73 int glightid[MAXLIGHTS] = {GL_LIGHT0, GL_LIGHT1, GL_LIGHT2,
74 GL_LIGHT3, GL_LIGHT4, GL_LIGHT5, GL_LIGHT6, GL_LIGHT7};
75
76 static int lightlist; /* light list id */
77
78 /* source types */
79 #define L_NONE 0
80 #define L_SOURCE 1
81 #define L_FLAT 2
82 #define L_SPHERE 3
83
84 static struct {
85 int type; /* light type (0 if none) */
86 MATREC *m; /* light material */
87 FVECT pos; /* light position (or direction) */
88 FVECT norm; /* flat source normal */
89 double area; /* source area (or solid angle) */
90 } lightrec[MAXLIGHTS]; /* light source list */
91
92 static int nlights; /* number of defined lights */
93
94 static void l_flatsrc(), l_sphsrc(), l_source();
95
96
97 void
98 lightinit() /* initialize lighting */
99 {
100 GLfloat ambv[4];
101 register int i;
102
103 if (!dolights)
104 return;
105 glPushAttrib(GL_LIGHTING_BIT);
106 if (expval <= FTINY && bright(ambval) > FTINY)
107 expval = 0.2/bright(ambval);
108 ambv[0] = expval*colval(ambval,RED);
109 ambv[1] = expval*colval(ambval,GRN);
110 ambv[2] = expval*colval(ambval,BLU);
111 ambv[3] = 1.;
112 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambv);
113 glCallList(lightlist = newglist());
114 rgl_checkerr("in lightinit");
115 nlights = 0;
116 }
117
118
119 void
120 lightclean() /* clean up light source commands */
121 {
122 if ((dolights += nlights) <= 0)
123 return;
124 glPopAttrib();
125 }
126
127
128 void
129 lightdefs() /* define light source list */
130 {
131 register int i;
132
133 if (!nlights)
134 return;
135 glNewList(lightlist, GL_COMPILE);
136 while (nlights--) {
137 switch (lightrec[nlights].type) {
138 case L_FLAT:
139 l_flatsrc(nlights);
140 break;
141 case L_SPHERE:
142 l_sphsrc(nlights);
143 break;
144 case L_SOURCE:
145 l_source(nlights);
146 break;
147 default:
148 error(CONSISTENCY, "botched light type in lightdefs");
149 }
150 freemtl(lightrec[nlights].m);
151 lightrec[nlights].type = L_NONE;
152 }
153 glEndList();
154 rgl_checkerr("defining lights");
155 }
156
157
158 int
159 o_source(o) /* record a distant source */
160 register OBJREC *o;
161 {
162 if (!dolights || !issrcmat((MATREC *)o->os))
163 return(0);
164 if (o->oargs.nfargs != 4)
165 objerror(o, USER, "bad # real arguments");
166 /* record type & material */
167 lightrec[nlights].type = L_SOURCE;
168 (lightrec[nlights].m = (MATREC *)o->os)->nlinks++;
169 /* assign direction */
170 VCOPY(lightrec[nlights].pos, o->oargs.farg);
171 /* compute solid angle */
172 if (o->oargs.farg[3] <= FTINY)
173 objerror(o, USER, "zero size");
174 lightrec[nlights].area = 2.*PI*(1. - cos(PI/180./2.*o->oargs.farg[3]));
175 nlights++; dolights--;
176 return(1);
177 }
178
179
180 int
181 doflatsrc(m, pos, norm, area) /* record a flat source */
182 MATREC *m;
183 FVECT pos, norm;
184 double area;
185 {
186 if (!dolights || !issrcmat(m) || area <= FTINY)
187 return(0);
188 /* record type & material */
189 lightrec[nlights].type = L_FLAT;
190 (lightrec[nlights].m = m)->nlinks++;
191 /* assign geometry */
192 VCOPY(lightrec[nlights].pos, pos);
193 VCOPY(lightrec[nlights].norm, norm);
194 lightrec[nlights].area = area;
195 nlights++; dolights--;
196 return(1);
197 }
198
199
200 int
201 dosphsrc(m, pos, area) /* record a spherical source */
202 register MATREC *m;
203 FVECT pos;
204 double area;
205 {
206 if (!dolights || !issrcmat(m) || area <= FTINY)
207 return(0);
208 /* record type & material */
209 lightrec[nlights].type = L_SPHERE;
210 (lightrec[nlights].m = m)->nlinks++;
211 /* assign geometry */
212 VCOPY(lightrec[nlights].pos, pos);
213 lightrec[nlights].area = area;
214 nlights++; dolights--;
215 return(1);
216 }
217
218
219 static void
220 l_source(n) /* convert a distant source */
221 register int n;
222 {
223 register MATREC *m = lightrec[n].m;
224 int thislight = glightid[n];
225 GLfloat vec[4];
226 /* assign direction */
227 VCOPY(vec, lightrec[n].pos);
228 vec[3] = 0.;
229 glLightfv(thislight, GL_POSITION, vec);
230 /* assign color */
231 vec[0] = expval*lightrec[n].area*colval(m->u.l.emission,RED);
232 vec[1] = expval*lightrec[n].area*colval(m->u.l.emission,GRN);
233 vec[2] = expval*lightrec[n].area*colval(m->u.l.emission,BLU);
234 vec[3] = 1.;
235 glLightfv(thislight, GL_SPECULAR, vec);
236 glLightfv(thislight, GL_DIFFUSE, vec);
237 vec[0] = vec[1] = vec[2] = 0.; vec[3] = 1.;
238 glLightfv(thislight, GL_AMBIENT, vec);
239 glEnable(thislight);
240 }
241
242
243 static void
244 l_flatsrc(n) /* convert a flat source */
245 register int n;
246 {
247 GLfloat vec[4];
248 register MATREC *m = lightrec[n].m;
249 int thislight = glightid[n];
250 /* assign position */
251 VCOPY(vec, lightrec[n].pos); vec[3] = 1.;
252 glLightfv(thislight, GL_POSITION, vec);
253 /* assign color */
254 vec[0] = expval*lightrec[n].area*colval(m->u.l.emission,RED);
255 vec[1] = expval*lightrec[n].area*colval(m->u.l.emission,GRN);
256 vec[2] = expval*lightrec[n].area*colval(m->u.l.emission,BLU);
257 vec[3] = 1.;
258 glLightfv(thislight, GL_SPECULAR, vec);
259 glLightfv(thislight, GL_DIFFUSE, vec);
260 vec[0] = vec[1] = vec[2] = 0.; vec[3] = 1.;
261 glLightfv(thislight, GL_AMBIENT, vec);
262 glLightf(thislight, GL_SPOT_EXPONENT, 1.);
263 glLightf(thislight, GL_CONSTANT_ATTENUATION, 0.);
264 glLightf(thislight, GL_LINEAR_ATTENUATION, 0.);
265 glLightf(thislight, GL_QUADRATIC_ATTENUATION, 1.);
266 if (m->type == MAT_SPOT && m->u.l.spotang < 90.) {
267 glLightf(thislight, GL_SPOT_CUTOFF, m->u.l.spotang);
268 glLightfv(thislight, GL_SPOT_DIRECTION, m->u.l.spotdir);
269 } else {
270 glLightf(thislight, GL_SPOT_CUTOFF, 90.);
271 VCOPY(vec, lightrec[n].norm);
272 glLightfv(thislight, GL_SPOT_DIRECTION, vec);
273 }
274 glEnable(thislight);
275 }
276
277
278 static void
279 l_sphsrc(n) /* convert a spherical source */
280 register int n;
281 {
282 GLfloat vec[4];
283 register MATREC *m = lightrec[n].m;
284 int thislight = glightid[n];
285 /* assign position */
286 VCOPY(vec, lightrec[n].pos); vec[3] = 1.;
287 glLightfv(thislight, GL_POSITION, vec);
288 /* assign color */
289 vec[0] = expval*lightrec[n].area*colval(m->u.l.emission,RED);
290 vec[1] = expval*lightrec[n].area*colval(m->u.l.emission,GRN);
291 vec[2] = expval*lightrec[n].area*colval(m->u.l.emission,BLU);
292 vec[3] = 1.;
293 glLightfv(thislight, GL_SPECULAR, vec);
294 glLightfv(thislight, GL_DIFFUSE, vec);
295 vec[0] = vec[1] = vec[2] = 0.; vec[3] = 1.;
296 glLightfv(thislight, GL_AMBIENT, vec);
297 glLightf(thislight, GL_SPOT_EXPONENT, 0.);
298 glLightf(thislight, GL_CONSTANT_ATTENUATION, 0.);
299 glLightf(thislight, GL_LINEAR_ATTENUATION, 0.);
300 glLightf(thislight, GL_QUADRATIC_ATTENUATION, 1.);
301 if (m->type == MAT_SPOT && m->u.l.spotang <= 90.) {
302 glLightf(thislight, GL_SPOT_CUTOFF, m->u.l.spotang);
303 glLightfv(thislight, GL_SPOT_DIRECTION, m->u.l.spotdir);
304 } else
305 glLightf(thislight, GL_SPOT_CUTOFF, 180.);
306 glEnable(thislight);
307 }