PF_PTEX.C 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459
  1. /******************************************************************************
  2. Plush Version 1.2
  3. pf_ptex.c
  4. Perspective Correct Texture Mapping Rasterizers
  5. Copyright (c) 1996-2000, Justin Frankel
  6. ******************************************************************************/
  7. #include "plush.h"
  8. #include "putface.h"
  9. void plPF_PTexF(pl_Cam *cam, pl_Face *TriFace) {
  10. pl_uChar i0, i1, i2;
  11. pl_uChar *gmem = cam->frameBuffer;
  12. pl_uChar *remap = TriFace->Material->_ReMapTable;
  13. pl_ZBuffer *zbuf = cam->zBuffer;
  14. pl_Float MappingU1, MappingU2, MappingU3;
  15. pl_Float MappingV1, MappingV2, MappingV3;
  16. pl_sInt32 MappingU_AND, MappingV_AND;
  17. pl_uChar *texture;
  18. pl_uChar vshift;
  19. pl_uInt16 bc;
  20. pl_Texture *Texture;
  21. pl_sInt32 iShade;
  22. pl_uChar nm, nmb;
  23. pl_sInt n;
  24. pl_Float U1,V1,U2,V2,dU1=0,dU2=0,dV1=0,dV2=0,dUL=0,dVL=0,UL,VL;
  25. pl_sInt32 iUL, iVL, idUL=0, idVL=0, iULnext, iVLnext;
  26. pl_sInt32 scrwidth = cam->ScreenWidth;
  27. pl_sInt32 X1, X2, dX1=0, dX2=0, XL1, Xlen;
  28. pl_ZBuffer Z1, dZ1=0, dZ2=0, Z2, dZL=0, ZL, pZL, pdZL;
  29. pl_sInt32 Y1, Y2, Y0, dY;
  30. pl_uChar stat;
  31. pl_Bool zb = (zbuf&&TriFace->Material->zBufferable) ? 1 : 0;
  32. if (TriFace->Material->Environment) Texture = TriFace->Material->Environment;
  33. else Texture = TriFace->Material->Texture;
  34. if (!Texture) return;
  35. texture = Texture->Data;
  36. iShade = (pl_sInt32)(TriFace->fShade*256.0);
  37. if (iShade < 0) iShade=0;
  38. if (iShade > 255) iShade=255;
  39. if (!TriFace->Material->_AddTable) bc=0;
  40. else bc = TriFace->Material->_AddTable[iShade];
  41. nm = TriFace->Material->PerspectiveCorrect;
  42. nmb = 0; while (nm) { nmb++; nm >>= 1; }
  43. nmb = plMin(6,nmb);
  44. nm = 1<<nmb;
  45. MappingV_AND = ((1<<Texture->Height)-1)<<Texture->Width;
  46. MappingU_AND = (1<<Texture->Width)-1;
  47. vshift = 16 - Texture->Width;
  48. if (TriFace->Material->Environment) {
  49. PUTFACE_SORT_ENV();
  50. } else {
  51. PUTFACE_SORT_TEX();
  52. }
  53. MappingU1 *= TriFace->Scrz[i0]/65536.0f;
  54. MappingV1 *= TriFace->Scrz[i0]/65536.0f;
  55. MappingU2 *= TriFace->Scrz[i1]/65536.0f;
  56. MappingV2 *= TriFace->Scrz[i1]/65536.0f;
  57. MappingU3 *= TriFace->Scrz[i2]/65536.0f;
  58. MappingV3 *= TriFace->Scrz[i2]/65536.0f;
  59. U1 = U2 = MappingU1;
  60. V1 = V2 = MappingV1;
  61. X2 = X1 = TriFace->Scrx[i0];
  62. Z2 = Z1 = TriFace->Scrz[i0];
  63. Y0 = (TriFace->Scry[i0]+(1<<19))>>20;
  64. Y1 = (TriFace->Scry[i1]+(1<<19))>>20;
  65. Y2 = (TriFace->Scry[i2]+(1<<19))>>20;
  66. dY = Y2-Y0;
  67. if (dY) {
  68. dX2 = (TriFace->Scrx[i2] - X1) / dY;
  69. dZ2 = (TriFace->Scrz[i2] - Z1) / dY;
  70. dU2 = (MappingU3 - U1) / dY;
  71. dV2 = (MappingV3 - V1) / dY;
  72. }
  73. dY = Y1-Y0;
  74. if (dY) {
  75. dX1 = (TriFace->Scrx[i1] - X1) / dY;
  76. dZ1 = (TriFace->Scrz[i1] - Z1) / dY;
  77. dU1 = (MappingU2 - U1) / dY;
  78. dV1 = (MappingV2 - V1) / dY;
  79. if (dX2 < dX1) {
  80. XL1 = dX2; dX2 = dX1; dX1 = XL1;
  81. dUL = dU1; dU1 = dU2; dU2 = dUL;
  82. dVL = dV1; dV1 = dV2; dV2 = dVL;
  83. dZL = dZ1; dZ1 = dZ2; dZ2 = dZL;
  84. stat = 2;
  85. } else stat = 1;
  86. } else {
  87. if (TriFace->Scrx[i1] > X1) {
  88. X2 = TriFace->Scrx[i1];
  89. Z2 = TriFace->Scrz[i1];
  90. U2 = MappingU2;
  91. V2 = MappingV2;
  92. stat = 2|4;
  93. } else {
  94. X1 = TriFace->Scrx[i1];
  95. Z1 = TriFace->Scrz[i1];
  96. U1 = MappingU2;
  97. V1 = MappingV2;
  98. stat = 1|8;
  99. }
  100. }
  101. gmem += (Y0 * cam->ScreenWidth);
  102. zbuf += (Y0 * cam->ScreenWidth);
  103. XL1 = ((dX1-dX2)*dY+(1<<19))>>20;
  104. if (XL1) {
  105. dUL = ((dU1-dU2)*dY)/XL1;
  106. dVL = ((dV1-dV2)*dY)/XL1;
  107. dZL = ((dZ1-dZ2)*dY)/XL1;
  108. } else {
  109. XL1 = ((X2-X1+(1<<19))>>20);
  110. if (XL1) {
  111. dUL = (U2-U1)/XL1;
  112. dVL = (V2-V1)/XL1;
  113. dZL = (Z2-Z1)/XL1;
  114. }
  115. }
  116. pdZL = dZL * nm;
  117. dUL *= nm;
  118. dVL *= nm;
  119. while (Y0 < Y2) {
  120. if (Y0 == Y1) {
  121. dY = Y2-((TriFace->Scry[i1]+(1<<19))>>20);
  122. if (dY) {
  123. if (stat & 1) {
  124. X1 = TriFace->Scrx[i1];
  125. dX1 = (TriFace->Scrx[i2]-TriFace->Scrx[i1])/dY;
  126. }
  127. if (stat & 2) {
  128. X2 = TriFace->Scrx[i1];
  129. dX2 = (TriFace->Scrx[i2]-TriFace->Scrx[i1])/dY;
  130. }
  131. if (stat & 4) {
  132. X1 = TriFace->Scrx[i0];
  133. dX1 = (TriFace->Scrx[i2]-TriFace->Scrx[i0])/dY;
  134. }
  135. if (stat & 8) {
  136. X2 = TriFace->Scrx[i0];
  137. dX2 = (TriFace->Scrx[i2]-TriFace->Scrx[i0])/dY;
  138. }
  139. dZ1 = (TriFace->Scrz[i2]-Z1)/dY;
  140. dV1 = (MappingV3 - V1) / dY;
  141. dU1 = (MappingU3 - U1) / dY;
  142. }
  143. }
  144. XL1 = (X1+(1<<19))>>20;
  145. Xlen = ((X2+(1<<19))>>20) - XL1;
  146. if (Xlen > 0) {
  147. register pl_Float t;
  148. pZL = ZL = Z1;
  149. UL = U1;
  150. VL = V1;
  151. gmem += XL1;
  152. zbuf += XL1;
  153. XL1 += Xlen-scrwidth;
  154. t = 65536.0f/ZL;
  155. iUL = iULnext = ((pl_sInt32) (UL*t));
  156. iVL = iVLnext = ((pl_sInt32) (VL*t));
  157. do {
  158. UL += dUL;
  159. VL += dVL;
  160. iUL = iULnext;
  161. iVL = iVLnext;
  162. pZL += pdZL;
  163. t = 65536.0f/pZL;
  164. iULnext = ((pl_sInt32) (UL*t));
  165. iVLnext = ((pl_sInt32) (VL*t));
  166. idUL = (iULnext - iUL)>>nmb;
  167. idVL = (iVLnext - iVL)>>nmb;
  168. n = nm;
  169. Xlen -= n;
  170. if (Xlen < 0) n += Xlen;
  171. if (zb) do {
  172. if (*zbuf < ZL) {
  173. *zbuf = ZL;
  174. *gmem = remap[bc + texture[((iUL>>16)&MappingU_AND) +
  175. ((iVL>>vshift)&MappingV_AND)]];
  176. }
  177. zbuf++;
  178. gmem++;
  179. ZL += dZL;
  180. iUL += idUL;
  181. iVL += idVL;
  182. } while (--n);
  183. else do {
  184. *gmem++ = remap[bc + texture[((iUL>>16)&MappingU_AND) +
  185. ((iVL>>vshift)&MappingV_AND)]];
  186. iUL += idUL;
  187. iVL += idVL;
  188. } while (--n);
  189. } while (Xlen > 0);
  190. gmem -= XL1;
  191. zbuf -= XL1;
  192. } else {
  193. zbuf += cam->ScreenWidth;
  194. gmem += cam->ScreenWidth;
  195. }
  196. Z1 += dZ1;
  197. U1 += dU1;
  198. V1 += dV1;
  199. X1 += dX1;
  200. X2 += dX2;
  201. Y0++;
  202. }
  203. }
  204. void plPF_PTexG(pl_Cam *cam, pl_Face *TriFace) {
  205. pl_uChar i0, i1, i2;
  206. pl_Float MappingU1, MappingU2, MappingU3;
  207. pl_Float MappingV1, MappingV2, MappingV3;
  208. pl_Texture *Texture;
  209. pl_Bool zb = (cam->zBuffer&&TriFace->Material->zBufferable) ? 1 : 0;
  210. pl_uChar nm, nmb;
  211. pl_uInt n;
  212. pl_sInt32 MappingU_AND, MappingV_AND;
  213. pl_uChar vshift;
  214. pl_uChar *texture;
  215. pl_uInt16 *addtable;
  216. pl_uChar *remap = TriFace->Material->_ReMapTable;
  217. pl_sInt32 iUL, iVL, idUL, idVL, iULnext, iVLnext;
  218. pl_Float U2,V2,dU2=0,dV2=0,dUL=0,dVL=0,UL,VL;
  219. pl_sInt32 XL1, Xlen;
  220. pl_sInt32 C2, dC2=0, CL, dCL=0;
  221. pl_Float ZL, Z2, dZ2=0, dZL=0, pdZL, pZL;
  222. pl_sInt32 Y2, dY;
  223. pl_uChar stat;
  224. /* Cache line */
  225. pl_sInt32 Y0,Y1;
  226. pl_sInt32 C1, dC1=0, X2, dX2=0, X1, dX1=0;
  227. /* Cache line */
  228. pl_Float dU1=0, U1, dZ1=0, Z1, V1, dV1=0;
  229. pl_sInt32 scrwidth = cam->ScreenWidth;
  230. pl_uChar *gmem = cam->frameBuffer;
  231. pl_ZBuffer *zbuf = cam->zBuffer;
  232. if (TriFace->Material->Environment) Texture = TriFace->Material->Environment;
  233. else Texture = TriFace->Material->Texture;
  234. if (!Texture) return;
  235. texture = Texture->Data;
  236. addtable = TriFace->Material->_AddTable;
  237. if (!addtable) return;
  238. nm = TriFace->Material->PerspectiveCorrect;
  239. nmb = 0; while (nm) { nmb++; nm >>= 1; }
  240. nmb = plMin(6,nmb);
  241. nm = 1<<nmb;
  242. MappingV_AND = ((1<<Texture->Height)-1)<<Texture->Width;
  243. MappingU_AND = (1<<Texture->Width)-1;
  244. vshift = 16 - Texture->Width;
  245. if (TriFace->Material->Environment) {
  246. PUTFACE_SORT_ENV();
  247. } else {
  248. PUTFACE_SORT_TEX();
  249. }
  250. MappingU1 *= TriFace->Scrz[i0]/65536.0f;
  251. MappingV1 *= TriFace->Scrz[i0]/65536.0f;
  252. MappingU2 *= TriFace->Scrz[i1]/65536.0f;
  253. MappingV2 *= TriFace->Scrz[i1]/65536.0f;
  254. MappingU3 *= TriFace->Scrz[i2]/65536.0f;
  255. MappingV3 *= TriFace->Scrz[i2]/65536.0f;
  256. TriFace->Shades[0] *= 65536.0f;
  257. TriFace->Shades[1] *= 65536.0f;
  258. TriFace->Shades[2] *= 65536.0f;
  259. C1 = C2 = (pl_sInt32) TriFace->Shades[i0];
  260. U1 = U2 = MappingU1;
  261. V1 = V2 = MappingV1;
  262. X2 = X1 = TriFace->Scrx[i0];
  263. Z2 = Z1 = TriFace->Scrz[i0];
  264. Y0 = (TriFace->Scry[i0]+(1<<19))>>20;
  265. Y1 = (TriFace->Scry[i1]+(1<<19))>>20;
  266. Y2 = (TriFace->Scry[i2]+(1<<19))>>20;
  267. dY = Y2-Y0;
  268. if (dY) {
  269. dX2 = (TriFace->Scrx[i2] - X1) / dY;
  270. dZ2 = (TriFace->Scrz[i2] - Z1) / dY;
  271. dC2 = (pl_sInt32) ((TriFace->Shades[i2] - C1) / dY);
  272. dU2 = (MappingU3 - U1) / dY;
  273. dV2 = (MappingV3 - V1) / dY;
  274. }
  275. dY = Y1-Y0;
  276. if (dY) {
  277. dX1 = (TriFace->Scrx[i1] - X1) / dY;
  278. dZ1 = (TriFace->Scrz[i1] - Z1) / dY;
  279. dC1 = (pl_sInt32) ((TriFace->Shades[i1] - C1) / dY);
  280. dU1 = (MappingU2 - U1) / dY;
  281. dV1 = (MappingV2 - V1) / dY;
  282. if (dX2 < dX1) {
  283. dX2 ^= dX1; dX1 ^= dX2; dX2 ^= dX1;
  284. dUL = dU1; dU1 = dU2; dU2 = dUL;
  285. dVL = dV1; dV1 = dV2; dV2 = dVL;
  286. dZL = dZ1; dZ1 = dZ2; dZ2 = dZL;
  287. dCL = dC1; dC1 = dC2; dC2 = dCL;
  288. stat = 2;
  289. } else stat = 1;
  290. } else {
  291. if (TriFace->Scrx[i1] > X1) {
  292. X2 = TriFace->Scrx[i1];
  293. Z2 = TriFace->Scrz[i1];
  294. C2 = (pl_sInt32)TriFace->Shades[i1];
  295. U2 = MappingU2;
  296. V2 = MappingV2;
  297. stat = 2|4;
  298. } else {
  299. X1 = TriFace->Scrx[i1];
  300. Z1 = TriFace->Scrz[i1];
  301. C1 = (pl_sInt32)TriFace->Shades[i1];
  302. U1 = MappingU2;
  303. V1 = MappingV2;
  304. stat = 1|8;
  305. }
  306. }
  307. gmem += (Y0 * scrwidth);
  308. zbuf += (Y0 * scrwidth);
  309. XL1 = (((dX1-dX2)*dY+(1<<19))>>20);
  310. if (XL1) {
  311. dUL = ((dU1-dU2)*dY)/XL1;
  312. dVL = ((dV1-dV2)*dY)/XL1;
  313. dZL = ((dZ1-dZ2)*dY)/XL1;
  314. dCL = ((dC1-dC2)*dY)/XL1;
  315. } else {
  316. XL1 = ((X2-X1+(1<<19))>>20);
  317. if (XL1) {
  318. dUL = (U2-U1)/XL1;
  319. dVL = (V2-V1)/XL1;
  320. dZL = (Z2-Z1)/XL1;
  321. dCL = (C2-C1)/XL1;
  322. }
  323. }
  324. pdZL = dZL * nm;
  325. dUL *= nm;
  326. dVL *= nm;
  327. Y1 -= Y0;
  328. Y0 = Y2-Y0;
  329. while (Y0--) {
  330. if (!Y1--) {
  331. dY = Y2-((TriFace->Scry[i1]+(1<<19))>>20);
  332. if (dY) {
  333. if (stat & 1) {
  334. X1 = TriFace->Scrx[i1];
  335. dX1 = (TriFace->Scrx[i2]-TriFace->Scrx[i1])/dY;
  336. }
  337. if (stat & 2) {
  338. X2 = TriFace->Scrx[i1];
  339. dX2 = (TriFace->Scrx[i2]-TriFace->Scrx[i1])/dY;
  340. }
  341. if (stat & 4) {
  342. X1 = TriFace->Scrx[i0];
  343. dX1 = (TriFace->Scrx[i2]-TriFace->Scrx[i0])/dY;
  344. }
  345. if (stat & 8) {
  346. X2 = TriFace->Scrx[i0];
  347. dX2 = (TriFace->Scrx[i2]-TriFace->Scrx[i0])/dY;
  348. }
  349. dZ1 = (TriFace->Scrz[i2]-Z1)/dY;
  350. dC1 = (pl_sInt32)((TriFace->Shades[i2]-C1)/dY);
  351. dV1 = (MappingV3 - V1) / dY;
  352. dU1 = (MappingU3 - U1) / dY;
  353. }
  354. }
  355. XL1 = (X1+(1<<19))>>20;
  356. Xlen = ((X2+(1<<19))>>20) - XL1;
  357. if (Xlen > 0) {
  358. register pl_Float t;
  359. CL = C1;
  360. pZL = ZL = Z1;
  361. UL = U1;
  362. VL = V1;
  363. gmem += XL1;
  364. zbuf += XL1;
  365. XL1 += Xlen-scrwidth;
  366. t = 65536.0f / ZL;
  367. iUL = iULnext = ((pl_sInt32) (UL*t));
  368. iVL = iVLnext = ((pl_sInt32) (VL*t));
  369. do {
  370. UL += dUL;
  371. VL += dVL;
  372. iUL = iULnext;
  373. iVL = iVLnext;
  374. pZL += pdZL;
  375. t = 65536.0f/pZL;
  376. iULnext = ((pl_sInt32) (UL*t));
  377. iVLnext = ((pl_sInt32) (VL*t));
  378. idUL = (iULnext - iUL)>>nmb;
  379. idVL = (iVLnext - iVL)>>nmb;
  380. n = nm;
  381. Xlen -= n;
  382. if (Xlen < 0) n += Xlen;
  383. if (zb) do {
  384. if (*zbuf < ZL) {
  385. int av;
  386. if (CL < 0) av=addtable[0];
  387. else if (CL > (255<<8)) av=addtable[255];
  388. else av=addtable[CL>>8];
  389. *zbuf = ZL;
  390. *gmem = remap[av +
  391. texture[((iUL>>16)&MappingU_AND) +
  392. ((iVL>>vshift)&MappingV_AND)]];
  393. }
  394. zbuf++;
  395. gmem++;
  396. ZL += dZL;
  397. CL += dCL;
  398. iUL += idUL;
  399. iVL += idVL;
  400. } while (--n);
  401. else do {
  402. int av;
  403. if (CL < 0) av=addtable[0];
  404. else if (CL > (255<<8)) av=addtable[255];
  405. else av=addtable[CL>>8];
  406. *gmem++ = remap[av +
  407. texture[((iUL>>16)&MappingU_AND) +
  408. ((iVL>>vshift)&MappingV_AND)]];
  409. CL += dCL;
  410. iUL += idUL;
  411. iVL += idVL;
  412. } while (--n);
  413. } while (Xlen > 0);
  414. gmem -= XL1;
  415. zbuf -= XL1;
  416. } else {
  417. zbuf += scrwidth;
  418. gmem += scrwidth;
  419. }
  420. Z1 += dZ1;
  421. U1 += dU1;
  422. V1 += dV1;
  423. X1 += dX1;
  424. X2 += dX2;
  425. C1 += dC1;
  426. }
  427. }