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_misc.c |
||
21 | |||
22 | #include "quakedef.h" |
||
23 | #include "r_local.h" |
||
24 | |||
25 | |||
26 | /* |
||
27 | =============== |
||
28 | R_CheckVariables |
||
29 | =============== |
||
30 | */ |
||
31 | void R_CheckVariables (void) |
||
32 | { |
||
33 | static float oldbright; |
||
34 | |||
35 | if (r_fullbright.value != oldbright) |
||
36 | { |
||
37 | oldbright = r_fullbright.value; |
||
38 | D_FlushCaches (); // so all lighting changes |
||
39 | } |
||
40 | } |
||
41 | |||
42 | |||
43 | /* |
||
44 | ============ |
||
45 | Show |
||
46 | |||
47 | Debugging use |
||
48 | ============ |
||
49 | */ |
||
50 | void Show (void) |
||
51 | { |
||
52 | vrect_t vr; |
||
53 | |||
54 | vr.x = vr.y = 0; |
||
55 | vr.width = vid.width; |
||
56 | vr.height = vid.height; |
||
57 | vr.pnext = NULL; |
||
58 | VID_Update (&vr); |
||
59 | } |
||
60 | |||
61 | |||
62 | /* |
||
63 | ==================== |
||
64 | R_TimeRefresh_f |
||
65 | |||
66 | For program optimization |
||
67 | ==================== |
||
68 | */ |
||
69 | void R_TimeRefresh_f (void) |
||
70 | { |
||
71 | int i; |
||
72 | float start, stop, time; |
||
73 | int startangle; |
||
74 | vrect_t vr; |
||
75 | |||
76 | startangle = r_refdef.viewangles[1]; |
||
77 | |||
78 | start = Sys_FloatTime (); |
||
79 | for (i=0 ; i<128 ; i++) |
||
80 | { |
||
81 | r_refdef.viewangles[1] = i/128.0*360.0; |
||
82 | |||
83 | VID_LockBuffer (); |
||
84 | |||
85 | R_RenderView (); |
||
86 | |||
87 | VID_UnlockBuffer (); |
||
88 | |||
89 | vr.x = r_refdef.vrect.x; |
||
90 | vr.y = r_refdef.vrect.y; |
||
91 | vr.width = r_refdef.vrect.width; |
||
92 | vr.height = r_refdef.vrect.height; |
||
93 | vr.pnext = NULL; |
||
94 | VID_Update (&vr); |
||
95 | } |
||
96 | stop = Sys_FloatTime (); |
||
97 | time = stop-start; |
||
98 | Con_Printf ("%f seconds (%f fps)\n", time, 128/time); |
||
99 | |||
100 | r_refdef.viewangles[1] = startangle; |
||
101 | } |
||
102 | |||
103 | |||
104 | /* |
||
105 | ================ |
||
106 | R_LineGraph |
||
107 | |||
108 | Only called by R_DisplayTime |
||
109 | ================ |
||
110 | */ |
||
111 | void R_LineGraph (int x, int y, int h) |
||
112 | { |
||
113 | int i; |
||
114 | byte *dest; |
||
115 | int s; |
||
116 | |||
117 | // FIXME: should be disabled on no-buffer adapters, or should be in the driver |
||
118 | |||
119 | x += r_refdef.vrect.x; |
||
120 | y += r_refdef.vrect.y; |
||
121 | |||
122 | dest = vid.buffer + vid.rowbytes*y + x; |
||
123 | |||
124 | s = r_graphheight.value; |
||
125 | |||
126 | if (h>s) |
||
127 | h = s; |
||
128 | |||
129 | for (i=0 ; i |
||
130 | { |
||
131 | dest[0] = 0xff; |
||
132 | *(dest-vid.rowbytes) = 0x30; |
||
133 | } |
||
134 | for ( ; i |
||
135 | { |
||
136 | dest[0] = 0x30; |
||
137 | *(dest-vid.rowbytes) = 0x30; |
||
138 | } |
||
139 | } |
||
140 | |||
141 | /* |
||
142 | ============== |
||
143 | R_TimeGraph |
||
144 | |||
145 | Performance monitoring tool |
||
146 | ============== |
||
147 | */ |
||
148 | #define MAX_TIMINGS 100 |
||
149 | extern float mouse_x, mouse_y; |
||
150 | void R_TimeGraph (void) |
||
151 | { |
||
152 | static int timex; |
||
153 | int a; |
||
154 | float r_time2; |
||
155 | static byte r_timings[MAX_TIMINGS]; |
||
156 | int x; |
||
157 | |||
158 | r_time2 = Sys_FloatTime (); |
||
159 | |||
160 | a = (r_time2-r_time1)/0.01; |
||
161 | //a = fabs(mouse_y * 0.05); |
||
162 | //a = (int)((r_refdef.vieworg[2] + 1024)/1)%(int)r_graphheight.value; |
||
163 | //a = fabs(velocity[0])/20; |
||
164 | //a = ((int)fabs(origin[0])/8)%20; |
||
165 | //a = (cl.idealpitch + 30)/5; |
||
166 | r_timings[timex] = a; |
||
167 | a = timex; |
||
168 | |||
169 | if (r_refdef.vrect.width <= MAX_TIMINGS) |
||
170 | x = r_refdef.vrect.width-1; |
||
171 | else |
||
172 | x = r_refdef.vrect.width - |
||
173 | (r_refdef.vrect.width - MAX_TIMINGS)/2; |
||
174 | do |
||
175 | { |
||
176 | R_LineGraph (x, r_refdef.vrect.height-2, r_timings[a]); |
||
177 | if (x==0) |
||
178 | break; // screen too small to hold entire thing |
||
179 | x--; |
||
180 | a--; |
||
181 | if (a == -1) |
||
182 | a = MAX_TIMINGS-1; |
||
183 | } while (a != timex); |
||
184 | |||
185 | timex = (timex+1)%MAX_TIMINGS; |
||
186 | } |
||
187 | |||
188 | |||
189 | /* |
||
190 | ============= |
||
191 | R_PrintTimes |
||
192 | ============= |
||
193 | */ |
||
194 | void R_PrintTimes (void) |
||
195 | { |
||
196 | float r_time2; |
||
197 | float ms; |
||
198 | |||
199 | r_time2 = Sys_FloatTime (); |
||
200 | |||
201 | ms = 1000* (r_time2 - r_time1); |
||
202 | |||
203 | Con_Printf ("%5.1f ms %3i/%3i/%3i poly %3i surf\n", |
||
204 | ms, c_faceclip, r_polycount, r_drawnpolycount, c_surf); |
||
205 | c_surf = 0; |
||
206 | } |
||
207 | |||
208 | |||
209 | /* |
||
210 | ============= |
||
211 | R_PrintDSpeeds |
||
212 | ============= |
||
213 | */ |
||
214 | void R_PrintDSpeeds (void) |
||
215 | { |
||
216 | float ms, dp_time, r_time2, rw_time, db_time, se_time, de_time, dv_time; |
||
217 | |||
218 | r_time2 = Sys_FloatTime (); |
||
219 | |||
220 | dp_time = (dp_time2 - dp_time1) * 1000; |
||
221 | rw_time = (rw_time2 - rw_time1) * 1000; |
||
222 | db_time = (db_time2 - db_time1) * 1000; |
||
223 | se_time = (se_time2 - se_time1) * 1000; |
||
224 | de_time = (de_time2 - de_time1) * 1000; |
||
225 | dv_time = (dv_time2 - dv_time1) * 1000; |
||
226 | ms = (r_time2 - r_time1) * 1000; |
||
227 | |||
228 | Con_Printf ("%3i %4.1fp %3iw %4.1fb %3is %4.1fe %4.1fv\n", |
||
229 | (int)ms, dp_time, (int)rw_time, db_time, (int)se_time, de_time, |
||
230 | dv_time); |
||
231 | } |
||
232 | |||
233 | |||
234 | /* |
||
235 | ============= |
||
236 | R_PrintAliasStats |
||
237 | ============= |
||
238 | */ |
||
239 | void R_PrintAliasStats (void) |
||
240 | { |
||
241 | Con_Printf ("%3i polygon model drawn\n", r_amodels_drawn); |
||
242 | } |
||
243 | |||
244 | |||
245 | void WarpPalette (void) |
||
246 | { |
||
247 | int i,j; |
||
248 | byte newpalette[768]; |
||
249 | int basecolor[3]; |
||
250 | |||
251 | basecolor[0] = 130; |
||
252 | basecolor[1] = 80; |
||
253 | basecolor[2] = 50; |
||
254 | |||
255 | // pull the colors halfway to bright brown |
||
256 | for (i=0 ; i<256 ; i++) |
||
257 | { |
||
258 | for (j=0 ; j<3 ; j++) |
||
259 | { |
||
260 | newpalette[i*3+j] = (host_basepal[i*3+j] + basecolor[j])/2; |
||
261 | } |
||
262 | } |
||
263 | |||
264 | VID_ShiftPalette (newpalette); |
||
265 | } |
||
266 | |||
267 | |||
268 | /* |
||
269 | =================== |
||
270 | R_TransformFrustum |
||
271 | =================== |
||
272 | */ |
||
273 | void R_TransformFrustum (void) |
||
274 | { |
||
275 | int i; |
||
276 | vec3_t v, v2; |
||
277 | |||
278 | for (i=0 ; i<4 ; i++) |
||
279 | { |
||
280 | v[0] = screenedge[i].normal[2]; |
||
281 | v[1] = -screenedge[i].normal[0]; |
||
282 | v[2] = screenedge[i].normal[1]; |
||
283 | |||
284 | v2[0] = v[1]*vright[0] + v[2]*vup[0] + v[0]*vpn[0]; |
||
285 | v2[1] = v[1]*vright[1] + v[2]*vup[1] + v[0]*vpn[1]; |
||
286 | v2[2] = v[1]*vright[2] + v[2]*vup[2] + v[0]*vpn[2]; |
||
287 | |||
288 | VectorCopy (v2, view_clipplanes[i].normal); |
||
289 | |||
290 | view_clipplanes[i].dist = DotProduct (modelorg, v2); |
||
291 | } |
||
292 | } |
||
293 | |||
294 | |||
295 | #if !id386 |
||
296 | |||
297 | /* |
||
298 | ================ |
||
299 | TransformVector |
||
300 | ================ |
||
301 | */ |
||
302 | void TransformVector (vec3_t in, vec3_t out) |
||
303 | { |
||
304 | out[0] = DotProduct(in,vright); |
||
305 | out[1] = DotProduct(in,vup); |
||
306 | out[2] = DotProduct(in,vpn); |
||
307 | } |
||
308 | |||
309 | #endif |
||
310 | |||
311 | |||
312 | /* |
||
313 | ================ |
||
314 | R_TransformPlane |
||
315 | ================ |
||
316 | */ |
||
317 | void R_TransformPlane (mplane_t *p, float *normal, float *dist) |
||
318 | { |
||
319 | float d; |
||
320 | |||
321 | d = DotProduct (r_origin, p->normal); |
||
322 | *dist = p->dist - d; |
||
323 | // TODO: when we have rotating entities, this will need to use the view matrix |
||
324 | TransformVector (p->normal, normal); |
||
325 | } |
||
326 | |||
327 | |||
328 | /* |
||
329 | =============== |
||
330 | R_SetUpFrustumIndexes |
||
331 | =============== |
||
332 | */ |
||
333 | void R_SetUpFrustumIndexes (void) |
||
334 | { |
||
335 | int i, j, *pindex; |
||
336 | |||
337 | pindex = r_frustum_indexes; |
||
338 | |||
339 | for (i=0 ; i<4 ; i++) |
||
340 | { |
||
341 | for (j=0 ; j<3 ; j++) |
||
342 | { |
||
343 | if (view_clipplanes[i].normal[j] < 0) |
||
344 | { |
||
345 | pindex[j] = j; |
||
346 | pindex[j+3] = j+3; |
||
347 | } |
||
348 | else |
||
349 | { |
||
350 | pindex[j] = j+3; |
||
351 | pindex[j+3] = j; |
||
352 | } |
||
353 | } |
||
354 | |||
355 | // FIXME: do just once at start |
||
356 | pfrustum_indexes[i] = pindex; |
||
357 | pindex += 6; |
||
358 | } |
||
359 | } |
||
360 | |||
361 | |||
362 | /* |
||
363 | =============== |
||
364 | R_SetupFrame |
||
365 | =============== |
||
366 | */ |
||
367 | void R_SetupFrame (void) |
||
368 | { |
||
369 | int edgecount; |
||
370 | vrect_t vrect; |
||
371 | float w, h; |
||
372 | |||
373 | // don't allow cheats in multiplayer |
||
374 | if (cl.maxclients > 1) |
||
375 | { |
||
376 | Cvar_Set ("r_draworder", "0"); |
||
377 | Cvar_Set ("r_fullbright", "0"); |
||
378 | Cvar_Set ("r_ambient", "0"); |
||
379 | Cvar_Set ("r_drawflat", "0"); |
||
380 | } |
||
381 | |||
382 | if (r_numsurfs.value) |
||
383 | { |
||
384 | if ((surface_p - surfaces) > r_maxsurfsseen) |
||
385 | r_maxsurfsseen = surface_p - surfaces; |
||
386 | |||
387 | Con_Printf ("Used %d of %d surfs; %d max\n", surface_p - surfaces, |
||
388 | surf_max - surfaces, r_maxsurfsseen); |
||
389 | } |
||
390 | |||
391 | if (r_numedges.value) |
||
392 | { |
||
393 | edgecount = edge_p - r_edges; |
||
394 | |||
395 | if (edgecount > r_maxedgesseen) |
||
396 | r_maxedgesseen = edgecount; |
||
397 | |||
398 | Con_Printf ("Used %d of %d edges; %d max\n", edgecount, |
||
399 | r_numallocatededges, r_maxedgesseen); |
||
400 | } |
||
401 | |||
402 | r_refdef.ambientlight = r_ambient.value; |
||
403 | |||
404 | if (r_refdef.ambientlight < 0) |
||
405 | r_refdef.ambientlight = 0; |
||
406 | |||
407 | if (!sv.active) |
||
408 | r_draworder.value = 0; // don't let cheaters look behind walls |
||
409 | |||
410 | R_CheckVariables (); |
||
411 | |||
412 | R_AnimateLight (); |
||
413 | |||
414 | r_framecount++; |
||
415 | |||
416 | numbtofpolys = 0; |
||
417 | |||
418 | // debugging |
||
419 | #if 0 |
||
420 | r_refdef.vieworg[0]= 80; |
||
421 | r_refdef.vieworg[1]= 64; |
||
422 | r_refdef.vieworg[2]= 40; |
||
423 | r_refdef.viewangles[0]= 0; |
||
424 | r_refdef.viewangles[1]= 46.763641357; |
||
425 | r_refdef.viewangles[2]= 0; |
||
426 | #endif |
||
427 | |||
428 | // build the transformation matrix for the given view angles |
||
429 | VectorCopy (r_refdef.vieworg, modelorg); |
||
430 | VectorCopy (r_refdef.vieworg, r_origin); |
||
431 | |||
432 | AngleVectors (r_refdef.viewangles, vpn, vright, vup); |
||
433 | |||
434 | // current viewleaf |
||
435 | r_oldviewleaf = r_viewleaf; |
||
436 | r_viewleaf = Mod_PointInLeaf (r_origin, cl.worldmodel); |
||
437 | |||
438 | r_dowarpold = r_dowarp; |
||
439 | r_dowarp = r_waterwarp.value && (r_viewleaf->contents <= CONTENTS_WATER); |
||
440 | |||
441 | if ((r_dowarp != r_dowarpold) || r_viewchanged || lcd_x.value) |
||
442 | { |
||
443 | if (r_dowarp) |
||
444 | { |
||
445 | if ((vid.width <= vid.maxwarpwidth) && |
||
446 | (vid.height <= vid.maxwarpheight)) |
||
447 | { |
||
448 | vrect.x = 0; |
||
449 | vrect.y = 0; |
||
450 | vrect.width = vid.width; |
||
451 | vrect.height = vid.height; |
||
452 | |||
453 | R_ViewChanged (&vrect, sb_lines, vid.aspect); |
||
454 | } |
||
455 | else |
||
456 | { |
||
457 | w = vid.width; |
||
458 | h = vid.height; |
||
459 | |||
460 | if (w > vid.maxwarpwidth) |
||
461 | { |
||
462 | h *= (float)vid.maxwarpwidth / w; |
||
463 | w = vid.maxwarpwidth; |
||
464 | } |
||
465 | |||
466 | if (h > vid.maxwarpheight) |
||
467 | { |
||
468 | h = vid.maxwarpheight; |
||
469 | w *= (float)vid.maxwarpheight / h; |
||
470 | } |
||
471 | |||
472 | vrect.x = 0; |
||
473 | vrect.y = 0; |
||
474 | vrect.width = (int)w; |
||
475 | vrect.height = (int)h; |
||
476 | |||
477 | R_ViewChanged (&vrect, |
||
478 | (int)((float)sb_lines * (h/(float)vid.height)), |
||
479 | vid.aspect * (h / w) * |
||
480 | ((float)vid.width / (float)vid.height)); |
||
481 | } |
||
482 | } |
||
483 | else |
||
484 | { |
||
485 | vrect.x = 0; |
||
486 | vrect.y = 0; |
||
487 | vrect.width = vid.width; |
||
488 | vrect.height = vid.height; |
||
489 | |||
490 | R_ViewChanged (&vrect, sb_lines, vid.aspect); |
||
491 | } |
||
492 | |||
493 | r_viewchanged = false; |
||
494 | } |
||
495 | |||
496 | // start off with just the four screen edge clip planes |
||
497 | R_TransformFrustum (); |
||
498 | |||
499 | // save base values |
||
500 | VectorCopy (vpn, base_vpn); |
||
501 | VectorCopy (vright, base_vright); |
||
502 | VectorCopy (vup, base_vup); |
||
503 | VectorCopy (modelorg, base_modelorg); |
||
504 | |||
505 | R_SetSkyFrame (); |
||
506 | |||
507 | R_SetUpFrustumIndexes (); |
||
508 | |||
509 | r_cache_thrash = false; |
||
510 | |||
511 | // clear frame counts |
||
512 | c_faceclip = 0; |
||
513 | d_spanpixcount = 0; |
||
514 | r_polycount = 0; |
||
515 | r_drawnpolycount = 0; |
||
516 | r_wholepolycount = 0; |
||
517 | r_amodels_drawn = 0; |
||
518 | r_outofsurfaces = 0; |
||
519 | r_outofedges = 0; |
||
520 | |||
521 | D_SetupFrame (); |
||
522 | }=>=>=>>>3>4>4>3>256>=>128> |
||
523 |