1 /*
2 sw_rmisc.c
3
4 (description)
5
6 Copyright (C) 1996-1997 Id Software, Inc.
7
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License
10 as published by the Free Software Foundation; either version 2
11 of the License, or (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16
17 See the GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to:
21
22 Free Software Foundation, Inc.
23 59 Temple Place - Suite 330
24 Boston, MA 02111-1307, USA
25
26 */
27 #ifdef HAVE_CONFIG_H
28 # include "config.h"
29 #endif
30
31 #include "QF/cmd.h"
32 #include "QF/cvar.h"
33 #include "QF/draw.h"
34 #include "QF/render.h"
35 #include "QF/sys.h"
36
37 #include "compat.h"
38 #include "r_internal.h"
39 #include "vid_internal.h"
40
41
42 static void
R_CheckVariables(void)43 R_CheckVariables (void)
44 {
45 }
46
47 /*
48 R_TimeRefresh_f
49
50 For program optimization
51 */
52 void
R_TimeRefresh_f(void)53 R_TimeRefresh_f (void)
54 {
55 int i;
56 float start, stop, time;
57 int startangle;
58 vrect_t vr;
59
60 startangle = r_refdef.viewangles[1];
61
62 start = Sys_DoubleTime ();
63 for (i = 0; i < 128; i++) {
64 r_refdef.viewangles[1] = i / 128.0 * 360.0;
65
66 VID_LockBuffer ();
67
68 R_RenderView ();
69
70 VID_UnlockBuffer ();
71
72 vr.x = r_refdef.vrect.x;
73 vr.y = r_refdef.vrect.y;
74 vr.width = r_refdef.vrect.width;
75 vr.height = r_refdef.vrect.height;
76 vr.next = NULL;
77 VID_Update (&vr);
78 }
79 stop = Sys_DoubleTime ();
80 time = stop - start;
81 Sys_Printf ("%f seconds (%f fps)\n", time, 128 / time);
82
83 r_refdef.viewangles[1] = startangle;
84 }
85
86 void
R_LoadSky_f(void)87 R_LoadSky_f (void)
88 {
89 if (Cmd_Argc () != 2) {
90 Sys_Printf ("loadsky <name> : load a skybox\n");
91 return;
92 }
93
94 R_LoadSkys (Cmd_Argv (1));
95 }
96
97 void
R_PrintTimes(void)98 R_PrintTimes (void)
99 {
100 float r_time2;
101 float ms;
102
103 r_time2 = Sys_DoubleTime ();
104
105 ms = 1000 * (r_time2 - r_time1);
106
107 Sys_Printf ("%5.1f ms %3i/%3i/%3i poly %3i surf\n",
108 ms, c_faceclip, r_polycount, r_drawnpolycount, c_surf);
109 c_surf = 0;
110 }
111
112 void
R_PrintAliasStats(void)113 R_PrintAliasStats (void)
114 {
115 Sys_Printf ("%3i polygon model drawn\n", r_amodels_drawn);
116 }
117
118 void
R_TransformFrustum(void)119 R_TransformFrustum (void)
120 {
121 int i;
122 vec3_t v, v2;
123
124 for (i = 0; i < 4; i++) {
125 v[0] = screenedge[i].normal[2];
126 v[1] = -screenedge[i].normal[0];
127 v[2] = screenedge[i].normal[1];
128
129 v2[0] = v[1] * vright[0] + v[2] * vup[0] + v[0] * vpn[0];
130 v2[1] = v[1] * vright[1] + v[2] * vup[1] + v[0] * vpn[1];
131 v2[2] = v[1] * vright[2] + v[2] * vup[2] + v[0] * vpn[2];
132
133 VectorCopy (v2, view_clipplanes[i].normal);
134
135 view_clipplanes[i].dist = DotProduct (modelorg, v2);
136 }
137 }
138
139 #ifdef PIC
140 # undef USE_INTEL_ASM //XXX asm pic hack
141 #endif
142
143 #ifndef USE_INTEL_ASM
144 void
TransformVector(const vec3_t in,vec3_t out)145 TransformVector (const vec3_t in, vec3_t out)
146 {
147 out[0] = DotProduct (in, vright);
148 out[1] = DotProduct (in, vup);
149 out[2] = DotProduct (in, vpn);
150 }
151 #endif
152
153 void
R_TransformPlane(plane_t * p,float * normal,float * dist)154 R_TransformPlane (plane_t *p, float *normal, float *dist)
155 {
156 float d;
157
158 d = DotProduct (r_origin, p->normal);
159 *dist = p->dist - d;
160 // TODO: when we have rotating entities, this will need to use the view matrix
161 TransformVector (p->normal, normal);
162 }
163
164 static void
R_SetUpFrustumIndexes(void)165 R_SetUpFrustumIndexes (void)
166 {
167 int i, j, *pindex;
168
169 pindex = r_frustum_indexes;
170
171 for (i = 0; i < 4; i++) {
172 for (j = 0; j < 3; j++) {
173 if (view_clipplanes[i].normal[j] < 0) {
174 pindex[j] = j;
175 pindex[j + 3] = j + 3;
176 } else {
177 pindex[j] = j + 3;
178 pindex[j + 3] = j;
179 }
180 }
181
182 // FIXME: do just once at start
183 pfrustum_indexes[i] = pindex;
184 pindex += 6;
185 }
186 }
187
188 void
R_SetupFrame(void)189 R_SetupFrame (void)
190 {
191 int edgecount;
192 vrect_t vrect;
193 float w, h;
194
195 // don't allow cheats in multiplayer
196 Cvar_SetValue (r_ambient, 0);
197 Cvar_SetValue (r_drawflat, 0);
198
199 if (r_numsurfs->int_val) {
200 if ((surface_p - surfaces) > r_maxsurfsseen)
201 r_maxsurfsseen = surface_p - surfaces;
202
203 Sys_Printf ("Used %ld of %ld surfs; %d max\n",
204 (long)(surface_p - surfaces),
205 (long)(surf_max - surfaces), r_maxsurfsseen);
206 }
207
208 if (r_numedges->int_val) {
209 edgecount = edge_p - r_edges;
210
211 if (edgecount > r_maxedgesseen)
212 r_maxedgesseen = edgecount;
213
214 Sys_Printf ("Used %d of %d edges; %d max\n", edgecount,
215 r_numallocatededges, r_maxedgesseen);
216 }
217
218 r_refdef.ambientlight = max (r_ambient->value, 0);
219
220 R_CheckVariables ();
221
222 R_AnimateLight ();
223 R_ClearEnts ();
224 r_framecount++;
225
226 numbtofpolys = 0;
227
228 // debugging
229 #if 0
230 r_refdef.vieworg[0] = 80;
231 r_refdef.vieworg[1] = 64;
232 r_refdef.vieworg[2] = 40;
233 r_refdef.viewangles[0] = 0;
234 r_refdef.viewangles[1] = 46.763641357;
235 r_refdef.viewangles[2] = 0;
236 #endif
237
238 // build the transformation matrix for the given view angles
239 VectorCopy (r_refdef.vieworg, modelorg);
240 VectorCopy (r_refdef.vieworg, r_origin);
241
242 AngleVectors (r_refdef.viewangles, vpn, vright, vup);
243 R_SetFrustum ();
244
245 // current viewleaf
246 r_viewleaf = Mod_PointInLeaf (r_origin, r_worldentity.model);
247
248 r_dowarpold = r_dowarp;
249 r_dowarp = r_waterwarp->int_val && (r_viewleaf->contents <=
250 CONTENTS_WATER);
251
252 if ((r_dowarp != r_dowarpold) || r_viewchanged) {
253 if (r_dowarp) {
254 if ((vid.width <= WARP_WIDTH)
255 && (vid.height <= WARP_HEIGHT)) {
256 vrect.x = 0;
257 vrect.y = 0;
258 vrect.width = vid.width;
259 vrect.height = vid.height;
260
261 R_SetVrect (&vrect, &r_refdef.vrect, vr_data.lineadj);
262 R_ViewChanged (vid.aspect);
263 } else {
264 w = vid.width;
265 h = vid.height;
266
267 if (w > WARP_WIDTH) {
268 h *= (float) WARP_WIDTH / w;
269 w = WARP_WIDTH;
270 }
271
272 if (h > WARP_HEIGHT) {
273 h = WARP_HEIGHT;
274 w *= (float) WARP_HEIGHT / h;
275 }
276
277 vrect.x = 0;
278 vrect.y = 0;
279 vrect.width = (int) w;
280 vrect.height = (int) h;
281
282 R_SetVrect (&vrect, &r_refdef.vrect,
283 (int) ((float) vr_data.lineadj *
284 (h / (float) vid.height)));
285 R_ViewChanged (vid.aspect * (h / w) * ((float) vid.width /
286 (float) vid.height));
287 }
288 } else {
289 r_refdef.vrect = scr_vrect;
290 R_ViewChanged (vid.aspect);
291 }
292
293 r_viewchanged = false;
294 }
295 // start off with just the four screen edge clip planes
296 R_TransformFrustum ();
297
298 // save base values
299 VectorCopy (vpn, base_vpn);
300 VectorCopy (vright, base_vright);
301 VectorCopy (vup, base_vup);
302 VectorCopy (modelorg, base_modelorg);
303
304 R_SetSkyFrame ();
305
306 R_SetUpFrustumIndexes ();
307
308 r_cache_thrash = false;
309
310 // clear frame counts
311 c_faceclip = 0;
312 r_polycount = 0;
313 r_drawnpolycount = 0;
314 r_amodels_drawn = 0;
315 r_outofsurfaces = 0;
316 r_outofedges = 0;
317
318 D_SetupFrame ();
319 }
320