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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

1 bearsoft 1.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