Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
5131 | clevermous | 1 | /* |
2 | Copyright (C) 1996-1997 Id Software, Inc. |
||
3 | |||
4 | This program is free software; you can redistribute it and/or |
||
5 | modify it under the terms of the GNU General Public License |
||
6 | as published by the Free Software Foundation; either version 2 |
||
7 | of the License, or (at your option) any later version. |
||
8 | |||
9 | This program is distributed in the hope that it will be useful, |
||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
||
12 | |||
13 | See the GNU General Public License for more details. |
||
14 | |||
15 | You should have received a copy of the GNU General Public License |
||
16 | along with this program; if not, write to the Free Software |
||
17 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
||
18 | |||
19 | */ |
||
20 | // r_light.c |
||
21 | |||
22 | #include "quakedef.h" |
||
23 | #include "r_local.h" |
||
24 | |||
25 | int r_dlightframecount; |
||
26 | |||
27 | |||
28 | /* |
||
29 | ================== |
||
30 | R_AnimateLight |
||
31 | ================== |
||
32 | */ |
||
33 | void R_AnimateLight (void) |
||
34 | { |
||
35 | int i,j,k; |
||
36 | |||
37 | // |
||
38 | // light animations |
||
39 | // 'm' is normal light, 'a' is no light, 'z' is double bright |
||
40 | i = (int)(cl.time*10); |
||
41 | for (j=0 ; j |
||
42 | { |
||
43 | if (!cl_lightstyle[j].length) |
||
44 | { |
||
45 | d_lightstylevalue[j] = 256; |
||
46 | continue; |
||
47 | } |
||
48 | k = i % cl_lightstyle[j].length; |
||
49 | k = cl_lightstyle[j].map[k] - 'a'; |
||
50 | k = k*22; |
||
51 | d_lightstylevalue[j] = k; |
||
52 | } |
||
53 | } |
||
54 | |||
55 | |||
56 | /* |
||
57 | ============================================================================= |
||
58 | |||
59 | DYNAMIC LIGHTS |
||
60 | |||
61 | ============================================================================= |
||
62 | */ |
||
63 | |||
64 | /* |
||
65 | ============= |
||
66 | R_MarkLights |
||
67 | ============= |
||
68 | */ |
||
69 | void R_MarkLights (dlight_t *light, int bit, mnode_t *node) |
||
70 | { |
||
71 | mplane_t *splitplane; |
||
72 | float dist; |
||
73 | msurface_t *surf; |
||
74 | int i; |
||
75 | |||
76 | if (node->contents < 0) |
||
77 | return; |
||
78 | |||
79 | splitplane = node->plane; |
||
80 | dist = DotProduct (light->origin, splitplane->normal) - splitplane->dist; |
||
81 | |||
82 | if (dist > light->radius) |
||
83 | { |
||
84 | R_MarkLights (light, bit, node->children[0]); |
||
85 | return; |
||
86 | } |
||
87 | if (dist < -light->radius) |
||
88 | { |
||
89 | R_MarkLights (light, bit, node->children[1]); |
||
90 | return; |
||
91 | } |
||
92 | |||
93 | // mark the polygons |
||
94 | surf = cl.worldmodel->surfaces + node->firstsurface; |
||
95 | for (i=0 ; i |
||
96 | { |
||
97 | if (surf->dlightframe != r_dlightframecount) |
||
98 | { |
||
99 | surf->dlightbits = 0; |
||
100 | surf->dlightframe = r_dlightframecount; |
||
101 | } |
||
102 | surf->dlightbits |= bit; |
||
103 | } |
||
104 | |||
105 | R_MarkLights (light, bit, node->children[0]); |
||
106 | R_MarkLights (light, bit, node->children[1]); |
||
107 | } |
||
108 | |||
109 | |||
110 | /* |
||
111 | ============= |
||
112 | R_PushDlights |
||
113 | ============= |
||
114 | */ |
||
115 | void R_PushDlights (void) |
||
116 | { |
||
117 | int i; |
||
118 | dlight_t *l; |
||
119 | |||
120 | r_dlightframecount = r_framecount + 1; // because the count hasn't |
||
121 | // advanced yet for this frame |
||
122 | l = cl_dlights; |
||
123 | |||
124 | for (i=0 ; i |
||
125 | { |
||
126 | if (l->die < cl.time || !l->radius) |
||
127 | continue; |
||
128 | R_MarkLights ( l, 1<nodes ); |
||
129 | } |
||
130 | } |
||
131 | |||
132 | |||
133 | /* |
||
134 | ============================================================================= |
||
135 | |||
136 | LIGHT SAMPLING |
||
137 | |||
138 | ============================================================================= |
||
139 | */ |
||
140 | |||
141 | int RecursiveLightPoint (mnode_t *node, vec3_t start, vec3_t end) |
||
142 | { |
||
143 | int r; |
||
144 | float front, back, frac; |
||
145 | int side; |
||
146 | mplane_t *plane; |
||
147 | vec3_t mid; |
||
148 | msurface_t *surf; |
||
149 | int s, t, ds, dt; |
||
150 | int i; |
||
151 | mtexinfo_t *tex; |
||
152 | byte *lightmap; |
||
153 | unsigned scale; |
||
154 | int maps; |
||
155 | |||
156 | if (node->contents < 0) |
||
157 | return -1; // didn't hit anything |
||
158 | |||
159 | // calculate mid point |
||
160 | |||
161 | // FIXME: optimize for axial |
||
162 | plane = node->plane; |
||
163 | front = DotProduct (start, plane->normal) - plane->dist; |
||
164 | back = DotProduct (end, plane->normal) - plane->dist; |
||
165 | side = front < 0; |
||
166 | |||
167 | if ( (back < 0) == side) |
||
168 | return RecursiveLightPoint (node->children[side], start, end); |
||
169 | |||
170 | frac = front / (front-back); |
||
171 | mid[0] = start[0] + (end[0] - start[0])*frac; |
||
172 | mid[1] = start[1] + (end[1] - start[1])*frac; |
||
173 | mid[2] = start[2] + (end[2] - start[2])*frac; |
||
174 | |||
175 | // go down front side |
||
176 | r = RecursiveLightPoint (node->children[side], start, mid); |
||
177 | if (r >= 0) |
||
178 | return r; // hit something |
||
179 | |||
180 | if ( (back < 0) == side ) |
||
181 | return -1; // didn't hit anuthing |
||
182 | |||
183 | // check for impact on this node |
||
184 | |||
185 | surf = cl.worldmodel->surfaces + node->firstsurface; |
||
186 | for (i=0 ; i |
||
187 | { |
||
188 | if (surf->flags & SURF_DRAWTILED) |
||
189 | continue; // no lightmaps |
||
190 | |||
191 | tex = surf->texinfo; |
||
192 | |||
193 | s = DotProduct (mid, tex->vecs[0]) + tex->vecs[0][3]; |
||
194 | t = DotProduct (mid, tex->vecs[1]) + tex->vecs[1][3];; |
||
195 | |||
196 | if (s < surf->texturemins[0] || |
||
197 | t < surf->texturemins[1]) |
||
198 | continue; |
||
199 | |||
200 | ds = s - surf->texturemins[0]; |
||
201 | dt = t - surf->texturemins[1]; |
||
202 | |||
203 | if ( ds > surf->extents[0] || dt > surf->extents[1] ) |
||
204 | continue; |
||
205 | |||
206 | if (!surf->samples) |
||
207 | return 0; |
||
208 | |||
209 | ds >>= 4; |
||
210 | dt >>= 4; |
||
211 | |||
212 | lightmap = surf->samples; |
||
213 | r = 0; |
||
214 | if (lightmap) |
||
215 | { |
||
216 | |||
217 | lightmap += dt * ((surf->extents[0]>>4)+1) + ds; |
||
218 | |||
219 | for (maps = 0 ; maps < MAXLIGHTMAPS && surf->styles[maps] != 255 ; |
||
220 | maps++) |
||
221 | { |
||
222 | scale = d_lightstylevalue[surf->styles[maps]]; |
||
223 | r += *lightmap * scale; |
||
224 | lightmap += ((surf->extents[0]>>4)+1) * |
||
225 | ((surf->extents[1]>>4)+1); |
||
226 | } |
||
227 | |||
228 | r >>= 8; |
||
229 | } |
||
230 | |||
231 | return r; |
||
232 | } |
||
233 | |||
234 | // go down back side |
||
235 | return RecursiveLightPoint (node->children[!side], mid, end); |
||
236 | } |
||
237 | |||
238 | int R_LightPoint (vec3_t p) |
||
239 | { |
||
240 | vec3_t end; |
||
241 | int r; |
||
242 | |||
243 | if (!cl.worldmodel->lightdata) |
||
244 | return 255; |
||
245 | |||
246 | end[0] = p[0]; |
||
247 | end[1] = p[1]; |
||
248 | end[2] = p[2] - 2048; |
||
249 | |||
250 | r = RecursiveLightPoint (cl.worldmodel->nodes, p, end); |
||
251 | |||
252 | if (r == -1) |
||
253 | r = 0; |
||
254 | |||
255 | if (r < r_refdef.ambientlight) |
||
256 | r = r_refdef.ambientlight; |
||
257 | |||
258 | return r; |
||
259 | }>>>>>>>>>>> |
||
260 |