Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
5131 clevermous 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
*/
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
 
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
 
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
 
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
 
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
 
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
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
*/
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
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
344
	{
345
		mtri.vertindex[1] = i;
346
		mtri.vertindex[2] = i+1;
347
		D_PolysetDraw ();
348
	}
349
}
350