home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Game Programming for Teens / VBGPFT.cdr / DirectX8 / dx8a_sdk.exe / samples / multimedia / common / src / d3dutil.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-11-04  |  20.4 KB  |  629 lines

  1. //-----------------------------------------------------------------------------
  2. // File: D3DUtil.cpp
  3. //
  4. // Desc: Shortcut macros and functions for using DX objects
  5. //
  6. //
  7. // Copyright (c) 1997-2000 Microsoft Corporation. All rights reserved
  8. //-----------------------------------------------------------------------------
  9. #define STRICT
  10. #include <tchar.h>
  11. #include <stdio.h>
  12. #include "D3DUtil.h"
  13. #include "DXUtil.h"
  14. #include "D3DX8.h"
  15.  
  16.  
  17.  
  18.  
  19. //-----------------------------------------------------------------------------
  20. // Name: D3DUtil_InitMaterial()
  21. // Desc: Initializes a D3DMATERIAL8 structure, setting the diffuse and ambient
  22. //       colors. It does not set emissive or specular colors.
  23. //-----------------------------------------------------------------------------
  24. VOID D3DUtil_InitMaterial( D3DMATERIAL8& mtrl, FLOAT r, FLOAT g, FLOAT b,
  25.                            FLOAT a )
  26. {
  27.     ZeroMemory( &mtrl, sizeof(D3DMATERIAL8) );
  28.     mtrl.Diffuse.r = mtrl.Ambient.r = r;
  29.     mtrl.Diffuse.g = mtrl.Ambient.g = g;
  30.     mtrl.Diffuse.b = mtrl.Ambient.b = b;
  31.     mtrl.Diffuse.a = mtrl.Ambient.a = a;
  32. }
  33.  
  34.  
  35.  
  36.  
  37. //-----------------------------------------------------------------------------
  38. // Name: D3DUtil_InitLight()
  39. // Desc: Initializes a D3DLIGHT structure, setting the light position. The
  40. //       diffuse color is set to white; specular and ambient are left as black.
  41. //-----------------------------------------------------------------------------
  42. VOID D3DUtil_InitLight( D3DLIGHT8& light, D3DLIGHTTYPE ltType,
  43.                         FLOAT x, FLOAT y, FLOAT z )
  44. {
  45.     ZeroMemory( &light, sizeof(D3DLIGHT8) );
  46.     light.Type        = ltType;
  47.     light.Diffuse.r   = 1.0f;
  48.     light.Diffuse.g   = 1.0f;
  49.     light.Diffuse.b   = 1.0f;
  50.     D3DXVec3Normalize( (D3DXVECTOR3*)&light.Direction, &D3DXVECTOR3(x, y, z) );
  51.     light.Position.x   = x;
  52.     light.Position.y   = y;
  53.     light.Position.z   = z;
  54.     light.Range        = 1000.0f;
  55. }
  56.  
  57.  
  58.  
  59.  
  60. //-----------------------------------------------------------------------------
  61. // Name: D3DUtil_CreateTexture()
  62. // Desc: Helper function to create a texture. It checks the root path first,
  63. //       then tries the DXSDK media path (as specified in the system registry).
  64. //-----------------------------------------------------------------------------
  65. HRESULT D3DUtil_CreateTexture( LPDIRECT3DDEVICE8 pd3dDevice, TCHAR* strTexture,
  66.                                LPDIRECT3DTEXTURE8* ppTexture, D3DFORMAT d3dFormat )
  67. {
  68.     // Get the path to the texture
  69.     TCHAR strPath[MAX_PATH];
  70.     DXUtil_FindMediaFile( strPath, strTexture );
  71.  
  72.     // Create the texture using D3DX
  73.     return D3DXCreateTextureFromFileEx( pd3dDevice, strPath, 
  74.                 D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, d3dFormat, 
  75.                 D3DPOOL_MANAGED, D3DX_FILTER_TRIANGLE|D3DX_FILTER_MIRROR, 
  76.                 D3DX_FILTER_TRIANGLE|D3DX_FILTER_MIRROR, 0, NULL, NULL, ppTexture );
  77. }
  78.  
  79.  
  80.  
  81.  
  82. //-----------------------------------------------------------------------------
  83. // Name: D3DUtil_SetColorKey()
  84. // Desc: Changes all texels matching the colorkey to transparent, black.
  85. //-----------------------------------------------------------------------------
  86. HRESULT D3DUtil_SetColorKey( LPDIRECT3DTEXTURE8 pTexture, DWORD dwColorKey )
  87. {
  88.     // Get colorkey's red, green, and blue components
  89.     DWORD r = ((dwColorKey&0x00ff0000)>>16);
  90.     DWORD g = ((dwColorKey&0x0000ff00)>>8);
  91.     DWORD b = ((dwColorKey&0x000000ff)>>0);
  92.  
  93.     // Put the colorkey in the texture's native format
  94.     D3DSURFACE_DESC d3dsd;
  95.     pTexture->GetLevelDesc( 0, &d3dsd );
  96.     if( d3dsd.Format == D3DFMT_A4R4G4B4 )
  97.         dwColorKey = 0xf000 + ((r>>4)<<8) + ((g>>4)<<4) + (b>>4);
  98.     else if( d3dsd.Format == D3DFMT_A1R5G5B5 )
  99.         dwColorKey = 0x8000 + ((r>>3)<<10) + ((g>>3)<<5) + (b>>3);
  100.     else if( d3dsd.Format != D3DFMT_A8R8G8B8 )
  101.         return E_FAIL;
  102.  
  103.     // Lock the texture
  104.     D3DLOCKED_RECT  d3dlr;
  105.     if( FAILED( pTexture->LockRect( 0, &d3dlr, 0, 0 ) ) )
  106.         return E_FAIL;
  107.  
  108.     // Scan through each pixel, looking for the colorkey to replace
  109.     for( DWORD y=0; y<d3dsd.Height; y++ )
  110.     {
  111.         for( DWORD x=0; x<d3dsd.Width; x++ )
  112.         {
  113.             if( d3dsd.Format==D3DFMT_A8R8G8B8 )
  114.             {
  115.                 // Handle 32-bit formats
  116.                 if( ((DWORD*)d3dlr.pBits)[d3dsd.Width*y+x] == dwColorKey )
  117.                     ((DWORD*)d3dlr.pBits)[d3dsd.Width*y+x] = 0x00000000;
  118.             }
  119.             else
  120.             {
  121.                 // Handle 16-bit formats
  122.                 if( ((WORD*)d3dlr.pBits)[d3dsd.Width*y+x] == dwColorKey )
  123.                     ((WORD*)d3dlr.pBits)[d3dsd.Width*y+x] = 0x0000;
  124.             }
  125.         }
  126.     }
  127.  
  128.     // Unlock the texture and return OK.
  129.     pTexture->UnlockRect(0);
  130.     return S_OK;
  131. }
  132.  
  133.  
  134.  
  135.  
  136. //-----------------------------------------------------------------------------
  137. // Name: D3DUtil_CreateVertexShader()
  138. // Desc: Assembles and creates a file-based vertex shader
  139. //-----------------------------------------------------------------------------
  140. HRESULT D3DUtil_CreateVertexShader( LPDIRECT3DDEVICE8 pd3dDevice, 
  141.                                     TCHAR* strFilename, DWORD* pdwVertexDecl,
  142.                                     DWORD* pdwVertexShader )
  143. {
  144.     LPD3DXBUFFER pCode;
  145.     TCHAR        strPath[MAX_PATH];
  146.     HRESULT      hr;
  147.  
  148.     // Get the path to the vertex shader file
  149.     DXUtil_FindMediaFile( strPath, strFilename );
  150.  
  151.     // Assemble the vertex shader file
  152.     if( FAILED( hr = D3DXAssembleShaderFromFile( strPath, 0, NULL, &pCode, NULL ) ) )
  153.         return hr;
  154.  
  155.     // Create the vertex shader
  156.     hr = pd3dDevice->CreateVertexShader( pdwVertexDecl, 
  157.                                          (DWORD*)pCode->GetBufferPointer(),
  158.                                          pdwVertexShader, 0 );
  159.     pCode->Release();
  160.     return hr;
  161. }
  162.  
  163.  
  164.  
  165.  
  166. //-----------------------------------------------------------------------------
  167. // Name: D3DUtil_GetCubeMapViewMatrix()
  168. // Desc: Returns a view matrix for rendering to a face of a cubemap.
  169. //-----------------------------------------------------------------------------
  170. D3DXMATRIX D3DUtil_GetCubeMapViewMatrix( DWORD dwFace )
  171. {
  172.     D3DXVECTOR3 vEyePt   = D3DXVECTOR3( 0.0f, 0.0f, 0.0f );
  173.     D3DXVECTOR3 vLookDir;
  174.     D3DXVECTOR3 vUpDir;
  175.  
  176.     switch( dwFace )
  177.     {
  178.         case D3DCUBEMAP_FACE_POSITIVE_X:
  179.             vLookDir = D3DXVECTOR3( 1.0f, 0.0f, 0.0f );
  180.             vUpDir   = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );
  181.             break;
  182.         case D3DCUBEMAP_FACE_NEGATIVE_X:
  183.             vLookDir = D3DXVECTOR3(-1.0f, 0.0f, 0.0f );
  184.             vUpDir   = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );
  185.             break;
  186.         case D3DCUBEMAP_FACE_POSITIVE_Y:
  187.             vLookDir = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );
  188.             vUpDir   = D3DXVECTOR3( 0.0f, 0.0f,-1.0f );
  189.             break;
  190.         case D3DCUBEMAP_FACE_NEGATIVE_Y:
  191.             vLookDir = D3DXVECTOR3( 0.0f,-1.0f, 0.0f );
  192.             vUpDir   = D3DXVECTOR3( 0.0f, 0.0f, 1.0f );
  193.             break;
  194.         case D3DCUBEMAP_FACE_POSITIVE_Z:
  195.             vLookDir = D3DXVECTOR3( 0.0f, 0.0f, 1.0f );
  196.             vUpDir   = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );
  197.             break;
  198.         case D3DCUBEMAP_FACE_NEGATIVE_Z:
  199.             vLookDir = D3DXVECTOR3( 0.0f, 0.0f,-1.0f );
  200.             vUpDir   = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );
  201.             break;
  202.     }
  203.  
  204.     // Set the view transform for this cubemap surface
  205.     D3DXMATRIX matView;
  206.     D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookDir, &vUpDir );
  207.     return matView;
  208. }
  209.  
  210.  
  211.  
  212.  
  213. //-----------------------------------------------------------------------------
  214. // Name: D3DUtil_GetRotationFromCursor()
  215. // Desc: Returns a quaternion for the rotation implied by the window's cursor
  216. //       position.
  217. //-----------------------------------------------------------------------------
  218. D3DXQUATERNION D3DUtil_GetRotationFromCursor( HWND hWnd,
  219.                                               FLOAT fTrackBallRadius )
  220. {
  221.     POINT pt;
  222.     RECT  rc;
  223.     GetCursorPos( &pt );
  224.     GetClientRect( hWnd, &rc );
  225.     ScreenToClient( hWnd, &pt );
  226.     FLOAT sx = ( ( ( 2.0f * pt.x ) / (rc.right-rc.left) ) - 1 );
  227.     FLOAT sy = ( ( ( 2.0f * pt.y ) / (rc.bottom-rc.top) ) - 1 );
  228.     FLOAT sz;
  229.  
  230.     if( sx == 0.0f && sy == 0.0f )
  231.         return D3DXQUATERNION( 0.0f, 0.0f, 0.0f, 1.0f );
  232.  
  233.     FLOAT d1 = 0.0f;
  234.     FLOAT d2 = sqrtf( sx*sx + sy*sy );
  235.  
  236.     if( d2 < fTrackBallRadius * 0.70710678118654752440 ) // Inside sphere
  237.         sz = sqrtf( fTrackBallRadius*fTrackBallRadius - d2*d2 );
  238.     else                                                 // On hyperbola
  239.         sz = (fTrackBallRadius*fTrackBallRadius) / (2.0f*d2);
  240.  
  241.     // Get two points on trackball's sphere
  242.     D3DXVECTOR3 p1( sx, sy, sz );
  243.     D3DXVECTOR3 p2( 0.0f, 0.0f, fTrackBallRadius );
  244.  
  245.     // Get axis of rotation, which is cross product of p1 and p2
  246.     D3DXVECTOR3 vAxis;
  247.     D3DXVec3Cross( &vAxis, &p1, &p2);
  248.  
  249.     // Calculate angle for the rotation about that axis
  250.     FLOAT t = D3DXVec3Length( &(p2-p1) ) / ( 2.0f*fTrackBallRadius );
  251.     if( t > +1.0f) t = +1.0f;
  252.     if( t < -1.0f) t = -1.0f;
  253.     FLOAT fAngle = 2.0f * asinf( t );
  254.  
  255.     // Convert axis to quaternion
  256.     D3DXQUATERNION quat;
  257.     D3DXQuaternionRotationAxis( &quat, &vAxis, fAngle );
  258.     return quat;
  259. }
  260.  
  261.  
  262.  
  263.  
  264. //-----------------------------------------------------------------------------
  265. // Name: D3DUtil_SetDeviceCursor
  266. // Desc: Gives the D3D device a cursor with image and hotspot from hCursor.
  267. //-----------------------------------------------------------------------------
  268. HRESULT D3DUtil_SetDeviceCursor( LPDIRECT3DDEVICE8 pd3dDevice, HCURSOR hCursor )
  269. {
  270.     HRESULT hr = E_FAIL;
  271.     ICONINFO iconinfo;
  272.     BOOL bBWCursor;
  273.     LPDIRECT3DSURFACE8 pCursorBitmap = NULL;
  274.     HDC hdcColor = NULL;
  275.     HDC hdcMask = NULL;
  276.     HDC hdcScreen = NULL;
  277.     BITMAP bm;
  278.     DWORD dwWidth;
  279.     DWORD dwHeightSrc;
  280.     DWORD dwHeightDest;
  281.     COLORREF crColor;
  282.     COLORREF crMask;
  283.     UINT x;
  284.     UINT y;
  285.     BITMAPINFO bmi;
  286.     COLORREF* pcrArrayColor = NULL;
  287.     COLORREF* pcrArrayMask = NULL;
  288.     DWORD* pBitmap;
  289.     HGDIOBJ hgdiobjOld;
  290.  
  291.     ZeroMemory( &iconinfo, sizeof(iconinfo) );
  292.     if( !GetIconInfo( hCursor, &iconinfo ) )
  293.         goto End;
  294.  
  295.     if (0 == GetObject((HGDIOBJ)iconinfo.hbmMask, sizeof(BITMAP), (LPVOID)&bm))
  296.         goto End;
  297.     dwWidth = bm.bmWidth;
  298.     dwHeightSrc = bm.bmHeight;
  299.  
  300.     if( iconinfo.hbmColor == NULL )
  301.     {
  302.         bBWCursor = TRUE;
  303.         dwHeightDest = dwHeightSrc / 2;
  304.     }
  305.     else 
  306.     {
  307.         bBWCursor = FALSE;
  308.         dwHeightDest = dwHeightSrc;
  309.     }
  310.  
  311.     // Create a surface for the fullscreen cursor
  312.     if( FAILED( hr = pd3dDevice->CreateImageSurface( dwWidth, dwHeightDest, 
  313.         D3DFMT_A8R8G8B8, &pCursorBitmap ) ) )
  314.     {
  315.         goto End;
  316.     }
  317.  
  318.     pcrArrayMask = new DWORD[dwWidth * dwHeightSrc];
  319.  
  320.     ZeroMemory(&bmi, sizeof(bmi));
  321.     bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
  322.     bmi.bmiHeader.biWidth = dwWidth;
  323.     bmi.bmiHeader.biHeight = dwHeightSrc;
  324.     bmi.bmiHeader.biPlanes = 1;
  325.     bmi.bmiHeader.biBitCount = 32;
  326.     bmi.bmiHeader.biCompression = BI_RGB;
  327.  
  328.     hdcScreen = GetDC( NULL );
  329.     hdcMask = CreateCompatibleDC( hdcScreen );
  330.     if( hdcMask == NULL )
  331.     {
  332.         hr = E_FAIL;
  333.         goto End;
  334.     }
  335.     hgdiobjOld = SelectObject(hdcMask, iconinfo.hbmMask);
  336.     GetDIBits(hdcMask, iconinfo.hbmMask, 0, dwHeightSrc, 
  337.         pcrArrayMask, &bmi, DIB_RGB_COLORS);
  338.     SelectObject(hdcMask, hgdiobjOld);
  339.  
  340.     if (!bBWCursor)
  341.     {
  342.         pcrArrayColor = new DWORD[dwWidth * dwHeightDest];
  343.         hdcColor = CreateCompatibleDC( GetDC( NULL ) );
  344.         if( hdcColor == NULL )
  345.         {
  346.             hr = E_FAIL;
  347.             goto End;
  348.         }
  349.         SelectObject(hdcColor, iconinfo.hbmColor);
  350.         GetDIBits(hdcColor, iconinfo.hbmColor, 0, dwHeightDest, 
  351.             pcrArrayColor, &bmi, DIB_RGB_COLORS);
  352.     }
  353.  
  354.     // Transfer cursor image into the surface
  355.     D3DLOCKED_RECT lr;
  356.     pCursorBitmap->LockRect( &lr, NULL, 0 );
  357.     pBitmap = (DWORD*)lr.pBits;
  358.     for( y = 0; y < dwHeightDest; y++ )
  359.     {
  360.         for( x = 0; x < dwWidth; x++ )
  361.         {
  362.             if (bBWCursor)
  363.             {
  364.                 crColor = pcrArrayMask[dwWidth*(dwHeightDest-1-y) + x];
  365.                 crMask = pcrArrayMask[dwWidth*(dwHeightSrc-1-y) + x];
  366.             }
  367.             else
  368.             {
  369.                 crColor = pcrArrayColor[dwWidth*(dwHeightDest-1-y) + x];
  370.                 crMask = pcrArrayMask[dwWidth*(dwHeightDest-1-y) + x];
  371.             }
  372.             if (crMask == 0)
  373.                 pBitmap[dwWidth*y + x] = 0xff000000 | crColor;
  374.             else
  375.                 pBitmap[dwWidth*y + x] = 0x00000000;
  376.         }
  377.     }
  378.     pCursorBitmap->UnlockRect();
  379.  
  380.     // Set the device cursor
  381.     if( FAILED( hr = pd3dDevice->SetCursorProperties( iconinfo.xHotspot, 
  382.         iconinfo.yHotspot, pCursorBitmap ) ) )
  383.     {
  384.         goto End;
  385.     }
  386.  
  387.     hr = S_OK;
  388.  
  389. End:
  390.     if( iconinfo.hbmMask != NULL )
  391.         DeleteObject( iconinfo.hbmMask );
  392.     if( iconinfo.hbmColor != NULL )
  393.         DeleteObject( iconinfo.hbmColor );
  394.     if( hdcScreen != NULL )
  395.         ReleaseDC( NULL, hdcScreen );
  396.     if( hdcColor != NULL )
  397.         DeleteDC( hdcColor );
  398.     if( hdcMask != NULL )
  399.         DeleteDC( hdcMask );
  400.     SAFE_DELETE_ARRAY( pcrArrayColor );
  401.     SAFE_DELETE_ARRAY( pcrArrayMask );
  402.     SAFE_RELEASE( pCursorBitmap );
  403.     return hr;
  404. }
  405.  
  406.  
  407.  
  408.  
  409. //-----------------------------------------------------------------------------
  410. // Name:
  411. // Desc:
  412. //-----------------------------------------------------------------------------
  413. CD3DArcBall::CD3DArcBall()
  414. {
  415.     D3DXQuaternionIdentity( &m_qDown );
  416.     D3DXQuaternionIdentity( &m_qNow );
  417.     D3DXMatrixIdentity( &m_matRotation );
  418.     D3DXMatrixIdentity( &m_matRotationDelta );
  419.     D3DXMatrixIdentity( &m_matTranslation );
  420.     D3DXMatrixIdentity( &m_matTranslationDelta );
  421.     m_bDrag = FALSE;
  422. }
  423.  
  424.  
  425.  
  426.  
  427. //-----------------------------------------------------------------------------
  428. // Name:
  429. // Desc:
  430. //-----------------------------------------------------------------------------
  431. VOID CD3DArcBall::SetWindow( int iWidth, int iHeight, float fRadius )
  432. {
  433.     // Set ArcBall info
  434.     m_iWidth  = iWidth;
  435.     m_iHeight = iHeight;
  436.     m_fRadius = fRadius;
  437. }
  438.  
  439.  
  440.  
  441.  
  442. //-----------------------------------------------------------------------------
  443. // Name:
  444. // Desc:
  445. //-----------------------------------------------------------------------------
  446. D3DXVECTOR3 CD3DArcBall::ScreenToVector( int sx, int sy )
  447. {
  448.     // Scale to screen
  449.     FLOAT x   =  (sx - m_iWidth/2)  / (m_fRadius*m_iWidth/2);
  450.     FLOAT y   = -(sy - m_iHeight/2) / (m_fRadius*m_iHeight/2);
  451.     FLOAT z   = 0.0f;
  452.     FLOAT mag = x*x + y*y;
  453.  
  454.     if( mag > 1.0f )
  455.     {
  456.         FLOAT scale = 1.0f/sqrtf(mag);
  457.         x *= scale;
  458.         y *= scale;
  459.     }
  460.     else
  461.         z = sqrtf( 1.0f - mag );
  462.  
  463.     // Return vector
  464.     return D3DXVECTOR3( x, y, z );
  465. }
  466.  
  467.  
  468.  
  469.  
  470. //-----------------------------------------------------------------------------
  471. // Name:
  472. // Desc:
  473. //-----------------------------------------------------------------------------
  474. VOID CD3DArcBall::SetRadius( FLOAT fRadius )
  475. {
  476.     m_fRadius2 = fRadius;
  477. }
  478.  
  479.  
  480.  
  481.  
  482. //-----------------------------------------------------------------------------
  483. // Name:
  484. // Desc:
  485. //-----------------------------------------------------------------------------
  486. LRESULT CD3DArcBall::HandleMouseMessages( HWND hWnd, UINT uMsg, WPARAM wParam,
  487.                                           LPARAM lParam )
  488. {
  489.     static int         iCurMouseX;      // Saved mouse position
  490.     static int         iCurMouseY;
  491.     static D3DXVECTOR3 m_vDown;         // Button down quaternion
  492.     static D3DXVECTOR3 m_vCur;          // Current quaternion
  493.  
  494.     // Current mouse position
  495.     int iMouseX = LOWORD(lParam);
  496.     int iMouseY = HIWORD(lParam);
  497.  
  498.     switch( uMsg )
  499.     {
  500.         case WM_RBUTTONDOWN:
  501.         case WM_MBUTTONDOWN:
  502.             // Store off the position of the cursor when the button is pressed
  503.             iCurMouseX = iMouseX;
  504.             iCurMouseY = iMouseY;
  505.             return TRUE;
  506.  
  507.         case WM_LBUTTONDOWN:
  508.             // Start drag mode
  509.             m_bDrag = TRUE;
  510.             m_vDown = ScreenToVector( iMouseX, iMouseY );
  511.             return TRUE;
  512.  
  513.         case WM_LBUTTONUP:
  514.             // End drag mode
  515.             m_bDrag = FALSE;
  516.             m_qDown = m_qNow;
  517.             return TRUE;
  518.  
  519.         case WM_MOUSEMOVE:
  520.             // Drag object
  521.             if( MK_LBUTTON&wParam )
  522.             {
  523.                 if( m_bDrag )
  524.                 {
  525.                     D3DXVECTOR3 vPart;
  526.                     D3DXVECTOR3 vCur = ScreenToVector( iMouseX, iMouseY );
  527.                     D3DXVec3Cross( &vPart, &m_vDown, &vCur );
  528.                     m_qNow = m_qDown * D3DXQUATERNION( vPart.x, vPart.y, vPart.z,
  529.                                                        D3DXVec3Dot( &m_vDown, &vCur ) );
  530.                 }
  531.  
  532.                 D3DXQUATERNION qConj;
  533.                 D3DXQuaternionConjugate( &qConj, &m_qNow );
  534.  
  535.                 D3DXMatrixRotationQuaternion( &m_matRotationDelta, &qConj );
  536.                 D3DXMatrixTranspose( &m_matRotationDelta, &m_matRotationDelta );
  537.                 D3DXMatrixMultiply( &m_matRotation, &m_matRotation, &m_matRotationDelta );
  538.  
  539.                 D3DXQuaternionIdentity( &m_qDown );
  540.                 D3DXQuaternionIdentity( &m_qNow );
  541.                 m_vDown = ScreenToVector( iMouseX, iMouseY );
  542.                 m_bDrag = TRUE;
  543.             }
  544.             else if( (MK_RBUTTON&wParam) || (MK_MBUTTON&wParam) )
  545.             {
  546.                 // Normalize based on size of window and bounding sphere radius
  547.                 FLOAT fDeltaX = ( iCurMouseX-iMouseX ) * m_fRadius2 / m_iWidth;
  548.                 FLOAT fDeltaY = ( iCurMouseY-iMouseY ) * m_fRadius2 / m_iHeight;
  549.  
  550.                 if( wParam & MK_RBUTTON )
  551.                 {
  552.                     D3DXMatrixTranslation( &m_matTranslationDelta, -2*fDeltaX, 2*fDeltaY, 0.0f );
  553.                     D3DXMatrixMultiply( &m_matTranslation, &m_matTranslation, &m_matTranslationDelta );
  554.                 }
  555.                 else  // wParam & MK_MBUTTON
  556.                 {
  557.                     D3DXMatrixTranslation( &m_matTranslationDelta, 0.0f, 0.0f, 5*fDeltaY );
  558.                     D3DXMatrixMultiply( &m_matTranslation, &m_matTranslation, &m_matTranslationDelta );
  559.                 }
  560.  
  561.                 // Store mouse coordinate
  562.                 iCurMouseX = iMouseX;
  563.                 iCurMouseY = iMouseY;
  564.             }
  565.             return TRUE;
  566.     }
  567.  
  568.     return FALSE;
  569. }
  570.  
  571.  
  572.  
  573. //-----------------------------------------------------------------------------
  574. // Name:
  575. // Desc:
  576. //-----------------------------------------------------------------------------
  577. CD3DCamera::CD3DCamera()
  578. {
  579.     // Set attributes for the view matrix
  580.     SetViewParams( D3DXVECTOR3(0.0f,0.0f,0.0f), D3DXVECTOR3(0.0f,0.0f,1.0f),
  581.                    D3DXVECTOR3(0.0f,1.0f,0.0f) );
  582.  
  583.     // Set attributes for the projection matrix
  584.     SetProjParams( D3DX_PI/4, 1.0f, 1.0f, 1000.0f );
  585. }
  586.  
  587.  
  588.  
  589.  
  590. //-----------------------------------------------------------------------------
  591. // Name:
  592. // Desc:
  593. //-----------------------------------------------------------------------------
  594. VOID CD3DCamera::SetViewParams( D3DXVECTOR3 &vEyePt, D3DXVECTOR3& vLookatPt,
  595.                                 D3DXVECTOR3& vUpVec )
  596. {
  597.     // Set attributes for the view matrix
  598.     m_vEyePt    = vEyePt;
  599.     m_vLookatPt = vLookatPt;
  600.     m_vUpVec    = vUpVec;
  601.     D3DXVec3Normalize( &m_vView, &(m_vLookatPt - m_vEyePt) );
  602.     D3DXVec3Cross( &m_vCross, &m_vView, &m_vUpVec );
  603.  
  604.     D3DXMatrixLookAtLH( &m_matView, &m_vEyePt, &m_vLookatPt, &m_vUpVec );
  605.     D3DXMatrixInverse( &m_matBillboard, NULL, &m_matView );
  606.     m_matBillboard._41 = 0.0f;
  607.     m_matBillboard._42 = 0.0f;
  608.     m_matBillboard._43 = 0.0f;
  609. }
  610.  
  611.  
  612.  
  613.  
  614. //-----------------------------------------------------------------------------
  615. // Name:
  616. // Desc:
  617. //-----------------------------------------------------------------------------
  618. VOID CD3DCamera::SetProjParams( FLOAT fFOV, FLOAT fAspect, FLOAT fNearPlane,
  619.                                 FLOAT fFarPlane )
  620. {
  621.     // Set attributes for the projection matrix
  622.     m_fFOV        = fFOV;
  623.     m_fAspect     = fAspect;
  624.     m_fNearPlane  = fNearPlane;
  625.     m_fFarPlane   = fFarPlane;
  626.  
  627.     D3DXMatrixPerspectiveFovLH( &m_matProj, fFOV, fAspect, fNearPlane, fFarPlane );
  628. }
  629.