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

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id$";
3 #endif
4 /*
5 * Routines for handling OpenGL light sources
6 */
7
8 #include "copyright.h"
9
10 #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 int glightid[MAXLIGHTS] = {GL_LIGHT0, GL_LIGHT1, GL_LIGHT2,
19 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 static void l_flatsrc(), l_sphsrc(), l_source();
40
41
42 void
43 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 void
65 lightclean() /* clean up light source commands */
66 {
67 if ((dolights += nlights) <= 0)
68 return;
69 glPopAttrib();
70 }
71
72
73 void
74 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 int
104 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 static void
165 l_source(n) /* convert a distant source */
166 register int n;
167 {
168 register MATREC *m = lightrec[n].m;
169 int thislight = glightid[n];
170 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 static void
189 l_flatsrc(n) /* convert a flat source */
190 register int n;
191 {
192 GLfloat vec[4];
193 register MATREC *m = lightrec[n].m;
194 int thislight = glightid[n];
195 /* 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 static void
224 l_sphsrc(n) /* convert a spherical source */
225 register int n;
226 {
227 GLfloat vec[4];
228 register MATREC *m = lightrec[n].m;
229 int thislight = glightid[n];
230 /* 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 }