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.

175 lines
5.9 KiB

  1. /*==========================================================================;
  2. *
  3. * Copyright (C) 1998 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: haltrans.cpp
  6. * Content: Direct3D HAL transform handler
  7. *
  8. ***************************************************************************/
  9. #include "pch.cpp"
  10. #pragma hdrstop
  11. //---------------------------------------------------------------------
  12. // Update pre-computed constants related to viewport
  13. //
  14. // This functions should be called every time the viewport parameters are
  15. // changed
  16. //
  17. // Notes:
  18. // 1. scaleY and offsetY are computed to flip Y axes from up to down.
  19. // 2. Mclip matrix is computed multiplied by Mshift matrix
  20. //
  21. const D3DVALUE SMALL_NUMBER = 0.000001f;
  22. void UpdateViewportCache(LPDIRECT3DDEVICEI device, D3DVIEWPORT2 *data)
  23. {
  24. // Bail if we are going to cause any divide by zero exceptions.
  25. // The likely reason is that we have a bogus viewport set by
  26. // TLVertex execute buffer app.
  27. if(data->dwWidth == 0 ||
  28. data->dwHeight == 0 ||
  29. FLOAT_EQZ(data->dvClipWidth) ||
  30. FLOAT_EQZ(data->dvClipHeight) ||
  31. data->dvMaxZ - data->dvMinZ == D3DVAL(0.f))
  32. return;
  33. D3DFE_VIEWPORTCACHE *cache = &device->vcache;
  34. cache->dvX = D3DVAL(data->dwX);
  35. cache->dvY = D3DVAL(data->dwY);
  36. cache->dvWidth = D3DVAL(data->dwWidth);
  37. cache->dvHeight = D3DVAL(data->dwHeight);
  38. cache->mclip11 = D3DVAL(1.0) / data->dvClipWidth;
  39. cache->mclip41 = - cache->mclip11 * data->dvClipX;
  40. cache->mclip22 = D3DVAL(1) / data->dvClipHeight;
  41. cache->mclip42 = D3DVAL(1) - cache->mclip22 * data->dvClipY;
  42. cache->mclip33 = D3DVAL(1) / (data->dvMaxZ - data->dvMinZ);
  43. cache->mclip43 = - data->dvMinZ * cache->mclip33;
  44. cache->scaleX = cache->dvWidth;
  45. cache->scaleY = - cache->dvHeight;
  46. cache->offsetX = cache->dvX;
  47. cache->offsetY = cache->dvY + cache->dvHeight;
  48. // Small offset is added to prevent generation of negative screen
  49. // coordinates (this could happen because of precision errors).
  50. // Not needed (or wanted) for devices which do guardband.
  51. if (IS_HW_DEVICE(device))
  52. {
  53. cache->offsetX += SMALL_NUMBER;
  54. cache->offsetY += SMALL_NUMBER;
  55. }
  56. device->dwFEFlags |= D3DFE_VIEWPORT_DIRTY | D3DFE_INVERSEMCLIP_DIRTY;
  57. cache->scaleXi = D3DVAL(1) / cache->scaleX;
  58. cache->scaleYi = D3DVAL(1) / cache->scaleY;
  59. cache->minX = cache->dvX;
  60. cache->maxX = cache->dvX + cache->dvWidth;
  61. cache->minY = cache->dvY;
  62. cache->maxY = cache->dvY + cache->dvHeight;
  63. cache->minXi = FTOI(cache->minX);
  64. cache->maxXi = FTOI(cache->maxX);
  65. cache->minYi = FTOI(cache->minY);
  66. cache->maxYi = FTOI(cache->maxY);
  67. if (device->dwDeviceFlags & D3DDEV_GUARDBAND)
  68. {
  69. LPD3DHAL_D3DEXTENDEDCAPS lpCaps = device->lpD3DExtendedCaps;
  70. // Because we clip by guard band window we have to use its extents
  71. cache->minXgb = lpCaps->dvGuardBandLeft;
  72. cache->maxXgb = lpCaps->dvGuardBandRight;
  73. cache->minYgb = lpCaps->dvGuardBandTop;
  74. cache->maxYgb = lpCaps->dvGuardBandBottom;
  75. D3DVALUE w = 2.0f / cache->dvWidth;
  76. D3DVALUE h = 2.0f / cache->dvHeight;
  77. D3DVALUE ax1 = -lpCaps->dvGuardBandLeft * w + 1.0f;
  78. D3DVALUE ax2 = lpCaps->dvGuardBandRight * w - 1.0f;
  79. D3DVALUE ay1 = lpCaps->dvGuardBandBottom * h - 1.0f;
  80. D3DVALUE ay2 = -lpCaps->dvGuardBandTop * h + 1.0f;
  81. cache->gb11 = 2.0f / (ax1 + ax2);
  82. cache->gb41 = cache->gb11 * (ax1 - 1.0f) * 0.5f;
  83. cache->gb22 = 2.0f / (ay1 + ay2);
  84. cache->gb42 = cache->gb22 * (ay1 - 1.0f) * 0.5f;
  85. cache->Kgbx1 = 0.5f * (1.0f - ax1);
  86. cache->Kgbx2 = 0.5f * (1.0f + ax2);
  87. cache->Kgby1 = 0.5f * (1.0f - ay1);
  88. cache->Kgby2 = 0.5f * (1.0f + ay2);
  89. }
  90. else
  91. {
  92. cache->minXgb = cache->minX;
  93. cache->maxXgb = cache->maxX;
  94. cache->minYgb = cache->minY;
  95. cache->maxYgb = cache->maxY;
  96. }
  97. }
  98. //---------------------------------------------------------------------
  99. HRESULT
  100. D3DHAL_MatrixCreate(LPDIRECT3DDEVICEI lpDevI, LPD3DMATRIXHANDLE lphMat)
  101. {
  102. LPD3DMATRIXI lpMat;
  103. HRESULT ret;
  104. if ((ret = D3DMalloc((void**)&lpMat, sizeof(D3DMATRIXI))) != DD_OK)
  105. {
  106. return ret;
  107. }
  108. setIdentity(lpMat);
  109. LIST_INSERT_ROOT(&lpDevI->transform.matrices, lpMat, link);
  110. *lphMat = (DWORD)((ULONG_PTR)lpMat);
  111. return (D3D_OK);
  112. }
  113. //---------------------------------------------------------------------
  114. HRESULT
  115. D3DHAL_MatrixDestroy(LPDIRECT3DDEVICEI lpDevI, D3DMATRIXHANDLE hMat)
  116. {
  117. LPD3DMATRIXI lpMat = (LPD3DMATRIXI)ULongToPtr(hMat);
  118. LIST_DELETE(lpMat, link);
  119. D3DFree(lpMat);
  120. return D3D_OK;
  121. }
  122. //---------------------------------------------------------------------
  123. HRESULT
  124. D3DHAL_MatrixSetData(LPDIRECT3DDEVICEI lpDevI, D3DMATRIXHANDLE hMat,
  125. LPD3DMATRIX lpMat)
  126. {
  127. D3DFE_TRANSFORM& TRANSFORM = lpDevI->transform;
  128. LPD3DMATRIXI lpDstMat;
  129. lpDstMat = HANDLE_TO_MAT(lpDevI, hMat);
  130. if (!lpDstMat)
  131. {
  132. return D3DERR_MATRIX_SETDATA_FAILED;
  133. }
  134. *(D3DMATRIX*)lpDstMat = *lpMat;
  135. if (hMat == TRANSFORM.hWorld)
  136. D3DFE_SetMatrixWorld(lpDevI, lpMat);
  137. else
  138. if (hMat == TRANSFORM.hView)
  139. D3DFE_SetMatrixView(lpDevI, lpMat);
  140. else
  141. if (hMat == TRANSFORM.hProj)
  142. D3DFE_SetMatrixProj(lpDevI, lpMat);
  143. return (D3D_OK);
  144. }
  145. //---------------------------------------------------------------------
  146. HRESULT
  147. D3DHAL_MatrixGetData(LPDIRECT3DDEVICEI lpDevI, D3DMATRIXHANDLE hMat,
  148. LPD3DMATRIX lpMat)
  149. {
  150. LPD3DMATRIXI lpSrcMat = HANDLE_TO_MAT(lpDevI, hMat);
  151. if (!lpSrcMat)
  152. return D3DERR_MATRIX_GETDATA_FAILED;
  153. *lpMat = *(D3DMATRIX*)lpSrcMat;
  154. return (D3D_OK);
  155. }