Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

474 lines
16 KiB

  1. ///////////////////////////////////////////////////////////////////////////////
  2. // Copyright (C) Microsoft Corporation, 1998.
  3. //
  4. // AttrFunc.cpp
  5. //
  6. // Direct3D Reference Rasterizer - Attribute Function Processing
  7. //
  8. ///////////////////////////////////////////////////////////////////////////////
  9. #include "pch.cpp"
  10. #pragma hdrstop
  11. //-----------------------------------------------------------------------------
  12. //
  13. // WrapDiff - returns the difference (B-A) as defined under the D3D WRAPU/V
  14. // rules which is the shortest path between the two assuming a coincident
  15. // position at 1. and 0. The fA and fB input range is 0. to 1.
  16. //
  17. //-----------------------------------------------------------------------------
  18. static FLOAT
  19. WrapDiff( FLOAT fB, FLOAT fA )
  20. {
  21. // compute straight distance
  22. FLOAT fDist1 = fB - fA;
  23. // compute distance 'warping' between 0. and 1.
  24. FLOAT fDist2 = ( fDist1 < 0 ) ? ( fDist1+1 ) : ( fDist1-1 );
  25. // return minimum of these
  26. return ( fabs( fDist1) < fabs( fDist2) ) ? ( fDist1) : ( fDist2 );
  27. }
  28. ///////////////////////////////////////////////////////////////////////////////
  29. //
  30. // RRAttribFuncStatic - Attribute function data which is shared by all
  31. // attributes and contains per-primitive and per-pixel data. Cannot use static
  32. // data members in RRAttribFunc class because there can be multiple instances
  33. // of rasterizer object.
  34. //
  35. ///////////////////////////////////////////////////////////////////////////////
  36. //-----------------------------------------------------------------------------
  37. //
  38. // SetPerTriangleData - Called once per triangle during setup to set per-triangle
  39. // data used to compute attribute functions.
  40. //
  41. //-----------------------------------------------------------------------------
  42. void
  43. RRAttribFuncStatic::SetPerTriangleData(
  44. FLOAT fX0, FLOAT fY0, FLOAT fRHW0,
  45. FLOAT fX1, FLOAT fY1, FLOAT fRHW1,
  46. FLOAT fX2, FLOAT fY2, FLOAT fRHW2,
  47. INT32 cTextureStages,
  48. FLOAT* pfRHQW,
  49. FLOAT fDet )
  50. {
  51. m_PrimType = RR_TRIANGLE;
  52. // compute fixed point x,y coords snapped to n.4 with nearest-even round
  53. INT32 iX0 = AS_INT32( (DOUBLE)fX0 + DOUBLE_4_SNAP );
  54. INT32 iY0 = AS_INT32( (DOUBLE)fY0 + DOUBLE_4_SNAP );
  55. INT32 iX1 = AS_INT32( (DOUBLE)fX1 + DOUBLE_4_SNAP );
  56. INT32 iY1 = AS_INT32( (DOUBLE)fY1 + DOUBLE_4_SNAP );
  57. INT32 iX2 = AS_INT32( (DOUBLE)fX2 + DOUBLE_4_SNAP );
  58. INT32 iY2 = AS_INT32( (DOUBLE)fY2 + DOUBLE_4_SNAP );
  59. fX0 = (FLOAT)iX0 * 1.0F/16.0F;
  60. fY0 = (FLOAT)iY0 * 1.0F/16.0F;
  61. fX1 = (FLOAT)iX1 * 1.0F/16.0F;
  62. fY1 = (FLOAT)iY1 * 1.0F/16.0F;
  63. fX2 = (FLOAT)iX2 * 1.0F/16.0F;
  64. fY2 = (FLOAT)iY2 * 1.0F/16.0F;
  65. m_fX0 = fX0;
  66. m_fY0 = fY0;
  67. m_cTextureStages = cTextureStages;
  68. m_fRHW0 = fRHW0;
  69. m_fRHW1 = fRHW1;
  70. m_fRHW2 = fRHW2;
  71. m_fDelX10 = fX1 - fX0;
  72. m_fDelX02 = fX0 - fX2;
  73. m_fDelY01 = fY0 - fY1;
  74. m_fDelY20 = fY2 - fY0;
  75. // compute inverse determinant
  76. m_fTriOODet = 1.f/fDet;
  77. // compute linear function for 1/W (for perspective correction)
  78. // compute linear deltas along two edges
  79. FLOAT fDelAttrib10 = m_fRHW1 - m_fRHW0;
  80. FLOAT fDelAttrib20 = m_fRHW2 - m_fRHW0;
  81. // compute A & B terms (dVdX and dVdY)
  82. m_fRHWA = m_fTriOODet * ( fDelAttrib10 * m_fDelY20 + fDelAttrib20 * m_fDelY01 );
  83. m_fRHWB = m_fTriOODet * ( fDelAttrib20 * m_fDelX10 + fDelAttrib10 * m_fDelX02 );
  84. // compute C term (Fv = A*Xv + B*Yv + C => C = Fv - A*Xv - B*Yv)
  85. m_fRHWC = m_fRHW0 - ( m_fRHWA * m_fX0 ) - ( m_fRHWB * m_fY0 );
  86. for(INT32 i = 0; i < m_cTextureStages; i++)
  87. {
  88. m_fRHQW0[i] = pfRHQW[0];
  89. m_fRHQW1[i] = pfRHQW[1];
  90. m_fRHQW2[i] = pfRHQW[2];
  91. pfRHQW += 3;
  92. // compute linear function for Q/W (for transformed, projected, perspective corrected texture)
  93. fDelAttrib10 = m_fRHQW1[i] - m_fRHQW0[i];
  94. fDelAttrib20 = m_fRHQW2[i] - m_fRHQW0[i];
  95. // compute A & B terms (dVdX and dVdY)
  96. m_fRHQWA[i] = m_fTriOODet * ( fDelAttrib10 * m_fDelY20 + fDelAttrib20 * m_fDelY01 );
  97. m_fRHQWB[i] = m_fTriOODet * ( fDelAttrib20 * m_fDelX10 + fDelAttrib10 * m_fDelX02 );
  98. // compute C term (Fv = A*Xv + B*Yv + C => C = Fv - A*Xv - B*Yv)
  99. m_fRHQWC[i] = m_fRHQW0[i] - ( m_fRHQWA[i] * m_fX0 ) - ( m_fRHQWB[i] * m_fY0 );
  100. }
  101. }
  102. //-----------------------------------------------------------------------------
  103. //
  104. // SetPerLineData - Called once per line during setup to set per-line
  105. // data used to compute attribute functions.
  106. //
  107. //-----------------------------------------------------------------------------
  108. void
  109. RRAttribFuncStatic::SetPerLineData(
  110. FLOAT fX0, FLOAT fY0, FLOAT fRHW0,
  111. FLOAT fX1, FLOAT fY1, FLOAT fRHW1,
  112. INT32 cTextureStages,
  113. FLOAT* pfRHQW,
  114. FLOAT fMajorExtent, BOOL bXMajor )
  115. {
  116. m_PrimType = RR_LINE;
  117. m_fLineMajorLength = fMajorExtent;
  118. m_bLineXMajor = bXMajor;
  119. m_fX0 = fX0;
  120. m_fY0 = fY0;
  121. m_cTextureStages = cTextureStages;
  122. m_fRHW0 = fRHW0;
  123. m_fRHW1 = fRHW1;
  124. // compute linear function for 1/W (for perspective correction)
  125. FLOAT fDelta = ( m_fRHW1 - m_fRHW0 ) / m_fLineMajorLength;
  126. m_fRHWA = ( m_bLineXMajor ) ? ( fDelta ) : ( 0. );
  127. m_fRHWB = ( m_bLineXMajor ) ? ( 0. ) : ( fDelta );
  128. m_fRHWC = fRHW0 - ( m_fRHWA * m_fX0 ) - ( m_fRHWB * m_fY0 );
  129. for(INT32 i = 0; i < m_cTextureStages; i++)
  130. {
  131. m_fRHQW0[i] = pfRHQW[0];
  132. m_fRHQW1[i] = pfRHQW[1];
  133. pfRHQW += 3;
  134. // compute linear function for Q/W (for transformed, projected, perspective corrected texture)
  135. FLOAT fDelta = ( m_fRHQW1[i] - m_fRHQW0[i] ) / m_fLineMajorLength;
  136. m_fRHQWA[i] = ( m_bLineXMajor ) ? ( fDelta ) : ( 0. );
  137. m_fRHQWB[i] = ( m_bLineXMajor ) ? ( 0. ) : ( fDelta );
  138. m_fRHQWC[i] = m_fRHQW0[i] - ( m_fRHQWA[i] * m_fX0 ) - ( m_fRHQWB[i] * m_fY0 );
  139. }
  140. }
  141. //-----------------------------------------------------------------------------
  142. //
  143. // SetPixel - Called once per pixel to do preparation for per-pixel attribute
  144. // evaluations.
  145. //
  146. //-----------------------------------------------------------------------------
  147. void
  148. RRAttribFuncStatic::SetPerPixelData( INT16 iX, INT16 iY )
  149. {
  150. m_iX = iX;
  151. m_iY = iY;
  152. // evalute 1/W function
  153. FLOAT fPixelRHW =
  154. ( m_fRHWA * (FLOAT)m_iX ) + ( m_fRHWB * (FLOAT)m_iY ) + m_fRHWC;
  155. m_fPixelW = ( 0. != fPixelRHW ) ? ( 1./fPixelRHW ) : ( 0. );
  156. for(INT32 i = 0; i < m_cTextureStages; i++)
  157. {
  158. FLOAT fPixelRHQW =
  159. ( m_fRHQWA[i] * (FLOAT)m_iX ) + ( m_fRHQWB[i] * (FLOAT)m_iY ) + m_fRHQWC[i];
  160. m_fPixelQW[i] = ( 0. != fPixelRHQW ) ? ( 1./fPixelRHQW ) : ( 0. );
  161. }
  162. }
  163. //-----------------------------------------------------------------------------
  164. //
  165. // GetPixelW,GetPixelQW,GetRhwXGradient,GetRhwYGradient,
  166. // GetRhqwXGradient,GetRhqwYGradient - Functions to get static
  167. // data members.
  168. //
  169. //-----------------------------------------------------------------------------
  170. FLOAT RRAttribFuncStatic::GetPixelW( void ) { return m_fPixelW; }
  171. FLOAT RRAttribFuncStatic::GetPixelQW( INT32 iStage ) { return m_fPixelQW[iStage]; }
  172. FLOAT RRAttribFuncStatic::GetRhqwXGradient( INT32 iStage ) { return m_fRHQWA[iStage]; }
  173. FLOAT RRAttribFuncStatic::GetRhqwYGradient( INT32 iStage ) { return m_fRHQWB[iStage]; }
  174. ///////////////////////////////////////////////////////////////////////////////
  175. //
  176. // RRAttribFunc - methods
  177. //
  178. ///////////////////////////////////////////////////////////////////////////////
  179. //-----------------------------------------------------------------------------
  180. //
  181. // SetConstant - Sets function to evaluate to constant value.
  182. //
  183. //-----------------------------------------------------------------------------
  184. void
  185. RRAttribFunc::SetConstant(
  186. FLOAT fC )
  187. {
  188. m_bIsPerspective = FALSE;
  189. m_fA = 0.; m_fB = 0.; m_fC = fC;
  190. }
  191. //-----------------------------------------------------------------------------
  192. //
  193. // SetLinearFunc - Computes linear function for scalar attribute specified at
  194. // triangle vertices.
  195. //
  196. //-----------------------------------------------------------------------------
  197. void
  198. RRAttribFunc::SetLinearFunc(
  199. FLOAT fVal0, FLOAT fVal1, FLOAT fVal2 )
  200. {
  201. m_bIsPerspective = FALSE;
  202. switch ( m_pSD->m_PrimType )
  203. {
  204. case RR_TRIANGLE:
  205. {
  206. // compute A,B,C for triangle function
  207. // compute linear deltas along two edges
  208. FLOAT fDelAttrib10 = fVal1 - fVal0;
  209. FLOAT fDelAttrib20 = fVal2 - fVal0;
  210. // compute A & B terms (dVdX and dVdY)
  211. m_fA = m_pSD->m_fTriOODet *
  212. ( fDelAttrib10 * m_pSD->m_fDelY20 + fDelAttrib20 * m_pSD->m_fDelY01 );
  213. m_fB = m_pSD->m_fTriOODet *
  214. ( fDelAttrib20 * m_pSD->m_fDelX10 + fDelAttrib10 * m_pSD->m_fDelX02 );
  215. // compute C term (Fv = A*Xv + B*Yv + C => C = Fv - A*Xv - B*Yv)
  216. m_fC = fVal0 - ( m_fA * m_pSD->m_fX0 ) - ( m_fB * m_pSD->m_fY0 );
  217. }
  218. break;
  219. case RR_LINE:
  220. {
  221. // compute A,B,C for line function - delta is normalized difference
  222. // in major direction; C is computed from knowing the function value
  223. // at the vertices (vertex 0 is always used here)
  224. FLOAT fDelta = ( fVal1 - fVal0 ) / m_pSD->m_fLineMajorLength;
  225. m_fA = ( m_pSD->m_bLineXMajor ) ? ( fDelta ) : ( 0. );
  226. m_fB = ( m_pSD->m_bLineXMajor ) ? ( 0. ) : ( fDelta );
  227. // compute C term (Fv = A*Xv + B*Yv + C => C = Fv - A*Xv - B*Yv)
  228. m_fC = fVal0 - ( m_fA * m_pSD->m_fX0 ) - ( m_fB * m_pSD->m_fY0 );
  229. }
  230. break;
  231. case RR_POINT:
  232. // use constant function for point
  233. m_fA = 0.;
  234. m_fB = 0.;
  235. m_fC = fVal0;
  236. break;
  237. }
  238. }
  239. //-----------------------------------------------------------------------------
  240. //
  241. // SetPerspFunc - Computes perspective corrected function for scalar attribute
  242. // specified at triangle vertices.
  243. //
  244. //-----------------------------------------------------------------------------
  245. void
  246. RRAttribFunc::SetPerspFunc(
  247. FLOAT fVal0, FLOAT fVal1, FLOAT fVal2 )
  248. {
  249. switch ( m_pSD->m_PrimType )
  250. {
  251. case RR_TRIANGLE:
  252. {
  253. // triangle function
  254. // compute adjusted values for vertices 1,2 based on wrap flag
  255. FLOAT fVal1P = (fVal1);
  256. FLOAT fVal2P = (fVal2);
  257. // compute perspective corrected linear deltas along two edges
  258. FLOAT fDelAttrib10 = ( fVal1P * m_pSD->m_fRHW1 ) - ( fVal0 * m_pSD->m_fRHW0 );
  259. FLOAT fDelAttrib20 = ( fVal2P * m_pSD->m_fRHW2 ) - ( fVal0 * m_pSD->m_fRHW0 );
  260. // compute A & B terms (dVdX and dVdY)
  261. m_fA = m_pSD->m_fTriOODet *
  262. ( fDelAttrib10 * m_pSD->m_fDelY20 + fDelAttrib20 * m_pSD->m_fDelY01 );
  263. m_fB = m_pSD->m_fTriOODet *
  264. ( fDelAttrib20 * m_pSD->m_fDelX10 + fDelAttrib10 * m_pSD->m_fDelX02 );
  265. // compute C term (Fv = A*Xv + B*Yv + C => C = Fv - A*Xv - B*Yv)
  266. m_fC = ( fVal0* m_pSD->m_fRHW0)
  267. - ( m_fA * m_pSD->m_fX0 ) - ( m_fB * m_pSD->m_fY0 );
  268. m_bIsPerspective = TRUE;
  269. }
  270. break;
  271. case RR_LINE:
  272. {
  273. // line function
  274. FLOAT fVal1P = (fVal1);
  275. FLOAT fDelta =
  276. ( fVal1P*m_pSD->m_fRHW1 - fVal0*m_pSD->m_fRHW0) / m_pSD->m_fLineMajorLength;
  277. m_fA = ( m_pSD->m_bLineXMajor ) ? ( fDelta ) : ( 0. );
  278. m_fB = ( m_pSD->m_bLineXMajor ) ? ( 0. ) : ( fDelta );
  279. // compute C term (Fv = A*Xv + B*Yv + C => C = Fv - A*Xv - B*Yv)
  280. m_fC = ( fVal0* m_pSD->m_fRHW0)
  281. - ( m_fA * m_pSD->m_fX0 ) - ( m_fB * m_pSD->m_fY0 );
  282. m_bIsPerspective = TRUE;
  283. }
  284. break;
  285. case RR_POINT:
  286. // use constant function for point
  287. m_fA = 0.;
  288. m_fB = 0.;
  289. m_fC = fVal0;
  290. // don't correct constant functions
  291. m_bIsPerspective = FALSE;
  292. break;
  293. }
  294. }
  295. //-----------------------------------------------------------------------------
  296. //
  297. // Eval - Evaluates function at pixel position set in RRAttribFunc::SetPerPixelData.
  298. // Functions know if they are perspective corrected or not, and if so then do
  299. // the multiply through by the 1/(1/w) term to normalize.
  300. //
  301. //-----------------------------------------------------------------------------
  302. FLOAT
  303. RRAttribFunc::Eval( void )
  304. {
  305. FLOAT fRet =
  306. ( m_fA * (FLOAT)m_pSD->m_iX ) + ( m_fB * (FLOAT)m_pSD->m_iY ) + m_fC;
  307. if ( m_bIsPerspective ) { fRet *= m_pSD->m_fPixelW; }
  308. return fRet;
  309. }
  310. //-----------------------------------------------------------------------------
  311. //
  312. // SetPerspFunc - Computes perspective corrected function for scalar attribute
  313. // specified at triangle vertices.
  314. //
  315. //-----------------------------------------------------------------------------
  316. void
  317. RRAttribFunc::SetPerspFunc(
  318. FLOAT fVal0, FLOAT fVal1, FLOAT fVal2,
  319. BOOL bWrap, BOOL bIsShadowMap )
  320. {
  321. switch ( m_pSD->m_PrimType )
  322. {
  323. case RR_TRIANGLE:
  324. {
  325. // triangle function
  326. FLOAT fRHW0 = m_pSD->m_fRHW0;
  327. FLOAT fRHW1 = m_pSD->m_fRHW1;
  328. FLOAT fRHW2 = m_pSD->m_fRHW2;
  329. if (bIsShadowMap)
  330. {
  331. fRHW0 = 1.0f;
  332. fRHW1 = 1.0f;
  333. fRHW2 = 1.0f;
  334. }
  335. // compute adjusted values for vertices 1,2 based on wrap flag
  336. FLOAT fVal1P = bWrap ? ( fVal0 + WrapDiff(fVal1,fVal0) ) : (fVal1);
  337. FLOAT fVal2P = bWrap ? ( fVal0 + WrapDiff(fVal2,fVal0) ) : (fVal2);
  338. // compute perspective corrected linear deltas along two edges
  339. FLOAT fDelAttrib10 = ( fVal1P * fRHW1 ) - ( fVal0 * fRHW0 );
  340. FLOAT fDelAttrib20 = ( fVal2P * fRHW2 ) - ( fVal0 * fRHW0 );
  341. // compute A & B terms (dVdX and dVdY)
  342. m_fA = m_pSD->m_fTriOODet *
  343. ( fDelAttrib10 * m_pSD->m_fDelY20 + fDelAttrib20 * m_pSD->m_fDelY01 );
  344. m_fB = m_pSD->m_fTriOODet *
  345. ( fDelAttrib20 * m_pSD->m_fDelX10 + fDelAttrib10 * m_pSD->m_fDelX02 );
  346. // compute C term (Fv = A*Xv + B*Yv + C => C = Fv - A*Xv - B*Yv)
  347. m_fC = ( fVal0 * fRHW0 )
  348. - ( m_fA * m_pSD->m_fX0 ) - ( m_fB * m_pSD->m_fY0 );
  349. m_bIsPerspective = TRUE;
  350. }
  351. break;
  352. case RR_LINE:
  353. {
  354. // line function
  355. FLOAT fRHW0 = m_pSD->m_fRHW0;
  356. FLOAT fRHW1 = m_pSD->m_fRHW1;
  357. if (bIsShadowMap)
  358. {
  359. fRHW0 = 1.0f;
  360. fRHW1 = 1.0f;
  361. }
  362. FLOAT fVal1P = bWrap ? ( fVal0 + WrapDiff(fVal1,fVal0) ) : (fVal1);
  363. FLOAT fDelta =
  364. ( fVal1P*fRHW1 - fVal0*fRHW0) / m_pSD->m_fLineMajorLength;
  365. m_fA = ( m_pSD->m_bLineXMajor ) ? ( fDelta ) : ( 0. );
  366. m_fB = ( m_pSD->m_bLineXMajor ) ? ( 0. ) : ( fDelta );
  367. // compute C term (Fv = A*Xv + B*Yv + C => C = Fv - A*Xv - B*Yv)
  368. m_fC = ( fVal0* fRHW0)
  369. - ( m_fA * m_pSD->m_fX0 ) - ( m_fB * m_pSD->m_fY0 );
  370. m_bIsPerspective = TRUE;
  371. }
  372. break;
  373. case RR_POINT:
  374. // use constant function for point
  375. m_fA = 0.;
  376. m_fB = 0.;
  377. m_fC = fVal0;
  378. // don't correct constant functions
  379. m_bIsPerspective = FALSE;
  380. break;
  381. }
  382. }
  383. //-----------------------------------------------------------------------------
  384. //
  385. // Eval - Evaluates function at pixel position set in RRAttribFunc::SetPerPixelData.
  386. // Functions know if they are perspective corrected or not, and if so then do
  387. // the multiply through by the 1/(q/w) term to normalize.
  388. //
  389. //-----------------------------------------------------------------------------
  390. FLOAT
  391. RRAttribFunc::Eval( INT32 iStage )
  392. {
  393. FLOAT fRet =
  394. ( m_fA * (FLOAT)m_pSD->m_iX ) + ( m_fB * (FLOAT)m_pSD->m_iY ) + m_fC;
  395. // m_bIsPerspective will always be set since persp function is always
  396. // used for texture coords
  397. if ( m_bIsPerspective ) { fRet *= m_pSD->m_fPixelQW[iStage]; }
  398. return fRet;
  399. }
  400. ///////////////////////////////////////////////////////////////////////////////
  401. // end