Leaked source code of windows server 2003
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.

859 lines
27 KiB

  1. ///////////////////////////////////////////////////////////////////////////////
  2. // Copyright (C) Microsoft Corporation, 1998.
  3. //
  4. // rrutil.hpp
  5. //
  6. // Direct3D Reference Rasterizer - Utilities
  7. //
  8. ///////////////////////////////////////////////////////////////////////////////
  9. #ifndef _RRUTIL_HPP
  10. #define _RRUTIL_HPP
  11. #include <math.h>
  12. #ifndef FASTCALL
  13. #ifdef _X86_
  14. #define FASTCALL __fastcall
  15. #else
  16. #define FASTCALL
  17. #endif
  18. #endif
  19. #ifndef CDECL
  20. #ifdef _X86_
  21. #define CDECL __cdecl
  22. #else
  23. #define CDECL
  24. #endif
  25. #endif
  26. ///////////////////////////////////////////////////////////////////////////////
  27. // //
  28. // Globals //
  29. // //
  30. ///////////////////////////////////////////////////////////////////////////////
  31. // memory allocation callbacks
  32. extern LPVOID (__cdecl *g_pfnMemAlloc)( size_t size );
  33. extern void (__cdecl *g_pfnMemFree)( LPVOID lptr );
  34. extern LPVOID (__cdecl *g_pfnMemReAlloc)( LPVOID ptr, size_t size );
  35. // debug print controls
  36. extern int g_iDPFLevel;
  37. extern unsigned long g_uDPFMask;
  38. ///////////////////////////////////////////////////////////////////////////////
  39. // //
  40. // Typedefs //
  41. // //
  42. ///////////////////////////////////////////////////////////////////////////////
  43. #ifndef DllExport
  44. #define DllExport __declspec( dllexport )
  45. #endif
  46. // width-specific typedefs for basic types
  47. #ifndef _BASETSD_H_
  48. typedef signed char INT8, *PINT8;
  49. typedef short int INT16, *PINT16;
  50. typedef int INT32, *PINT32;
  51. typedef __int64 INT64, *PINT64;
  52. typedef unsigned char UINT8, *PUINT8;
  53. typedef unsigned short int UINT16, *PUINT16;
  54. typedef unsigned int UINT32, *PUINT32;
  55. typedef unsigned __int64 UINT64, *PUINT64;
  56. #endif
  57. typedef float FLOAT, *PFLOAT;
  58. typedef double DOUBLE, *PDOUBLE;
  59. typedef int BOOL;
  60. typedef struct _RRVECTOR4
  61. {
  62. D3DVALUE x;
  63. D3DVALUE y;
  64. D3DVALUE z;
  65. D3DVALUE w;
  66. } RRVECTOR4, *LPRRVECTOR4;
  67. //-----------------------------------------------------------------------------
  68. //
  69. // Private FVF flags for texgen.
  70. //
  71. //-----------------------------------------------------------------------------
  72. #define D3DFVFP_EYENORMAL ((UINT64)1<<32)
  73. #define D3DFVFP_EYEXYZ ((UINT64)1<<33)
  74. ///////////////////////////////////////////////////////////////////////////////
  75. // //
  76. // Macros //
  77. // //
  78. ///////////////////////////////////////////////////////////////////////////////
  79. #ifndef TRUE
  80. #define TRUE 1
  81. #endif
  82. #ifndef FALSE
  83. #define FALSE 0
  84. #endif
  85. #ifndef NULL
  86. #define NULL 0
  87. #endif
  88. #define MAX(a,b) (((a) > (b)) ? (a) : (b))
  89. #define MIN(a,b) (((a) < (b)) ? (a) : (b))
  90. #define ABS(a) (((a) < 0) ? (-(a)) : (a))
  91. // Check the return value and return if something wrong.
  92. // Assume hr has been declared
  93. #define HR_RET(exp) \
  94. { \
  95. hr = (exp); \
  96. if (hr != D3D_OK) \
  97. { \
  98. return hr; \
  99. } \
  100. }
  101. //-----------------------------------------------------------------------------
  102. //
  103. // macros for accessing floating point data as 32 bit integers and vice versa
  104. //
  105. // This is used primarily to do floating point to fixed point conversion with
  106. // the unbiased nearest-even rounding that IEEE floating point does internally
  107. // between operations. Adding a big number slides the mantissa down to where
  108. // the fixed point equivalent is aligned to the LSB. IEEE applies a nearest-
  109. // even round to the bits it lops off before storing. The mantissa can then
  110. // be grabbed by the AS_INT* operations. Note that the sign and exponent are
  111. // still there, so the easiest thing is to do it with doubles and grab the low
  112. // 32 bits.
  113. //
  114. // The snap values (i.e. the "big number") is the sum of 2**n and 2**(n-1),
  115. // which makes the trick return signed numbers (at least within the mantissa).
  116. //
  117. //-----------------------------------------------------------------------------
  118. #if 0
  119. // NOTE: vc5 optimizing compiler bug breaks this pointer casting technique
  120. #define AS_FLOAT(i) ( *(FLOAT*)&(i) )
  121. #define AS_INT32(f) ( *(INT32*)&(f) )
  122. #define AS_INT16(f) ( *(INT16*)&(f) )
  123. #define AS_UINT32(f) ( *(UINT32*)&(f) )
  124. #else
  125. // workaround using union
  126. typedef union { float f; UINT32 u; INT32 i; } VAL32;
  127. typedef union { double d; UINT64 u; INT64 i; } VAL64;
  128. inline FLOAT AS_FLOAT( long int iVal ) { VAL32 v; v.i = iVal; return v.f; }
  129. inline FLOAT AS_FLOAT( unsigned long int uVal ) { VAL32 v; v.u = uVal; return v.f; }
  130. inline INT32 AS_INT32( FLOAT fVal ) { VAL32 v; v.f = fVal; return v.i; }
  131. inline INT32 AS_INT32( DOUBLE dVal ) { VAL64 v; v.d = dVal; return (INT32)(v.u & 0xffffffff); }
  132. inline INT16 AS_INT16( FLOAT fVal ) { VAL32 v; v.f = fVal; return (INT16)(v.u & 0xffff); }
  133. inline INT16 AS_INT16( DOUBLE dVal ) { VAL64 v; v.d = dVal; return (INT16)(v.u & 0xffff); }
  134. inline INT32 AS_UINT32( FLOAT fVal ) { VAL32 v; v.f = fVal; return v.u; }
  135. #endif
  136. //-----------------------------------------------------------------------------
  137. //
  138. // Some common FP values as constants
  139. // point values
  140. //
  141. //-----------------------------------------------------------------------------
  142. #define g_fZero (0.0f)
  143. #define g_fOne (1.0f)
  144. // Integer representation of 1.0f.
  145. #define INT32_FLOAT_ONE 0x3f800000
  146. //-----------------------------------------------------------------------------
  147. //
  148. // these are handy to form 'magic' constants to snap real values to fixed
  149. // point values
  150. //
  151. //-----------------------------------------------------------------------------
  152. #define C2POW0 1
  153. #define C2POW1 2
  154. #define C2POW2 4
  155. #define C2POW3 8
  156. #define C2POW4 16
  157. #define C2POW5 32
  158. #define C2POW6 64
  159. #define C2POW7 128
  160. #define C2POW8 256
  161. #define C2POW9 512
  162. #define C2POW10 1024
  163. #define C2POW11 2048
  164. #define C2POW12 4096
  165. #define C2POW13 8192
  166. #define C2POW14 16384
  167. #define C2POW15 32768
  168. #define C2POW16 65536
  169. #define C2POW17 131072
  170. #define C2POW18 262144
  171. #define C2POW19 524288
  172. #define C2POW20 1048576
  173. #define C2POW21 2097152
  174. #define C2POW22 4194304
  175. #define C2POW23 8388608
  176. #define C2POW24 16777216
  177. #define C2POW25 33554432
  178. #define C2POW26 67108864
  179. #define C2POW27 134217728
  180. #define C2POW28 268435456
  181. #define C2POW29 536870912
  182. #define C2POW30 1073741824
  183. #define C2POW31 2147483648
  184. #define C2POW32 4294967296
  185. #define C2POW33 8589934592
  186. #define C2POW34 17179869184
  187. #define C2POW35 34359738368
  188. #define C2POW36 68719476736
  189. #define C2POW37 137438953472
  190. #define C2POW38 274877906944
  191. #define C2POW39 549755813888
  192. #define C2POW40 1099511627776
  193. #define C2POW41 2199023255552
  194. #define C2POW42 4398046511104
  195. #define C2POW43 8796093022208
  196. #define C2POW44 17592186044416
  197. #define C2POW45 35184372088832
  198. #define C2POW46 70368744177664
  199. #define C2POW47 140737488355328
  200. #define C2POW48 281474976710656
  201. #define C2POW49 562949953421312
  202. #define C2POW50 1125899906842624
  203. #define C2POW51 2251799813685248
  204. #define C2POW52 4503599627370496
  205. #define FLOAT_0_SNAP (FLOAT)(C2POW23+C2POW22)
  206. #define FLOAT_4_SNAP (FLOAT)(C2POW19+C2POW18)
  207. #define FLOAT_5_SNAP (FLOAT)(C2POW18+C2POW17)
  208. #define FLOAT_8_SNAP (FLOAT)(C2POW15+C2POW14)
  209. #define FLOAT_17_SNAP (FLOAT)(C2POW6 +C2POW5 )
  210. #define FLOAT_18_SNAP (FLOAT)(C2POW5 +C2POW4 )
  211. #define DOUBLE_0_SNAP (DOUBLE)(C2POW52+C2POW51)
  212. #define DOUBLE_4_SNAP (DOUBLE)(C2POW48+C2POW47)
  213. #define DOUBLE_5_SNAP (DOUBLE)(C2POW47+C2POW46)
  214. #define DOUBLE_8_SNAP (DOUBLE)(C2POW44+C2POW43)
  215. #define DOUBLE_17_SNAP (DOUBLE)(C2POW35+C2POW34)
  216. #define DOUBLE_18_SNAP (DOUBLE)(C2POW34+C2POW33)
  217. //-----------------------------------------------------------------------------
  218. //
  219. // Floating point related macros
  220. //
  221. //-----------------------------------------------------------------------------
  222. #define COSF(fV) ((FLOAT)cos((double)(fV)))
  223. #define SINF(fV) ((FLOAT)sin((double)(fV)))
  224. #define SQRTF(fV) ((FLOAT)sqrt((double)(fV)))
  225. #define POWF(fV, fE) ((FLOAT)pow((double)(fV), (double)(fE)))
  226. #ifdef _X86_
  227. #define FLOAT_CMP_POS(fa, op, fb) (AS_INT32(fa) op AS_INT32(fb))
  228. #define FLOAT_CMP_PONE(flt, op) (AS_INT32(flt) op INT32_FLOAT_ONE)
  229. __inline int FLOAT_GTZ(FLOAT f)
  230. {
  231. VAL32 fi;
  232. fi.f = f;
  233. return fi.i > 0;
  234. }
  235. __inline int FLOAT_LTZ(FLOAT f)
  236. {
  237. VAL32 fi;
  238. fi.f = f;
  239. return fi.u > 0x80000000;
  240. }
  241. __inline int FLOAT_GEZ(FLOAT f)
  242. {
  243. VAL32 fi;
  244. fi.f = f;
  245. return fi.u <= 0x80000000;
  246. }
  247. __inline int FLOAT_LEZ(FLOAT f)
  248. {
  249. VAL32 fi;
  250. fi.f = f;
  251. return fi.i <= 0;
  252. }
  253. __inline int FLOAT_EQZ(FLOAT f)
  254. {
  255. VAL32 fi;
  256. fi.f = f;
  257. return (fi.u & 0x7fffffff) == 0;
  258. }
  259. __inline int FLOAT_NEZ(FLOAT f)
  260. {
  261. VAL32 fi;
  262. fi.f = f;
  263. return (fi.u & 0x7fffffff) != 0;
  264. }
  265. // Strip sign bit in integer.
  266. __inline FLOAT
  267. ABSF(FLOAT f)
  268. {
  269. VAL32 fi;
  270. fi.f = f;
  271. fi.u &= 0x7fffffff;
  272. return fi.f;
  273. }
  274. // Requires chop rounding.
  275. __inline INT
  276. FTOI(FLOAT f)
  277. {
  278. LARGE_INTEGER i;
  279. __asm
  280. {
  281. fld f
  282. fistp i
  283. }
  284. return i.LowPart;
  285. }
  286. #else
  287. #define FLOAT_GTZ(flt) ((flt) > g_fZero)
  288. #define FLOAT_LTZ(flt) ((flt) < g_fZero)
  289. #define FLOAT_GEZ(flt) ((flt) >= g_fZero)
  290. #define FLOAT_LEZ(flt) ((flt) <= g_fZero)
  291. #define FLOAT_EQZ(flt) ((flt) == g_fZero)
  292. #define FLOAT_NEZ(flt) ((flt) != g_fZero)
  293. #define FLOAT_CMP_POS(fa, op, fb) ((fa) op (fb))
  294. #define FLOAT_CMP_PONE(flt, op) ((flt) op g_fOne)
  295. #define ABSF(f) ((FLOAT)fabs((double)(f)))
  296. #define FTOI(f) ((INT)(f))
  297. #endif // _X86_
  298. //-----------------------------------------------------------------------------
  299. //
  300. // macro wrappers for memory allocation - wrapped around global function ptrs
  301. // set by RefRastSetMemif
  302. //
  303. //-----------------------------------------------------------------------------
  304. #define MEMALLOC(_size) ((*g_pfnMemAlloc)(_size))
  305. #define MEMFREE(_ptr) { if (NULL != (_ptr)) { ((*g_pfnMemFree)(_ptr)); } }
  306. #define MEMREALLOC(_ptr,_size) ((*g_pfnMemReAlloc)((_ptr),(_size)))
  307. //////////////////////////////////////////////////////////////////////////////////
  308. // //
  309. // Utility Functions //
  310. // //
  311. //////////////////////////////////////////////////////////////////////////////////
  312. //-----------------------------------------------------------------------------
  313. //
  314. // debug printf support
  315. //
  316. //-----------------------------------------------------------------------------
  317. void RRDebugPrintfL( int iLevel, const char* pszFormat, ... );
  318. void RRDebugPrintf( const char* pszFormat, ... );
  319. #define _DPF_IF 0x0001
  320. #define _DPF_INPUT 0x0002
  321. #define _DPF_SETUP 0x0004
  322. #define _DPF_RAST 0x0008
  323. #define _DPF_TEX 0x0010
  324. #define _DPF_PIX 0x0020
  325. #define _DPF_FRAG 0x0040
  326. #define _DPF_STATS 0x0080
  327. #define _DPF_DRV 0x0100
  328. #define _DPF_TNL 0x0200
  329. #define _DPF_ANY 0xffff
  330. #define _DPF_TEMP 0x8000
  331. #ifdef DBG
  332. #define DPFRR RRDebugPrintfL
  333. #define DPFM( _level, _mask, _message) \
  334. if ((g_iDPFLevel >= (_level)) && (g_uDPFMask & (_DPF_##_mask))) { \
  335. RRDebugPrintf ## _message; \
  336. }
  337. #else
  338. #pragma warning(disable:4002)
  339. #define DPFRR()
  340. #define DPFM( _level, _mask, _message)
  341. #endif
  342. //-----------------------------------------------------------------------------
  343. //
  344. // assert macros and reporting functions
  345. //
  346. //-----------------------------------------------------------------------------
  347. // ASSERT with simple string
  348. #undef _ASSERT
  349. #define _ASSERT( value, string ) \
  350. if ( !(value) ) { \
  351. RRAssertReport( string, __FILE__, __LINE__ ); \
  352. }
  353. // ASSERT with formatted string - note extra parenthesis on report
  354. // usage: _ASSERTf(foo,("foo is %d",foo))
  355. #undef _ASSERTf
  356. #define _ASSERTf(value,report) \
  357. if (!(value)) { \
  358. char __sz__FILE__[] = __FILE__; \
  359. RRAssertReportPrefix(__sz__FILE__,__LINE__); \
  360. RRAssertReportMessage ## report; \
  361. }
  362. // ASSERT with action field
  363. #undef _ASSERTa
  364. #define _ASSERTa(value,string,action) \
  365. if (!(value)) { \
  366. RRAssertReport(string,__FILE__,__LINE__); \
  367. action \
  368. }
  369. // ASSERTf with action field
  370. #undef _ASSERTfa
  371. #define _ASSERTfa(value,report,action) \
  372. if (!(value)) { \
  373. RRAssertReportPrefix(__FILE__,__LINE__); \
  374. RRAssertReportMessage ## report; \
  375. action \
  376. }
  377. extern void RRAssertReport( const char* pszString, const char* pszFile, int iLine );
  378. extern void RRAssertReportPrefix( const char* pszFile, int iLine );
  379. extern void RRAssertReportMessage( const char* pszFormat, ... );
  380. //-----------------------------------------------------------------------------
  381. //
  382. // bit twiddling utilities
  383. //
  384. //-----------------------------------------------------------------------------
  385. extern INT32 CountSetBits( UINT32 uVal, INT32 nBits );
  386. extern INT32 FindFirstSetBit( UINT32 uVal, INT32 nBits );
  387. extern INT32 FindMostSignificantSetBit( UINT32 uVal, INT32 nBits );
  388. extern INT32 FindLastSetBit( UINT32 uVal, INT32 nBits );
  389. // TRUE if integer is a power of 2
  390. inline BOOL IsPowerOf2( INT32 i )
  391. {
  392. if ( i <= 0 ) return 0;
  393. return ( 0x0 == ( i & (i-1) ) );
  394. }
  395. //-----------------------------------------------------------------------------
  396. //
  397. // multiply/add routines & macros for unsigned 8 bit values, signed 16 bit values
  398. //
  399. // These are not currently used, but the Mult8x8Scl is an interesting routine
  400. // for hardware designers to look at. This does a 8x8 multiply combined with
  401. // a 256/255 scale which accurately solves the "0xff * value = value" issue.
  402. // There are refinements on this (involving half-adders) which are not easily
  403. // representable in C. Credits to Steve Gabriel and Jim Blinn.
  404. //
  405. //-----------------------------------------------------------------------------
  406. // straight 8x8 unsigned multiply returning 8 bits, tossing fractional
  407. // bits (no rounding)
  408. inline UINT8 Mult8x8( const UINT8 uA, const UINT8 uB )
  409. {
  410. UINT16 uA16 = (UINT16)uA;
  411. UINT16 uB16 = (UINT16)uB;
  412. UINT16 uRes16 = uA16*uB16;
  413. UINT8 uRes8 = (UINT8)(uRes16>>8);
  414. return uRes8;
  415. }
  416. // 8x8 unsigned multiply with ff*val = val scale adjustment (scale by (256/255))
  417. inline UINT8 Mult8x8Scl( const UINT8 uA, const UINT8 uB )
  418. {
  419. UINT16 uA16 = (UINT16)uA;
  420. UINT16 uB16 = (UINT16)uB;
  421. UINT16 uRes16 = uA16*uB16;
  422. uRes16 += 0x0080;
  423. uRes16 += (uRes16>>8);
  424. UINT8 uRes8 = (UINT8)(uRes16>>8);
  425. return uRes8;
  426. }
  427. // 8x8 saturated addition - result > 0xff returns 0xff
  428. inline UINT8 SatAdd8x8( const UINT8 uA, const UINT8 uB )
  429. {
  430. UINT16 uA16 = (UINT16)uA;
  431. UINT16 uB16 = (UINT16)uB;
  432. UINT16 uRes16 = uA16+uB16;
  433. UINT8 uRes8 = (uRes16 > 0xff) ? (0xff) : ((UINT8)uRes16);
  434. return uRes8;
  435. }
  436. //----------------------------------------------------------------------------
  437. //
  438. // IntLog2
  439. //
  440. // Do a quick, integer log2 for exact powers of 2.
  441. //
  442. //----------------------------------------------------------------------------
  443. inline UINT32 FASTCALL
  444. IntLog2(UINT32 x)
  445. {
  446. UINT32 y = 0;
  447. x >>= 1;
  448. while(x != 0)
  449. {
  450. x >>= 1;
  451. y++;
  452. }
  453. return y;
  454. }
  455. //////////////////////////////////////////////////////////////////////////////
  456. // FVF related macros
  457. //////////////////////////////////////////////////////////////////////////////
  458. #define FVF_TRANSFORMED(dwFVF) ((dwFVF & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW)
  459. #define FVF_TEXCOORD_NUMBER(dwFVF) \
  460. (((dwFVF) & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT)
  461. //////////////////////////////////////////////////////////////////////////////
  462. // State Override Macros
  463. //////////////////////////////////////////////////////////////////////////////
  464. #define IS_OVERRIDE(type) ((DWORD)(type) > D3DSTATE_OVERRIDE_BIAS)
  465. #define GET_OVERRIDE(type) ((DWORD)(type) - D3DSTATE_OVERRIDE_BIAS)
  466. #define STATESET_MASK(set, state) \
  467. (set).bits[((state) - 1) >> RRSTATEOVERRIDE_DWORD_SHIFT]
  468. #define STATESET_BIT(state) (1 << (((state) - 1) & (RRSTATEOVERRIDE_DWORD_BITS - 1)))
  469. #define STATESET_ISSET(set, state) \
  470. STATESET_MASK(set, state) & STATESET_BIT(state)
  471. #define STATESET_SET(set, state) \
  472. STATESET_MASK(set, state) |= STATESET_BIT(state)
  473. #define STATESET_CLEAR(set, state) \
  474. STATESET_MASK(set, state) &= ~STATESET_BIT(state)
  475. #define STATESET_INIT(set) memset(&(set), 0, sizeof(set))
  476. //---------------------------------------------------------------------
  477. // GetFVFVertexSize:
  478. // Computes total vertex size in bytes for given fvf
  479. // including the texture coordinates
  480. //---------------------------------------------------------------------
  481. __inline DWORD
  482. GetFVFVertexSize( UINT64 qwFVF )
  483. {
  484. // Texture formats size 00 01 10 11
  485. static DWORD dwTextureSize[4] = {2*4, 3*4, 4*4, 4};
  486. DWORD dwSize = 3 << 2;
  487. switch( qwFVF & D3DFVF_POSITION_MASK )
  488. {
  489. case D3DFVF_XYZRHW: dwSize += 4; break;
  490. case D3DFVF_XYZB1: dwSize += 1*4; break;
  491. case D3DFVF_XYZB2: dwSize += 2*4; break;
  492. case D3DFVF_XYZB3: dwSize += 3*4; break;
  493. case D3DFVF_XYZB4: dwSize += 4*4; break;
  494. case D3DFVF_XYZB5: dwSize += 5*4; break;
  495. }
  496. if (qwFVF & D3DFVF_NORMAL)
  497. dwSize += 3*4;
  498. if (qwFVF & D3DFVF_RESERVED1)
  499. dwSize += 4;
  500. if (qwFVF & D3DFVF_DIFFUSE)
  501. dwSize += 4;
  502. if (qwFVF & D3DFVF_SPECULAR)
  503. dwSize += 4;
  504. // Texture coordinates
  505. DWORD dwNumTexCoord = (DWORD)(FVF_TEXCOORD_NUMBER(qwFVF));
  506. DWORD dwTextureFormats = (DWORD)qwFVF >> 16;
  507. if (dwTextureFormats == 0)
  508. {
  509. dwSize += dwNumTexCoord * 2 * 4;
  510. }
  511. else
  512. {
  513. for (DWORD i=0; i < dwNumTexCoord; i++)
  514. {
  515. dwSize += dwTextureSize[dwTextureFormats & 3];
  516. dwTextureFormats >>= 2;
  517. }
  518. }
  519. if (qwFVF & D3DFVF_S)
  520. dwSize += 4;
  521. if (qwFVF & D3DFVFP_EYENORMAL)
  522. dwSize += 3*4;
  523. if (qwFVF & D3DFVFP_EYEXYZ)
  524. dwSize += 3*4;
  525. return dwSize;
  526. }
  527. HRESULT
  528. RRFVFCheckAndStride( DWORD dwFVF, DWORD* pdwStride );
  529. ///////////////////////////////////////////////////////////////////////////////
  530. // Matrix and Vector routines
  531. ///////////////////////////////////////////////////////////////////////////////
  532. inline void
  533. ReverseVector(const D3DVECTOR &in, D3DVECTOR &out)
  534. {
  535. out.x = -in.x;
  536. out.y = -in.y;
  537. out.z = -in.z;
  538. }
  539. inline void
  540. AddVector(const D3DVECTOR &v1, const D3DVECTOR &v2, D3DVECTOR &out)
  541. {
  542. out.x = v1.x + v2.x;
  543. out.y = v1.y + v2.y;
  544. out.z = v1.z + v2.z;
  545. }
  546. inline void
  547. SubtractVector(const D3DVECTOR &v1, const D3DVECTOR &v2, D3DVECTOR &out)
  548. {
  549. out.x = v1.x - v2.x;
  550. out.y = v1.y - v2.y;
  551. out.z = v1.z - v2.z;
  552. }
  553. inline void
  554. SetIdentity(D3DMATRIX &m)
  555. {
  556. m._11 = m._22 = m._33 = m._44 = 1.0f;
  557. m._12 = m._13 = m._14 = 0.0f;
  558. m._21 = m._23 = m._24 = 0.0f;
  559. m._31 = m._32 = m._34 = 0.0f;
  560. m._41 = m._42 = m._43 = 0.0f;
  561. }
  562. inline void
  563. SetNull(D3DMATRIX &m)
  564. {
  565. m._11 = m._22 = m._33 = m._44 = 0.0f;
  566. m._12 = m._13 = m._14 = 0.0f;
  567. m._21 = m._23 = m._24 = 0.0f;
  568. m._31 = m._32 = m._34 = 0.0f;
  569. m._41 = m._42 = m._43 = 0.0f;
  570. }
  571. inline void
  572. CopyMatrix(D3DMATRIX &s, D3DMATRIX &d)
  573. {
  574. d._11 = s._11;
  575. d._12 = s._12;
  576. d._13 = s._13;
  577. d._14 = s._14;
  578. d._21 = s._21;
  579. d._22 = s._22;
  580. d._23 = s._23;
  581. d._24 = s._24;
  582. d._31 = s._31;
  583. d._32 = s._32;
  584. d._33 = s._33;
  585. d._34 = s._34;
  586. d._41 = s._41;
  587. d._42 = s._42;
  588. d._43 = s._43;
  589. d._44 = s._44;
  590. }
  591. inline D3DVALUE
  592. SquareMagnitude (const D3DVECTOR& v)
  593. {
  594. return v.x*v.x + v.y*v.y + v.z*v.z;
  595. }
  596. inline D3DVALUE
  597. Magnitude (const D3DVECTOR& v)
  598. {
  599. return (D3DVALUE) sqrt(SquareMagnitude(v));
  600. }
  601. inline D3DVECTOR
  602. Normalize (const D3DVECTOR& v)
  603. {
  604. D3DVECTOR nv = {0.0f, 0.0f, 0.0f};
  605. D3DVALUE mag = Magnitude(v);
  606. nv.x = v.x/mag;
  607. nv.y = v.y/mag;
  608. nv.z = v.z/mag;
  609. return nv;
  610. }
  611. inline void
  612. Normalize (D3DVECTOR& v)
  613. {
  614. D3DVALUE mag = Magnitude(v);
  615. v.x = v.x/mag;
  616. v.y = v.y/mag;
  617. v.z = v.z/mag;
  618. return;
  619. }
  620. inline D3DVECTOR
  621. CrossProduct (const D3DVECTOR& v1, const D3DVECTOR& v2)
  622. {
  623. D3DVECTOR result;
  624. result.x = v1.y*v2.z - v1.z*v2.y;
  625. result.y = v1.z*v2.x - v1.x*v2.z;
  626. result.z = v1.x*v2.y - v1.y*v2.x;
  627. return result;
  628. }
  629. inline D3DVALUE
  630. DotProduct (const D3DVECTOR& v1, const D3DVECTOR& v2)
  631. {
  632. return v1.x*v2.x + v1.y*v2.y + v1.z*v2.z;
  633. }
  634. //---------------------------------------------------------------------
  635. // Multiplies vector (x,y,z,w) by a 4x4 matrix transposed,
  636. // producing a homogeneous vector
  637. //
  638. // res and v should not be the same
  639. //---------------------------------------------------------------------
  640. inline void
  641. XformPlaneBy4x4Transposed(RRVECTOR4 *v, D3DMATRIX *m, RRVECTOR4 *res)
  642. {
  643. res->x = v->x*m->_11 + v->y*m->_12 + v->z*m->_13 + v->w*m->_14;
  644. res->y = v->x*m->_21 + v->y*m->_22 + v->z*m->_23 + v->w*m->_24;
  645. res->z = v->x*m->_31 + v->y*m->_32 + v->z*m->_33 + v->w*m->_34;
  646. res->w = v->x*m->_41 + v->y*m->_42 + v->z*m->_43 + v->w*m->_44;
  647. }
  648. //---------------------------------------------------------------------
  649. // Multiplies vector (x,y,z,w) by 4x4 matrix, producing a homogeneous vector
  650. //
  651. // res and v should not be the same
  652. //---------------------------------------------------------------------
  653. inline void
  654. XformPlaneBy4x4(RRVECTOR4 *v, D3DMATRIX *m, RRVECTOR4 *res)
  655. {
  656. res->x = v->x*m->_11 + v->y*m->_21 + v->z*m->_31 + v->w*m->_41;
  657. res->y = v->x*m->_12 + v->y*m->_22 + v->z*m->_32 + v->w*m->_42;
  658. res->z = v->x*m->_13 + v->y*m->_23 + v->z*m->_33 + v->w*m->_43;
  659. res->w = v->x*m->_14 + v->y*m->_24 + v->z*m->_34 + v->w*m->_44;
  660. }
  661. //---------------------------------------------------------------------
  662. // Multiplies vector (x,y,z,1) by 4x4 matrix, producing a homogeneous vector
  663. //
  664. // res and v should not be the same
  665. //---------------------------------------------------------------------
  666. inline void
  667. XformBy4x4(D3DVECTOR *v, D3DMATRIX *m, RRVECTOR4 *res)
  668. {
  669. res->x = v->x*m->_11 + v->y*m->_21 + v->z*m->_31 + m->_41;
  670. res->y = v->x*m->_12 + v->y*m->_22 + v->z*m->_32 + m->_42;
  671. res->z = v->x*m->_13 + v->y*m->_23 + v->z*m->_33 + m->_43;
  672. res->w = v->x*m->_14 + v->y*m->_24 + v->z*m->_34 + m->_44;
  673. }
  674. //---------------------------------------------------------------------
  675. // Multiplies vector (x,y,z,1) by 4x3 matrix
  676. //
  677. // res and v should not be the same
  678. //---------------------------------------------------------------------
  679. inline void
  680. XformBy4x3(D3DVECTOR *v, D3DMATRIX *m, D3DVECTOR *res)
  681. {
  682. res->x = v->x*m->_11 + v->y*m->_21 + v->z*m->_31 + m->_41;
  683. res->y = v->x*m->_12 + v->y*m->_22 + v->z*m->_32 + m->_42;
  684. res->z = v->x*m->_13 + v->y*m->_23 + v->z*m->_33 + m->_43;
  685. }
  686. //---------------------------------------------------------------------
  687. // Multiplies vector (x,y,z) by 3x3 matrix
  688. //
  689. // res and v should not be the same
  690. //---------------------------------------------------------------------
  691. inline void
  692. Xform3VecBy3x3(D3DVECTOR *v, D3DMATRIX *m, D3DVECTOR *res)
  693. {
  694. res->x = v->x*m->_11 + v->y*m->_21 + v->z*m->_31;
  695. res->y = v->x*m->_12 + v->y*m->_22 + v->z*m->_32;
  696. res->z = v->x*m->_13 + v->y*m->_23 + v->z*m->_33;
  697. }
  698. //---------------------------------------------------------------------
  699. // This function uses Cramer's Rule to calculate the matrix inverse.
  700. // See nt\private\windows\opengl\serever\soft\so_math.c
  701. //
  702. // Returns:
  703. // 0 - if success
  704. // -1 - if input matrix is singular
  705. //---------------------------------------------------------------------
  706. int Inverse4x4(D3DMATRIX *src, D3DMATRIX *inverse);
  707. ////////////////////////////////////////////////////////////////////////
  708. //
  709. // Macros used to access DDRAW surface info.
  710. //
  711. ////////////////////////////////////////////////////////////////////////
  712. #define DDSurf_Width(lpLcl) ( (lpLcl)->lpGbl->wWidth )
  713. #define DDSurf_Pitch(lpLcl) ( (lpLcl)->lpGbl->lPitch )
  714. #define DDSurf_Height(lpLcl) ( (lpLcl)->lpGbl->wHeight )
  715. #define DDSurf_BitDepth(lpLcl) \
  716. ( (lpLcl->dwFlags & DDRAWISURF_HASPIXELFORMAT) ? \
  717. (lpLcl->lpGbl->ddpfSurface.dwRGBBitCount) : \
  718. (lpLcl->lpGbl->lpDD->vmiData.ddpfDisplay.dwRGBBitCount) \
  719. )
  720. #define DDSurf_PixFmt(lpLcl) \
  721. ( ((lpLcl)->dwFlags & DDRAWISURF_HASPIXELFORMAT) ? \
  722. ((lpLcl)->lpGbl->ddpfSurface) : \
  723. ((lpLcl)->lpGbl->lpDD->vmiData.ddpfDisplay) \
  724. )
  725. #define VIDEO_MEMORY(pDDSLcl) \
  726. (!((pDDSLcl)->lpGbl->dwGlobalFlags & DDRAWISURFGBL_SYSMEMREQUESTED))
  727. #define SURFACE_LOCKED(pDDSLcl) \
  728. ((pDDSLcl)->lpGbl->dwUsageCount > 0)
  729. #define SURFACE_MEMORY(surfLcl) \
  730. (LPVOID)((surfLcl)->lpGbl->fpVidMem)
  731. //---------------------------------------------------------------------
  732. // DDraw extern functions
  733. //---------------------------------------------------------------------
  734. extern "C" HRESULT WINAPI
  735. DDInternalLock( LPDDRAWI_DDRAWSURFACE_LCL this_lcl, LPVOID* lpBits );
  736. extern "C" HRESULT WINAPI
  737. DDInternalUnlock( LPDDRAWI_DDRAWSURFACE_LCL this_lcl );
  738. extern "C" HRESULT WINAPI DDGetAttachedSurfaceLcl(
  739. LPDDRAWI_DDRAWSURFACE_LCL this_lcl,
  740. LPDDSCAPS2 lpDDSCaps,
  741. LPDDRAWI_DDRAWSURFACE_LCL *lplpDDAttachedSurfaceLcl);
  742. extern "C" LPDDRAWI_DDRAWSURFACE_LCL WINAPI
  743. GetDDSurfaceLocal( LPDDRAWI_DIRECTDRAW_LCL this_lcl, DWORD handle, BOOL* isnew );
  744. ///////////////////////////////////////////////////////////////////////////////
  745. #endif // _RRUTIL_HPP