//----------------------------------------------------------------------------- // File: D3DUtil.cpp // // Desc: Shortcut macros and functions for using DX objects // // // Copyright (c) 1997-1999 Microsoft Corporation. All rights reserved //----------------------------------------------------------------------------- #define D3D_OVERLOADS #define STRICT #include "StdAfx.h" #include #include "D3DUtil.h" //----------------------------------------------------------------------------- // Name: D3DUtil_GetDXSDKMediaPath() // Desc: Returns the DirectX SDK media path, as stored in the system registry // during the SDK install. //----------------------------------------------------------------------------- const TCHAR* D3DUtil_GetDXSDKMediaPath() { static TCHAR strNull[2] = TEXT(""); static TCHAR strPath[512]; HKEY key; DWORD type, size = 512; // Open the appropriate registry key LONG result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("Software\\Microsoft\\DirectX"), 0, KEY_READ, &key); if (ERROR_SUCCESS != result) return strNull; result = RegQueryValueEx(key, TEXT("DXSDK Samples Path"), NULL, &type, (BYTE*)strPath, &size); RegCloseKey(key); if (ERROR_SUCCESS != result) return strNull; lstrcat(strPath, TEXT("\\D3DIM\\Media\\")); return strPath; } //----------------------------------------------------------------------------- // Name: D3DUtil_InitSurfaceDesc() // Desc: Helper function called to build a DDSURFACEDESC2 structure, // typically before calling CreateSurface() or GetSurfaceDesc() //----------------------------------------------------------------------------- VOID D3DUtil_InitSurfaceDesc(DDSURFACEDESC2& ddsd, DWORD dwFlags, DWORD dwCaps) { ZeroMemory(&ddsd, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); ddsd.dwFlags = dwFlags; ddsd.ddsCaps.dwCaps = dwCaps; ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT); } //----------------------------------------------------------------------------- // Name: D3DUtil_InitMaterial() // Desc: Helper function called to build a D3DMATERIAL7 structure //----------------------------------------------------------------------------- VOID D3DUtil_InitMaterial(D3DMATERIAL7& mtrl, FLOAT r, FLOAT g, FLOAT b, FLOAT a) { ZeroMemory(&mtrl, sizeof(D3DMATERIAL7)); mtrl.dcvDiffuse.r = mtrl.dcvAmbient.r = r; mtrl.dcvDiffuse.g = mtrl.dcvAmbient.g = g; mtrl.dcvDiffuse.b = mtrl.dcvAmbient.b = b; mtrl.dcvDiffuse.a = mtrl.dcvAmbient.a = a; } //----------------------------------------------------------------------------- // Name: D3DUtil_InitLight() // Desc: Initializes a D3DLIGHT7 structure //----------------------------------------------------------------------------- VOID D3DUtil_InitLight(D3DLIGHT7& light, D3DLIGHTTYPE ltType, FLOAT x, FLOAT y, FLOAT z) { ZeroMemory(&light, sizeof(D3DLIGHT7)); light.dltType = ltType; light.dcvDiffuse.r = 1.0f; light.dcvDiffuse.g = 1.0f; light.dcvDiffuse.b = 1.0f; light.dcvSpecular = light.dcvDiffuse; light.dvPosition.x = light.dvDirection.x = x; light.dvPosition.y = light.dvDirection.y = y; light.dvPosition.z = light.dvDirection.z = z; light.dvAttenuation0 = 1.0f; light.dvRange = D3DLIGHT_RANGE_MAX; } //----------------------------------------------------------------------------- // Name: D3DUtil_SetViewMatrix() // Desc: Given an eye point, a lookat point, and an up vector, this // function builds a 4x4 view matrix. //----------------------------------------------------------------------------- HRESULT D3DUtil_SetViewMatrix(D3DMATRIX& mat, D3DVECTOR& vFrom, D3DVECTOR& vAt, D3DVECTOR& vWorldUp) { // Get the z basis vector, which points straight ahead. This is the // difference from the eyepoint to the lookat point. D3DVECTOR vView = vAt - vFrom; FLOAT fLength = Magnitude(vView); if (fLength < 1e-6f) return E_INVALIDARG; // Normalize the z basis vector vView /= fLength; // Get the dot product, and calculate the projection of the z basis // vector onto the up vector. The projection is the y basis vector. FLOAT fDotProduct = DotProduct(vWorldUp, vView); D3DVECTOR vUp = vWorldUp - fDotProduct * vView; // If this vector has near-zero length because the input specified a // bogus up vector, let's try a default up vector if (1e-6f > (fLength = Magnitude(vUp))) { vUp = D3DVECTOR(0.0f, 1.0f, 0.0f) - vView.y * vView; // If we still have near-zero length, resort to a different axis. if (1e-6f > (fLength = Magnitude(vUp))) { vUp = D3DVECTOR(0.0f, 0.0f, 1.0f) - vView.z * vView; if (1e-6f > (fLength = Magnitude(vUp))) return E_INVALIDARG; } } // Normalize the y basis vector vUp /= fLength; // The x basis vector is found simply with the cross product of the y // and z basis vectors D3DVECTOR vRight = CrossProduct(vUp, vView); // Start building the matrix. The first three rows contains the basis // vectors used to rotate the view to point at the lookat point D3DUtil_SetIdentityMatrix(mat); mat._11 = vRight.x; mat._12 = vUp.x; mat._13 = vView.x; mat._21 = vRight.y; mat._22 = vUp.y; mat._23 = vView.y; mat._31 = vRight.z; mat._32 = vUp.z; mat._33 = vView.z; // Do the translation values (rotations are still about the eyepoint) mat._41 = - DotProduct(vFrom, vRight); mat._42 = - DotProduct(vFrom, vUp); mat._43 = - DotProduct(vFrom, vView); return S_OK; } //----------------------------------------------------------------------------- // Name: D3DUtil_SetProjectionMatrix() // Desc: Sets the passed in 4x4 matrix to a perpsective projection matrix built // from the field-of-view (fov, in y), aspect ratio, near plane (D), // and far plane (F). Note that the projection matrix is normalized for // element [3][4] to be 1.0. This is performed so that W-based range fog // will work correctly. //----------------------------------------------------------------------------- HRESULT D3DUtil_SetProjectionMatrix(D3DMATRIX& mat, FLOAT fFOV, FLOAT fAspect, FLOAT fNearPlane, FLOAT fFarPlane) { if (fabs(fFarPlane-fNearPlane) < 0.01f) return E_INVALIDARG; if (fabs(sin(fFOV/2)) < 0.01f) return E_INVALIDARG; FLOAT w = fAspect * (cosf(fFOV/2)/sinf(fFOV/2)); FLOAT h = 1.0f * (cosf(fFOV/2)/sinf(fFOV/2)); FLOAT Q = fFarPlane / (fFarPlane - fNearPlane); ZeroMemory(&mat, sizeof(D3DMATRIX)); mat._11 = w; mat._22 = h; mat._33 = Q; mat._34 = 1.0f; mat._43 = -Q*fNearPlane; return S_OK; } //----------------------------------------------------------------------------- // Name: D3DUtil_SetRotateXMatrix() // Desc: Create Rotation matrix about X axis //----------------------------------------------------------------------------- VOID D3DUtil_SetRotateXMatrix(D3DMATRIX& mat, FLOAT fRads) { D3DUtil_SetIdentityMatrix(mat); mat._22 = cosf(fRads); mat._23 = sinf(fRads); mat._32 = -sinf(fRads); mat._33 = cosf(fRads); } //----------------------------------------------------------------------------- // Name: D3DUtil_SetRotateYMatrix() // Desc: Create Rotation matrix about Y axis //----------------------------------------------------------------------------- VOID D3DUtil_SetRotateYMatrix(D3DMATRIX& mat, FLOAT fRads) { D3DUtil_SetIdentityMatrix(mat); mat._11 = cosf(fRads); mat._13 = -sinf(fRads); mat._31 = sinf(fRads); mat._33 = cosf(fRads); } //----------------------------------------------------------------------------- // Name: D3DUtil_SetRotateZMatrix() // Desc: Create Rotation matrix about Z axis //----------------------------------------------------------------------------- VOID D3DUtil_SetRotateZMatrix(D3DMATRIX& mat, FLOAT fRads) { D3DUtil_SetIdentityMatrix(mat); mat._11 = cosf(fRads); mat._12 = sinf(fRads); mat._21 = -sinf(fRads); mat._22 = cosf(fRads); } //----------------------------------------------------------------------------- // Name: D3DUtil_SetRotationMatrix // Desc: Create a Rotation matrix about vector direction //----------------------------------------------------------------------------- VOID D3DUtil_SetRotationMatrix(D3DMATRIX& mat, D3DVECTOR& vDir, FLOAT fRads) { FLOAT fCos = cosf(fRads); FLOAT fSin = sinf(fRads); D3DVECTOR v = Normalize(vDir); mat._11 = (v.x * v.x) * (1.0f - fCos) + fCos; mat._12 = (v.x * v.y) * (1.0f - fCos) - (v.z * fSin); mat._13 = (v.x * v.z) * (1.0f - fCos) + (v.y * fSin); mat._21 = (v.y * v.x) * (1.0f - fCos) + (v.z * fSin); mat._22 = (v.y * v.y) * (1.0f - fCos) + fCos ; mat._23 = (v.y * v.z) * (1.0f - fCos) - (v.x * fSin); mat._31 = (v.z * v.x) * (1.0f - fCos) - (v.y * fSin); mat._32 = (v.z * v.y) * (1.0f - fCos) + (v.x * fSin); mat._33 = (v.z * v.z) * (1.0f - fCos) + fCos; mat._14 = mat._24 = mat._34 = 0.0f; mat._41 = mat._42 = mat._43 = 0.0f; mat._44 = 1.0f; } //----------------------------------------------------------------------------- // Name: _DbgOut() // Desc: Outputs a message to the debug stream //----------------------------------------------------------------------------- HRESULT _DbgOut(TCHAR* strFile, DWORD dwLine, HRESULT hr, TCHAR* strMsg) { TCHAR buffer[256]; wsprintf(buffer, TEXT("%s(%ld): "), strFile, dwLine); OutputDebugString(buffer); OutputDebugString(strMsg); if (hr) { wsprintf(buffer, TEXT("(hr=%08lx)\n"), hr); OutputDebugString(buffer); } OutputDebugString(TEXT("\n")); return hr; }