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 */