2 Copyright (C) 1996-1997 Id Software, Inc.
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.
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.
13 See the GNU General Public License for more details.
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.
20 // r_aclip.c: clip routines for drawing Alias models directly to the screen
26 static finalvert_t fv
[2][8];
27 static auxvert_t av
[8];
29 void R_AliasProjectFinalVert (finalvert_t
*fv
, auxvert_t
*av
);
30 void R_Alias_clip_top (finalvert_t
*pfv0
, finalvert_t
*pfv1
,
32 void R_Alias_clip_bottom (finalvert_t
*pfv0
, finalvert_t
*pfv1
,
34 void R_Alias_clip_left (finalvert_t
*pfv0
, finalvert_t
*pfv1
,
36 void R_Alias_clip_right (finalvert_t
*pfv0
, finalvert_t
*pfv1
,
44 pfv0 is the unclipped vertex, pfv1 is the z-clipped vertex
47 void R_Alias_clip_z (finalvert_t
*pfv0
, finalvert_t
*pfv1
, finalvert_t
*out
)
50 auxvert_t
*pav0
, *pav1
, avout
;
52 pav0
= &av
[pfv0
- &fv
[0][0]];
53 pav1
= &av
[pfv1
- &fv
[0][0]];
55 if (pfv0
->v
[1] >= pfv1
->v
[1])
57 scale
= (ALIAS_Z_CLIP_PLANE
- pav0
->fv
[2]) /
58 (pav1
->fv
[2] - pav0
->fv
[2]);
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
;
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
;
70 scale
= (ALIAS_Z_CLIP_PLANE
- pav1
->fv
[2]) /
71 (pav0
->fv
[2] - pav1
->fv
[2]);
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
;
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
;
82 R_AliasProjectFinalVert (out
, &avout
);
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
;
97 void R_Alias_clip_left (finalvert_t
*pfv0
, finalvert_t
*pfv1
, finalvert_t
*out
)
102 if (pfv0
->v
[1] >= pfv1
->v
[1])
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;
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;
119 void R_Alias_clip_right (finalvert_t
*pfv0
, finalvert_t
*pfv1
,
125 if (pfv0
->v
[1] >= pfv1
->v
[1])
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;
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;
142 void R_Alias_clip_top (finalvert_t
*pfv0
, finalvert_t
*pfv1
, finalvert_t
*out
)
147 if (pfv0
->v
[1] >= pfv1
->v
[1])
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;
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;
164 void R_Alias_clip_bottom (finalvert_t
*pfv0
, finalvert_t
*pfv1
,
170 if (pfv0
->v
[1] >= pfv1
->v
[1])
172 scale
= (float)(r_refdef
.aliasvrectbottom
- pfv0
->v
[1]) /
173 (pfv1
->v
[1] - pfv0
->v
[1]);
175 for (i
=0 ; i
<6 ; i
++)
176 out
->v
[i
] = pfv0
->v
[i
] + (pfv1
->v
[i
] - pfv0
->v
[i
])*scale
+ 0.5;
180 scale
= (float)(r_refdef
.aliasvrectbottom
- pfv1
->v
[1]) /
181 (pfv0
->v
[1] - pfv1
->v
[1]);
183 for (i
=0 ; i
<6 ; i
++)
184 out
->v
[i
] = pfv1
->v
[i
] + (pfv0
->v
[i
] - pfv1
->v
[i
])*scale
+ 0.5;
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
) )
199 for (i
=0 ; i
<count
; j
= i
, i
++)
201 oldflags
= in
[j
].flags
& flag
;
202 flags
= in
[i
].flags
& flag
;
204 if (flags
&& oldflags
)
206 if (oldflags
^ flags
)
208 clip (&in
[j
], &in
[i
], &out
[k
]);
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
;
236 void R_AliasClipTriangle (mtriangle_t
*ptri
)
242 // copy vertexes and fix seam texture coordinates
243 if (ptri
->facesfront
)
245 fv
[0][0] = pfinalverts
[ptri
->vertindex
[0]];
246 fv
[0][1] = pfinalverts
[ptri
->vertindex
[1]];
247 fv
[0][2] = pfinalverts
[ptri
->vertindex
[2]];
251 for (i
=0 ; i
<3 ; i
++)
253 fv
[0][i
] = pfinalverts
[ptri
->vertindex
[i
]];
255 if (!ptri
->facesfront
&& (fv
[0][i
].flags
& ALIAS_ONSEAM
) )
256 fv
[0][i
].v
[2] += r_affinetridesc
.seamfixupX16
;
261 clipflags
= fv
[0][0].flags
| fv
[0][1].flags
| fv
[0][2].flags
;
263 if (clipflags
& ALIAS_Z_CLIP
)
265 for (i
=0 ; i
<3 ; i
++)
266 av
[i
] = pauxverts
[ptri
->vertindex
[i
]];
268 k
= R_AliasClip (fv
[0], fv
[1], ALIAS_Z_CLIP
, 3, R_Alias_clip_z
);
273 clipflags
= fv
[1][0].flags
| fv
[1][1].flags
| fv
[1][2].flags
;
281 if (clipflags
& ALIAS_LEFT_CLIP
)
283 k
= R_AliasClip (fv
[pingpong
], fv
[pingpong
^ 1],
284 ALIAS_LEFT_CLIP
, k
, R_Alias_clip_left
);
291 if (clipflags
& ALIAS_RIGHT_CLIP
)
293 k
= R_AliasClip (fv
[pingpong
], fv
[pingpong
^ 1],
294 ALIAS_RIGHT_CLIP
, k
, R_Alias_clip_right
);
301 if (clipflags
& ALIAS_BOTTOM_CLIP
)
303 k
= R_AliasClip (fv
[pingpong
], fv
[pingpong
^ 1],
304 ALIAS_BOTTOM_CLIP
, k
, R_Alias_clip_bottom
);
311 if (clipflags
& ALIAS_TOP_CLIP
)
313 k
= R_AliasClip (fv
[pingpong
], fv
[pingpong
^ 1],
314 ALIAS_TOP_CLIP
, k
, R_Alias_clip_top
);
321 for (i
=0 ; i
<k
; i
++)
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
;
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
;
333 fv
[pingpong
][i
].flags
= 0;
337 mtri
.facesfront
= ptri
->facesfront
;
338 r_affinetridesc
.ptriangles
= &mtri
;
339 r_affinetridesc
.pfinalverts
= fv
[pingpong
];
341 // FIXME: do all at once as trifan?
342 mtri
.vertindex
[0] = 0;
343 for (i
=1 ; i
<k
-1 ; i
++)
345 mtri
.vertindex
[1] = i
;
346 mtri
.vertindex
[2] = i
+1;