Source code of Windows XP (NT5)
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.

312 lines
9.9 KiB

  1. //-----------------------------------------------------------------------------
  2. // File: D3DUtil.cpp
  3. //
  4. // Desc: Shortcut macros and functions for using DX objects
  5. //
  6. //
  7. // Copyright (c) 1997-1999 Microsoft Corporation. All rights reserved
  8. //-----------------------------------------------------------------------------
  9. #define D3D_OVERLOADS
  10. #define STRICT
  11. #include "StdAfx.h"
  12. #include <math.h>
  13. #include "D3DUtil.h"
  14. //-----------------------------------------------------------------------------
  15. // Name: D3DUtil_GetDXSDKMediaPath()
  16. // Desc: Returns the DirectX SDK media path, as stored in the system registry
  17. // during the SDK install.
  18. //-----------------------------------------------------------------------------
  19. const TCHAR* D3DUtil_GetDXSDKMediaPath()
  20. {
  21. static TCHAR strNull[2] = TEXT("");
  22. static TCHAR strPath[512];
  23. HKEY key;
  24. DWORD type, size = 512;
  25. // Open the appropriate registry key
  26. LONG result = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  27. TEXT("Software\\Microsoft\\DirectX"),
  28. 0, KEY_READ, &key);
  29. if (ERROR_SUCCESS != result)
  30. return strNull;
  31. result = RegQueryValueEx(key, TEXT("DXSDK Samples Path"), NULL,
  32. &type, (BYTE*)strPath, &size);
  33. RegCloseKey(key);
  34. if (ERROR_SUCCESS != result)
  35. return strNull;
  36. lstrcat(strPath, TEXT("\\D3DIM\\Media\\"));
  37. return strPath;
  38. }
  39. //-----------------------------------------------------------------------------
  40. // Name: D3DUtil_InitSurfaceDesc()
  41. // Desc: Helper function called to build a DDSURFACEDESC2 structure,
  42. // typically before calling CreateSurface() or GetSurfaceDesc()
  43. //-----------------------------------------------------------------------------
  44. VOID D3DUtil_InitSurfaceDesc(DDSURFACEDESC2& ddsd, DWORD dwFlags,
  45. DWORD dwCaps)
  46. {
  47. ZeroMemory(&ddsd, sizeof(ddsd));
  48. ddsd.dwSize = sizeof(ddsd);
  49. ddsd.dwFlags = dwFlags;
  50. ddsd.ddsCaps.dwCaps = dwCaps;
  51. ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
  52. }
  53. //-----------------------------------------------------------------------------
  54. // Name: D3DUtil_InitMaterial()
  55. // Desc: Helper function called to build a D3DMATERIAL7 structure
  56. //-----------------------------------------------------------------------------
  57. VOID D3DUtil_InitMaterial(D3DMATERIAL7& mtrl, FLOAT r, FLOAT g, FLOAT b,
  58. FLOAT a)
  59. {
  60. ZeroMemory(&mtrl, sizeof(D3DMATERIAL7));
  61. mtrl.dcvDiffuse.r = mtrl.dcvAmbient.r = r;
  62. mtrl.dcvDiffuse.g = mtrl.dcvAmbient.g = g;
  63. mtrl.dcvDiffuse.b = mtrl.dcvAmbient.b = b;
  64. mtrl.dcvDiffuse.a = mtrl.dcvAmbient.a = a;
  65. }
  66. //-----------------------------------------------------------------------------
  67. // Name: D3DUtil_InitLight()
  68. // Desc: Initializes a D3DLIGHT7 structure
  69. //-----------------------------------------------------------------------------
  70. VOID D3DUtil_InitLight(D3DLIGHT7& light, D3DLIGHTTYPE ltType,
  71. FLOAT x, FLOAT y, FLOAT z)
  72. {
  73. ZeroMemory(&light, sizeof(D3DLIGHT7));
  74. light.dltType = ltType;
  75. light.dcvDiffuse.r = 1.0f;
  76. light.dcvDiffuse.g = 1.0f;
  77. light.dcvDiffuse.b = 1.0f;
  78. light.dcvSpecular = light.dcvDiffuse;
  79. light.dvPosition.x = light.dvDirection.x = x;
  80. light.dvPosition.y = light.dvDirection.y = y;
  81. light.dvPosition.z = light.dvDirection.z = z;
  82. light.dvAttenuation0 = 1.0f;
  83. light.dvRange = D3DLIGHT_RANGE_MAX;
  84. }
  85. //-----------------------------------------------------------------------------
  86. // Name: D3DUtil_SetViewMatrix()
  87. // Desc: Given an eye point, a lookat point, and an up vector, this
  88. // function builds a 4x4 view matrix.
  89. //-----------------------------------------------------------------------------
  90. HRESULT D3DUtil_SetViewMatrix(D3DMATRIX& mat, D3DVECTOR& vFrom,
  91. D3DVECTOR& vAt, D3DVECTOR& vWorldUp)
  92. {
  93. // Get the z basis vector, which points straight ahead. This is the
  94. // difference from the eyepoint to the lookat point.
  95. D3DVECTOR vView = vAt - vFrom;
  96. FLOAT fLength = Magnitude(vView);
  97. if (fLength < 1e-6f)
  98. return E_INVALIDARG;
  99. // Normalize the z basis vector
  100. vView /= fLength;
  101. // Get the dot product, and calculate the projection of the z basis
  102. // vector onto the up vector. The projection is the y basis vector.
  103. FLOAT fDotProduct = DotProduct(vWorldUp, vView);
  104. D3DVECTOR vUp = vWorldUp - fDotProduct * vView;
  105. // If this vector has near-zero length because the input specified a
  106. // bogus up vector, let's try a default up vector
  107. if (1e-6f > (fLength = Magnitude(vUp)))
  108. {
  109. vUp = D3DVECTOR(0.0f, 1.0f, 0.0f) - vView.y * vView;
  110. // If we still have near-zero length, resort to a different axis.
  111. if (1e-6f > (fLength = Magnitude(vUp)))
  112. {
  113. vUp = D3DVECTOR(0.0f, 0.0f, 1.0f) - vView.z * vView;
  114. if (1e-6f > (fLength = Magnitude(vUp)))
  115. return E_INVALIDARG;
  116. }
  117. }
  118. // Normalize the y basis vector
  119. vUp /= fLength;
  120. // The x basis vector is found simply with the cross product of the y
  121. // and z basis vectors
  122. D3DVECTOR vRight = CrossProduct(vUp, vView);
  123. // Start building the matrix. The first three rows contains the basis
  124. // vectors used to rotate the view to point at the lookat point
  125. D3DUtil_SetIdentityMatrix(mat);
  126. mat._11 = vRight.x; mat._12 = vUp.x; mat._13 = vView.x;
  127. mat._21 = vRight.y; mat._22 = vUp.y; mat._23 = vView.y;
  128. mat._31 = vRight.z; mat._32 = vUp.z; mat._33 = vView.z;
  129. // Do the translation values (rotations are still about the eyepoint)
  130. mat._41 = - DotProduct(vFrom, vRight);
  131. mat._42 = - DotProduct(vFrom, vUp);
  132. mat._43 = - DotProduct(vFrom, vView);
  133. return S_OK;
  134. }
  135. //-----------------------------------------------------------------------------
  136. // Name: D3DUtil_SetProjectionMatrix()
  137. // Desc: Sets the passed in 4x4 matrix to a perpsective projection matrix built
  138. // from the field-of-view (fov, in y), aspect ratio, near plane (D),
  139. // and far plane (F). Note that the projection matrix is normalized for
  140. // element [3][4] to be 1.0. This is performed so that W-based range fog
  141. // will work correctly.
  142. //-----------------------------------------------------------------------------
  143. HRESULT D3DUtil_SetProjectionMatrix(D3DMATRIX& mat, FLOAT fFOV, FLOAT fAspect,
  144. FLOAT fNearPlane, FLOAT fFarPlane)
  145. {
  146. if (fabs(fFarPlane-fNearPlane) < 0.01f)
  147. return E_INVALIDARG;
  148. if (fabs(sin(fFOV/2)) < 0.01f)
  149. return E_INVALIDARG;
  150. FLOAT w = fAspect * (cosf(fFOV/2)/sinf(fFOV/2));
  151. FLOAT h = 1.0f * (cosf(fFOV/2)/sinf(fFOV/2));
  152. FLOAT Q = fFarPlane / (fFarPlane - fNearPlane);
  153. ZeroMemory(&mat, sizeof(D3DMATRIX));
  154. mat._11 = w;
  155. mat._22 = h;
  156. mat._33 = Q;
  157. mat._34 = 1.0f;
  158. mat._43 = -Q*fNearPlane;
  159. return S_OK;
  160. }
  161. //-----------------------------------------------------------------------------
  162. // Name: D3DUtil_SetRotateXMatrix()
  163. // Desc: Create Rotation matrix about X axis
  164. //-----------------------------------------------------------------------------
  165. VOID D3DUtil_SetRotateXMatrix(D3DMATRIX& mat, FLOAT fRads)
  166. {
  167. D3DUtil_SetIdentityMatrix(mat);
  168. mat._22 = cosf(fRads);
  169. mat._23 = sinf(fRads);
  170. mat._32 = -sinf(fRads);
  171. mat._33 = cosf(fRads);
  172. }
  173. //-----------------------------------------------------------------------------
  174. // Name: D3DUtil_SetRotateYMatrix()
  175. // Desc: Create Rotation matrix about Y axis
  176. //-----------------------------------------------------------------------------
  177. VOID D3DUtil_SetRotateYMatrix(D3DMATRIX& mat, FLOAT fRads)
  178. {
  179. D3DUtil_SetIdentityMatrix(mat);
  180. mat._11 = cosf(fRads);
  181. mat._13 = -sinf(fRads);
  182. mat._31 = sinf(fRads);
  183. mat._33 = cosf(fRads);
  184. }
  185. //-----------------------------------------------------------------------------
  186. // Name: D3DUtil_SetRotateZMatrix()
  187. // Desc: Create Rotation matrix about Z axis
  188. //-----------------------------------------------------------------------------
  189. VOID D3DUtil_SetRotateZMatrix(D3DMATRIX& mat, FLOAT fRads)
  190. {
  191. D3DUtil_SetIdentityMatrix(mat);
  192. mat._11 = cosf(fRads);
  193. mat._12 = sinf(fRads);
  194. mat._21 = -sinf(fRads);
  195. mat._22 = cosf(fRads);
  196. }
  197. //-----------------------------------------------------------------------------
  198. // Name: D3DUtil_SetRotationMatrix
  199. // Desc: Create a Rotation matrix about vector direction
  200. //-----------------------------------------------------------------------------
  201. VOID D3DUtil_SetRotationMatrix(D3DMATRIX& mat, D3DVECTOR& vDir, FLOAT fRads)
  202. {
  203. FLOAT fCos = cosf(fRads);
  204. FLOAT fSin = sinf(fRads);
  205. D3DVECTOR v = Normalize(vDir);
  206. mat._11 = (v.x * v.x) * (1.0f - fCos) + fCos;
  207. mat._12 = (v.x * v.y) * (1.0f - fCos) - (v.z * fSin);
  208. mat._13 = (v.x * v.z) * (1.0f - fCos) + (v.y * fSin);
  209. mat._21 = (v.y * v.x) * (1.0f - fCos) + (v.z * fSin);
  210. mat._22 = (v.y * v.y) * (1.0f - fCos) + fCos ;
  211. mat._23 = (v.y * v.z) * (1.0f - fCos) - (v.x * fSin);
  212. mat._31 = (v.z * v.x) * (1.0f - fCos) - (v.y * fSin);
  213. mat._32 = (v.z * v.y) * (1.0f - fCos) + (v.x * fSin);
  214. mat._33 = (v.z * v.z) * (1.0f - fCos) + fCos;
  215. mat._14 = mat._24 = mat._34 = 0.0f;
  216. mat._41 = mat._42 = mat._43 = 0.0f;
  217. mat._44 = 1.0f;
  218. }
  219. //-----------------------------------------------------------------------------
  220. // Name: _DbgOut()
  221. // Desc: Outputs a message to the debug stream
  222. //-----------------------------------------------------------------------------
  223. HRESULT _DbgOut(TCHAR* strFile, DWORD dwLine, HRESULT hr, TCHAR* strMsg)
  224. {
  225. TCHAR buffer[256];
  226. wsprintf(buffer, TEXT("%s(%ld): "), strFile, dwLine);
  227. OutputDebugString(buffer);
  228. OutputDebugString(strMsg);
  229. if (hr)
  230. {
  231. wsprintf(buffer, TEXT("(hr=%08lx)\n"), hr);
  232. OutputDebugString(buffer);
  233. }
  234. OutputDebugString(TEXT("\n"));
  235. return hr;
  236. }