ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/rglsrc.c
Revision: 3.4
Committed: Tue Feb 25 02:47:22 2003 UTC (21 years, 2 months ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad3R5
Changes since 3.3: +1 -56 lines
Log Message:
Replaced inline copyright notice with #include "copyright.h"

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.4 #include "copyright.h"
9 greg 3.3
10 gwlarson 3.1 #include "radogl.h"
11    
12     double expval = 0.; /* global exposure value */
13    
14     COLOR ambval = {0.2, 0.2, 0.2}; /* global ambient value */
15    
16     int dolights = MAXLIGHTS; /* do how many more light sources? */
17    
18 gwlarson 3.2 int glightid[MAXLIGHTS] = {GL_LIGHT0, GL_LIGHT1, GL_LIGHT2,
19 gwlarson 3.1 GL_LIGHT3, GL_LIGHT4, GL_LIGHT5, GL_LIGHT6, GL_LIGHT7};
20    
21     static int lightlist; /* light list id */
22    
23     /* source types */
24     #define L_NONE 0
25     #define L_SOURCE 1
26     #define L_FLAT 2
27     #define L_SPHERE 3
28    
29     static struct {
30     int type; /* light type (0 if none) */
31     MATREC *m; /* light material */
32     FVECT pos; /* light position (or direction) */
33     FVECT norm; /* flat source normal */
34     double area; /* source area (or solid angle) */
35     } lightrec[MAXLIGHTS]; /* light source list */
36    
37     static int nlights; /* number of defined lights */
38    
39 greg 3.3 static void l_flatsrc(), l_sphsrc(), l_source();
40 gwlarson 3.1
41    
42 greg 3.3 void
43 gwlarson 3.1 lightinit() /* initialize lighting */
44     {
45     GLfloat ambv[4];
46     register int i;
47    
48     if (!dolights)
49     return;
50     glPushAttrib(GL_LIGHTING_BIT);
51     if (expval <= FTINY && bright(ambval) > FTINY)
52     expval = 0.2/bright(ambval);
53     ambv[0] = expval*colval(ambval,RED);
54     ambv[1] = expval*colval(ambval,GRN);
55     ambv[2] = expval*colval(ambval,BLU);
56     ambv[3] = 1.;
57     glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambv);
58     glCallList(lightlist = newglist());
59     rgl_checkerr("in lightinit");
60     nlights = 0;
61     }
62    
63    
64 greg 3.3 void
65 gwlarson 3.1 lightclean() /* clean up light source commands */
66     {
67     if ((dolights += nlights) <= 0)
68     return;
69     glPopAttrib();
70     }
71    
72    
73 greg 3.3 void
74 gwlarson 3.1 lightdefs() /* define light source list */
75     {
76     register int i;
77    
78     if (!nlights)
79     return;
80     glNewList(lightlist, GL_COMPILE);
81     while (nlights--) {
82     switch (lightrec[nlights].type) {
83     case L_FLAT:
84     l_flatsrc(nlights);
85     break;
86     case L_SPHERE:
87     l_sphsrc(nlights);
88     break;
89     case L_SOURCE:
90     l_source(nlights);
91     break;
92     default:
93     error(CONSISTENCY, "botched light type in lightdefs");
94     }
95     freemtl(lightrec[nlights].m);
96     lightrec[nlights].type = L_NONE;
97     }
98     glEndList();
99     rgl_checkerr("defining lights");
100     }
101    
102    
103 greg 3.3 int
104 gwlarson 3.1 o_source(o) /* record a distant source */
105     register OBJREC *o;
106     {
107     if (!dolights || !issrcmat((MATREC *)o->os))
108     return(0);
109     if (o->oargs.nfargs != 4)
110     objerror(o, USER, "bad # real arguments");
111     /* record type & material */
112     lightrec[nlights].type = L_SOURCE;
113     (lightrec[nlights].m = (MATREC *)o->os)->nlinks++;
114     /* assign direction */
115     VCOPY(lightrec[nlights].pos, o->oargs.farg);
116     /* compute solid angle */
117     if (o->oargs.farg[3] <= FTINY)
118     objerror(o, USER, "zero size");
119     lightrec[nlights].area = 2.*PI*(1. - cos(PI/180./2.*o->oargs.farg[3]));
120     nlights++; dolights--;
121     return(1);
122     }
123    
124    
125     int
126     doflatsrc(m, pos, norm, area) /* record a flat source */
127     MATREC *m;
128     FVECT pos, norm;
129     double area;
130     {
131     if (!dolights || !issrcmat(m) || area <= FTINY)
132     return(0);
133     /* record type & material */
134     lightrec[nlights].type = L_FLAT;
135     (lightrec[nlights].m = m)->nlinks++;
136     /* assign geometry */
137     VCOPY(lightrec[nlights].pos, pos);
138     VCOPY(lightrec[nlights].norm, norm);
139     lightrec[nlights].area = area;
140     nlights++; dolights--;
141     return(1);
142     }
143    
144    
145     int
146     dosphsrc(m, pos, area) /* record a spherical source */
147     register MATREC *m;
148     FVECT pos;
149     double area;
150     {
151     if (!dolights || !issrcmat(m) || area <= FTINY)
152     return(0);
153     /* record type & material */
154     lightrec[nlights].type = L_SPHERE;
155     (lightrec[nlights].m = m)->nlinks++;
156     /* assign geometry */
157     VCOPY(lightrec[nlights].pos, pos);
158     lightrec[nlights].area = area;
159     nlights++; dolights--;
160     return(1);
161     }
162    
163    
164 greg 3.3 static void
165 gwlarson 3.1 l_source(n) /* convert a distant source */
166     register int n;
167     {
168     register MATREC *m = lightrec[n].m;
169 gwlarson 3.2 int thislight = glightid[n];
170 gwlarson 3.1 GLfloat vec[4];
171     /* assign direction */
172     VCOPY(vec, lightrec[n].pos);
173     vec[3] = 0.;
174     glLightfv(thislight, GL_POSITION, vec);
175     /* assign color */
176     vec[0] = expval*lightrec[n].area*colval(m->u.l.emission,RED);
177     vec[1] = expval*lightrec[n].area*colval(m->u.l.emission,GRN);
178     vec[2] = expval*lightrec[n].area*colval(m->u.l.emission,BLU);
179     vec[3] = 1.;
180     glLightfv(thislight, GL_SPECULAR, vec);
181     glLightfv(thislight, GL_DIFFUSE, vec);
182     vec[0] = vec[1] = vec[2] = 0.; vec[3] = 1.;
183     glLightfv(thislight, GL_AMBIENT, vec);
184     glEnable(thislight);
185     }
186    
187    
188 greg 3.3 static void
189 gwlarson 3.1 l_flatsrc(n) /* convert a flat source */
190     register int n;
191     {
192     GLfloat vec[4];
193     register MATREC *m = lightrec[n].m;
194 gwlarson 3.2 int thislight = glightid[n];
195 gwlarson 3.1 /* assign position */
196     VCOPY(vec, lightrec[n].pos); vec[3] = 1.;
197     glLightfv(thislight, GL_POSITION, vec);
198     /* assign color */
199     vec[0] = expval*lightrec[n].area*colval(m->u.l.emission,RED);
200     vec[1] = expval*lightrec[n].area*colval(m->u.l.emission,GRN);
201     vec[2] = expval*lightrec[n].area*colval(m->u.l.emission,BLU);
202     vec[3] = 1.;
203     glLightfv(thislight, GL_SPECULAR, vec);
204     glLightfv(thislight, GL_DIFFUSE, vec);
205     vec[0] = vec[1] = vec[2] = 0.; vec[3] = 1.;
206     glLightfv(thislight, GL_AMBIENT, vec);
207     glLightf(thislight, GL_SPOT_EXPONENT, 1.);
208     glLightf(thislight, GL_CONSTANT_ATTENUATION, 0.);
209     glLightf(thislight, GL_LINEAR_ATTENUATION, 0.);
210     glLightf(thislight, GL_QUADRATIC_ATTENUATION, 1.);
211     if (m->type == MAT_SPOT && m->u.l.spotang < 90.) {
212     glLightf(thislight, GL_SPOT_CUTOFF, m->u.l.spotang);
213     glLightfv(thislight, GL_SPOT_DIRECTION, m->u.l.spotdir);
214     } else {
215     glLightf(thislight, GL_SPOT_CUTOFF, 90.);
216     VCOPY(vec, lightrec[n].norm);
217     glLightfv(thislight, GL_SPOT_DIRECTION, vec);
218     }
219     glEnable(thislight);
220     }
221    
222    
223 greg 3.3 static void
224 gwlarson 3.1 l_sphsrc(n) /* convert a spherical source */
225     register int n;
226     {
227     GLfloat vec[4];
228     register MATREC *m = lightrec[n].m;
229 gwlarson 3.2 int thislight = glightid[n];
230 gwlarson 3.1 /* assign position */
231     VCOPY(vec, lightrec[n].pos); vec[3] = 1.;
232     glLightfv(thislight, GL_POSITION, vec);
233     /* assign color */
234     vec[0] = expval*lightrec[n].area*colval(m->u.l.emission,RED);
235     vec[1] = expval*lightrec[n].area*colval(m->u.l.emission,GRN);
236     vec[2] = expval*lightrec[n].area*colval(m->u.l.emission,BLU);
237     vec[3] = 1.;
238     glLightfv(thislight, GL_SPECULAR, vec);
239     glLightfv(thislight, GL_DIFFUSE, vec);
240     vec[0] = vec[1] = vec[2] = 0.; vec[3] = 1.;
241     glLightfv(thislight, GL_AMBIENT, vec);
242     glLightf(thislight, GL_SPOT_EXPONENT, 0.);
243     glLightf(thislight, GL_CONSTANT_ATTENUATION, 0.);
244     glLightf(thislight, GL_LINEAR_ATTENUATION, 0.);
245     glLightf(thislight, GL_QUADRATIC_ATTENUATION, 1.);
246     if (m->type == MAT_SPOT && m->u.l.spotang <= 90.) {
247     glLightf(thislight, GL_SPOT_CUTOFF, m->u.l.spotang);
248     glLightfv(thislight, GL_SPOT_DIRECTION, m->u.l.spotdir);
249     } else
250     glLightf(thislight, GL_SPOT_CUTOFF, 180.);
251     glEnable(thislight);
252     }