/src/dep/src/irrlicht/CTRTextureLightMap2_M1.cpp

https://github.com/Pepsi1x1/pseuwow · C++ · 678 lines · 466 code · 172 blank · 40 comment · 18 complexity · dec25acbebcdd9636bae64b5238cf958 MD5 · raw file

  1. // Copyright (C) 2002-2008 Nikolaus Gebhardt / Thomas Alten
  2. // This file is part of the "Irrlicht Engine".
  3. // For conditions of distribution and use, see copyright notice in irrlicht.h
  4. #include "IrrCompileConfig.h"
  5. #include "IBurningShader.h"
  6. #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
  7. // compile flag for this file
  8. #undef USE_ZBUFFER
  9. #undef IPOL_Z
  10. #undef CMP_Z
  11. #undef WRITE_Z
  12. #undef IPOL_W
  13. #undef CMP_W
  14. #undef WRITE_W
  15. #undef SUBTEXEL
  16. #undef INVERSE_W
  17. #undef IPOL_C0
  18. #undef IPOL_T0
  19. #undef IPOL_T1
  20. // define render case
  21. #define SUBTEXEL
  22. #define INVERSE_W
  23. #define USE_ZBUFFER
  24. #define IPOL_W
  25. #define CMP_W
  26. #define WRITE_W
  27. //#define IPOL_C0
  28. #define IPOL_T0
  29. #define IPOL_T1
  30. // apply global override
  31. #ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
  32. #undef INVERSE_W
  33. #endif
  34. #ifndef SOFTWARE_DRIVER_2_SUBTEXEL
  35. #undef SUBTEXEL
  36. #endif
  37. #ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
  38. #undef IPOL_C0
  39. #endif
  40. #if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER )
  41. #ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
  42. #undef IPOL_W
  43. #endif
  44. #define IPOL_Z
  45. #ifdef CMP_W
  46. #undef CMP_W
  47. #define CMP_Z
  48. #endif
  49. #ifdef WRITE_W
  50. #undef WRITE_W
  51. #define WRITE_Z
  52. #endif
  53. #endif
  54. namespace irr
  55. {
  56. namespace video
  57. {
  58. class CTRTextureLightMap2_M1 : public IBurningShader
  59. {
  60. public:
  61. //! constructor
  62. CTRTextureLightMap2_M1(IDepthBuffer* zbuffer);
  63. //! draws an indexed triangle list
  64. virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c );
  65. private:
  66. void scanline_bilinear2 ();
  67. sScanLineData line;
  68. };
  69. //! constructor
  70. CTRTextureLightMap2_M1::CTRTextureLightMap2_M1(IDepthBuffer* zbuffer)
  71. : IBurningShader(zbuffer)
  72. {
  73. #ifdef _DEBUG
  74. setDebugName("CTRTextureLightMap2_M1");
  75. #endif
  76. }
  77. /*!
  78. */
  79. REALINLINE void CTRTextureLightMap2_M1::scanline_bilinear2 ()
  80. {
  81. tVideoSample *dst;
  82. fp24 *z;
  83. s32 xStart;
  84. s32 xEnd;
  85. s32 dx;
  86. s32 i;
  87. // apply top-left fill-convention, left
  88. xStart = core::ceil32( line.x[0] );
  89. xEnd = core::ceil32( line.x[1] ) - 1;
  90. dx = xEnd - xStart;
  91. if ( dx < 0 )
  92. return;
  93. // slopes
  94. const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );
  95. // search z-buffer for first not occulled pixel
  96. z = lockedDepthBuffer + ( line.y * RenderTarget->getDimension().Width ) + xStart;
  97. // subTexel
  98. const f32 subPixel = ( (f32) xStart ) - line.x[0];
  99. #ifdef IPOL_W
  100. const f32 b = (line.w[1] - line.w[0]) * invDeltaX;
  101. f32 a = line.w[0] + ( b * subPixel );
  102. i = 0;
  103. while ( a <= z[i] )
  104. {
  105. a += b;
  106. i += 1;
  107. if ( i > dx )
  108. return;
  109. }
  110. // lazy setup rest of scanline
  111. line.w[0] = a;
  112. line.w[1] = b;
  113. #else
  114. const f32 b = (line.z[1] - line.z[0]) * invDeltaX;
  115. f32 a = line.z[0] + ( b * subPixel );
  116. i = 0;
  117. while ( a > z[i] )
  118. {
  119. a += b;
  120. i += 1;
  121. if ( i > dx )
  122. return;
  123. }
  124. // lazy setup rest of scanline
  125. line.z[0] = a;
  126. line.z[1] = b;
  127. #endif
  128. dst = lockedSurface + ( line.y * RenderTarget->getDimension().Width ) + xStart;
  129. a = (f32) i + subPixel;
  130. line.t[0][1] = (line.t[0][1] - line.t[0][0]) * invDeltaX;
  131. line.t[1][1] = (line.t[1][1] - line.t[1][0]) * invDeltaX;
  132. line.t[0][0] += line.t[0][1] * a;
  133. line.t[1][0] += line.t[1][1] * a;
  134. #ifdef BURNINGVIDEO_RENDERER_FAST
  135. u32 dIndex = ( line.y & 3 ) << 2;
  136. #else
  137. //
  138. tFixPoint r0, g0, b0;
  139. tFixPoint r1, g1, b1;
  140. #endif
  141. for ( ;i <= dx; i++ )
  142. {
  143. #ifdef IPOL_W
  144. if ( line.w[0] >= z[i] )
  145. {
  146. z[i] = line.w[0];
  147. #else
  148. if ( line.z[0] < z[i] )
  149. {
  150. z[i] = line.z[0];
  151. #endif
  152. #ifdef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
  153. f32 inversew = fix_inverse32 ( line.w[0] );
  154. #else
  155. f32 inversew = FIX_POINT_F32_MUL;
  156. #endif
  157. #ifdef BURNINGVIDEO_RENDERER_FAST
  158. const tFixPointu d = dithermask [ dIndex | ( i ) & 3 ];
  159. dst[i] = PixelMul32 (
  160. getTexel_plain ( &IT[0], d + f32_to_fixPoint ( line.t[0][0].x,inversew),
  161. d + f32_to_fixPoint ( line.t[0][0].y,inversew) ),
  162. getTexel_plain ( &IT[1], d + f32_to_fixPoint ( line.t[1][0].x,inversew),
  163. d + f32_to_fixPoint ( line.t[1][0].y,inversew) )
  164. );
  165. #else
  166. getSample_texture ( r0, g0, b0, &IT[0], f32_to_fixPoint ( line.t[0][0].x,inversew), f32_to_fixPoint ( line.t[0][0].y,inversew) );
  167. getSample_texture ( r1, g1, b1, &IT[1], f32_to_fixPoint ( line.t[1][0].x,inversew), f32_to_fixPoint ( line.t[1][0].y,inversew) );
  168. dst[i] = fix_to_color ( clampfix_maxcolor ( imulFix_tex1 ( r0, r1 ) ),
  169. clampfix_maxcolor ( imulFix_tex1 ( g0, g1 ) ),
  170. clampfix_maxcolor ( imulFix_tex1 ( b0, b1 ) )
  171. );
  172. #endif
  173. }
  174. #ifdef IPOL_W
  175. line.w[0] += line.w[1];
  176. #else
  177. line.z[0] += line.z[1];
  178. #endif
  179. line.t[0][0] += line.t[0][1];
  180. line.t[1][0] += line.t[1][1];
  181. }
  182. }
  183. void CTRTextureLightMap2_M1::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
  184. {
  185. sScanConvertData scan;
  186. // sort on height, y
  187. if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
  188. if ( F32_A_GREATER_B ( a->Pos.y , c->Pos.y ) ) swapVertexPointer(&a, &c);
  189. if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c);
  190. // calculate delta y of the edges
  191. scan.invDeltaY[0] = core::reciprocal ( c->Pos.y - a->Pos.y );
  192. scan.invDeltaY[1] = core::reciprocal ( b->Pos.y - a->Pos.y );
  193. scan.invDeltaY[2] = core::reciprocal ( c->Pos.y - b->Pos.y );
  194. if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
  195. return;
  196. // find if the major edge is left or right aligned
  197. f32 temp[4];
  198. temp[0] = a->Pos.x - c->Pos.x;
  199. temp[1] = a->Pos.y - c->Pos.y;
  200. temp[2] = b->Pos.x - a->Pos.x;
  201. temp[3] = b->Pos.y - a->Pos.y;
  202. scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > (f32) 0.0 ? 0 : 1;
  203. scan.right = 1 - scan.left;
  204. // calculate slopes for the major edge
  205. scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0];
  206. scan.x[0] = a->Pos.x;
  207. #ifdef IPOL_Z
  208. scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0];
  209. scan.z[0] = a->Pos.z;
  210. #endif
  211. #ifdef IPOL_W
  212. scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0];
  213. scan.w[0] = a->Pos.w;
  214. #endif
  215. #ifdef IPOL_C0
  216. scan.slopeC[0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0];
  217. scan.c[0] = a->Color[0];
  218. #endif
  219. #ifdef IPOL_T0
  220. scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0];
  221. scan.t[0][0] = a->Tex[0];
  222. #endif
  223. #ifdef IPOL_T1
  224. scan.slopeT[1][0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0];
  225. scan.t[1][0] = a->Tex[1];
  226. #endif
  227. // top left fill convention y run
  228. s32 yStart;
  229. s32 yEnd;
  230. #ifdef SUBTEXEL
  231. f32 subPixel;
  232. #endif
  233. // query access to TexMaps
  234. lockedSurface = (tVideoSample*)RenderTarget->lock();
  235. #ifdef USE_ZBUFFER
  236. lockedDepthBuffer = (fp24*) DepthBuffer->lock();
  237. #endif
  238. #ifdef IPOL_T0
  239. IT[0].data = (tVideoSample*)IT[0].Texture->lock();
  240. #endif
  241. #ifdef IPOL_T1
  242. IT[1].data = (tVideoSample*)IT[1].Texture->lock();
  243. #endif
  244. // rasterize upper sub-triangle
  245. if ( F32_GREATER_0 ( scan.invDeltaY[1] ) )
  246. {
  247. // calculate slopes for top edge
  248. scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1];
  249. scan.x[1] = a->Pos.x;
  250. #ifdef IPOL_Z
  251. scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1];
  252. scan.z[1] = a->Pos.z;
  253. #endif
  254. #ifdef IPOL_W
  255. scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1];
  256. scan.w[1] = a->Pos.w;
  257. #endif
  258. #ifdef IPOL_C0
  259. scan.slopeC[1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1];
  260. scan.c[1] = a->Color[0];
  261. #endif
  262. #ifdef IPOL_T0
  263. scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1];
  264. scan.t[0][1] = a->Tex[0];
  265. #endif
  266. #ifdef IPOL_T1
  267. scan.slopeT[1][1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1];
  268. scan.t[1][1] = a->Tex[1];
  269. #endif
  270. // apply top-left fill convention, top part
  271. yStart = core::ceil32( a->Pos.y );
  272. yEnd = core::ceil32( b->Pos.y ) - 1;
  273. #ifdef SUBTEXEL
  274. subPixel = ( (f32) yStart ) - a->Pos.y;
  275. // correct to pixel center
  276. scan.x[0] += scan.slopeX[0] * subPixel;
  277. scan.x[1] += scan.slopeX[1] * subPixel;
  278. #ifdef IPOL_Z
  279. scan.z[0] += scan.slopeZ[0] * subPixel;
  280. scan.z[1] += scan.slopeZ[1] * subPixel;
  281. #endif
  282. #ifdef IPOL_W
  283. scan.w[0] += scan.slopeW[0] * subPixel;
  284. scan.w[1] += scan.slopeW[1] * subPixel;
  285. #endif
  286. #ifdef IPOL_C0
  287. scan.c[0] += scan.slopeC[0] * subPixel;
  288. scan.c[1] += scan.slopeC[1] * subPixel;
  289. #endif
  290. #ifdef IPOL_T0
  291. scan.t[0][0] += scan.slopeT[0][0] * subPixel;
  292. scan.t[0][1] += scan.slopeT[0][1] * subPixel;
  293. #endif
  294. #ifdef IPOL_T1
  295. scan.t[1][0] += scan.slopeT[1][0] * subPixel;
  296. scan.t[1][1] += scan.slopeT[1][1] * subPixel;
  297. #endif
  298. #endif
  299. // rasterize the edge scanlines
  300. for( line.y = yStart; line.y <= yEnd; ++line.y)
  301. {
  302. line.x[scan.left] = scan.x[0];
  303. line.x[scan.right] = scan.x[1];
  304. #ifdef IPOL_Z
  305. line.z[scan.left] = scan.z[0];
  306. line.z[scan.right] = scan.z[1];
  307. #endif
  308. #ifdef IPOL_W
  309. line.w[scan.left] = scan.w[0];
  310. line.w[scan.right] = scan.w[1];
  311. #endif
  312. #ifdef IPOL_C0
  313. line.c[scan.left] = scan.c[0];
  314. line.c[scan.right] = scan.c[1];
  315. #endif
  316. #ifdef IPOL_T0
  317. line.t[0][scan.left] = scan.t[0][0];
  318. line.t[0][scan.right] = scan.t[0][1];
  319. #endif
  320. #ifdef IPOL_T1
  321. line.t[1][scan.left] = scan.t[1][0];
  322. line.t[1][scan.right] = scan.t[1][1];
  323. #endif
  324. // render a scanline
  325. scanline_bilinear2 ();
  326. scan.x[0] += scan.slopeX[0];
  327. scan.x[1] += scan.slopeX[1];
  328. #ifdef IPOL_Z
  329. scan.z[0] += scan.slopeZ[0];
  330. scan.z[1] += scan.slopeZ[1];
  331. #endif
  332. #ifdef IPOL_W
  333. scan.w[0] += scan.slopeW[0];
  334. scan.w[1] += scan.slopeW[1];
  335. #endif
  336. #ifdef IPOL_C0
  337. scan.c[0] += scan.slopeC[0];
  338. scan.c[1] += scan.slopeC[1];
  339. #endif
  340. #ifdef IPOL_T0
  341. scan.t[0][0] += scan.slopeT[0][0];
  342. scan.t[0][1] += scan.slopeT[0][1];
  343. #endif
  344. #ifdef IPOL_T1
  345. scan.t[1][0] += scan.slopeT[1][0];
  346. scan.t[1][1] += scan.slopeT[1][1];
  347. #endif
  348. }
  349. }
  350. // rasterize lower sub-triangle
  351. //if ( (f32) 0.0 != scan.invDeltaY[2] )
  352. if ( F32_GREATER_0 ( scan.invDeltaY[2] ) )
  353. {
  354. // advance to middle point
  355. if ( F32_GREATER_0 ( scan.invDeltaY[1] ) )
  356. {
  357. temp[0] = b->Pos.y - a->Pos.y; // dy
  358. scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0];
  359. #ifdef IPOL_Z
  360. scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0];
  361. #endif
  362. #ifdef IPOL_W
  363. scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0];
  364. #endif
  365. #ifdef IPOL_C0
  366. scan.c[0] = a->Color[0] + scan.slopeC[0] * temp[0];
  367. #endif
  368. #ifdef IPOL_T0
  369. scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0];
  370. #endif
  371. #ifdef IPOL_T1
  372. scan.t[1][0] = a->Tex[1] + scan.slopeT[1][0] * temp[0];
  373. #endif
  374. }
  375. // calculate slopes for bottom edge
  376. scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2];
  377. scan.x[1] = b->Pos.x;
  378. #ifdef IPOL_Z
  379. scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2];
  380. scan.z[1] = b->Pos.z;
  381. #endif
  382. #ifdef IPOL_W
  383. scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2];
  384. scan.w[1] = b->Pos.w;
  385. #endif
  386. #ifdef IPOL_C0
  387. scan.slopeC[1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2];
  388. scan.c[1] = b->Color[0];
  389. #endif
  390. #ifdef IPOL_T0
  391. scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2];
  392. scan.t[0][1] = b->Tex[0];
  393. #endif
  394. #ifdef IPOL_T1
  395. scan.slopeT[1][1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2];
  396. scan.t[1][1] = b->Tex[1];
  397. #endif
  398. // apply top-left fill convention, top part
  399. yStart = core::ceil32( b->Pos.y );
  400. yEnd = core::ceil32( c->Pos.y ) - 1;
  401. #ifdef SUBTEXEL
  402. subPixel = ( (f32) yStart ) - b->Pos.y;
  403. // correct to pixel center
  404. scan.x[0] += scan.slopeX[0] * subPixel;
  405. scan.x[1] += scan.slopeX[1] * subPixel;
  406. #ifdef IPOL_Z
  407. scan.z[0] += scan.slopeZ[0] * subPixel;
  408. scan.z[1] += scan.slopeZ[1] * subPixel;
  409. #endif
  410. #ifdef IPOL_W
  411. scan.w[0] += scan.slopeW[0] * subPixel;
  412. scan.w[1] += scan.slopeW[1] * subPixel;
  413. #endif
  414. #ifdef IPOL_C0
  415. scan.c[0] += scan.slopeC[0] * subPixel;
  416. scan.c[1] += scan.slopeC[1] * subPixel;
  417. #endif
  418. #ifdef IPOL_T0
  419. scan.t[0][0] += scan.slopeT[0][0] * subPixel;
  420. scan.t[0][1] += scan.slopeT[0][1] * subPixel;
  421. #endif
  422. #ifdef IPOL_T1
  423. scan.t[1][0] += scan.slopeT[1][0] * subPixel;
  424. scan.t[1][1] += scan.slopeT[1][1] * subPixel;
  425. #endif
  426. #endif
  427. // rasterize the edge scanlines
  428. for( line.y = yStart; line.y <= yEnd; ++line.y)
  429. {
  430. line.x[scan.left] = scan.x[0];
  431. line.x[scan.right] = scan.x[1];
  432. #ifdef IPOL_Z
  433. line.z[scan.left] = scan.z[0];
  434. line.z[scan.right] = scan.z[1];
  435. #endif
  436. #ifdef IPOL_W
  437. line.w[scan.left] = scan.w[0];
  438. line.w[scan.right] = scan.w[1];
  439. #endif
  440. #ifdef IPOL_C0
  441. line.c[scan.left] = scan.c[0];
  442. line.c[scan.right] = scan.c[1];
  443. #endif
  444. #ifdef IPOL_T0
  445. line.t[0][scan.left] = scan.t[0][0];
  446. line.t[0][scan.right] = scan.t[0][1];
  447. #endif
  448. #ifdef IPOL_T1
  449. line.t[1][scan.left] = scan.t[1][0];
  450. line.t[1][scan.right] = scan.t[1][1];
  451. #endif
  452. // render a scanline
  453. scanline_bilinear2 ();
  454. scan.x[0] += scan.slopeX[0];
  455. scan.x[1] += scan.slopeX[1];
  456. #ifdef IPOL_Z
  457. scan.z[0] += scan.slopeZ[0];
  458. scan.z[1] += scan.slopeZ[1];
  459. #endif
  460. #ifdef IPOL_W
  461. scan.w[0] += scan.slopeW[0];
  462. scan.w[1] += scan.slopeW[1];
  463. #endif
  464. #ifdef IPOL_C0
  465. scan.c[0] += scan.slopeC[0];
  466. scan.c[1] += scan.slopeC[1];
  467. #endif
  468. #ifdef IPOL_T0
  469. scan.t[0][0] += scan.slopeT[0][0];
  470. scan.t[0][1] += scan.slopeT[0][1];
  471. #endif
  472. #ifdef IPOL_T1
  473. scan.t[1][0] += scan.slopeT[1][0];
  474. scan.t[1][1] += scan.slopeT[1][1];
  475. #endif
  476. }
  477. }
  478. RenderTarget->unlock();
  479. #ifdef USE_ZBUFFER
  480. DepthBuffer->unlock();
  481. #endif
  482. #ifdef IPOL_T0
  483. IT[0].Texture->unlock();
  484. #endif
  485. #ifdef IPOL_T1
  486. IT[1].Texture->unlock();
  487. #endif
  488. }
  489. } // end namespace video
  490. } // end namespace irr
  491. #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
  492. namespace irr
  493. {
  494. namespace video
  495. {
  496. //! creates a flat triangle renderer
  497. IBurningShader* createTriangleRendererTextureLightMap2_M1(IDepthBuffer* zbuffer)
  498. {
  499. #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
  500. return new CTRTextureLightMap2_M1(zbuffer);
  501. #else
  502. return 0;
  503. #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
  504. }
  505. } // end namespace video
  506. } // end namespace irr