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

# User Rev Content
1 gwlarson 3.1 #ifndef lint
2 greg 3.3 static const char RCSid[] = "$Id$";
3 gwlarson 3.1 #endif
4     /*
5     * Routines for handling OpenGL light sources
6     */
7    
8 greg 3.3 /* ====================================================================
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 gwlarson 3.1 #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 gwlarson 3.2 int glightid[MAXLIGHTS] = {GL_LIGHT0, GL_LIGHT1, GL_LIGHT2,
74 gwlarson 3.1 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 greg 3.3 static void l_flatsrc(), l_sphsrc(), l_source();
95 gwlarson 3.1
96    
97 greg 3.3 void
98 gwlarson 3.1 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 greg 3.3 void
120 gwlarson 3.1 lightclean() /* clean up light source commands */
121     {
122     if ((dolights += nlights) <= 0)
123     return;
124     glPopAttrib();
125     }
126    
127    
128 greg 3.3 void
129 gwlarson 3.1 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 greg 3.3 int
159 gwlarson 3.1 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 greg 3.3 static void
220 gwlarson 3.1 l_source(n) /* convert a distant source */
221     register int n;
222     {
223     register MATREC *m = lightrec[n].m;
224 gwlarson 3.2 int thislight = glightid[n];
225 gwlarson 3.1 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 greg 3.3 static void
244 gwlarson 3.1 l_flatsrc(n) /* convert a flat source */
245     register int n;
246     {
247     GLfloat vec[4];
248     register MATREC *m = lightrec[n].m;
249 gwlarson 3.2 int thislight = glightid[n];
250 gwlarson 3.1 /* 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 greg 3.3 static void
279 gwlarson 3.1 l_sphsrc(n) /* convert a spherical source */
280     register int n;
281     {
282     GLfloat vec[4];
283     register MATREC *m = lightrec[n].m;
284 gwlarson 3.2 int thislight = glightid[n];
285 gwlarson 3.1 /* 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     }