HOOPS/3dGS I.M. Interface

     << Back      Full Index      Forward >>


span.h

00001 /*
00002  * Copyright (c) 1998 by Tech Soft 3D, LLC.
00003  * The information contained herein is confidential and proprietary to
00004  * Tech Soft 3D, LLC., and considered a trade secret as defined under
00005  * civil and criminal statutes.  Tech Soft 3D shall pursue its civil
00006  * and criminal remedies in the event of unauthorized use or misappropriation
00007  * of its trade secrets.  Use of this information by anyone other than
00008  * authorized employees of Tech Soft 3D, LLC. is granted only under a
00009  * written non-disclosure agreement, expressly prescribing the scope and
00010  * manner of such use.
00011  *
00012  * $Id: span_8h-source.html,v 1.29 2008-03-10 07:09:28 stage Exp $
00013  */
00014 
00015 #ifndef SPAN_DEFINED
00016 #define SPAN_DEFINED
00017 
00018 
00019 /*
00020  * A fixed point number is used to represent a 32 bit number, with
00021  * 16 bits of integral and 16 bit fractional precision.
00022  * Truncation is accomplished by merely accessing the integer part.
00023  * Arithmetic operations can be accomplished by accessing the entire
00024  * structure as a single unit (the "number" field).
00025  */
00026 struct HT_Fixed_Point_Bytes {
00027 #    if HOOPS_BIGENDIAN
00028         unsigned char   b3;
00029         unsigned char   b2;
00030         unsigned char   b1;
00031         unsigned char   b0;
00032 #    else
00033         unsigned char   b0;
00034         unsigned char   b1;
00035         unsigned char   b2;
00036         unsigned char   b3;
00037 #    endif
00038 };
00039 
00040 struct HT_Fixed_Point_Parts {
00041 #   if HOOPS_BIGENDIAN
00042         short               integer;        /* integral part, 16b.0b   */
00043         unsigned short      fraction;       /* fractional part, 0b.16b */
00044 #   else
00045         unsigned short      fraction;       /* fractional part, 0b.16b */
00046         short               integer;        /* integral part, 16b.0b   */
00047 #   endif
00048 };
00049 
00050 
00051 union HT_Fixed_Point {
00052     HT_Integer32                        number;         /* entire number, 16b.16b  */
00053     struct HT_Fixed_Point_Bytes bytes;
00054     struct HT_Fixed_Point_Parts parts;
00055 };
00056 
00057 
00058 struct HT_Fixed_Color{
00059     HT_Fixed_Point      r;
00060     HT_Fixed_Point      g;
00061     HT_Fixed_Point      b;
00062 };
00063 
00064 
00065 #ifdef DISABLE_TABLE_LOOKUPS
00066 #    define MULU(a, b) ((a) * (b))
00067 #else
00068     EXTERNAL const unsigned short mulu[256][256];
00069 #    define MULU(a, b) (mulu[a][b])
00070 #endif
00071 
00072 #ifdef USE_M_IX86_ASM
00073 #   define SET_TRUNCATION()                     \
00074         long    fp_control_word;                \
00075         __asm fnstcw    { fp_control_word       }               \
00076         __asm or        { fp_control_word, 0x0C00       }       \
00077         __asm fldcw {   fp_control_word                 }
00078     
00079 
00080 #   define LOAD_ARGUMENT(arg)                   \
00081         __asm   { mov   eax, DWORD PTR arg      }       
00082    
00083 
00084 #   define TRUNCATE_POINT(src, sindex, dst, dindex, field)      \
00085         __asm   { fld   DWORD PTR [eax + sindex * TYPE HT_DC_Point]src.field    } \
00086         __asm   { fistp DWORD PTR dst[dindex * TYPE HT_Int_Point]dst.field      }
00087    
00088 
00089 #else
00090 #   define SET_TRUNCATION()
00091 #   define LOAD_ARGUMENT(arg)   (void)(arg)
00092 #   define TRUNCATE_POINT(src, sindex, dst, dindex, field)      \
00093         dst[dindex].field = (int)src[sindex].field
00094 #endif
00095 
00096 #define TRUNCATE_3_POINTS(src, dst, n1, n2, n3, field)  \
00097         TRUNCATE_POINT (src, n1, dst, 0, field);                \
00098         TRUNCATE_POINT (src, n2, dst, 1, field);                \
00099         TRUNCATE_POINT (src, n3, dst, 2, field); 
00100 
00101 #define TRUNCATE_2_POINTS(src, dst, n1, n2, field)              \
00102         TRUNCATE_POINT (src, n1, dst, 0, field);                \
00103         TRUNCATE_POINT (src, n2, dst, 1, field); 
00104 
00105 #define PRIORITIZE_PTRS(src, dst, n1, n2, n3)   \
00106         dst[0] = &src[n1]; dst[1] = &src[n2]; dst[2] = &src[n3];
00107 
00108 #define PRIORITIZE_RGBAS32(src, dst, n1, n2, n3) \
00109         dst[0].r = UNSIGNED_CHARTOINT(src[n1].rgb.r);   \
00110         dst[0].g = UNSIGNED_CHARTOINT(src[n1].rgb.g);   \
00111         dst[0].b = UNSIGNED_CHARTOINT(src[n1].rgb.b);   \
00112         dst[1].r = UNSIGNED_CHARTOINT(src[n2].rgb.r);   \
00113         dst[1].g = UNSIGNED_CHARTOINT(src[n2].rgb.g);   \
00114         dst[1].b = UNSIGNED_CHARTOINT(src[n2].rgb.b);   \
00115         dst[2].r = UNSIGNED_CHARTOINT(src[n3].rgb.r);   \
00116         dst[2].g = UNSIGNED_CHARTOINT(src[n3].rgb.g);   \
00117         dst[2].b = UNSIGNED_CHARTOINT(src[n3].rgb.b);
00118 
00119     
00120 #define COLOR_TOLERANCE 4
00121 #define RGBSAME(a,b,which) \
00122                 ((diff = a.rgb.which - b.rgb.which) < COLOR_TOLERANCE && diff > -COLOR_TOLERANCE)
00123 
00124 
00125 #define SWAP_INT(a, b) {register int _swap_temp_ = (a); (a) = (b); (b) = _swap_temp_;}
00126 
00127 #define DITHER(thresh, c0, d1, c1, d2, c2, d3, c3) \
00128     (((d1) <= (thresh)) ? ((d2) <= (thresh)) ? ((d3) <= (thresh)) ? (c3) : (c2) : (c1) : (c0))
00129 
00130 #define DIVIDE(numer, denom, quotient, remainder) \
00131     quotient = numer / denom; \
00132     remainder = numer % denom;
00133 
00134 
00135 struct HT_Span_Rendition {
00136     HT_Light_Rendition const    *light_rendition;       /* for reshading only */
00137     HT_Material_Rendition const *material_rendition;    /* for reshading only */
00138     HT_Driver_Color             color;
00139     int                         color_system;   /* defines type of "color" field */
00140     int                         pattern;
00141     HT_Driver_Color             contrast_color; /* matches dc->physical.color_system */
00142     HT_Integer32                        z;
00143 };
00144 
00145 
00146 
00147 /*
00148  * Interpolant types
00149  */
00150  
00151 struct HT_UFixed_Point_Bytes {
00152 #   if HOOPS_BIGENDIAN
00153         unsigned char   b3;
00154         unsigned char   b2;
00155         unsigned char   b1;
00156         unsigned char   b0;
00157 #   else
00158         unsigned char   b0;
00159         unsigned char   b1;
00160         unsigned char   b2;
00161         unsigned char   b3;
00162 #   endif
00163 };
00164 
00165 struct HT_UFixed_Point_Parts {
00166 #   if HOOPS_BIGENDIAN
00167         unsigned short      integer;        /* integral part, 16b.0b   */
00168         unsigned short      fraction;       /* fractional part, 0b.16b */
00169 #   else
00170         unsigned short      fraction;       /* fractional part, 0b.16b */
00171         unsigned short      integer;        /* integral part, 16b.0b   */
00172 #   endif
00173 };
00174 
00175 union HT_UFixed_Point{
00176     unsigned HT_Integer32                number;         /* entire number, 16b.16b  */
00177     HT_UFixed_Point_Bytes bytes;
00178     HT_UFixed_Point_Parts parts;
00179 };
00180 
00181 
00182 struct HT_Fixed_Interpolant {
00183     HT_Fixed_Point      val;
00184     HT_Fixed_Point      slope;
00185 };
00186 
00187 struct HT_UFixed_Interpolant {
00188     HT_UFixed_Point     val;
00189     HT_Fixed_Point      slope;
00190 };
00191 
00192 #define SETUP_FIXED(f, t0, t1, dy)      \
00193     f.val.number = 0;                           \
00194     f.val.parts.fraction = 0x8000;              \
00195     f.val.parts.integer = t0;                   \
00196     f.slope.number = 0;                         \
00197     f.slope.parts.fraction = 0;                 \
00198     f.slope.parts.integer = (t1) - (t0);        \
00199     switch (dy) {                               \
00200         case 0: break;                          \
00201         case 1: break;                          \
00202         case 2: f.slope.number >>= 1; break;    \
00203         case 3: f.slope.number /=  3; break;    \
00204         case 4: f.slope.number >>= 2; break;    \
00205         case 5: f.slope.number /=  5; break;    \
00206         case 6: f.slope.number /=  6; break;    \
00207         case 7: f.slope.number /=  7; break;    \
00208         case 8: f.slope.number >>= 3; break;    \
00209         default: f.slope.number /= (int)dy;} 
00210 
00211 #define COPY_FIXED(s, d)                        \
00212     (d).val.number         = (s).val.number;    \
00213     (d).slope.number       = (s).slope.number;
00214 
00215 #define UPDATE_FIXED(f)                         \
00216     f.val.number += f.slope.number
00217 
00218 #define SKIP_FIXED(f,n)                         \
00219     f.val.number += f.slope.number * (n)
00220 
00221 #define HALF_STEP_FIXED(f)              \
00222     f.val.number += f.slope.number / 2
00223 
00224 
00225 
00226 
00227 struct HT_Floating_Interpolant {
00228     float               val;
00229     float               slope;
00230 };
00231 
00232 #define SETUP_FLOAT(f, t0, t1, dy)              \
00233     f.val = t0;                                 \
00234     f.slope = (t1) - (t0);                      \
00235     if (dy != 0 && dy != 1)                     \
00236         f.slope /= (float)dy;
00237 
00238 #define COPY_FLOAT(s, d)                        \
00239     (d).val                = (s).val;           \
00240     (d).slope              = (s).slope;
00241 
00242 #define UPDATE_FLOAT(f)                         \
00243     f.val += f.slope
00244 
00245 #define SKIP_FLOAT(f,n)                         \
00246     f.val += f.slope * (n)
00247 
00248 #define HALF_STEP_FLOAT(f)              \
00249     f.val += 0.5f * f.slope
00250 
00251 
00252 
00253 
00254 struct HT_Bresenham_Interpolant {
00255     struct {
00256         HT_Integer32    integer;
00257         HT_Integer32    fraction;
00258         float           simple;
00259     } val;
00260     struct {
00261         struct {
00262             HT_Integer32        integer;
00263             HT_Integer32        fraction;
00264         } acc, cor; /* accumulation, correction */
00265         float           simple;
00266     } slope;
00267 };
00268 
00269 #define SETUP_BRESENHAM(b, t0, t1, dy)                                  \
00270 {   HT_Integer32    dt = t1 - t0;                           \
00271     int             _delta_ = dy ? dy : 1;                  \
00272     b.val.simple = t0 + 0.5f;                                           \
00273     b.slope.simple = (float)dt / (float)_delta_;                        \
00274     DIVIDE (dt, _delta_, b.slope.acc.integer, b.slope.acc.fraction);    \
00275     if (dt < 0) {                                                       \
00276         b.slope.acc.fraction = -(b.slope.acc.fraction << 1);            \
00277         b.slope.cor.integer  = b.slope.acc.integer - 1;                 \
00278     }                                                                   \
00279     else {                                                              \
00280         b.slope.acc.fraction = b.slope.acc.fraction << 1;               \
00281         b.slope.cor.integer  = b.slope.acc.integer + 1;                 \
00282     }                                                                   \
00283     b.slope.cor.fraction = b.slope.acc.fraction - (_delta_ << 1);       \
00284     b.val.integer = t0;                                                 \
00285     b.val.fraction = b.slope.acc.fraction - _delta_; }
00286 
00287 #define COPY_BRESENHAM(s, d)                            \
00288     (d).val.integer         = (s).val.integer;          \
00289     (d).val.fraction        = (s).val.fraction;         \
00290     (d).val.simple          = (s).val.simple;           \
00291     (d).slope.acc.integer   = (s).slope.acc.integer;    \
00292     (d).slope.acc.fraction  = (s).slope.acc.fraction;   \
00293     (d).slope.cor.integer   = (s).slope.cor.integer;    \
00294     (d).slope.cor.fraction  = (s).slope.cor.fraction;   \
00295     (d).slope.simple        = (s).slope.simple;
00296 
00297 #define UPDATE_BRESENHAM(b)                                             \
00298     b.val.simple += b.slope.simple;                                     \
00299     if (b.val.fraction >= 0) {b.val.integer  += b.slope.cor.integer;    \
00300                               b.val.fraction += b.slope.cor.fraction;}  \
00301     else                     {b.val.integer  += b.slope.acc.integer;    \
00302                               b.val.fraction += b.slope.acc.fraction;}
00303 
00304 #define SKIP_BRESENHAM(b,n) do {    \
00305         int _n_ = (n);      \
00306         while (_n_-- > 0) {         \
00307             UPDATE_BRESENHAM (b);   \
00308         }                           \
00309     } while (0)
00310 
00311 #define HALF_STEP_BRESENHAM(b)                                          \
00312     b.val.simple += 0.5f * b.slope.simple;                          \
00313     if (b.val.fraction >= 0) {b.val.integer  += b.slope.cor.integer/2;  \
00314                               b.val.fraction += b.slope.cor.fraction/2;}\
00315     else                     {b.val.integer  += b.slope.acc.integer/2;  \
00316                               b.val.fraction += b.slope.acc.fraction/2;}
00317 
00318 
00319 
00320 /*
00321  * a span anchor is an edge of sorts,
00322  * and therefore contains all associated interpolants
00323  */
00324 #define SPAN_PARAM_COUNT 64
00325 
00326 struct HT_Span_Anchor {
00327     int                         dy;             /* height of the side, in pixels, minus 1 */
00328 
00329     HT_Fixed_Interpolant        x;              /* horizontal position */
00330     HT_Fixed_Interpolant        y;              /* vertical position */
00331 
00332     HT_Bresenham_Interpolant    bx;             /* can deal with unclipped coordinates */
00333     HT_Bresenham_Interpolant    bz;             /* depth (32 bits or less) */
00334 
00335     HT_Fixed_Interpolant        r;              /* color red */
00336     HT_Fixed_Interpolant        g;              /* color green */
00337     HT_Fixed_Interpolant        b;              /* color blue */
00338 
00339     /* everything below for phong and/or textures, individual parts may be present or not */
00340     HT_Floating_Interpolant     fr;             /* floating point red */
00341     HT_Floating_Interpolant     fg;             /* floating point green */
00342     HT_Floating_Interpolant     fb;             /* floating point blue */
00343 
00344     HT_Floating_Interpolant     pa;             /* plane a */
00345     HT_Floating_Interpolant     pb;             /* plane b */
00346     HT_Floating_Interpolant     pc;             /* plane c */
00347     HT_Floating_Interpolant     pd;             /* plane d */
00348 
00349 
00350     HT_Fixed_Interpolant        uu;
00351     HT_Fixed_Interpolant        vv;
00352 
00353 
00354     HT_Floating_Interpolant     wx;             /* world x */
00355     HT_Floating_Interpolant     wy;             /* world y */
00356     HT_Floating_Interpolant     wz;             /* world z */
00357 
00358     HT_Floating_Interpolant     numwx;          /* perspective correct numerator x */
00359     HT_Floating_Interpolant     numwy;          /* perspective correct numerator y */
00360     HT_Floating_Interpolant     numwz;          /* perspective correct numerator z */
00361     float                       startwx, startwy, startwz;  /* perspective correct start values */
00362 
00363     int                         param_width;
00364     HT_Floating_Interpolant     param[SPAN_PARAM_COUNT];            /* parameter */
00365     HT_Floating_Interpolant     num_param[SPAN_PARAM_COUNT];        /* perspective correct numerators */
00366     float                       start_param[SPAN_PARAM_COUNT];      /* perspective correct start values */
00367 
00368     HT_Floating_Interpolant     homog;  /* Homogeneous coord */
00369     HT_Floating_Interpolant     den;    /* perspective correct denominator */
00370 };
00371 
00372 
00373 struct HT_Anchor_X {
00374     int                         dy;
00375     HT_Fixed_Interpolant        x;              /* horizontal position */
00376 };
00377 
00378 struct HT_Anchor_XZ {
00379     int                         dy;
00380     HT_Fixed_Interpolant        x;              /* horizontal position */
00381     HT_Bresenham_Interpolant    bz;             /* depth (32 bits or less) */
00382 };
00383 
00384 
00385 /*
00386  * SPAN_BUFFER_SIZE *must* be at least 2
00387  */
00388 
00389 #define SPAN_BUFFER_SIZE 64
00390 
00391 
00392 struct HT_Span {
00393     HT_Span_Anchor                      left, right;
00394 
00395 #define Span_RGB        0x01
00396 #define Span_PLANE      0x02
00397 #define Span_PARAMETERS 0x04    /* and all associated stuff like homog & num/den */
00398 #define Span_WORLD      0x08    /* and numw if appropriate */
00399     int                         valid;
00400 };
00401 
00402 
00403 #define C08PP   unsigned char alter * alter *
00404 #define C32PP   HT_RGBAS32 alter * alter *
00405 #define DepthPP HT_Depth alter * alter *
00406 
00407 #endif /* SPAN_DEFINED */
Main Index
HOOPS/3dGS I.M. Interface

     << Back      Full Index      Forward >>