icculus quake2 doxygen  1.0 dev
r_aclip.c
Go to the documentation of this file.
1 /*
2 Copyright (C) 1997-2001 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 "r_local.h"
23 
24 static finalvert_t fv[2][8];
25 
27 void R_Alias_clip_top (finalvert_t *pfv0, finalvert_t *pfv1,
28  finalvert_t *out);
30  finalvert_t *out);
31 void R_Alias_clip_left (finalvert_t *pfv0, finalvert_t *pfv1,
32  finalvert_t *out);
33 void R_Alias_clip_right (finalvert_t *pfv0, finalvert_t *pfv1,
34  finalvert_t *out);
35 
36 
37 /*
38 ================
39 R_Alias_clip_z
40 
41 pfv0 is the unclipped vertex, pfv1 is the z-clipped vertex
42 ================
43 */
45 {
46  float scale;
47 
48  scale = (ALIAS_Z_CLIP_PLANE - pfv0->xyz[2]) /
49  (pfv1->xyz[2] - pfv0->xyz[2]);
50 
51  out->xyz[0] = pfv0->xyz[0] + (pfv1->xyz[0] - pfv0->xyz[0]) * scale;
52  out->xyz[1] = pfv0->xyz[1] + (pfv1->xyz[1] - pfv0->xyz[1]) * scale;
53  out->xyz[2] = ALIAS_Z_CLIP_PLANE;
54 
55  out->s = pfv0->s + (pfv1->s - pfv0->s) * scale;
56  out->t = pfv0->t + (pfv1->t - pfv0->t) * scale;
57  out->l = pfv0->l + (pfv1->l - pfv0->l) * scale;
58 
60 }
61 
62 
63 #if !id386
64 
66 {
67  float scale;
68 
69  if (pfv0->v >= pfv1->v )
70  {
71  scale = (float)(r_refdef.aliasvrect.x - pfv0->u) /
72  (pfv1->u - pfv0->u);
73  out->u = pfv0->u + ( pfv1->u - pfv0->u ) * scale + 0.5;
74  out->v = pfv0->v + ( pfv1->v - pfv0->v ) * scale + 0.5;
75  out->s = pfv0->s + ( pfv1->s - pfv0->s ) * scale + 0.5;
76  out->t = pfv0->t + ( pfv1->t - pfv0->t ) * scale + 0.5;
77  out->l = pfv0->l + ( pfv1->l - pfv0->l ) * scale + 0.5;
78  out->zi = pfv0->zi + ( pfv1->zi - pfv0->zi) * scale + 0.5;
79  }
80  else
81  {
82  scale = (float)(r_refdef.aliasvrect.x - pfv1->u) /
83  (pfv0->u - pfv1->u);
84  out->u = pfv1->u + ( pfv0->u - pfv1->u ) * scale + 0.5;
85  out->v = pfv1->v + ( pfv0->v - pfv1->v ) * scale + 0.5;
86  out->s = pfv1->s + ( pfv0->s - pfv1->s ) * scale + 0.5;
87  out->t = pfv1->t + ( pfv0->t - pfv1->t ) * scale + 0.5;
88  out->l = pfv1->l + ( pfv0->l - pfv1->l ) * scale + 0.5;
89  out->zi = pfv1->zi + ( pfv0->zi - pfv1->zi) * scale + 0.5;
90  }
91 }
92 
93 
95 {
96  float scale;
97 
98  if ( pfv0->v >= pfv1->v )
99  {
100  scale = (float)(r_refdef.aliasvrectright - pfv0->u ) /
101  (pfv1->u - pfv0->u );
102  out->u = pfv0->u + ( pfv1->u - pfv0->u ) * scale + 0.5;
103  out->v = pfv0->v + ( pfv1->v - pfv0->v ) * scale + 0.5;
104  out->s = pfv0->s + ( pfv1->s - pfv0->s ) * scale + 0.5;
105  out->t = pfv0->t + ( pfv1->t - pfv0->t ) * scale + 0.5;
106  out->l = pfv0->l + ( pfv1->l - pfv0->l ) * scale + 0.5;
107  out->zi = pfv0->zi + ( pfv1->zi - pfv0->zi) * scale + 0.5;
108  }
109  else
110  {
111  scale = (float)(r_refdef.aliasvrectright - pfv1->u ) /
112  (pfv0->u - pfv1->u );
113  out->u = pfv1->u + ( pfv0->u - pfv1->u ) * scale + 0.5;
114  out->v = pfv1->v + ( pfv0->v - pfv1->v ) * scale + 0.5;
115  out->s = pfv1->s + ( pfv0->s - pfv1->s ) * scale + 0.5;
116  out->t = pfv1->t + ( pfv0->t - pfv1->t ) * scale + 0.5;
117  out->l = pfv1->l + ( pfv0->l - pfv1->l ) * scale + 0.5;
118  out->zi = pfv1->zi + ( pfv0->zi - pfv1->zi) * scale + 0.5;
119  }
120 }
121 
122 
124 {
125  float scale;
126 
127  if (pfv0->v >= pfv1->v)
128  {
129  scale = (float)(r_refdef.aliasvrect.y - pfv0->v) /
130  (pfv1->v - pfv0->v);
131  out->u = pfv0->u + ( pfv1->u - pfv0->u ) * scale + 0.5;
132  out->v = pfv0->v + ( pfv1->v - pfv0->v ) * scale + 0.5;
133  out->s = pfv0->s + ( pfv1->s - pfv0->s ) * scale + 0.5;
134  out->t = pfv0->t + ( pfv1->t - pfv0->t ) * scale + 0.5;
135  out->l = pfv0->l + ( pfv1->l - pfv0->l ) * scale + 0.5;
136  out->zi = pfv0->zi + ( pfv1->zi - pfv0->zi) * scale + 0.5;
137  }
138  else
139  {
140  scale = (float)(r_refdef.aliasvrect.y - pfv1->v) /
141  (pfv0->v - pfv1->v);
142  out->u = pfv1->u + ( pfv0->u - pfv1->u ) * scale + 0.5;
143  out->v = pfv1->v + ( pfv0->v - pfv1->v ) * scale + 0.5;
144  out->s = pfv1->s + ( pfv0->s - pfv1->s ) * scale + 0.5;
145  out->t = pfv1->t + ( pfv0->t - pfv1->t ) * scale + 0.5;
146  out->l = pfv1->l + ( pfv0->l - pfv1->l ) * scale + 0.5;
147  out->zi = pfv1->zi + ( pfv0->zi - pfv1->zi) * scale + 0.5;
148  }
149 }
150 
151 
153  finalvert_t *out)
154 {
155  float scale;
156 
157  if (pfv0->v >= pfv1->v)
158  {
159  scale = (float)(r_refdef.aliasvrectbottom - pfv0->v) /
160  (pfv1->v - pfv0->v);
161 
162  out->u = pfv0->u + ( pfv1->u - pfv0->u ) * scale + 0.5;
163  out->v = pfv0->v + ( pfv1->v - pfv0->v ) * scale + 0.5;
164  out->s = pfv0->s + ( pfv1->s - pfv0->s ) * scale + 0.5;
165  out->t = pfv0->t + ( pfv1->t - pfv0->t ) * scale + 0.5;
166  out->l = pfv0->l + ( pfv1->l - pfv0->l ) * scale + 0.5;
167  out->zi = pfv0->zi + ( pfv1->zi - pfv0->zi) * scale + 0.5;
168  }
169  else
170  {
171  scale = (float)(r_refdef.aliasvrectbottom - pfv1->v) /
172  (pfv0->v - pfv1->v);
173 
174  out->u = pfv1->u + ( pfv0->u - pfv1->u ) * scale + 0.5;
175  out->v = pfv1->v + ( pfv0->v - pfv1->v ) * scale + 0.5;
176  out->s = pfv1->s + ( pfv0->s - pfv1->s ) * scale + 0.5;
177  out->t = pfv1->t + ( pfv0->t - pfv1->t ) * scale + 0.5;
178  out->l = pfv1->l + ( pfv0->l - pfv1->l ) * scale + 0.5;
179  out->zi = pfv1->zi + ( pfv0->zi - pfv1->zi) * scale + 0.5;
180  }
181 }
182 
183 #endif
184 
185 
186 int R_AliasClip (finalvert_t *in, finalvert_t *out, int flag, int count,
187  void(*clip)(finalvert_t *pfv0, finalvert_t *pfv1, finalvert_t *out) )
188 {
189  int i,j,k;
190  int flags, oldflags;
191 
192  j = count-1;
193  k = 0;
194  for (i=0 ; i<count ; j = i, i++)
195  {
196  oldflags = in[j].flags & flag;
197  flags = in[i].flags & flag;
198 
199  if (flags && oldflags)
200  continue;
201  if (oldflags ^ flags)
202  {
203  clip (&in[j], &in[i], &out[k]);
204  out[k].flags = 0;
205  if (out[k].u < r_refdef.aliasvrect.x)
206  out[k].flags |= ALIAS_LEFT_CLIP;
207  if (out[k].v < r_refdef.aliasvrect.y)
208  out[k].flags |= ALIAS_TOP_CLIP;
209  if (out[k].u > r_refdef.aliasvrectright)
210  out[k].flags |= ALIAS_RIGHT_CLIP;
211  if (out[k].v > r_refdef.aliasvrectbottom)
212  out[k].flags |= ALIAS_BOTTOM_CLIP;
213  k++;
214  }
215  if (!flags)
216  {
217  out[k] = in[i];
218  k++;
219  }
220  }
221 
222  return k;
223 }
224 
225 
226 /*
227 ================
228 R_AliasClipTriangle
229 ================
230 */
231 void R_AliasClipTriangle (finalvert_t *index0, finalvert_t *index1, finalvert_t *index2)
232 {
233  int i, k, pingpong;
234  unsigned clipflags;
235 
236 // copy vertexes and fix seam texture coordinates
237  fv[0][0] = *index0;
238  fv[0][1] = *index1;
239  fv[0][2] = *index2;
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  k = R_AliasClip (fv[0], fv[1], ALIAS_Z_CLIP, 3, R_Alias_clip_z);
247  if (k == 0)
248  return;
249 
250  pingpong = 1;
251  clipflags = fv[1][0].flags | fv[1][1].flags | fv[1][2].flags;
252  }
253  else
254  {
255  pingpong = 0;
256  k = 3;
257  }
258 
259  if (clipflags & ALIAS_LEFT_CLIP)
260  {
261  k = R_AliasClip (fv[pingpong], fv[pingpong ^ 1],
263  if (k == 0)
264  return;
265 
266  pingpong ^= 1;
267  }
268 
269  if (clipflags & ALIAS_RIGHT_CLIP)
270  {
271  k = R_AliasClip (fv[pingpong], fv[pingpong ^ 1],
273  if (k == 0)
274  return;
275 
276  pingpong ^= 1;
277  }
278 
279  if (clipflags & ALIAS_BOTTOM_CLIP)
280  {
281  k = R_AliasClip (fv[pingpong], fv[pingpong ^ 1],
283  if (k == 0)
284  return;
285 
286  pingpong ^= 1;
287  }
288 
289  if (clipflags & ALIAS_TOP_CLIP)
290  {
291  k = R_AliasClip (fv[pingpong], fv[pingpong ^ 1],
293  if (k == 0)
294  return;
295 
296  pingpong ^= 1;
297  }
298 
299  for (i=0 ; i<k ; i++)
300  {
301  if (fv[pingpong][i].u < r_refdef.aliasvrect.x)
302  fv[pingpong][i].u = r_refdef.aliasvrect.x;
303  else if (fv[pingpong][i].u > r_refdef.aliasvrectright)
304  fv[pingpong][i].u = r_refdef.aliasvrectright;
305 
306  if (fv[pingpong][i].v < r_refdef.aliasvrect.y)
307  fv[pingpong][i].v = r_refdef.aliasvrect.y;
308  else if (fv[pingpong][i].v > r_refdef.aliasvrectbottom)
309  fv[pingpong][i].v = r_refdef.aliasvrectbottom;
310 
311  fv[pingpong][i].flags = 0;
312  }
313 
314 // draw triangles
315  for (i=1 ; i<k-1 ; i++)
316  {
317  aliastriangleparms.a = &fv[pingpong][0];
318  aliastriangleparms.b = &fv[pingpong][i];
319  aliastriangleparms.c = &fv[pingpong][i+1];
320  R_DrawTriangle();
321  }
322 }
323 
R_Alias_clip_bottom
void R_Alias_clip_bottom(finalvert_t *pfv0, finalvert_t *pfv1, finalvert_t *out)
Definition: r_aclip.c:152
ALIAS_Z_CLIP_PLANE
#define ALIAS_Z_CLIP_PLANE
Definition: r_local.h:227
finalvert_s::u
int u
Definition: r_local.h:282
aliastriangleparms_t::b
finalvert_t * b
Definition: r_local.h:712
R_Alias_clip_z
void R_Alias_clip_z(finalvert_t *pfv0, finalvert_t *pfv1, finalvert_t *out)
Definition: r_aclip.c:44
v
GLdouble v
Definition: qgl_win.c:143
R_AliasClip
int R_AliasClip(finalvert_t *in, finalvert_t *out, int flag, int count, void(*clip)(finalvert_t *pfv0, finalvert_t *pfv1, finalvert_t *out))
Definition: r_aclip.c:186
i
int i
Definition: q_shared.c:305
finalvert_s::t
int t
Definition: r_local.h:282
r_local.h
finalvert_s
Definition: r_local.h:281
R_DrawTriangle
void R_DrawTriangle(void)
Definition: r_polyse.c:204
R_AliasClipTriangle
void R_AliasClipTriangle(finalvert_t *index0, finalvert_t *index1, finalvert_t *index2)
Definition: r_aclip.c:231
R_AliasProjectAndClipTestFinalVert
void R_AliasProjectAndClipTestFinalVert(finalvert_t *fv)
Definition: r_alias.c:803
ALIAS_Z_CLIP
#define ALIAS_Z_CLIP
Definition: r_local.h:207
j
GLint j
Definition: qgl_win.c:150
finalvert_s::v
int v
Definition: r_local.h:282
fv
static finalvert_t fv[2][8]
Definition: r_aclip.c:24
R_Alias_clip_right
void R_Alias_clip_right(finalvert_t *pfv0, finalvert_t *pfv1, finalvert_t *out)
Definition: r_aclip.c:94
R_Alias_clip_left
void R_Alias_clip_left(finalvert_t *pfv0, finalvert_t *pfv1, finalvert_t *out)
Definition: r_aclip.c:65
ALIAS_BOTTOM_CLIP
#define ALIAS_BOTTOM_CLIP
Definition: r_local.h:206
oldrefdef_t::aliasvrectbottom
int aliasvrectbottom
Definition: r_local.h:116
finalvert_s::xyz
float xyz[3]
Definition: r_local.h:286
vrect_s::x
int x
Definition: vid.h:24
finalvert_s::zi
int zi
Definition: r_local.h:284
aliastriangleparms_t::a
finalvert_t * a
Definition: r_local.h:712
oldrefdef_t::aliasvrectright
int aliasvrectright
Definition: r_local.h:116
R_Alias_clip_top
void R_Alias_clip_top(finalvert_t *pfv0, finalvert_t *pfv1, finalvert_t *out)
Definition: r_aclip.c:123
ALIAS_LEFT_CLIP
#define ALIAS_LEFT_CLIP
Definition: r_local.h:203
finalvert_s::s
int s
Definition: r_local.h:282
ALIAS_TOP_CLIP
#define ALIAS_TOP_CLIP
Definition: r_local.h:204
finalvert_s::flags
int flags
Definition: r_local.h:285
aliastriangleparms_t::c
finalvert_t * c
Definition: r_local.h:712
aliastriangleparms
aliastriangleparms_t aliastriangleparms
Definition: r_polyse.c:59
oldrefdef_t::aliasvrect
vrect_t aliasvrect
Definition: r_local.h:114
finalvert_s::l
int l
Definition: r_local.h:283
r_refdef
oldrefdef_t r_refdef
Definition: r_main.c:74
count
GLint GLsizei count
Definition: qgl_win.c:128
vrect_s::y
int y
Definition: vid.h:24
ALIAS_RIGHT_CLIP
#define ALIAS_RIGHT_CLIP
Definition: r_local.h:205