• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_aclip.c: clip routines for drawing Alias models directly to the screen
21 
22 #include "quakedef.h"
23 #include "r_local.h"
24 #include "d_local.h"
25 
26 static finalvert_t		fv[2][8];
27 static auxvert_t		av[8];
28 
29 void R_AliasProjectFinalVert (finalvert_t *fv, auxvert_t *av);
30 void R_Alias_clip_top (finalvert_t *pfv0, finalvert_t *pfv1,
31 	finalvert_t *out);
32 void R_Alias_clip_bottom (finalvert_t *pfv0, finalvert_t *pfv1,
33 	finalvert_t *out);
34 void R_Alias_clip_left (finalvert_t *pfv0, finalvert_t *pfv1,
35 	finalvert_t *out);
36 void R_Alias_clip_right (finalvert_t *pfv0, finalvert_t *pfv1,
37 	finalvert_t *out);
38 
39 
40 /*
41 ================
42 R_Alias_clip_z
43 
44 pfv0 is the unclipped vertex, pfv1 is the z-clipped vertex
45 ================
46 */
R_Alias_clip_z(finalvert_t * pfv0,finalvert_t * pfv1,finalvert_t * out)47 void R_Alias_clip_z (finalvert_t *pfv0, finalvert_t *pfv1, finalvert_t *out)
48 {
49 	float		scale;
50 	auxvert_t	*pav0, *pav1, avout;
51 
52 	pav0 = &av[pfv0 - &fv[0][0]];
53 	pav1 = &av[pfv1 - &fv[0][0]];
54 
55 	if (pfv0->v[1] >= pfv1->v[1])
56 	{
57 		scale = (ALIAS_Z_CLIP_PLANE - pav0->fv[2]) /
58 				(pav1->fv[2] - pav0->fv[2]);
59 
60 		avout.fv[0] = pav0->fv[0] + (pav1->fv[0] - pav0->fv[0]) * scale;
61 		avout.fv[1] = pav0->fv[1] + (pav1->fv[1] - pav0->fv[1]) * scale;
62 		avout.fv[2] = ALIAS_Z_CLIP_PLANE;
63 
64 		out->v[2] =	pfv0->v[2] + (pfv1->v[2] - pfv0->v[2]) * scale;
65 		out->v[3] =	pfv0->v[3] + (pfv1->v[3] - pfv0->v[3]) * scale;
66 		out->v[4] =	pfv0->v[4] + (pfv1->v[4] - pfv0->v[4]) * scale;
67 	}
68 	else
69 	{
70 		scale = (ALIAS_Z_CLIP_PLANE - pav1->fv[2]) /
71 				(pav0->fv[2] - pav1->fv[2]);
72 
73 		avout.fv[0] = pav1->fv[0] + (pav0->fv[0] - pav1->fv[0]) * scale;
74 		avout.fv[1] = pav1->fv[1] + (pav0->fv[1] - pav1->fv[1]) * scale;
75 		avout.fv[2] = ALIAS_Z_CLIP_PLANE;
76 
77 		out->v[2] =	pfv1->v[2] + (pfv0->v[2] - pfv1->v[2]) * scale;
78 		out->v[3] =	pfv1->v[3] + (pfv0->v[3] - pfv1->v[3]) * scale;
79 		out->v[4] =	pfv1->v[4] + (pfv0->v[4] - pfv1->v[4]) * scale;
80 	}
81 
82 	R_AliasProjectFinalVert (out, &avout);
83 
84 	if (out->v[0] < r_refdef.aliasvrect.x)
85 		out->flags |= ALIAS_LEFT_CLIP;
86 	if (out->v[1] < r_refdef.aliasvrect.y)
87 		out->flags |= ALIAS_TOP_CLIP;
88 	if (out->v[0] > r_refdef.aliasvrectright)
89 		out->flags |= ALIAS_RIGHT_CLIP;
90 	if (out->v[1] > r_refdef.aliasvrectbottom)
91 		out->flags |= ALIAS_BOTTOM_CLIP;
92 }
93 
94 
95 #if	!id386
96 
R_Alias_clip_left(finalvert_t * pfv0,finalvert_t * pfv1,finalvert_t * out)97 void R_Alias_clip_left (finalvert_t *pfv0, finalvert_t *pfv1, finalvert_t *out)
98 {
99 	float		scale;
100 	int			i;
101 
102 	if (pfv0->v[1] >= pfv1->v[1])
103 	{
104 		scale = (float)(r_refdef.aliasvrect.x - pfv0->v[0]) /
105 				(pfv1->v[0] - pfv0->v[0]);
106 		for (i=0 ; i<6 ; i++)
107 			out->v[i] = pfv0->v[i] + (pfv1->v[i] - pfv0->v[i])*scale + 0.5;
108 	}
109 	else
110 	{
111 		scale = (float)(r_refdef.aliasvrect.x - pfv1->v[0]) /
112 				(pfv0->v[0] - pfv1->v[0]);
113 		for (i=0 ; i<6 ; i++)
114 			out->v[i] = pfv1->v[i] + (pfv0->v[i] - pfv1->v[i])*scale + 0.5;
115 	}
116 }
117 
118 
R_Alias_clip_right(finalvert_t * pfv0,finalvert_t * pfv1,finalvert_t * out)119 void R_Alias_clip_right (finalvert_t *pfv0, finalvert_t *pfv1,
120 	finalvert_t *out)
121 {
122 	float		scale;
123 	int			i;
124 
125 	if (pfv0->v[1] >= pfv1->v[1])
126 	{
127 		scale = (float)(r_refdef.aliasvrectright - pfv0->v[0]) /
128 				(pfv1->v[0] - pfv0->v[0]);
129 		for (i=0 ; i<6 ; i++)
130 			out->v[i] = pfv0->v[i] + (pfv1->v[i] - pfv0->v[i])*scale + 0.5;
131 	}
132 	else
133 	{
134 		scale = (float)(r_refdef.aliasvrectright - pfv1->v[0]) /
135 				(pfv0->v[0] - pfv1->v[0]);
136 		for (i=0 ; i<6 ; i++)
137 			out->v[i] = pfv1->v[i] + (pfv0->v[i] - pfv1->v[i])*scale + 0.5;
138 	}
139 }
140 
141 
R_Alias_clip_top(finalvert_t * pfv0,finalvert_t * pfv1,finalvert_t * out)142 void R_Alias_clip_top (finalvert_t *pfv0, finalvert_t *pfv1, finalvert_t *out)
143 {
144 	float		scale;
145 	int			i;
146 
147 	if (pfv0->v[1] >= pfv1->v[1])
148 	{
149 		scale = (float)(r_refdef.aliasvrect.y - pfv0->v[1]) /
150 				(pfv1->v[1] - pfv0->v[1]);
151 		for (i=0 ; i<6 ; i++)
152 			out->v[i] = pfv0->v[i] + (pfv1->v[i] - pfv0->v[i])*scale + 0.5;
153 	}
154 	else
155 	{
156 		scale = (float)(r_refdef.aliasvrect.y - pfv1->v[1]) /
157 				(pfv0->v[1] - pfv1->v[1]);
158 		for (i=0 ; i<6 ; i++)
159 			out->v[i] = pfv1->v[i] + (pfv0->v[i] - pfv1->v[i])*scale + 0.5;
160 	}
161 }
162 
163 
R_Alias_clip_bottom(finalvert_t * pfv0,finalvert_t * pfv1,finalvert_t * out)164 void R_Alias_clip_bottom (finalvert_t *pfv0, finalvert_t *pfv1,
165 	finalvert_t *out)
166 {
167 	float		scale;
168 	int			i;
169 
170 	if (pfv0->v[1] >= pfv1->v[1])
171 	{
172 		scale = (float)(r_refdef.aliasvrectbottom - pfv0->v[1]) /
173 				(pfv1->v[1] - pfv0->v[1]);
174 
175 		for (i=0 ; i<6 ; i++)
176 			out->v[i] = pfv0->v[i] + (pfv1->v[i] - pfv0->v[i])*scale + 0.5;
177 	}
178 	else
179 	{
180 		scale = (float)(r_refdef.aliasvrectbottom - pfv1->v[1]) /
181 				(pfv0->v[1] - pfv1->v[1]);
182 
183 		for (i=0 ; i<6 ; i++)
184 			out->v[i] = pfv1->v[i] + (pfv0->v[i] - pfv1->v[i])*scale + 0.5;
185 	}
186 }
187 
188 #endif
189 
190 
R_AliasClip(finalvert_t * in,finalvert_t * out,int flag,int count,void (* clip)(finalvert_t * pfv0,finalvert_t * pfv1,finalvert_t * out))191 int R_AliasClip (finalvert_t *in, finalvert_t *out, int flag, int count,
192 	void(*clip)(finalvert_t *pfv0, finalvert_t *pfv1, finalvert_t *out) )
193 {
194 	int			i,j,k;
195 	int			flags, oldflags;
196 
197 	j = count-1;
198 	k = 0;
199 	for (i=0 ; i<count ; j = i, i++)
200 	{
201 		oldflags = in[j].flags & flag;
202 		flags = in[i].flags & flag;
203 
204 		if (flags && oldflags)
205 			continue;
206 		if (oldflags ^ flags)
207 		{
208 			clip (&in[j], &in[i], &out[k]);
209 			out[k].flags = 0;
210 			if (out[k].v[0] < r_refdef.aliasvrect.x)
211 				out[k].flags |= ALIAS_LEFT_CLIP;
212 			if (out[k].v[1] < r_refdef.aliasvrect.y)
213 				out[k].flags |= ALIAS_TOP_CLIP;
214 			if (out[k].v[0] > r_refdef.aliasvrectright)
215 				out[k].flags |= ALIAS_RIGHT_CLIP;
216 			if (out[k].v[1] > r_refdef.aliasvrectbottom)
217 				out[k].flags |= ALIAS_BOTTOM_CLIP;
218 			k++;
219 		}
220 		if (!flags)
221 		{
222 			out[k] = in[i];
223 			k++;
224 		}
225 	}
226 
227 	return k;
228 }
229 
230 
231 /*
232 ================
233 R_AliasClipTriangle
234 ================
235 */
R_AliasClipTriangle(mtriangle_t * ptri)236 void R_AliasClipTriangle (mtriangle_t *ptri)
237 {
238 	int				i, k, pingpong;
239 	mtriangle_t		mtri;
240 	unsigned		clipflags;
241 
242 // copy vertexes and fix seam texture coordinates
243 	if (ptri->facesfront)
244 	{
245 		fv[0][0] = pfinalverts[ptri->vertindex[0]];
246 		fv[0][1] = pfinalverts[ptri->vertindex[1]];
247 		fv[0][2] = pfinalverts[ptri->vertindex[2]];
248 	}
249 	else
250 	{
251 		for (i=0 ; i<3 ; i++)
252 		{
253 			fv[0][i] = pfinalverts[ptri->vertindex[i]];
254 
255 			if (!ptri->facesfront && (fv[0][i].flags & ALIAS_ONSEAM) )
256 				fv[0][i].v[2] += r_affinetridesc.seamfixupX16;
257 		}
258 	}
259 
260 // clip
261 	clipflags = fv[0][0].flags | fv[0][1].flags | fv[0][2].flags;
262 
263 	if (clipflags & ALIAS_Z_CLIP)
264 	{
265 		for (i=0 ; i<3 ; i++)
266 			av[i] = pauxverts[ptri->vertindex[i]];
267 
268 		k = R_AliasClip (fv[0], fv[1], ALIAS_Z_CLIP, 3, R_Alias_clip_z);
269 		if (k == 0)
270 			return;
271 
272 		pingpong = 1;
273 		clipflags = fv[1][0].flags | fv[1][1].flags | fv[1][2].flags;
274 	}
275 	else
276 	{
277 		pingpong = 0;
278 		k = 3;
279 	}
280 
281 	if (clipflags & ALIAS_LEFT_CLIP)
282 	{
283 		k = R_AliasClip (fv[pingpong], fv[pingpong ^ 1],
284 							ALIAS_LEFT_CLIP, k, R_Alias_clip_left);
285 		if (k == 0)
286 			return;
287 
288 		pingpong ^= 1;
289 	}
290 
291 	if (clipflags & ALIAS_RIGHT_CLIP)
292 	{
293 		k = R_AliasClip (fv[pingpong], fv[pingpong ^ 1],
294 							ALIAS_RIGHT_CLIP, k, R_Alias_clip_right);
295 		if (k == 0)
296 			return;
297 
298 		pingpong ^= 1;
299 	}
300 
301 	if (clipflags & ALIAS_BOTTOM_CLIP)
302 	{
303 		k = R_AliasClip (fv[pingpong], fv[pingpong ^ 1],
304 							ALIAS_BOTTOM_CLIP, k, R_Alias_clip_bottom);
305 		if (k == 0)
306 			return;
307 
308 		pingpong ^= 1;
309 	}
310 
311 	if (clipflags & ALIAS_TOP_CLIP)
312 	{
313 		k = R_AliasClip (fv[pingpong], fv[pingpong ^ 1],
314 							ALIAS_TOP_CLIP, k, R_Alias_clip_top);
315 		if (k == 0)
316 			return;
317 
318 		pingpong ^= 1;
319 	}
320 
321 	for (i=0 ; i<k ; i++)
322 	{
323 		if (fv[pingpong][i].v[0] < r_refdef.aliasvrect.x)
324 			fv[pingpong][i].v[0] = r_refdef.aliasvrect.x;
325 		else if (fv[pingpong][i].v[0] > r_refdef.aliasvrectright)
326 			fv[pingpong][i].v[0] = r_refdef.aliasvrectright;
327 
328 		if (fv[pingpong][i].v[1] < r_refdef.aliasvrect.y)
329 			fv[pingpong][i].v[1] = r_refdef.aliasvrect.y;
330 		else if (fv[pingpong][i].v[1] > r_refdef.aliasvrectbottom)
331 			fv[pingpong][i].v[1] = r_refdef.aliasvrectbottom;
332 
333 		fv[pingpong][i].flags = 0;
334 	}
335 
336 // draw triangles
337 	mtri.facesfront = ptri->facesfront;
338 	r_affinetridesc.ptriangles = &mtri;
339 	r_affinetridesc.pfinalverts = fv[pingpong];
340 
341 // FIXME: do all at once as trifan?
342 	mtri.vertindex[0] = 0;
343 	for (i=1 ; i<k-1 ; i++)
344 	{
345 		mtri.vertindex[1] = i;
346 		mtri.vertindex[2] = i+1;
347 		D_PolysetDraw ();
348 	}
349 }
350 
351