/[cvs]/api/Classes/Engine3d/TMapare.cpp
ViewVC logotype

Contents of /api/Classes/Engine3d/TMapare.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1.1.1 - (show annotations) (vendor branch)
Sun Jul 1 20:47:58 2001 UTC (23 years, 5 months ago) by bearsoft
Branch: lazy, MAIN
CVS Tags: start, HEAD
Changes since 1.1: +0 -0 lines
First import

1 #include "TMapare.h"
2
3 TMapare::TMapare(int *iscreen, int iscreenwidth, int iscreenheight)
4 {
5 screen=(int*)iscreen;
6 screenwidth=iscreenwidth;
7 screenheight=iscreenheight;
8
9 }
10
11 TMapare::~TMapare(){}
12
13 // Texturemapper with full perspective correction, subpixels and subtexels,
14 // uses floats all the way through
15
16 void TMapare::drawtpolyperspsubtri(TPolytri *poly)
17 {
18 float x1, y1, x2, y2, x3, y3;
19 float iz1, uiz1, viz1, iz2, uiz2, viz2, iz3, uiz3, viz3;
20 float dxdy1, dxdy2, dxdy3;
21 float tempf;
22 float denom;
23 float dy;
24 int y1i, y2i, y3i;
25 int side;
26
27 // Shift XY coordinate system (+0.5, +0.5) to match the subpixeling
28 // technique
29
30 x1 = (float) poly->x1 + 0.5f;
31 y1 = (float) poly->y1 + 0.5f;
32 x2 = (float) poly->x2 + 0.5f;
33 y2 = (float) poly->y2 + 0.5f;
34 x3 = (float) poly->x3 + 0.5f;
35 y3 = (float) poly->y3 + 0.5f;
36
37 // Calculate alternative 1/Z, U/Z and V/Z values which will be
38 // interpolated
39
40 iz1 = 1 / poly->z1;
41 iz2 = 1 / poly->z2;
42 iz3 = 1 / poly->z3;
43 uiz1 = poly->u1 * iz1;
44 viz1 = poly->v1 * iz1;
45 uiz2 = poly->u2 * iz2;
46 viz2 = poly->v2 * iz2;
47 uiz3 = poly->u3 * iz3;
48 viz3 = poly->v3 * iz3;
49
50 texture = poly->texture;
51
52 // Sort the vertices in ascending Y order
53
54 #define swapfloat(x, y) tempf = x; x = y; y = tempf;
55
56 if (y1 > y2)
57 {
58 swapfloat(x1, x2);
59 swapfloat(y1, y2);
60 swapfloat(iz1, iz2);
61 swapfloat(uiz1, uiz2);
62 swapfloat(viz1, viz2);
63 }
64
65 if (y1 > y3)
66 {
67 swapfloat(x1, x3);
68 swapfloat(y1, y3);
69 swapfloat(iz1, iz3);
70 swapfloat(uiz1, uiz3);
71 swapfloat(viz1, viz3);
72 }
73
74 if (y2 > y3)
75 {
76 swapfloat(x2, x3);
77 swapfloat(y2, y3);
78 swapfloat(iz2, iz3);
79 swapfloat(uiz2, uiz3);
80 swapfloat(viz2, viz3);
81 }
82
83 #undef swapfloat
84
85 y1i = (int) y1;
86 y2i = (int) y2;
87 y3i = (int) y3;
88
89 // Skip poly if it's too thin to cover any pixels at all
90
91 if (y1i == y2i == y3i || (int) x1 == (int) x2 == (int) x3)
92 {
93 return;
94 }
95
96 // Calculate horizontal and vertical increments for UV axes (these
97 // calcs are certainly not optimal, although they're stable
98 // (handles any dy being 0)
99
100 denom = ((x3 - x1) * (y2 - y1) - (x2 - x1) * (y3 - y1));
101
102 if (!denom) // Skip poly if it's an infinitely thin line
103 {
104 return;
105 }
106
107 denom = 1 / denom; // Reciprocal for speeding up
108 dizdx = ((iz3 - iz1) * (y2 - y1) - (iz2 - iz1) * (y3 - y1)) * denom;
109 duizdx = ((uiz3 - uiz1) * (y2 - y1) - (uiz2 - uiz1) * (y3 - y1)) * denom;
110 dvizdx = ((viz3 - viz1) * (y2 - y1) - (viz2 - viz1) * (y3 - y1)) * denom;
111
112 dizdy = ((iz2 - iz1) * (x3 - x1) - (iz3 - iz1) * (x2 - x1)) * denom;
113 duizdy = ((uiz2 - uiz1) * (x3 - x1) - (uiz3 - uiz1) * (x2 - x1)) * denom;
114 dvizdy = ((viz2 - viz1) * (x3 - x1) - (viz3 - viz1) * (x2 - x1)) * denom;
115
116 // Calculate X-slopes along the edges
117
118 if (y2 > y1)
119 dxdy1 = (x2 - x1) / (y2 - y1);
120 if (y3 > y1)
121 dxdy2 = (x3 - x1) / (y3 - y1);
122 if (y3 > y2)
123 dxdy3 = (x3 - x2) / (y3 - y2);
124
125 // Determine which side of the poly the longer edge is on
126
127 side = dxdy2 > dxdy1;
128
129 if (y1 == y2)
130 side = x1 > x2;
131 if (y2 == y3)
132 side = x3 > x2;
133
134 if (!side) // Longer edge is on the left side
135 {
136 // Calculate slopes along left edge
137
138 dxdya = dxdy2;
139 dizdya = dxdy2 * dizdx + dizdy;
140 duizdya = dxdy2 * duizdx + duizdy;
141 dvizdya = dxdy2 * dvizdx + dvizdy;
142
143 // Perform subpixel pre-stepping along left edge
144
145 dy = 1 - (y1 - y1i);
146 xa = x1 + dy * dxdya;
147 iza = iz1 + dy * dizdya;
148 uiza = uiz1 + dy * duizdya;
149 viza = viz1 + dy * dvizdya;
150
151 if (y1i < y2i) // Draw upper segment if possibly visible
152 {
153 // Set right edge X-slope and perform subpixel pre-
154 // stepping
155
156 xb = x1 + dy * dxdy1;
157 dxdyb = dxdy1;
158
159 drawtpolyperspsubtriseg(y1i, y2i);
160 }
161
162 if (y2i < y3i) // Draw lower segment if possibly visible
163 {
164 // Set right edge X-slope and perform subpixel pre-
165 // stepping
166
167 xb = x2 + (1 - (y2 - y2i)) * dxdy3;
168 dxdyb = dxdy3;
169
170 drawtpolyperspsubtriseg(y2i, y3i);
171 }
172 }
173 else // Longer edge is on the right side
174 {
175 // Set right edge X-slope and perform subpixel pre-stepping
176
177 dxdyb = dxdy2;
178 dy = 1 - (y1 - y1i);
179 xb = x1 + dy * dxdyb;
180
181 if (y1i < y2i) // Draw upper segment if possibly visible
182 {
183 // Set slopes along left edge and perform subpixel
184 // pre-stepping
185
186 dxdya = dxdy1;
187 dizdya = dxdy1 * dizdx + dizdy;
188 duizdya = dxdy1 * duizdx + duizdy;
189 dvizdya = dxdy1 * dvizdx + dvizdy;
190 xa = x1 + dy * dxdya;
191 iza = iz1 + dy * dizdya;
192 uiza = uiz1 + dy * duizdya;
193 viza = viz1 + dy * dvizdya;
194
195 drawtpolyperspsubtriseg(y1i, y2i);
196 }
197
198 if (y2i < y3i) // Draw lower segment if possibly visible
199 {
200 // Set slopes along left edge and perform subpixel
201 // pre-stepping
202
203 dxdya = dxdy3;
204 dizdya = dxdy3 * dizdx + dizdy;
205 duizdya = dxdy3 * duizdx + duizdy;
206 dvizdya = dxdy3 * dvizdx + dvizdy;
207 dy = 1 - (y2 - y2i);
208 xa = x2 + dy * dxdya;
209 iza = iz2 + dy * dizdya;
210 uiza = uiz2 + dy * duizdya;
211 viza = viz2 + dy * dvizdya;
212
213 drawtpolyperspsubtriseg(y2i, y3i);
214 }
215 }
216 }
217
218 void TMapare::drawtpolyperspsubtriseg(int y1, int y2)
219 {
220 int *scr;
221 int x1, x2;
222 float z, u, v, dx;
223 float iz, uiz, viz;
224
225 while (y1 < y2) // Loop through all lines in the segment
226 {
227 x1 = (int) xa;
228 x2 = (int) xb;
229
230 // Perform subtexel pre-stepping on 1/Z, U/Z and V/Z
231
232 dx = 1 - (xa - x1);
233 iz = iza + dx * dizdx;
234 uiz = uiza + dx * duizdx;
235 viz = viza + dx * dvizdx;
236
237 scr = &screen[(screenheight-y1) * screenwidth + x1];
238
239 while (x1++ < x2) // Draw horizontal line
240 {
241 // Calculate U and V from 1/Z, U/Z and V/Z
242
243 z = 1 / iz;
244 u = uiz * z;
245 v = viz * z;
246
247 // Copy pixel from texture to screen
248
249 *(scr++) = texture[((((int) v) & 0xff) << 8) + (((int) u) & 0xff)];
250
251 // Step 1/Z, U/Z and V/Z horizontally
252
253 iz += dizdx;
254 uiz += duizdx;
255 viz += dvizdx;
256 }
257
258 // Step along both edges
259
260 xa += dxdya;
261 xb += dxdyb;
262 iza += dizdya;
263 uiza += duizdya;
264 viza += dvizdya;
265
266 y1++;
267 }
268 }

root@recompile.se
ViewVC Help
Powered by ViewVC 1.1.26