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