PF_TRANS.C 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. /******************************************************************************
  2. Plush Version 1.2
  3. pf_trans.c
  4. Solid Translucent Rasterizers
  5. Copyright (c) 1996-2000, Justin Frankel
  6. ******************************************************************************/
  7. #include "plush.h"
  8. #include "putface.h"
  9. void plPF_TransF(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_sInt32 X1, X2, dX1=0, dX2=0, XL1, XL2;
  15. pl_ZBuffer Z1, ZL, dZ1=0, dZL=0, dZ2=0, Z2;
  16. pl_sInt32 Y1, Y2, Y0, dY;
  17. pl_uInt16 *lookuptable = TriFace->Material->_AddTable;
  18. pl_uChar stat;
  19. pl_sInt32 bc = (pl_sInt32) TriFace->fShade*TriFace->Material->_tsfact;
  20. pl_Bool zb = (zbuf&&TriFace->Material->zBufferable) ? 1 : 0;
  21. PUTFACE_SORT();
  22. if (bc < 0) bc=0;
  23. if (bc > (pl_sInt32) TriFace->Material->_tsfact-1) bc=TriFace->Material->_tsfact-1;
  24. remap+=bc;
  25. X2 = X1 = TriFace->Scrx[i0];
  26. Z2 = Z1 = TriFace->Scrz[i0];
  27. Y0 = (TriFace->Scry[i0]+(1<<19))>>20;
  28. Y1 = (TriFace->Scry[i1]+(1<<19))>>20;
  29. Y2 = (TriFace->Scry[i2]+(1<<19))>>20;
  30. dY = Y2 - Y0;
  31. if (dY) {
  32. dX2 = (TriFace->Scrx[i2] - X1) / dY;
  33. dZ2 = (TriFace->Scrz[i2] - Z1) / dY;
  34. }
  35. dY = Y1-Y0;
  36. if (dY) {
  37. dX1 = (TriFace->Scrx[i1] - X1) / dY;
  38. dZ1 = (TriFace->Scrz[i1] - Z1) / dY;
  39. if (dX2 < dX1) {
  40. dX2 ^= dX1; dX1 ^= dX2; dX2 ^= dX1;
  41. dZL = dZ1; dZ1 = dZ2; dZ2 = dZL;
  42. stat = 2;
  43. } else stat = 1;
  44. } else {
  45. if (TriFace->Scrx[i1] > X1) {
  46. X2 = TriFace->Scrx[i1];
  47. Z2 = TriFace->Scrz[i1];
  48. stat= 2|4;
  49. } else {
  50. X1 = TriFace->Scrx[i1];
  51. Z1 = TriFace->Scrz[i1];
  52. stat= 1|8;
  53. }
  54. }
  55. gmem += (Y0 * cam->ScreenWidth);
  56. zbuf += (Y0 * cam->ScreenWidth);
  57. if (zb) {
  58. XL1 = (((dX1-dX2)*dY+(1<<19))>>20);
  59. if (XL1) dZL = ((dZ1-dZ2)*dY)/XL1;
  60. else {
  61. XL1 = ((X2-X1+(1<<19))>>20);
  62. if (XL1) dZL = (Z2-Z1)/XL1;
  63. }
  64. }
  65. while (Y0 < Y2) {
  66. if (Y0 == Y1) {
  67. dY = Y2 - ((TriFace->Scry[i1]+(1<<19))>>20);
  68. if (dY) {
  69. if (stat & 1) {
  70. X1 = TriFace->Scrx[i1];
  71. dX1 = (TriFace->Scrx[i2]-TriFace->Scrx[i1])/dY;
  72. }
  73. if (stat & 2) {
  74. X2 = TriFace->Scrx[i1];
  75. dX2 = (TriFace->Scrx[i2]-TriFace->Scrx[i1])/dY;
  76. }
  77. if (stat & 4) {
  78. X1 = TriFace->Scrx[i0];
  79. dX1 = (TriFace->Scrx[i2]-TriFace->Scrx[i0])/dY;
  80. }
  81. if (stat & 8) {
  82. X2 = TriFace->Scrx[i0];
  83. dX2 = (TriFace->Scrx[i2]-TriFace->Scrx[i0])/dY;
  84. }
  85. dZ1 = (TriFace->Scrz[i2]- Z1)/dY;
  86. }
  87. }
  88. XL1 = (X1+(1<<19))>>20;
  89. XL2 = (X2+(1<<19))>>20;
  90. ZL = Z1;
  91. if ((XL2-XL1) > 0) {
  92. XL2 -= XL1;
  93. zbuf += XL1;
  94. gmem += XL1;
  95. XL1 += XL2;
  96. if (zb) do {
  97. if (*zbuf < ZL) {
  98. *zbuf = ZL;
  99. *gmem = remap[lookuptable[*gmem]];
  100. }
  101. gmem++;
  102. zbuf++;
  103. ZL += dZL;
  104. } while (--XL2);
  105. else do *gmem++ = remap[lookuptable[*gmem]]; while (--XL2);
  106. gmem -= XL1;
  107. zbuf -= XL1;
  108. }
  109. gmem += cam->ScreenWidth;
  110. zbuf += cam->ScreenWidth;
  111. Z1 += dZ1;
  112. X1 += dX1;
  113. X2 += dX2;
  114. Y0 ++;
  115. }
  116. }
  117. void plPF_TransG(pl_Cam *cam, pl_Face *TriFace) {
  118. pl_uChar i0, i1, i2;
  119. pl_uChar *gmem = cam->frameBuffer;
  120. pl_uChar *remap = TriFace->Material->_ReMapTable;
  121. pl_ZBuffer *zbuf = cam->zBuffer;
  122. pl_sInt32 X1, X2, dX1=0, dX2=0, XL1, XL2;
  123. pl_ZBuffer Z1, ZL, dZ1=0, dZL=0, dZ2=0, Z2;
  124. pl_sInt32 dC1=0, dCL=0, CL, C1, C2, dC2=0;
  125. pl_sInt32 Y1, Y2, Y0, dY;
  126. pl_Float nc = (TriFace->Material->_tsfact*65536.0f);
  127. pl_uInt16 *lookuptable = TriFace->Material->_AddTable;
  128. pl_Bool zb = (zbuf&&TriFace->Material->zBufferable) ? 1 : 0;
  129. pl_uChar stat;
  130. pl_sInt32 maxColor=((TriFace->Material->_tsfact-1)<<16);
  131. pl_sInt32 maxColorNonShift=TriFace->Material->_tsfact-1;
  132. PUTFACE_SORT();
  133. C1 = C2 = (pl_sInt32) (TriFace->Shades[i0]*nc);
  134. X2 = X1 = TriFace->Scrx[i0];
  135. Z2 = Z1 = TriFace->Scrz[i0];
  136. Y0 = (TriFace->Scry[i0]+(1<<19))>>20;
  137. Y1 = (TriFace->Scry[i1]+(1<<19))>>20;
  138. Y2 = (TriFace->Scry[i2]+(1<<19))>>20;
  139. dY = Y2 - Y0;
  140. if (dY) {
  141. dX2 = (TriFace->Scrx[i2] - X1) / dY;
  142. dC2 = (pl_sInt32) ((TriFace->Shades[i2]*nc - C1) / dY);
  143. dZ2 = (TriFace->Scrz[i2] - Z1) / dY;
  144. }
  145. dY = Y1-Y0;
  146. if (dY) {
  147. dX1 = (TriFace->Scrx[i1] - X1) / dY;
  148. dZ1 = (TriFace->Scrz[i1] - Z1) / dY;
  149. dC1 = (pl_sInt32) ((TriFace->Shades[i1]*nc - C1) / dY);
  150. if (dX2 < dX1) {
  151. dX2 ^= dX1; dX1 ^= dX2; dX2 ^= dX1;
  152. dC2 ^= dC1; dC1 ^= dC2; dC2 ^= dC1;
  153. dZL = dZ1; dZ1 = dZ2; dZ2 = dZL;
  154. stat = 2;
  155. } else stat = 1;
  156. } else {
  157. if (TriFace->Scrx[i1] > X1) {
  158. X2 = TriFace->Scrx[i1];
  159. Z2 = TriFace->Scrz[i1];
  160. C2 = (pl_sInt32) (TriFace->Shades[i1]*nc);
  161. stat = 2|4;
  162. } else {
  163. X1 = TriFace->Scrx[i1];
  164. Z1 = TriFace->Scrz[i1];
  165. C1 = (pl_sInt32) (TriFace->Shades[i1]*nc);
  166. stat = 1|8;
  167. }
  168. }
  169. gmem += (Y0 * cam->ScreenWidth);
  170. zbuf += (Y0 * cam->ScreenWidth);
  171. XL1 = (((dX1-dX2)*dY+(1<<19))>>20);
  172. if (XL1) {
  173. dCL = ((dC1-dC2)*dY)/XL1;
  174. dZL = ((dZ1-dZ2)*dY)/XL1;
  175. } else {
  176. XL1 = ((X2-X1+(1<<19))>>20);
  177. if (XL1) {
  178. dCL = (C2-C1)/XL1;
  179. dZL = (Z2-Z1)/XL1;
  180. }
  181. }
  182. while (Y0 < Y2) {
  183. if (Y0 == Y1) {
  184. dY = Y2 - ((TriFace->Scry[i1]+(1<<19))>>20);
  185. if (dY) {
  186. if (stat & 1) {
  187. X1 = TriFace->Scrx[i1];
  188. dX1 = (TriFace->Scrx[i2]-TriFace->Scrx[i1])/dY;
  189. }
  190. if (stat & 2) {
  191. X2 = TriFace->Scrx[i1];
  192. dX2 = (TriFace->Scrx[i2]-TriFace->Scrx[i1])/dY;
  193. }
  194. if (stat & 4) {
  195. X1 = TriFace->Scrx[i0];
  196. dX1 = (TriFace->Scrx[i2]-TriFace->Scrx[i0])/dY;
  197. }
  198. if (stat & 8) {
  199. X2 = TriFace->Scrx[i0];
  200. dX2 = (TriFace->Scrx[i2]-TriFace->Scrx[i0])/dY;
  201. }
  202. dZ1 = (TriFace->Scrz[i2]-Z1)/dY;
  203. dC1 = (pl_sInt32) ((TriFace->Shades[i2]*nc - C1) / dY);
  204. }
  205. }
  206. CL = C1;
  207. XL1 = (X1+(1<<19))>>20;
  208. XL2 = (X2+(1<<19))>>20;
  209. ZL = Z1;
  210. if ((XL2-XL1) > 0) {
  211. XL2 -= XL1;
  212. zbuf += XL1;
  213. gmem += XL1;
  214. XL1 += XL2;
  215. if (zb) do {
  216. if (*zbuf < ZL) {
  217. int av;
  218. if (CL >= maxColor) av=maxColorNonShift;
  219. else if (CL > 0) av=CL>>16;
  220. else av=0;
  221. *zbuf = ZL;
  222. *gmem = remap[av + lookuptable[*gmem]];
  223. }
  224. gmem++;
  225. CL += dCL;
  226. zbuf++;
  227. ZL += dZL;
  228. } while (--XL2);
  229. else do {
  230. int av;
  231. if (CL >= maxColor) av=maxColorNonShift;
  232. else if (CL > 0) av=CL>>16;
  233. else av=0;
  234. *gmem++ = remap[av + lookuptable[*gmem]];
  235. CL += dCL;
  236. } while (--XL2);
  237. gmem -= XL1;
  238. zbuf -= XL1;
  239. }
  240. gmem += cam->ScreenWidth;
  241. zbuf += cam->ScreenWidth;
  242. Z1 += dZ1;
  243. X1 += dX1;
  244. X2 += dX2;
  245. C1 += dC1;
  246. Y0++;
  247. }
  248. }