Panda3D
|
00001 /* 00002 * We draw a triangle with various interpolations 00003 */ 00004 00005 { 00006 ZBufferPoint *t,*pr1,*pr2,*l1,*l2; 00007 PN_stdfloat fdx1, fdx2, fdy1, fdy2, fz, d1, d2; 00008 ZPOINT *pz1; 00009 PIXEL *pp1; 00010 int part, update_left, update_right; 00011 00012 int nb_lines, dx1, dy1, tmp, dx2, dy2; 00013 00014 int error, derror; 00015 int x1, dxdy_min, dxdy_max; 00016 /* warning: x2 is multiplied by 2^16 */ 00017 int x2, dx2dy2; 00018 00019 #ifdef INTERP_Z 00020 int z1 = 0, dzdx = 0, dzdy = 0, dzdl_min = 0, dzdl_max = 0; 00021 #endif 00022 #ifdef INTERP_RGB 00023 int r1 = 0, drdx = 0, drdy = 0, drdl_min = 0, drdl_max = 0; 00024 int g1 = 0, dgdx = 0, dgdy = 0, dgdl_min = 0, dgdl_max = 0; 00025 int b1 = 0, dbdx = 0, dbdy = 0, dbdl_min = 0, dbdl_max = 0; 00026 int a1 = 0, dadx = 0, dady = 0, dadl_min = 0, dadl_max = 0; 00027 #endif 00028 #ifdef INTERP_ST 00029 int s1 = 0, dsdx = 0, dsdy = 0, dsdl_min = 0, dsdl_max = 0; 00030 int t1 = 0, dtdx = 0, dtdy = 0, dtdl_min = 0, dtdl_max = 0; 00031 #endif 00032 #ifdef INTERP_STZ 00033 PN_stdfloat sz1 = 0, dszdx = 0, dszdy = 0, dszdl_min = 0, dszdl_max = 0; 00034 PN_stdfloat tz1 = 0, dtzdx = 0, dtzdy = 0, dtzdl_min = 0, dtzdl_max = 0; 00035 #endif 00036 #ifdef INTERP_STZA 00037 PN_stdfloat sza1 = 0, dszadx = 0, dszady = 0, dszadl_min = 0, dszadl_max = 0; 00038 PN_stdfloat tza1 = 0, dtzadx = 0, dtzady = 0, dtzadl_min = 0, dtzadl_max = 0; 00039 #endif 00040 #ifdef INTERP_STZB 00041 PN_stdfloat szb1 = 0, dszbdx = 0, dszbdy = 0, dszbdl_min = 0, dszbdl_max = 0; 00042 PN_stdfloat tzb1 = 0, dtzbdx = 0, dtzbdy = 0, dtzbdl_min = 0, dtzbdl_max = 0; 00043 #endif 00044 #if defined(INTERP_MIPMAP) && (defined(INTERP_ST) || defined(INTERP_STZ)) 00045 unsigned int mipmap_dx = 0, mipmap_level = 0; 00046 #endif 00047 #if defined(INTERP_MIPMAP) && defined(INTERP_STZA) 00048 unsigned int mipmap_dxa = 0, mipmap_levela = 0; 00049 #endif 00050 #if defined(INTERP_MIPMAP) && defined(INTERP_STZB) 00051 unsigned int mipmap_dxb = 0, mipmap_levelb = 0; 00052 #endif 00053 00054 EARLY_OUT(); 00055 00056 COUNT_PIXELS(PIXEL_COUNT, p0, p1, p2); 00057 00058 /* we sort the vertex with increasing y */ 00059 if (p1->y < p0->y) { 00060 t = p0; 00061 p0 = p1; 00062 p1 = t; 00063 } 00064 if (p2->y < p0->y) { 00065 t = p2; 00066 p2 = p1; 00067 p1 = p0; 00068 p0 = t; 00069 } else if (p2->y < p1->y) { 00070 t = p1; 00071 p1 = p2; 00072 p2 = t; 00073 } 00074 00075 /* we compute dXdx and dXdy for all interpolated values */ 00076 00077 fdx1 = (PN_stdfloat) (p1->x - p0->x); 00078 fdy1 = (PN_stdfloat) (p1->y - p0->y); 00079 00080 fdx2 = (PN_stdfloat) (p2->x - p0->x); 00081 fdy2 = (PN_stdfloat) (p2->y - p0->y); 00082 00083 fz = fdx1 * fdy2 - fdx2 * fdy1; 00084 if (fz == 0) 00085 return; 00086 fz = 1.0f / fz; 00087 00088 fdx1 *= fz; 00089 fdy1 *= fz; 00090 fdx2 *= fz; 00091 fdy2 *= fz; 00092 00093 #ifdef INTERP_Z 00094 d1 = (PN_stdfloat) (p1->z - p0->z); 00095 d2 = (PN_stdfloat) (p2->z - p0->z); 00096 dzdx = (int) (fdy2 * d1 - fdy1 * d2); 00097 dzdy = (int) (fdx1 * d2 - fdx2 * d1); 00098 #endif 00099 00100 #ifdef INTERP_RGB 00101 d1 = (PN_stdfloat) (p1->r - p0->r); 00102 d2 = (PN_stdfloat) (p2->r - p0->r); 00103 drdx = (int) (fdy2 * d1 - fdy1 * d2); 00104 drdy = (int) (fdx1 * d2 - fdx2 * d1); 00105 00106 d1 = (PN_stdfloat) (p1->g - p0->g); 00107 d2 = (PN_stdfloat) (p2->g - p0->g); 00108 dgdx = (int) (fdy2 * d1 - fdy1 * d2); 00109 dgdy = (int) (fdx1 * d2 - fdx2 * d1); 00110 00111 d1 = (PN_stdfloat) (p1->b - p0->b); 00112 d2 = (PN_stdfloat) (p2->b - p0->b); 00113 dbdx = (int) (fdy2 * d1 - fdy1 * d2); 00114 dbdy = (int) (fdx1 * d2 - fdx2 * d1); 00115 00116 d1 = (PN_stdfloat) (p1->a - p0->a); 00117 d2 = (PN_stdfloat) (p2->a - p0->a); 00118 dadx = (int) (fdy2 * d1 - fdy1 * d2); 00119 dady = (int) (fdx1 * d2 - fdx2 * d1); 00120 00121 #endif 00122 00123 #ifdef INTERP_ST 00124 d1 = (PN_stdfloat) (p1->s - p0->s); 00125 d2 = (PN_stdfloat) (p2->s - p0->s); 00126 dsdx = (int) (fdy2 * d1 - fdy1 * d2); 00127 dsdy = (int) (fdx1 * d2 - fdx2 * d1); 00128 00129 d1 = (PN_stdfloat) (p1->t - p0->t); 00130 d2 = (PN_stdfloat) (p2->t - p0->t); 00131 dtdx = (int) (fdy2 * d1 - fdy1 * d2); 00132 dtdy = (int) (fdx1 * d2 - fdx2 * d1); 00133 00134 CALC_MIPMAP_LEVEL(mipmap_level, mipmap_dx, dsdx, dtdx); 00135 #endif 00136 00137 #ifdef INTERP_STZ 00138 { 00139 PN_stdfloat zz; 00140 zz=(PN_stdfloat) p0->z; 00141 p0->sz= (PN_stdfloat) p0->s * zz; 00142 p0->tz= (PN_stdfloat) p0->t * zz; 00143 zz=(PN_stdfloat) p1->z; 00144 p1->sz= (PN_stdfloat) p1->s * zz; 00145 p1->tz= (PN_stdfloat) p1->t * zz; 00146 zz=(PN_stdfloat) p2->z; 00147 p2->sz= (PN_stdfloat) p2->s * zz; 00148 p2->tz= (PN_stdfloat) p2->t * zz; 00149 00150 d1 = p1->sz - p0->sz; 00151 d2 = p2->sz - p0->sz; 00152 dszdx = (fdy2 * d1 - fdy1 * d2); 00153 dszdy = (fdx1 * d2 - fdx2 * d1); 00154 00155 d1 = p1->tz - p0->tz; 00156 d2 = p2->tz - p0->tz; 00157 dtzdx = (fdy2 * d1 - fdy1 * d2); 00158 dtzdy = (fdx1 * d2 - fdx2 * d1); 00159 } 00160 #endif 00161 00162 #ifdef INTERP_STZA 00163 { 00164 PN_stdfloat zz; 00165 zz=(PN_stdfloat) p0->z; 00166 p0->sza= (PN_stdfloat) p0->sa * zz; 00167 p0->tza= (PN_stdfloat) p0->ta * zz; 00168 zz=(PN_stdfloat) p1->z; 00169 p1->sza= (PN_stdfloat) p1->sa * zz; 00170 p1->tza= (PN_stdfloat) p1->ta * zz; 00171 zz=(PN_stdfloat) p2->z; 00172 p2->sza= (PN_stdfloat) p2->sa * zz; 00173 p2->tza= (PN_stdfloat) p2->ta * zz; 00174 00175 d1 = p1->sza - p0->sza; 00176 d2 = p2->sza - p0->sza; 00177 dszadx = (fdy2 * d1 - fdy1 * d2); 00178 dszady = (fdx1 * d2 - fdx2 * d1); 00179 00180 d1 = p1->tza - p0->tza; 00181 d2 = p2->tza - p0->tza; 00182 dtzadx = (fdy2 * d1 - fdy1 * d2); 00183 dtzady = (fdx1 * d2 - fdx2 * d1); 00184 } 00185 #endif 00186 00187 #ifdef INTERP_STZB 00188 { 00189 PN_stdfloat zz; 00190 zz=(PN_stdfloat) p0->z; 00191 p0->szb= (PN_stdfloat) p0->sb * zz; 00192 p0->tzb= (PN_stdfloat) p0->tb * zz; 00193 zz=(PN_stdfloat) p1->z; 00194 p1->szb= (PN_stdfloat) p1->sb * zz; 00195 p1->tzb= (PN_stdfloat) p1->tb * zz; 00196 zz=(PN_stdfloat) p2->z; 00197 p2->szb= (PN_stdfloat) p2->sb * zz; 00198 p2->tzb= (PN_stdfloat) p2->tb * zz; 00199 00200 d1 = p1->szb - p0->szb; 00201 d2 = p2->szb - p0->szb; 00202 dszbdx = (fdy2 * d1 - fdy1 * d2); 00203 dszbdy = (fdx1 * d2 - fdx2 * d1); 00204 00205 d1 = p1->tzb - p0->tzb; 00206 d2 = p2->tzb - p0->tzb; 00207 dtzbdx = (fdy2 * d1 - fdy1 * d2); 00208 dtzbdy = (fdx1 * d2 - fdx2 * d1); 00209 } 00210 #endif 00211 00212 /* screen coordinates */ 00213 00214 pp1 = (PIXEL *) ((char *) zb->pbuf + zb->linesize * p0->y); 00215 pz1 = zb->zbuf + p0->y * zb->xsize; 00216 00217 DRAW_INIT(); 00218 00219 for(part=0;part<2;part++) { 00220 if (part == 0) { 00221 if (fz > 0) { 00222 update_left=1; 00223 update_right=1; 00224 l1=p0; 00225 l2=p2; 00226 pr1=p0; 00227 pr2=p1; 00228 } else { 00229 update_left=1; 00230 update_right=1; 00231 l1=p0; 00232 l2=p1; 00233 pr1=p0; 00234 pr2=p2; 00235 } 00236 nb_lines = p1->y - p0->y; 00237 } else { 00238 /* second part */ 00239 if (fz > 0) { 00240 update_left=0; 00241 update_right=1; 00242 pr1=p1; 00243 pr2=p2; 00244 } else { 00245 update_left=1; 00246 update_right=0; 00247 l1=p1; 00248 l2=p2; 00249 } 00250 nb_lines = p2->y - p1->y + 1; 00251 } 00252 00253 /* compute the values for the left edge */ 00254 00255 if (update_left) { 00256 dy1 = l2->y - l1->y; 00257 dx1 = l2->x - l1->x; 00258 if (dy1 > 0) 00259 tmp = (dx1 << 16) / dy1; 00260 else 00261 tmp = 0; 00262 x1 = l1->x; 00263 error = 0; 00264 derror = tmp & 0x0000ffff; 00265 dxdy_min = tmp >> 16; 00266 dxdy_max = dxdy_min + 1; 00267 00268 #ifdef INTERP_Z 00269 z1=l1->z; 00270 dzdl_min=(dzdy + dzdx * dxdy_min); 00271 dzdl_max=dzdl_min + dzdx; 00272 #endif 00273 #ifdef INTERP_RGB 00274 r1=l1->r; 00275 drdl_min=(drdy + drdx * dxdy_min); 00276 drdl_max=drdl_min + drdx; 00277 00278 g1=l1->g; 00279 dgdl_min=(dgdy + dgdx * dxdy_min); 00280 dgdl_max=dgdl_min + dgdx; 00281 00282 b1=l1->b; 00283 dbdl_min=(dbdy + dbdx * dxdy_min); 00284 dbdl_max=dbdl_min + dbdx; 00285 00286 a1=l1->a; 00287 dadl_min=(dady + dadx * dxdy_min); 00288 dadl_max=dadl_min + dadx; 00289 #endif 00290 #ifdef INTERP_ST 00291 s1=l1->s; 00292 dsdl_min=(dsdy + dsdx * dxdy_min); 00293 dsdl_max=dsdl_min + dsdx; 00294 00295 t1=l1->t; 00296 dtdl_min=(dtdy + dtdx * dxdy_min); 00297 dtdl_max=dtdl_min + dtdx; 00298 #endif 00299 #ifdef INTERP_STZ 00300 sz1=l1->sz; 00301 dszdl_min=(dszdy + dszdx * dxdy_min); 00302 dszdl_max=dszdl_min + dszdx; 00303 00304 tz1=l1->tz; 00305 dtzdl_min=(dtzdy + dtzdx * dxdy_min); 00306 dtzdl_max=dtzdl_min + dtzdx; 00307 #endif 00308 #ifdef INTERP_STZA 00309 sza1=l1->sza; 00310 dszadl_min=(dszady + dszadx * dxdy_min); 00311 dszadl_max=dszadl_min + dszadx; 00312 00313 tza1=l1->tza; 00314 dtzadl_min=(dtzady + dtzadx * dxdy_min); 00315 dtzadl_max=dtzadl_min + dtzadx; 00316 #endif 00317 #ifdef INTERP_STZB 00318 szb1=l1->szb; 00319 dszbdl_min=(dszbdy + dszbdx * dxdy_min); 00320 dszbdl_max=dszbdl_min + dszbdx; 00321 00322 tzb1=l1->tzb; 00323 dtzbdl_min=(dtzbdy + dtzbdx * dxdy_min); 00324 dtzbdl_max=dtzbdl_min + dtzbdx; 00325 #endif 00326 } 00327 00328 /* compute values for the right edge */ 00329 00330 if (update_right) { 00331 dx2 = (pr2->x - pr1->x); 00332 dy2 = (pr2->y - pr1->y); 00333 if (dy2>0) 00334 dx2dy2 = ( dx2 << 16) / dy2; 00335 else 00336 dx2dy2 = 0; 00337 x2 = pr1->x << 16; 00338 } 00339 00340 /* we draw all the scan line of the part */ 00341 00342 while (nb_lines>0) { 00343 nb_lines--; 00344 #ifndef DRAW_LINE 00345 /* generic draw line */ 00346 { 00347 register PIXEL *pp; 00348 register int n; 00349 #ifdef INTERP_Z 00350 register ZPOINT *pz; 00351 register unsigned int z,zz; 00352 #endif 00353 #ifdef INTERP_RGB 00354 register unsigned int or1,og1,ob1,oa1; 00355 #endif 00356 #ifdef INTERP_ST 00357 register unsigned int s,t; 00358 #endif 00359 #ifdef INTERP_STZ 00360 PN_stdfloat sz,tz; 00361 #endif 00362 #ifdef INTERP_STZA 00363 PN_stdfloat sza,tza; 00364 #endif 00365 #ifdef INTERP_STZB 00366 PN_stdfloat szb,tzb; 00367 #endif 00368 00369 n=(x2 >> 16) - x1; 00370 pp=(PIXEL *)((char *)pp1 + x1 * PSZB); 00371 #ifdef INTERP_Z 00372 pz=pz1+x1; 00373 z=z1; 00374 #endif 00375 #ifdef INTERP_RGB 00376 or1 = r1; 00377 og1 = g1; 00378 ob1 = b1; 00379 oa1 = a1; 00380 #endif 00381 #ifdef INTERP_ST 00382 s=s1; 00383 t=t1; 00384 #endif 00385 #ifdef INTERP_STZ 00386 sz=sz1; 00387 tz=tz1; 00388 #endif 00389 #ifdef INTERP_STZA 00390 sza=sza1; 00391 tza=tza1; 00392 #endif 00393 #ifdef INTERP_STZB 00394 szb=szb1; 00395 tzb=tzb1; 00396 #endif 00397 while (n>=3) { 00398 PUT_PIXEL(0); 00399 PUT_PIXEL(1); 00400 PUT_PIXEL(2); 00401 PUT_PIXEL(3); 00402 #ifdef INTERP_Z 00403 pz+=4; 00404 #endif 00405 pp=(PIXEL *)((char *)pp + 4 * PSZB); 00406 n-=4; 00407 } 00408 while (n>=0) { 00409 PUT_PIXEL(0); 00410 #ifdef INTERP_Z 00411 pz+=1; 00412 #endif 00413 pp=(PIXEL *)((char *)pp + PSZB); 00414 n-=1; 00415 } 00416 } 00417 #else 00418 DRAW_LINE(); 00419 #endif 00420 00421 /* left edge */ 00422 error+=derror; 00423 if (error > 0) { 00424 error-=0x10000; 00425 x1+=dxdy_max; 00426 #ifdef INTERP_Z 00427 z1+=dzdl_max; 00428 #endif 00429 #ifdef INTERP_RGB 00430 r1+=drdl_max; 00431 g1+=dgdl_max; 00432 b1+=dbdl_max; 00433 a1+=dadl_max; 00434 #endif 00435 #ifdef INTERP_ST 00436 s1+=dsdl_max; 00437 t1+=dtdl_max; 00438 #endif 00439 #ifdef INTERP_STZ 00440 sz1+=dszdl_max; 00441 tz1+=dtzdl_max; 00442 #endif 00443 #ifdef INTERP_STZA 00444 sza1+=dszadl_max; 00445 tza1+=dtzadl_max; 00446 #endif 00447 #ifdef INTERP_STZB 00448 szb1+=dszbdl_max; 00449 tzb1+=dtzbdl_max; 00450 #endif 00451 } else { 00452 x1+=dxdy_min; 00453 #ifdef INTERP_Z 00454 z1+=dzdl_min; 00455 #endif 00456 #ifdef INTERP_RGB 00457 r1+=drdl_min; 00458 g1+=dgdl_min; 00459 b1+=dbdl_min; 00460 a1+=dadl_min; 00461 #endif 00462 #ifdef INTERP_ST 00463 s1+=dsdl_min; 00464 t1+=dtdl_min; 00465 #endif 00466 #ifdef INTERP_STZ 00467 sz1+=dszdl_min; 00468 tz1+=dtzdl_min; 00469 #endif 00470 #ifdef INTERP_STZA 00471 sza1+=dszadl_min; 00472 tza1+=dtzadl_min; 00473 #endif 00474 #ifdef INTERP_STZB 00475 szb1+=dszbdl_min; 00476 tzb1+=dtzbdl_min; 00477 #endif 00478 } 00479 00480 /* right edge */ 00481 x2+=dx2dy2; 00482 00483 /* screen coordinates */ 00484 pp1=(PIXEL *)((char *)pp1 + zb->linesize); 00485 pz1+=zb->xsize; 00486 } 00487 } 00488 } 00489 00490 #undef INTERP_Z 00491 #undef INTERP_RGB 00492 #undef INTERP_ST 00493 #undef INTERP_STZ 00494 #undef INTERP_STZA 00495 #undef INTERP_STZB 00496 00497 #undef EARLY_OUT 00498 #undef EARLY_OUT_FZ 00499 #undef DRAW_INIT 00500 #undef DRAW_LINE 00501 #undef PUT_PIXEL 00502 #undef PIXEL_COUNT