1 //-----------------------------------------------------------------------------
4 // Desc: Shortcut macros and functions for using DX objects
7 // Copyright (c) 1997-1998 Microsoft Corporation. All rights reserved
8 //-----------------------------------------------------------------------------
17 //-----------------------------------------------------------------------------
18 // Name: D3DUtil_InitDeviceDesc()
19 // Desc: Helper function called to initialize a D3DDEVICEDESC structure,
20 //-----------------------------------------------------------------------------
21 VOID D3DUtil_InitDeviceDesc( D3DDEVICEDESC& ddDevDesc )
23 ZeroMemory( &ddDevDesc, sizeof(D3DDEVICEDESC) );
24 ddDevDesc.dwSize = sizeof(D3DDEVICEDESC);
25 ddDevDesc.dtcTransformCaps.dwSize = sizeof(D3DTRANSFORMCAPS);
26 ddDevDesc.dlcLightingCaps.dwSize = sizeof(D3DLIGHTINGCAPS);
27 ddDevDesc.dpcLineCaps.dwSize = sizeof(D3DPRIMCAPS);
28 ddDevDesc.dpcTriCaps.dwSize = sizeof(D3DPRIMCAPS);
34 //-----------------------------------------------------------------------------
35 // Name: D3DUtil_InitSurfaceDesc()
36 // Desc: Helper function called to build a DDSURFACEDESC2 structure,
37 // typically before calling CreateSurface() or GetSurfaceDesc()
38 //-----------------------------------------------------------------------------
39 VOID D3DUtil_InitSurfaceDesc( DDSURFACEDESC2& ddsd, DWORD dwFlags,
42 ZeroMemory( &ddsd, sizeof(DDSURFACEDESC2) );
43 ddsd.dwSize = sizeof(DDSURFACEDESC2);
44 ddsd.dwFlags = dwFlags;
45 ddsd.ddsCaps.dwCaps = dwCaps;
46 ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
52 //-----------------------------------------------------------------------------
53 // Name: D3DUtil_InitViewport()
54 // Desc: Helper function called to build a D3DVIEWPORT3 structure
55 //-----------------------------------------------------------------------------
56 VOID D3DUtil_InitViewport( D3DVIEWPORT2& vp, DWORD dwWidth, DWORD dwHeight )
58 ZeroMemory( &vp, sizeof(D3DVIEWPORT2) );
59 vp.dwSize = sizeof(D3DVIEWPORT2);
61 vp.dwHeight = dwHeight;
65 vp.dvClipWidth = 2.0f;
67 vp.dvClipHeight = 2.0f;
73 //-----------------------------------------------------------------------------
74 // Name: D3DUtil_InitMaterial()
75 // Desc: Helper function called to build a D3DMATERIAL structure
76 //-----------------------------------------------------------------------------
77 VOID D3DUtil_InitMaterial( D3DMATERIAL& mtrl, FLOAT r, FLOAT g, FLOAT b )
79 ZeroMemory( &mtrl, sizeof(D3DMATERIAL) );
80 mtrl.dwSize = sizeof(D3DMATERIAL);
81 mtrl.dcvDiffuse.r = mtrl.dcvAmbient.r = r;
82 mtrl.dcvDiffuse.g = mtrl.dcvAmbient.g = g;
83 mtrl.dcvDiffuse.b = mtrl.dcvAmbient.b = b;
84 mtrl.dwRampSize = 16L; // A default ramp size
90 //-----------------------------------------------------------------------------
91 // Name: D3DUtil_InitLight()
92 // Desc: Initializes a D3DLIGHT structure
93 //-----------------------------------------------------------------------------
94 VOID D3DUtil_InitLight( D3DLIGHT& light, D3DLIGHTTYPE ltType,
95 FLOAT x, FLOAT y, FLOAT z )
97 ZeroMemory( &light, sizeof(D3DLIGHT) );
98 light.dwSize = sizeof(D3DLIGHT);
99 light.dltType = ltType;
100 light.dcvColor.r = 1.0f;
101 light.dcvColor.g = 1.0f;
102 light.dcvColor.b = 1.0f;
103 light.dvPosition.x = light.dvDirection.x = x;
104 light.dvPosition.y = light.dvDirection.y = y;
105 light.dvPosition.z = light.dvDirection.z = z;
111 //-----------------------------------------------------------------------------
112 // Name: D3DUtil_GetDirectDrawFromDevice()
113 // Desc: Get the DDraw interface from a D3DDevice.
114 //-----------------------------------------------------------------------------
115 LPDIRECTDRAW4 D3DUtil_GetDirectDrawFromDevice( LPDIRECT3DDEVICE3 pd3dDevice )
117 LPDIRECTDRAW4 pDD = NULL;
118 LPDIRECTDRAWSURFACE4 pddsRender;
122 // Get the current render target
123 if( SUCCEEDED( pd3dDevice->GetRenderTarget( &pddsRender ) ) )
125 // Get the DDraw4 interface from the render target
126 pddsRender->GetDDInterface( (VOID**)&pDD );
127 pddsRender->Release();
136 //-----------------------------------------------------------------------------
137 // Name: D3DUtil_GetDeviceMemoryType()
138 // Desc: Retreives the default memory type used for the device.
139 //-----------------------------------------------------------------------------
140 DWORD D3DUtil_GetDeviceMemoryType( LPDIRECT3DDEVICE3 pd3dDevice )
142 D3DDEVICEDESC ddHwDesc, ddSwDesc;
143 ddHwDesc.dwSize = sizeof(D3DDEVICEDESC);
144 ddSwDesc.dwSize = sizeof(D3DDEVICEDESC);
145 if( FAILED( pd3dDevice->GetCaps( &ddHwDesc, &ddSwDesc ) ) )
148 if( ddHwDesc.dwFlags )
149 return DDSCAPS_VIDEOMEMORY;
151 return DDSCAPS_SYSTEMMEMORY;
157 //-----------------------------------------------------------------------------
158 // Name: D3DUtil_SetViewMatrix()
159 // Desc: Given an eye point, a lookat point, and an up vector, this
160 // function builds a 4x4 view matrix.
161 //-----------------------------------------------------------------------------
162 HRESULT D3DUtil_SetViewMatrix( D3DMATRIX& mat, D3DVECTOR& vFrom,
163 D3DVECTOR& vAt, D3DVECTOR& vWorldUp )
165 // Get the z basis vector, which points straight ahead. This is the
166 // difference from the eyepoint to the lookat point.
167 D3DVECTOR vView = vAt - vFrom;
169 FLOAT fLength = Magnitude( vView );
170 if( fLength < 1e-6f )
173 // Normalize the z basis vector
176 // Get the dot product, and calculate the projection of the z basis
177 // vector onto the up vector. The projection is the y basis vector.
178 FLOAT fDotProduct = DotProduct( vWorldUp, vView );
180 D3DVECTOR vUp = vWorldUp - fDotProduct * vView;
182 // If this vector has near-zero length because the input specified a
183 // bogus up vector, let's try a default up vector
184 if( 1e-6f > ( fLength = Magnitude( vUp ) ) )
186 vUp = D3DVECTOR( 0.0f, 1.0f, 0.0f ) - vView.y * vView;
188 // If we still have near-zero length, resort to a different axis.
189 if( 1e-6f > ( fLength = Magnitude( vUp ) ) )
191 vUp = D3DVECTOR( 0.0f, 0.0f, 1.0f ) - vView.z * vView;
193 if( 1e-6f > ( fLength = Magnitude( vUp ) ) )
198 // Normalize the y basis vector
201 // The x basis vector is found simply with the cross product of the y
202 // and z basis vectors
203 D3DVECTOR vRight = CrossProduct( vUp, vView );
205 // Start building the matrix. The first three rows contains the basis
206 // vectors used to rotate the view to point at the lookat point
207 D3DUtil_SetIdentityMatrix( mat );
208 mat._11 = vRight.x; mat._12 = vUp.x; mat._13 = vView.x;
209 mat._21 = vRight.y; mat._22 = vUp.y; mat._23 = vView.y;
210 mat._31 = vRight.z; mat._32 = vUp.z; mat._33 = vView.z;
212 // Do the translation values (rotations are still about the eyepoint)
213 mat._41 = - DotProduct( vFrom, vRight );
214 mat._42 = - DotProduct( vFrom, vUp );
215 mat._43 = - DotProduct( vFrom, vView );
223 //-----------------------------------------------------------------------------
224 // Name: D3DUtil_SetProjectionMatrix()
225 // Desc: Sets the passed in 4x4 matrix to a perpsective projection matrix built
226 // from the field-of-view (fov, in y), aspect ratio, near plane (D),
227 // and far plane (F). Note that the projection matrix is normalized for
228 // element [3][4] to be 1.0. This is performed so that W-based range fog
229 // will work correctly.
230 //-----------------------------------------------------------------------------
231 HRESULT D3DUtil_SetProjectionMatrix( D3DMATRIX& mat, FLOAT fFOV, FLOAT fAspect,
232 FLOAT fNearPlane, FLOAT fFarPlane )
234 if( fabs(fFarPlane-fNearPlane) < 0.01f )
236 if( fabs(sin(fFOV/2)) < 0.01f )
239 FLOAT w = fAspect * (FLOAT)( cos(fFOV/2)/sin(fFOV/2) );
240 FLOAT h = 1.0f * (FLOAT)( cos(fFOV/2)/sin(fFOV/2) );
241 FLOAT Q = fFarPlane / ( fFarPlane - fNearPlane );
243 ZeroMemory( &mat, sizeof(D3DMATRIX) );
248 mat._43 = -Q*fNearPlane;
256 //-----------------------------------------------------------------------------
257 // Name: D3DUtil_SetRotateXMatrix()
258 // Desc: Create Rotation matrix about X axis
259 //-----------------------------------------------------------------------------
260 VOID D3DUtil_SetRotateXMatrix( D3DMATRIX& mat, FLOAT fRads )
262 D3DUtil_SetIdentityMatrix( mat );
263 mat._22 = (FLOAT)cos( fRads );
264 mat._23 = (FLOAT)sin( fRads );
265 mat._32 = -(FLOAT)sin( fRads );
266 mat._33 = (FLOAT)cos( fRads );
272 //-----------------------------------------------------------------------------
273 // Name: D3DUtil_SetRotateYMatrix()
274 // Desc: Create Rotation matrix about Y axis
275 //-----------------------------------------------------------------------------
276 VOID D3DUtil_SetRotateYMatrix( D3DMATRIX& mat, FLOAT fRads )
278 D3DUtil_SetIdentityMatrix( mat );
279 mat._11 = (FLOAT)cos( fRads );
280 mat._13 = -(FLOAT)sin( fRads );
281 mat._31 = (FLOAT)sin( fRads );
282 mat._33 = (FLOAT)cos( fRads );
288 //-----------------------------------------------------------------------------
289 // Name: D3DUtil_SetRotateZMatrix()
290 // Desc: Create Rotation matrix about Z axis
291 //-----------------------------------------------------------------------------
292 VOID D3DUtil_SetRotateZMatrix( D3DMATRIX& mat, FLOAT fRads )
294 D3DUtil_SetIdentityMatrix( mat );
295 mat._11 = (FLOAT)cos( fRads );
296 mat._12 = (FLOAT)sin( fRads );
297 mat._21 = -(FLOAT)sin( fRads );
298 mat._22 = (FLOAT)cos( fRads );
304 //-----------------------------------------------------------------------------
305 // Name: D3DUtil_SetRotationMatrix
306 // Desc: Create a Rotation matrix about vector direction
307 //-----------------------------------------------------------------------------
308 VOID D3DUtil_SetRotationMatrix( D3DMATRIX& mat, D3DVECTOR& vDir, FLOAT fRads )
310 FLOAT fCos = (FLOAT)cos( fRads );
311 FLOAT fSin = (FLOAT)sin( fRads );
312 D3DVECTOR v = Normalize( vDir );
314 mat._11 = ( v.x * v.x ) * ( 1.0f - fCos ) + fCos;
315 mat._12 = ( v.x * v.y ) * ( 1.0f - fCos ) - (v.z * fSin);
316 mat._13 = ( v.x * v.z ) * ( 1.0f - fCos ) + (v.y * fSin);
318 mat._21 = ( v.y * v.x ) * ( 1.0f - fCos ) + (v.z * fSin);
319 mat._22 = ( v.y * v.y ) * ( 1.0f - fCos ) + fCos ;
320 mat._23 = ( v.y * v.z ) * ( 1.0f - fCos ) - (v.x * fSin);
322 mat._31 = ( v.z * v.x ) * ( 1.0f - fCos ) - (v.y * fSin);
323 mat._32 = ( v.z * v.y ) * ( 1.0f - fCos ) + (v.x * fSin);
324 mat._33 = ( v.z * v.z ) * ( 1.0f - fCos ) + fCos;
326 mat._14 = mat._24 = mat._34 = 0.0f;
327 mat._41 = mat._42 = mat._43 = 0.0f;
334 //-----------------------------------------------------------------------------
335 // Name: D3DUtil_GetDisplayDepth()
336 // Desc: Returns the depth of the current display mode.
337 //-----------------------------------------------------------------------------
338 DWORD D3DUtil_GetDisplayDepth( LPDIRECTDRAW4 pDD4 )
340 // If the caller did not supply a DDraw object, just create a temp one.
344 if( FAILED( DirectDrawCreate( NULL, &pDD1, NULL ) ) )
347 HRESULT hr = pDD1->QueryInterface( IID_IDirectDraw4, (VOID**)&pDD4 );
355 // Get the display mode description
357 ZeroMemory( &ddsd, sizeof(DDSURFACEDESC2) );
358 ddsd.dwSize = sizeof(DDSURFACEDESC2);
359 pDD4->GetDisplayMode( &ddsd );
362 // Return the display mode's depth
363 return ddsd.ddpfPixelFormat.dwRGBBitCount;
369 //-----------------------------------------------------------------------------
371 // Desc: Outputs a message to the debug stream
372 //-----------------------------------------------------------------------------
373 HRESULT _DbgOut( TCHAR* strFile, DWORD dwLine, HRESULT hr, TCHAR* strMsg )
376 sprintf( buffer, "%s(%ld): ", strFile, dwLine );
377 OutputDebugString( buffer );
378 OutputDebugString( strMsg );
382 sprintf( buffer, "(hr=%08lx)\n", hr );
383 OutputDebugString( buffer );
386 OutputDebugString( "\n" );