source: proiecte/pmake3d/make3d_original/Make3dSingleImageStanford_version0.1/third_party/vrippack-0.31/src/softrender/sl_triangle.C @ 37

Last change on this file since 37 was 37, checked in by (none), 14 years ago

Added original make3d

File size: 8.8 KB
Line 
1/*
2
3Homan Igehy
4
5Computer Graphics Laboratory
6Stanford University
7
8---------------------------------------------------------------------
9
10Copyright (1997) The Board of Trustees of the Leland Stanford Junior
11University. Except for commercial resale, lease, license or other
12commercial transactions, permission is hereby given to use, copy,
13modify this software for academic purposes only.  No part of this
14software or any derivatives thereof may be used in the production of
15computer models for resale or for use in a commercial
16product. STANFORD MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND
17CONCERNING THIS SOFTWARE.  No support is implied or provided.
18
19*/
20
21
22/*
23 * sl_triangle.C
24 *
25 */
26
27#ifndef SL_TRIANGLE_C
28#define SL_TRIANGLE_C
29
30#include <assert.h>
31#include <iostream>
32
33#include "sl_vertex.H"
34#include "sl_texture.H"
35#include "sl_export.H"
36#include "sl_hack.H"
37#include "sl_common.H"
38
39
40#define SL_REGULAR   0
41#define SL_DEGENERATE   1
42#define SL_TOP_HORIZONTAL  2
43#define SL_BOT_HORIZONTAL  4
44
45
46typedef struct SL_Triangle {
47  Real fe_curx, fe_dxdy;
48  Real se_curx, se_dxdy;
49  Real me_curx, me_dxdy;
50  IN_DeclareArgs(cur)
51  IN_DeclareArgs(ddy)
52  IN_DeclareArgs(ddx)
53  Integer y_lo, y_mid, y_hi;
54#ifdef LevelOfDetail
55  Integer x_lo, x_mid, x_hi;
56#endif
57} SL_Triangle;
58
59
60
61#define VSWAP(a, b) { IS_Vertex *tmp = a; a = b; b = tmp; }
62#define ISWAP(a, b) { Integer tmp = a; a = b; b = tmp; }
63
64
65#define SetDdyCurDdx(i) \
66    lo = IN_IndexP(v_lo, i); \
67    ddy = (IN_IndexP(v_hi, i) - lo) * inv_ydiff_full; \
68    mid = IN_IndexP(v_mid, i); \
69    IN_Index(tri->ddx, i) = (((mid - lo) * inv_ydiff_slope) - ddy)*inv_xdiff; \
70    IN_Index(tri->cur, i) = lo + ddy * yfrac_lo; \
71    IN_Index(tri->ddy, i) = ddy; \
72
73
74
75#define SetDdyCurDdx_BotHor(i) \
76    hi = IN_IndexP(v_hi, i); \
77    lo = IN_IndexP(v_lo, i); \
78    ddy = (hi - lo) * inv_ydiff_full; \
79    mid = IN_IndexP(v_mid, i); \
80    IN_Index(tri->ddx, i) = (((hi - mid) * inv_ydiff_slope) - ddy)*inv_xdiff; \
81    IN_Index(tri->cur, i) = lo + ddy * yfrac_lo; \
82    IN_Index(tri->ddy, i) = ddy; \
83
84
85static inline Integer8
86SL_3VertexTo3Edge(SL_Triangle *tri,
87                  IS_Vertex *v_lo,
88                  IS_Vertex *v_mid,
89                  IS_Vertex *v_hi)
90{
91
92  Integer y_lo = CeilR2I(v_lo->y);
93  Integer y_mid = CeilR2I(v_mid->y);
94  Integer y_hi = CeilR2I(v_hi->y);
95
96  if (y_lo > y_mid) {
97    VSWAP(v_lo, v_mid);
98    ISWAP(y_lo, y_mid);
99  }
100
101  if (y_mid > y_hi) {
102    VSWAP(v_mid, v_hi);
103    ISWAP(y_mid, y_hi);
104  }
105
106  if (y_lo > y_mid) {
107    VSWAP(v_lo, v_mid);
108    ISWAP(y_lo, y_mid);
109  }
110
111  tri->y_lo  = y_lo;
112  tri->y_hi  = y_hi;
113  tri->y_mid = y_mid;
114
115
116
117#ifdef LevelOfDetail
118
119  Integer x_lo = CeilR2I(v_lo->x);
120  Integer x_mid = CeilR2I(v_mid->x);
121  Integer x_hi = CeilR2I(v_hi->x);
122
123  if (x_lo > x_mid) {
124    ISWAP(x_lo, x_mid);
125  }
126
127  if (x_mid > x_hi) {
128    ISWAP(x_mid, x_hi);
129  }
130
131  if (x_lo > x_mid) {
132    ISWAP(x_lo, x_mid);
133  }
134
135  tri->x_lo  = x_lo;
136  tri->x_hi  = x_hi;
137  tri->x_mid = x_mid;
138
139#endif
140
141
142  int type;
143
144  if (y_lo == y_hi) {
145    return SL_DEGENERATE;
146  }
147
148  Real inv_ydiff_full  = REAL_ONE / (v_hi->y - v_lo->y);
149
150  Real yfrac_lo =  (Real) y_lo - v_lo->y;
151  Real yfrac_mid = (Real) y_mid - v_mid->y;
152
153  if (y_lo == y_mid)
154    type = SL_BOT_HORIZONTAL;
155  else if (y_mid == y_hi)
156    type = SL_TOP_HORIZONTAL;
157  else
158    type = SL_REGULAR;
159
160  Real lo, mid, hi, ddy;
161
162  lo = v_lo->x;
163  ddy =  (v_hi->x - lo) * inv_ydiff_full;
164
165  Real inv_ydiff_slope;
166  if (type == SL_BOT_HORIZONTAL)
167    inv_ydiff_slope = REAL_ONE / (v_hi->y - v_mid->y);
168  else
169    inv_ydiff_slope = REAL_ONE / (v_mid->y - v_lo->y);
170
171  tri->fe_curx = lo + ddy * yfrac_lo;
172  tri->fe_dxdy = ddy;
173
174
175  if (type == SL_BOT_HORIZONTAL) {
176    mid = v_mid->x;
177    ddy =  (v_hi->x - mid) * inv_ydiff_slope;
178
179    Real inv_xdiff = REAL_ONE / (ddy - tri->fe_dxdy);
180
181    tri->se_curx = mid + ddy * yfrac_mid;
182    tri->se_dxdy = ddy;
183
184    IN_DoForEach(SetDdyCurDdx_BotHor);
185
186  }
187  else {
188    lo = v_lo->x;
189    ddy =  (v_mid->x - lo) * inv_ydiff_slope;
190
191    Real inv_xdiff = REAL_ONE / (ddy - tri->fe_dxdy);
192
193    tri->se_curx = lo + ddy * yfrac_lo;
194    tri->se_dxdy = ddy;
195
196    IN_DoForEach(SetDdyCurDdx);
197  }
198
199
200
201
202  if (type == SL_REGULAR) {
203    mid = v_mid->x;
204    ddy =  (v_hi->x - mid) / (v_hi->y - v_mid->y);
205    tri->me_curx = mid + ddy * yfrac_mid;
206    tri->me_dxdy = ddy;
207  }
208
209
210 
211
212  return type;
213
214}
215
216
217#define MAX(a, b) ((a) > (b) ? (a) : (b))
218
219#ifdef LevelOfDetail
220
221static inline void
222SL_InitializeNumPars(SL_Triangle *tri, Real *numParXArray, Real *numParYArray)
223{
224  Real dudy = tri->ddyU - tri->ddxU * tri->fe_dxdy;
225  Real dvdy = tri->ddyV - tri->ddxV * tri->fe_dxdy;
226  Real dwdy = tri->ddyW - tri->ddxW * tri->fe_dxdy;
227
228  Real x_frac = ((Real) tri->x_lo) - tri->fe_curx;
229
230  Real u_slope = tri->ddxU * dwdy - dudy * tri->ddxW;
231  Real v_slope = tri->ddxV * dwdy - dvdy * tri->ddxW;
232
233  Real uy_cur = (tri->curW * dudy - tri->curU * dwdy) - u_slope * x_frac;
234  Real vy_cur = (tri->curW * dvdy - tri->curV * dwdy) - v_slope * x_frac;
235
236  Real ux_cur = tri->curW * tri->ddxU - tri->curU * tri->ddxW;
237  Real vx_cur = tri->curW * tri->ddxV - tri->curV * tri->ddxW;
238
239
240  for (int x = tri->x_lo;
241       x != tri->x_hi;
242       x++, uy_cur -= u_slope, vy_cur -= v_slope)
243    numParYArray[x] = MAX(Abs(uy_cur), Abs(vy_cur));
244
245  for (int y = tri->y_lo;
246       y != tri->y_hi;
247       y++, ux_cur += u_slope, vx_cur += v_slope)
248    numParXArray[y] = MAX(Abs(ux_cur), Abs(vx_cur));
249
250
251}
252
253#endif
254
255
256#define CopyAll(i)    { IN_Index(cur, i) = IN_Index(tri->cur, i); \
257                        IN_Index(ddy, i) = IN_Index(tri->ddy, i); \
258                        IN_Index(ddx, i) = IN_Index(tri->ddx, i);   }
259
260#define IncrementY(i) { IN_Index(cur, i) += IN_Index(ddy, i); }
261
262
263static inline void
264SL_ScanConvertLR(SL_Triangle *tri,
265                 const IS_CAttr *cattr,
266                 const FB_Buffer *buffer)
267{
268#ifdef LevelOfDetail
269
270  Real numParXArray[MAX_SCREEN_DIMENSION];
271  Real numParYArray[MAX_SCREEN_DIMENSION];
272
273  SL_InitializeNumPars(tri, numParXArray, numParYArray);
274
275#endif
276
277  Integer cur_y = tri->y_lo;
278  Integer width = buffer->width;
279  Integer offset = cur_y * width;
280
281#ifdef LevelOfDetail
282  Real *numParXPtr = numParXArray + cur_y;
283#endif
284
285  Real lx = tri->fe_curx;
286  Real dlx = tri->fe_dxdy;
287
288  IN_DeclareArgs(cur);
289  IN_DeclareArgs(ddy);
290  IN_DeclareArgs(ddx);
291  IN_DoForEach(CopyAll);
292
293  Real rx = tri->se_curx;
294  Real drx = tri->se_dxdy;
295
296  while (cur_y != tri->y_mid) {
297    cur_y++;
298    SL_ScanXLeftToRight(lx, rx,
299                        IN_ListArgs(cur)
300                        IN_ListArgs(ddx)
301                        CA_ListArgs(cattr->)
302#ifdef LevelOfDetail
303                        *numParXPtr, numParYArray,
304#endif
305                        buffer, offset);
306    rx += drx;
307    lx += dlx;
308    offset += width;
309#ifdef LevelOfDetail
310    numParXPtr++;
311#endif
312    IN_DoForEach(IncrementY);
313  }
314
315  rx = tri->me_curx;
316  drx = tri->me_dxdy;
317
318  while (cur_y != tri->y_hi) {
319    cur_y++;
320    SL_ScanXLeftToRight(lx, rx,
321                        IN_ListArgs(cur)
322                        IN_ListArgs(ddx)
323                        CA_ListArgs(cattr->)
324#ifdef LevelOfDetail
325                        *numParXPtr, numParYArray,
326#endif
327                        buffer, offset);
328    rx += drx;
329    lx += dlx;
330    offset += width;
331#ifdef LevelOfDetail
332    numParXPtr++;
333#endif
334    IN_DoForEach(IncrementY);
335  }
336}
337
338
339static inline void
340SL_ScanConvertRL(SL_Triangle *tri,
341                 const IS_CAttr *cattr,
342                 const FB_Buffer *buffer)
343{
344#ifdef LevelOfDetail
345
346  Real numParXArray[MAX_SCREEN_DIMENSION];
347  Real numParYArray[MAX_SCREEN_DIMENSION];
348
349  SL_InitializeNumPars(tri, numParXArray, numParYArray);
350
351#endif
352
353  Integer cur_y = tri->y_lo;
354  Integer width = buffer->width;
355  Integer offset = cur_y * width;
356
357#ifdef LevelOfDetail
358  Real *numParXPtr = numParXArray + cur_y;
359#endif
360
361  Real rx = tri->fe_curx;
362  Real drx = tri->fe_dxdy;
363
364  IN_DeclareArgs(cur);
365  IN_DeclareArgs(ddy);
366  IN_DeclareArgs(ddx);
367  IN_DoForEach(CopyAll);
368
369  Real lx = tri->se_curx;
370  Real dlx = tri->se_dxdy;
371
372  while (cur_y != tri->y_mid) {
373    cur_y++;
374    SL_ScanXRightToLeft(lx, rx,
375                        IN_ListArgs(cur)
376                        IN_ListArgs(ddx)
377                        CA_ListArgs(cattr->)
378#ifdef LevelOfDetail
379                        *numParXPtr, numParYArray,
380#endif
381                        buffer, offset);
382    rx += drx;
383    lx += dlx;
384    offset += width;
385#ifdef LevelOfDetail
386    numParXPtr++;
387#endif
388    IN_DoForEach(IncrementY);
389  }
390
391  lx = tri->me_curx;
392  dlx = tri->me_dxdy;
393
394  while (cur_y != tri->y_hi) {
395    cur_y++;
396    SL_ScanXRightToLeft(lx, rx,
397                        IN_ListArgs(cur)
398                        IN_ListArgs(ddx)
399                        CA_ListArgs(cattr->)
400#ifdef LevelOfDetail
401                        *numParXPtr, numParYArray,
402#endif
403                        buffer, offset);
404    rx += drx;
405    lx += dlx;
406    offset += width;
407#ifdef LevelOfDetail
408    numParXPtr++;
409#endif
410    IN_DoForEach(IncrementY);
411  }
412}
413
414
415
416void
417#ifdef SampleCalc_Dda
418SL_SCTriangle_DDA
419#endif
420#ifdef SampleCalc_Ddx
421SL_SCTriangle_DDX
422#endif
423                 (
424                  IS_Vertex *v_lo,
425                  IS_Vertex *v_mid,
426                  IS_Vertex *v_hi,
427                  IS_CAttr  *cattr,
428                  FB_Buffer *buffer
429                  )
430{
431  SL_Triangle tri;
432
433  int type = SL_3VertexTo3Edge(&tri, v_lo, v_mid, v_hi);
434
435  if (type == SL_DEGENERATE)
436    return;
437
438  if (type == SL_BOT_HORIZONTAL)
439    tri.y_mid = tri.y_hi;
440
441  if ((tri.fe_dxdy <= tri.se_dxdy) ^ (type == SL_BOT_HORIZONTAL)) {
442    SL_ScanConvertLR(&tri, cattr, buffer);
443  }
444  else {
445    SL_ScanConvertRL(&tri, cattr, buffer);
446  }
447
448}
449
450
451
452#endif /* SL_TRIANGLE_C */
Note: See TracBrowser for help on using the repository browser.