FTEQW
Documentation of the FTE engine source tree.
sw_spans.h
Go to the documentation of this file.
1/*
2this file is expected to be #included as the body of a real function
3to define create a new pixel shader, define PLOT_PIXEL(outval) at the top of your function and you're good to go
4
5//modifiers:
6SPAN_ST - interpolates S+T across the span. access with 'sc' and 'tc'
7 affine... no perspective correction.
8
9
10*/
11
12{
13 swvert_t *vt;
14 int y;
16 int xl,xld, xr,xrd;
17#ifdef SPAN_ST
18 float sl,sld, sd;
19 float tl,tld, td;
20#endif
21#ifdef SPAN_Z
22 unsigned int zl,zld, zd;
23#endif
24 unsigned int *restrict outbuf;
25 unsigned int *restrict ti;
26 int i;
27 const swvert_t *vlt,*vlb,*vrt,*vrb;
30 unsigned int *vplout;
31 int dx, dy;
34
36
37 if (!img)
38 return;
39
40 /*we basically render a diamond
41 that is, the single triangle is split into two triangles, outwards towards the midpoint and inwards to the final position.
42 */
43
44 /*reorder the verticies for height*/
45 if (v1->vcoord[1] > v2->vcoord[1])
46 {
47 vt = v1;
48 v1 = v2;
49 v2 = vt;
50 }
51 if (v1->vcoord[1] > v3->vcoord[1])
52 {
53 vt = v1;
54 v1 = v3;
55 v3 = vt;
56 }
57 if (v2->vcoord[1] > v3->vcoord[1])
58 {
59 vt = v3;
60 v3 = v2;
61 v2 = vt;
62 }
63
64 {
65 const swvert_t *v[3];
66
67 v[0] = v1;
68 v[1] = v2;
69 v[2] = v3;
70
71 //reject triangles with any point offscreen, for now
72 for (i = 0; i < 3; i++)
73 {
74 if (v[i]->vcoord[0] < 0 || v[i]->vcoord[0] >= th->vpwidth)
75 return;
76 if (v[i]->vcoord[1] < 0 || v[i]->vcoord[1] >= th->vpheight)
77 return;
78 if (v[i]->vcoord[2] < 0)
79 return;
80 }
81
82 for (i = 0; i < 2; i++)
83 {
84 if (v[i]->vcoord[1] > v[i+1]->vcoord[1])
85 return;
86 }
87 }
88
89 fdx1 = v2->vcoord[0] - v1->vcoord[0];
90 fdy1 = v2->vcoord[1] - v1->vcoord[1];
91
92 fdx2 = v3->vcoord[0] - v1->vcoord[0];
93 fdy2 = v3->vcoord[1] - v1->vcoord[1];
94
95 fz = fdx1*fdy2 - fdx2*fdy1;
96
97 if (fz == 0)
98 {
99 //weird angle...
100 return;
101 }
102
103 fz = 1.0 / fz;
104 fdx1 *= fz;
105 fdy1 *= fz;
106 fdx2 *= fz;
107 fdy2 *= fz;
108
109#ifdef SPAN_ST //affine
110 d1 = v2->tccoord[0] - v1->tccoord[0];
111 d2 = v3->tccoord[0] - v1->tccoord[0];
112 sld = fdx1*d2 - fdx2*d1;
113 sd = fdy2*d1 - fdy1*d2;
114
115 d1 = v2->tccoord[1] - v1->tccoord[1];
116 d2 = v3->tccoord[1] - v1->tccoord[1];
117 tld = fdx1*d2 - fdx2*d1;
118 td = fdy2*d1 - fdy1*d2;
119#endif
120#ifdef SPAN_Z
121 d1 = (v2->vcoord[2] - v1->vcoord[2])*UINT_MAX;
122 d2 = (v3->vcoord[2] - v1->vcoord[2])*UINT_MAX;
123 zld = fdx1*d2 - fdx2*d1;
124 zd = fdy2*d1 - fdy1*d2;
125#endif
126
127 ti = img->data;
128
129 y = v1->vcoord[1];
130
132 {
133 if (secondhalf)
134 {
135 if (numspans < 0)
136 {
138 y+=interlace;
140
141 xl += xld*interlace;
142 xr += xrd*interlace;
143 vplout += th->vpcstride*interlace;
144
145#ifdef SPAN_ST
146 sl += sld*interlace;
147 tl += tld*interlace;
148#endif
149#ifdef SPAN_Z
150 zl += zld*interlace;
151#endif
152 }
153
154 /*v2->v3*/
155 if (fz <= 0)
156 {
157 vlt = v2;
158 //vrt == v1;
159 vlb = v3;
160 //vrb == v3;
161
162 recalcside = 1;
163
164#ifdef SPAN_ST
165 sld -= sd*xld/(float)(1<<16);
166 tld -= td*xld/(float)(1<<16);
167#endif
168#ifdef SPAN_Z
169 zld -= zd*xld/(float)(1<<16);
170#endif
171 }
172 else
173 {
174 //vlt == v1;
175 vrt = v2;
177 vrb = v3;
178
179 recalcside = 2;
180 }
181
182 //flip the triangle to keep it facing the screen (we swapped the verts almost randomly)
183 numspans = v3->vcoord[1] - y;
184 }
185 else
186 {
187 vlt = v1;
188 vrt = v1;
189 /*v1->v2*/
190 if (fz < 0)
191 {
192 vlb = v2;
193 vrb = v3;
194 }
195 else
196 {
197 vlb = v3;
198 vrb = v2;
199 }
200 recalcside = 3;
201
202 //flip the triangle to keep it facing the screen (we swapped the verts almost randomly)
203 numspans = v2->vcoord[1] - y;
204 }
205
206 if (recalcside & 1)
207 {
208 dx = (vlb->vcoord[0] - vlt->vcoord[0]);
209 dy = (vlb->vcoord[1] - vlt->vcoord[1]);
210 if (dy > 0)
211 xld = (dx<<16) / dy;
212 else
213 xld = 0;
214 xl = (int)vlt->vcoord[0]<<16;
215
216#ifdef SPAN_ST
217 sl = vlt->tccoord[0];
218 sld = sld + sd*xld/(float)(1<<16);
219 tl = vlt->tccoord[1];
220 tld = tld + td*xld/(float)(1<<16);
221#endif
222#ifdef SPAN_Z
223 zl = vlt->vcoord[2]*UINT_MAX;
224 zld = zld + zd*xld/(float)(1<<16);
225#endif
226 }
227
228 if (recalcside & 2)
229 {
230 dx = (vrb->vcoord[0] - vrt->vcoord[0]);
231 dy = (vrb->vcoord[1] - vrt->vcoord[1]);
232 if (dy)
233 xrd = (dx<<16) / dy;
234 else
235 xrd = 0;
236 xr = (int)vrt->vcoord[0]<<16;
237 }
238
239
240
241 if (y + numspans >= th->vpheight)
242 numspans = th->vpheight - y - 1;
243
244 if (numspans <= 0)
245 continue;
246
247
248 vplout = th->vpcbuf + y * th->vpcstride; //this is a pointer to the left of the viewport buffer.
249
250 interlace = ((y + th->interlaceline) % th->interlacemod);
251 if (interlace)
252 {
253 if (interlace > numspans)
254 {
256 y+=interlace;
257 }
258 else
259 {
260 y+=interlace;
262 }
263 xl += xld*interlace;
264 xr += xrd*interlace;
265 vplout += th->vpcstride*interlace;
266
267#ifdef SPAN_ST
268 sl += sld*interlace;
269 tl += tld*interlace;
270#endif
271#ifdef SPAN_Z
272 zl += zld*interlace;
273#endif
274 }
275
276 for (; numspans > 0;
277 numspans -= th->interlacemod
278 ,xl += xld*th->interlacemod
279 ,xr += xrd*th->interlacemod
280 ,vplout += th->vpcstride*th->interlacemod
281 ,y += th->interlacemod
282
283#ifdef SPAN_ST
284 ,sl += sld*th->interlacemod
285 ,tl += tld*th->interlacemod
286#endif
287#ifdef SPAN_Z
288 ,zl += zld*th->interlacemod
289#endif
290 )
291 {
292#ifdef SPAN_ST
293 float s = sl;
294 float t = tl;
295#endif
296#ifdef SPAN_Z
297 unsigned int z = zl;
298 unsigned int *restrict zb = th->vpdbuf + y * th->vpwidth + (xl>>16);
299#endif
300
301 spanlen = (xr - xl)>>16;
302 outbuf = vplout + (xl>>16);
303
304 while(spanlen-->=0)
305 {
306 PLOT_PIXEL(*outbuf);
307 outbuf++;
308
309#ifdef SPAN_ST
310 s += sd;
311 t += td;
312#endif
313#ifdef SPAN_Z
314 z += zd;
315 zb++;
316#endif
317 }
318 }
319 }
320}
321
322#undef SPAN_ST
323#undef PLOT_PIXEL
s
Definition: execloop.h:53
char * ifdef
Definition: generatebuiltin.c:9
GLfloat t
Definition: gl_vidcommon.c:184
static CONST PIXELFORMATDESCRIPTOR *static int
Definition: gl_vidnt.c:222
GLfloat GLfloat v1
Definition: glquake.h:163
GLfloat GLfloat GLfloat v2
Definition: glquake.h:163
GLfloat GLfloat GLfloat z
Definition: glquake.h:158
GLfloat GLfloat y
Definition: glquake.h:158
GLfloat GLfloat GLfloat GLfloat v3
Definition: glquake.h:163
const GLfloat * v
Definition: glsupp.h:466
Definition: sw.h:41
vec4_t vcoord
Definition: sw.h:44
vec2_t tccoord
Definition: sw.h:45
const swvert_t * vlt
Definition: sw_spans.h:27
float td
Definition: sw_spans.h:19
unsigned int zd
Definition: sw_spans.h:22
int interlace
Definition: sw_spans.h:33
int y
Definition: sw_spans.h:12
const swvert_t * vrt
Definition: sw_spans.h:27
int xrd
Definition: sw_spans.h:16
int recalcside
Definition: sw_spans.h:32
unsigned int * vplout
Definition: sw_spans.h:30
float d2
Definition: sw_spans.h:35
int dy
Definition: sw_spans.h:31
unsigned int zl
Definition: sw_spans.h:22
unsigned int *restrict ti
Definition: sw_spans.h:25
unsigned int *restrict outbuf
Definition: sw_spans.h:24
float tld
Definition: sw_spans.h:19
int dx
Definition: sw_spans.h:31
unsigned int zld
Definition: sw_spans.h:22
float fdx1
Definition: sw_spans.h:35
int spanlen
Definition: sw_spans.h:28
float tl
Definition: sw_spans.h:19
int xld
Definition: sw_spans.h:16
int numspans
Definition: sw_spans.h:29
int xl
Definition: sw_spans.h:16
float sl
Definition: sw_spans.h:18
float sld
Definition: sw_spans.h:18
float fdy2
Definition: sw_spans.h:35
float d1
Definition: sw_spans.h:35
const swvert_t * vlb
Definition: sw_spans.h:27
int i
Definition: sw_spans.h:26
float sd
Definition: sw_spans.h:18
float fz
Definition: sw_spans.h:35
const swvert_t * vrb
Definition: sw_spans.h:27
float fdx2
Definition: sw_spans.h:35
int xr
Definition: sw_spans.h:16
float fdy1
Definition: sw_spans.h:35
int secondhalf
Definition: sw_spans.h:15