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