1 //-----------------------------------------------------------------------------
2 // File: D3DUtil.cpp
3 //
4 // Desc: Shortcut macros and functions for using DX objects
5 //
6 //
7 // Copyright (c) 1997-1998 Microsoft Corporation. All rights reserved
8 //-----------------------------------------------------------------------------
9
10 #define D3D_OVERLOADS
11 #include <math.h>
12 #include <stdio.h>
13 #include "D3DUtil.h"
14
15
16
17 //-----------------------------------------------------------------------------
18 // Name: D3DUtil_InitDeviceDesc()
19 // Desc: Helper function called to initialize a D3DDEVICEDESC structure,
20 //-----------------------------------------------------------------------------
D3DUtil_InitDeviceDesc(D3DDEVICEDESC & ddDevDesc)21 VOID D3DUtil_InitDeviceDesc( D3DDEVICEDESC& ddDevDesc )
22 {
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);
29 }
30
31
32
33
34 //-----------------------------------------------------------------------------
35 // Name: D3DUtil_InitSurfaceDesc()
36 // Desc: Helper function called to build a DDSURFACEDESC2 structure,
37 // typically before calling CreateSurface() or GetSurfaceDesc()
38 //-----------------------------------------------------------------------------
D3DUtil_InitSurfaceDesc(DDSURFACEDESC2 & ddsd,DWORD dwFlags,DWORD dwCaps)39 VOID D3DUtil_InitSurfaceDesc( DDSURFACEDESC2& ddsd, DWORD dwFlags,
40 DWORD dwCaps )
41 {
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);
47 }
48
49
50
51
52 //-----------------------------------------------------------------------------
53 // Name: D3DUtil_InitViewport()
54 // Desc: Helper function called to build a D3DVIEWPORT3 structure
55 //-----------------------------------------------------------------------------
D3DUtil_InitViewport(D3DVIEWPORT2 & vp,DWORD dwWidth,DWORD dwHeight)56 VOID D3DUtil_InitViewport( D3DVIEWPORT2& vp, DWORD dwWidth, DWORD dwHeight )
57 {
58 ZeroMemory( &vp, sizeof(D3DVIEWPORT2) );
59 vp.dwSize = sizeof(D3DVIEWPORT2);
60 vp.dwWidth = dwWidth;
61 vp.dwHeight = dwHeight;
62 vp.dvMaxZ = 1.0f;
63
64 vp.dvClipX = -1.0f;
65 vp.dvClipWidth = 2.0f;
66 vp.dvClipY = 1.0f;
67 vp.dvClipHeight = 2.0f;
68 }
69
70
71
72
73 //-----------------------------------------------------------------------------
74 // Name: D3DUtil_InitMaterial()
75 // Desc: Helper function called to build a D3DMATERIAL structure
76 //-----------------------------------------------------------------------------
D3DUtil_InitMaterial(D3DMATERIAL & mtrl,FLOAT r,FLOAT g,FLOAT b)77 VOID D3DUtil_InitMaterial( D3DMATERIAL& mtrl, FLOAT r, FLOAT g, FLOAT b )
78 {
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
85 }
86
87
88
89
90 //-----------------------------------------------------------------------------
91 // Name: D3DUtil_InitLight()
92 // Desc: Initializes a D3DLIGHT structure
93 //-----------------------------------------------------------------------------
D3DUtil_InitLight(D3DLIGHT & light,D3DLIGHTTYPE ltType,FLOAT x,FLOAT y,FLOAT z)94 VOID D3DUtil_InitLight( D3DLIGHT& light, D3DLIGHTTYPE ltType,
95 FLOAT x, FLOAT y, FLOAT z )
96 {
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;
106 }
107
108
109
110
111 //-----------------------------------------------------------------------------
112 // Name: D3DUtil_GetDirectDrawFromDevice()
113 // Desc: Get the DDraw interface from a D3DDevice.
114 //-----------------------------------------------------------------------------
D3DUtil_GetDirectDrawFromDevice(LPDIRECT3DDEVICE3 pd3dDevice)115 LPDIRECTDRAW4 D3DUtil_GetDirectDrawFromDevice( LPDIRECT3DDEVICE3 pd3dDevice )
116 {
117 LPDIRECTDRAW4 pDD = NULL;
118 LPDIRECTDRAWSURFACE4 pddsRender;
119
120 if( pd3dDevice )
121 {
122 // Get the current render target
123 if( SUCCEEDED( pd3dDevice->GetRenderTarget( &pddsRender ) ) )
124 {
125 // Get the DDraw4 interface from the render target
126 pddsRender->GetDDInterface( (VOID**)&pDD );
127 pddsRender->Release();
128 }
129 }
130 return pDD;
131 }
132
133
134
135
136 //-----------------------------------------------------------------------------
137 // Name: D3DUtil_GetDeviceMemoryType()
138 // Desc: Retreives the default memory type used for the device.
139 //-----------------------------------------------------------------------------
D3DUtil_GetDeviceMemoryType(LPDIRECT3DDEVICE3 pd3dDevice)140 DWORD D3DUtil_GetDeviceMemoryType( LPDIRECT3DDEVICE3 pd3dDevice )
141 {
142 D3DDEVICEDESC ddHwDesc, ddSwDesc;
143 ddHwDesc.dwSize = sizeof(D3DDEVICEDESC);
144 ddSwDesc.dwSize = sizeof(D3DDEVICEDESC);
145 if( FAILED( pd3dDevice->GetCaps( &ddHwDesc, &ddSwDesc ) ) )
146 return 0L;
147
148 if( ddHwDesc.dwFlags )
149 return DDSCAPS_VIDEOMEMORY;
150
151 return DDSCAPS_SYSTEMMEMORY;
152 }
153
154
155
156
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 //-----------------------------------------------------------------------------
D3DUtil_SetViewMatrix(D3DMATRIX & mat,D3DVECTOR & vFrom,D3DVECTOR & vAt,D3DVECTOR & vWorldUp)162 HRESULT D3DUtil_SetViewMatrix( D3DMATRIX& mat, D3DVECTOR& vFrom,
163 D3DVECTOR& vAt, D3DVECTOR& vWorldUp )
164 {
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;
168
169 FLOAT fLength = Magnitude( vView );
170 if( fLength < 1e-6f )
171 return E_INVALIDARG;
172
173 // Normalize the z basis vector
174 vView /= fLength;
175
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 );
179
180 D3DVECTOR vUp = vWorldUp - fDotProduct * vView;
181
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 ) ) )
185 {
186 vUp = D3DVECTOR( 0.0f, 1.0f, 0.0f ) - vView.y * vView;
187
188 // If we still have near-zero length, resort to a different axis.
189 if( 1e-6f > ( fLength = Magnitude( vUp ) ) )
190 {
191 vUp = D3DVECTOR( 0.0f, 0.0f, 1.0f ) - vView.z * vView;
192
193 if( 1e-6f > ( fLength = Magnitude( vUp ) ) )
194 return E_INVALIDARG;
195 }
196 }
197
198 // Normalize the y basis vector
199 vUp /= fLength;
200
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 );
204
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;
211
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 );
216
217 return S_OK;
218 }
219
220
221
222
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 //-----------------------------------------------------------------------------
D3DUtil_SetProjectionMatrix(D3DMATRIX & mat,FLOAT fFOV,FLOAT fAspect,FLOAT fNearPlane,FLOAT fFarPlane)231 HRESULT D3DUtil_SetProjectionMatrix( D3DMATRIX& mat, FLOAT fFOV, FLOAT fAspect,
232 FLOAT fNearPlane, FLOAT fFarPlane )
233 {
234 if( fabs(fFarPlane-fNearPlane) < 0.01f )
235 return E_INVALIDARG;
236 if( fabs(sin(fFOV/2)) < 0.01f )
237 return E_INVALIDARG;
238
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 );
242
243 ZeroMemory( &mat, sizeof(D3DMATRIX) );
244 mat._11 = w;
245 mat._22 = h;
246 mat._33 = Q;
247 mat._34 = 1.0f;
248 mat._43 = -Q*fNearPlane;
249
250 return S_OK;
251 }
252
253
254
255
256 //-----------------------------------------------------------------------------
257 // Name: D3DUtil_SetRotateXMatrix()
258 // Desc: Create Rotation matrix about X axis
259 //-----------------------------------------------------------------------------
D3DUtil_SetRotateXMatrix(D3DMATRIX & mat,FLOAT fRads)260 VOID D3DUtil_SetRotateXMatrix( D3DMATRIX& mat, FLOAT fRads )
261 {
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 );
267 }
268
269
270
271
272 //-----------------------------------------------------------------------------
273 // Name: D3DUtil_SetRotateYMatrix()
274 // Desc: Create Rotation matrix about Y axis
275 //-----------------------------------------------------------------------------
D3DUtil_SetRotateYMatrix(D3DMATRIX & mat,FLOAT fRads)276 VOID D3DUtil_SetRotateYMatrix( D3DMATRIX& mat, FLOAT fRads )
277 {
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 );
283 }
284
285
286
287
288 //-----------------------------------------------------------------------------
289 // Name: D3DUtil_SetRotateZMatrix()
290 // Desc: Create Rotation matrix about Z axis
291 //-----------------------------------------------------------------------------
D3DUtil_SetRotateZMatrix(D3DMATRIX & mat,FLOAT fRads)292 VOID D3DUtil_SetRotateZMatrix( D3DMATRIX& mat, FLOAT fRads )
293 {
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 );
299 }
300
301
302
303
304 //-----------------------------------------------------------------------------
305 // Name: D3DUtil_SetRotationMatrix
306 // Desc: Create a Rotation matrix about vector direction
307 //-----------------------------------------------------------------------------
D3DUtil_SetRotationMatrix(D3DMATRIX & mat,D3DVECTOR & vDir,FLOAT fRads)308 VOID D3DUtil_SetRotationMatrix( D3DMATRIX& mat, D3DVECTOR& vDir, FLOAT fRads )
309 {
310 FLOAT fCos = (FLOAT)cos( fRads );
311 FLOAT fSin = (FLOAT)sin( fRads );
312 D3DVECTOR v = Normalize( vDir );
313
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);
317
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);
321
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;
325
326 mat._14 = mat._24 = mat._34 = 0.0f;
327 mat._41 = mat._42 = mat._43 = 0.0f;
328 mat._44 = 1.0f;
329 }
330
331
332
333
334 //-----------------------------------------------------------------------------
335 // Name: D3DUtil_GetDisplayDepth()
336 // Desc: Returns the depth of the current display mode.
337 //-----------------------------------------------------------------------------
D3DUtil_GetDisplayDepth(LPDIRECTDRAW4 pDD4)338 DWORD D3DUtil_GetDisplayDepth( LPDIRECTDRAW4 pDD4 )
339 {
340 // If the caller did not supply a DDraw object, just create a temp one.
341 if( NULL == pDD4 )
342 {
343 LPDIRECTDRAW pDD1;
344 if( FAILED( DirectDrawCreate( NULL, &pDD1, NULL ) ) )
345 return 0L;
346
347 HRESULT hr = pDD1->QueryInterface( IID_IDirectDraw4, (VOID**)&pDD4 );
348 pDD1->Release();
349 if( FAILED(hr) )
350 return 0L;
351 }
352 else
353 pDD4->AddRef();
354
355 // Get the display mode description
356 DDSURFACEDESC2 ddsd;
357 ZeroMemory( &ddsd, sizeof(DDSURFACEDESC2) );
358 ddsd.dwSize = sizeof(DDSURFACEDESC2);
359 pDD4->GetDisplayMode( &ddsd );
360 pDD4->Release();
361
362 // Return the display mode's depth
363 return ddsd.ddpfPixelFormat.dwRGBBitCount;
364 }
365
366
367
368
369 //-----------------------------------------------------------------------------
370 // Name: _DbgOut()
371 // Desc: Outputs a message to the debug stream
372 //-----------------------------------------------------------------------------
_DbgOut(TCHAR * strFile,DWORD dwLine,HRESULT hr,TCHAR * strMsg)373 HRESULT _DbgOut( TCHAR* strFile, DWORD dwLine, HRESULT hr, TCHAR* strMsg )
374 {
375 TCHAR buffer[256];
376 sprintf( buffer, "%s(%ld): ", strFile, dwLine );
377 OutputDebugString( buffer );
378 OutputDebugString( strMsg );
379
380 if( hr )
381 {
382 sprintf( buffer, "(hr=%08lx)\n", hr );
383 OutputDebugString( buffer );
384 }
385
386 OutputDebugString( "\n" );
387
388 return hr;
389 }
390
391