0001:
0002:
0003:
0004:
0005:
0006: #define STRICT
0007: #include <Windows.h>
0008: #include <WindowsX.h>
0009: #include <tchar.h>
0010: #include <stdio.h>
0011: #include "D3DUtil.h"
0012: #include "DXUtil.h"
0013: #include "D3DX9.h"
0014:
0015:
0016:
0017:
0018:
0019:
0020:
0021:
0022:
0023: VOID D3DUtil_InitMaterial( D3DMATERIAL9& mtrl, FLOAT r, FLOAT g, FLOAT b,
0024: FLOAT a )
0025: {
0026: ZeroMemory( &mtrl, sizeof(D3DMATERIAL9) );
0027: mtrl.Diffuse.r = mtrl.Ambient.r = r;
0028: mtrl.Diffuse.g = mtrl.Ambient.g = g;
0029: mtrl.Diffuse.b = mtrl.Ambient.b = b;
0030: mtrl.Diffuse.a = mtrl.Ambient.a = a;
0031: }
0032:
0033:
0034:
0035:
0036:
0037:
0038:
0039:
0040:
0041: VOID D3DUtil_InitLight( D3DLIGHT9& light, D3DLIGHTTYPE ltType,
0042: FLOAT x, FLOAT y, FLOAT z )
0043: {
0044: D3DXVECTOR3 vecLightDirUnnormalized(x, y, z);
0045: ZeroMemory( &light, sizeof(D3DLIGHT9) );
0046: light.Type = ltType;
0047: light.Diffuse.r = 1.0f;
0048: light.Diffuse.g = 1.0f;
0049: light.Diffuse.b = 1.0f;
0050: D3DXVec3Normalize( (D3DXVECTOR3*)&light.Direction, &vecLightDirUnnormalized );
0051: light.Position.x = x;
0052: light.Position.y = y;
0053: light.Position.z = z;
0054: light.Range = 1000.0f;
0055: }
0056:
0057:
0058:
0059:
0060:
0061:
0062:
0063:
0064:
0065: HRESULT D3DUtil_CreateTexture( LPDIRECT3DDEVICE9 pd3dDevice, TCHAR* strTexture,
0066: LPDIRECT3DTEXTURE9* ppTexture, D3DFORMAT d3dFormat )
0067: {
0068: HRESULT hr;
0069: TCHAR strPath[MAX_PATH];
0070:
0071:
0072: if( FAILED( hr = DXUtil_FindMediaFileCb( strPath, sizeof(strPath), strTexture ) ) )
0073: return hr;
0074:
0075:
0076: return D3DXCreateTextureFromFileEx( pd3dDevice, strPath,
0077: D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, d3dFormat,
0078: D3DPOOL_MANAGED, D3DX_FILTER_TRIANGLE|D3DX_FILTER_MIRROR,
0079: D3DX_FILTER_TRIANGLE|D3DX_FILTER_MIRROR, 0, NULL, NULL, ppTexture );
0080: }
0081:
0082:
0083:
0084:
0085:
0086:
0087:
0088:
0089: D3DXMATRIX D3DUtil_GetCubeMapViewMatrix( DWORD dwFace )
0090: {
0091: D3DXVECTOR3 vEyePt = D3DXVECTOR3( 0.0f, 0.0f, 0.0f );
0092: D3DXVECTOR3 vLookDir;
0093: D3DXVECTOR3 vUpDir;
0094:
0095: switch( dwFace )
0096: {
0097: case D3DCUBEMAP_FACE_POSITIVE_X:
0098: vLookDir = D3DXVECTOR3( 1.0f, 0.0f, 0.0f );
0099: vUpDir = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );
0100: break;
0101: case D3DCUBEMAP_FACE_NEGATIVE_X:
0102: vLookDir = D3DXVECTOR3(-1.0f, 0.0f, 0.0f );
0103: vUpDir = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );
0104: break;
0105: case D3DCUBEMAP_FACE_POSITIVE_Y:
0106: vLookDir = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );
0107: vUpDir = D3DXVECTOR3( 0.0f, 0.0f,-1.0f );
0108: break;
0109: case D3DCUBEMAP_FACE_NEGATIVE_Y:
0110: vLookDir = D3DXVECTOR3( 0.0f,-1.0f, 0.0f );
0111: vUpDir = D3DXVECTOR3( 0.0f, 0.0f, 1.0f );
0112: break;
0113: case D3DCUBEMAP_FACE_POSITIVE_Z:
0114: vLookDir = D3DXVECTOR3( 0.0f, 0.0f, 1.0f );
0115: vUpDir = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );
0116: break;
0117: case D3DCUBEMAP_FACE_NEGATIVE_Z:
0118: vLookDir = D3DXVECTOR3( 0.0f, 0.0f,-1.0f );
0119: vUpDir = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );
0120: break;
0121: }
0122:
0123:
0124: D3DXMATRIXA16 matView;
0125: D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookDir, &vUpDir );
0126: return matView;
0127: }
0128:
0129:
0130:
0131:
0132:
0133:
0134:
0135:
0136:
0137: D3DXQUATERNION D3DUtil_GetRotationFromCursor( HWND hWnd,
0138: FLOAT fTrackBallRadius )
0139: {
0140: POINT pt;
0141: RECT rc;
0142: GetCursorPos( &pt );
0143: GetClientRect( hWnd, &rc );
0144: ScreenToClient( hWnd, &pt );
0145: FLOAT sx = ( ( ( 2.0f * pt.x ) / (rc.right-rc.left) ) - 1 );
0146: FLOAT sy = ( ( ( 2.0f * pt.y ) / (rc.bottom-rc.top) ) - 1 );
0147: FLOAT sz;
0148:
0149: if( sx == 0.0f && sy == 0.0f )
0150: return D3DXQUATERNION( 0.0f, 0.0f, 0.0f, 1.0f );
0151:
0152: FLOAT d2 = sqrtf( sx*sx + sy*sy );
0153:
0154: if( d2 < fTrackBallRadius * 0.70710678118654752440 )
0155: sz = sqrtf( fTrackBallRadius*fTrackBallRadius - d2*d2 );
0156: else
0157: sz = (fTrackBallRadius*fTrackBallRadius) / (2.0f*d2);
0158:
0159:
0160: D3DXVECTOR3 p1( sx, sy, sz );
0161: D3DXVECTOR3 p2( 0.0f, 0.0f, fTrackBallRadius );
0162:
0163:
0164: D3DXVECTOR3 vAxis;
0165: D3DXVec3Cross( &vAxis, &p1, &p2);
0166:
0167:
0168: D3DXVECTOR3 vecDiff = p2-p1;
0169: FLOAT t = D3DXVec3Length( &vecDiff ) / ( 2.0f*fTrackBallRadius );
0170: if( t > +1.0f) t = +1.0f;
0171: if( t < -1.0f) t = -1.0f;
0172: FLOAT fAngle = 2.0f * asinf( t );
0173:
0174:
0175: D3DXQUATERNION quat;
0176: D3DXQuaternionRotationAxis( &quat, &vAxis, fAngle );
0177: return quat;
0178: }
0179:
0180:
0181:
0182:
0183:
0184:
0185:
0186:
0187: HRESULT D3DUtil_SetDeviceCursor( LPDIRECT3DDEVICE9 pd3dDevice, HCURSOR hCursor,
0188: BOOL bAddWatermark )
0189: {
0190: HRESULT hr = E_FAIL;
0191: ICONINFO iconinfo;
0192: BOOL bBWCursor;
0193: LPDIRECT3DSURFACE9 pCursorSurface = NULL;
0194: HDC hdcColor = NULL;
0195: HDC hdcMask = NULL;
0196: HDC hdcScreen = NULL;
0197: BITMAP bm;
0198: DWORD dwWidth;
0199: DWORD dwHeightSrc;
0200: DWORD dwHeightDest;
0201: COLORREF crColor;
0202: COLORREF crMask;
0203: UINT x;
0204: UINT y;
0205: BITMAPINFO bmi;
0206: COLORREF* pcrArrayColor = NULL;
0207: COLORREF* pcrArrayMask = NULL;
0208: DWORD* pBitmap;
0209: HGDIOBJ hgdiobjOld;
0210:
0211: ZeroMemory( &iconinfo, sizeof(iconinfo) );
0212: if( !GetIconInfo( hCursor, &iconinfo ) )
0213: goto End;
0214:
0215: if (0 == GetObject((HGDIOBJ)iconinfo.hbmMask, sizeof(BITMAP), (LPVOID)&bm))
0216: goto End;
0217: dwWidth = bm.bmWidth;
0218: dwHeightSrc = bm.bmHeight;
0219:
0220: if( iconinfo.hbmColor == NULL )
0221: {
0222: bBWCursor = TRUE;
0223: dwHeightDest = dwHeightSrc / 2;
0224: }
0225: else
0226: {
0227: bBWCursor = FALSE;
0228: dwHeightDest = dwHeightSrc;
0229: }
0230:
0231:
0232: if( FAILED( hr = pd3dDevice->CreateOffscreenPlainSurface( dwWidth, dwHeightDest,
0233: D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &pCursorSurface, NULL ) ) )
0234: {
0235: goto End;
0236: }
0237:
0238: pcrArrayMask = new DWORD[dwWidth * dwHeightSrc];
0239:
0240: ZeroMemory(&bmi, sizeof(bmi));
0241: bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
0242: bmi.bmiHeader.biWidth = dwWidth;
0243: bmi.bmiHeader.biHeight = dwHeightSrc;
0244: bmi.bmiHeader.biPlanes = 1;
0245: bmi.bmiHeader.biBitCount = 32;
0246: bmi.bmiHeader.biCompression = BI_RGB;
0247:
0248: hdcScreen = GetDC( NULL );
0249: hdcMask = CreateCompatibleDC( hdcScreen );
0250: if( hdcMask == NULL )
0251: {
0252: hr = E_FAIL;
0253: goto End;
0254: }
0255: hgdiobjOld = SelectObject(hdcMask, iconinfo.hbmMask);
0256: GetDIBits(hdcMask, iconinfo.hbmMask, 0, dwHeightSrc,
0257: pcrArrayMask, &bmi, DIB_RGB_COLORS);
0258: SelectObject(hdcMask, hgdiobjOld);
0259:
0260: if (!bBWCursor)
0261: {
0262: pcrArrayColor = new DWORD[dwWidth * dwHeightDest];
0263: hdcColor = CreateCompatibleDC( hdcScreen );
0264: if( hdcColor == NULL )
0265: {
0266: hr = E_FAIL;
0267: goto End;
0268: }
0269: SelectObject(hdcColor, iconinfo.hbmColor);
0270: GetDIBits(hdcColor, iconinfo.hbmColor, 0, dwHeightDest,
0271: pcrArrayColor, &bmi, DIB_RGB_COLORS);
0272: }
0273:
0274:
0275: D3DLOCKED_RECT lr;
0276: pCursorSurface->LockRect( &lr, NULL, 0 );
0277: pBitmap = (DWORD*)lr.pBits;
0278: for( y = 0; y < dwHeightDest; y++ )
0279: {
0280: for( x = 0; x < dwWidth; x++ )
0281: {
0282: if (bBWCursor)
0283: {
0284: crColor = pcrArrayMask[dwWidth*(dwHeightDest-1-y) + x];
0285: crMask = pcrArrayMask[dwWidth*(dwHeightSrc-1-y) + x];
0286: }
0287: else
0288: {
0289: crColor = pcrArrayColor[dwWidth*(dwHeightDest-1-y) + x];
0290: crMask = pcrArrayMask[dwWidth*(dwHeightDest-1-y) + x];
0291: }
0292: if (crMask == 0)
0293: pBitmap[dwWidth*y + x] = 0xff000000 | crColor;
0294: else
0295: pBitmap[dwWidth*y + x] = 0x00000000;
0296:
0297:
0298:
0299:
0300:
0301:
0302:
0303: if( bAddWatermark && x < 12 && y < 5 )
0304: {
0305:
0306:
0307:
0308:
0309:
0310:
0311: const WORD wMask[5] = { 0xccc0, 0xa2a0, 0xa4a0, 0xa2a0, 0xccc0 };
0312: if( wMask[y] & (1 << (15 - x)) )
0313: {
0314: pBitmap[dwWidth*y + x] |= 0xff808080;
0315: }
0316: }
0317: }
0318: }
0319: pCursorSurface->UnlockRect();
0320:
0321:
0322: if( FAILED( hr = pd3dDevice->SetCursorProperties( iconinfo.xHotspot,
0323: iconinfo.yHotspot, pCursorSurface ) ) )
0324: {
0325: goto End;
0326: }
0327:
0328: hr = S_OK;
0329:
0330: End:
0331: if( iconinfo.hbmMask != NULL )
0332: DeleteObject( iconinfo.hbmMask );
0333: if( iconinfo.hbmColor != NULL )
0334: DeleteObject( iconinfo.hbmColor );
0335: if( hdcScreen != NULL )
0336: ReleaseDC( NULL, hdcScreen );
0337: if( hdcColor != NULL )
0338: DeleteDC( hdcColor );
0339: if( hdcMask != NULL )
0340: DeleteDC( hdcMask );
0341: SAFE_DELETE_ARRAY( pcrArrayColor );
0342: SAFE_DELETE_ARRAY( pcrArrayMask );
0343: SAFE_RELEASE( pCursorSurface );
0344: return hr;
0345: }
0346:
0347:
0348:
0349:
0350:
0351:
0352:
0353: TCHAR* D3DUtil_D3DFormatToString( D3DFORMAT format, bool bWithPrefix )
0354: {
0355: TCHAR* pstr = NULL;
0356: switch( format )
0357: {
0358: case D3DFMT_UNKNOWN: pstr = TEXT("D3DFMT_UNKNOWN"); break;
0359: case D3DFMT_R8G8B8: pstr = TEXT("D3DFMT_R8G8B8"); break;
0360: case D3DFMT_A8R8G8B8: pstr = TEXT("D3DFMT_A8R8G8B8"); break;
0361: case D3DFMT_X8R8G8B8: pstr = TEXT("D3DFMT_X8R8G8B8"); break;
0362: case D3DFMT_R5G6B5: pstr = TEXT("D3DFMT_R5G6B5"); break;
0363: case D3DFMT_X1R5G5B5: pstr = TEXT("D3DFMT_X1R5G5B5"); break;
0364: case D3DFMT_A1R5G5B5: pstr = TEXT("D3DFMT_A1R5G5B5"); break;
0365: case D3DFMT_A4R4G4B4: pstr = TEXT("D3DFMT_A4R4G4B4"); break;
0366: case D3DFMT_R3G3B2: pstr = TEXT("D3DFMT_R3G3B2"); break;
0367: case D3DFMT_A8: pstr = TEXT("D3DFMT_A8"); break;
0368: case D3DFMT_A8R3G3B2: pstr = TEXT("D3DFMT_A8R3G3B2"); break;
0369: case D3DFMT_X4R4G4B4: pstr = TEXT("D3DFMT_X4R4G4B4"); break;
0370: case D3DFMT_A2B10G10R10: pstr = TEXT("D3DFMT_A2B10G10R10"); break;
0371: case D3DFMT_A8B8G8R8: pstr = TEXT("D3DFMT_A8B8G8R8"); break;
0372: case D3DFMT_X8B8G8R8: pstr = TEXT("D3DFMT_X8B8G8R8"); break;
0373: case D3DFMT_G16R16: pstr = TEXT("D3DFMT_G16R16"); break;
0374: case D3DFMT_A2R10G10B10: pstr = TEXT("D3DFMT_A2R10G10B10"); break;
0375: case D3DFMT_A16B16G16R16: pstr = TEXT("D3DFMT_A16B16G16R16"); break;
0376: case D3DFMT_A8P8: pstr = TEXT("D3DFMT_A8P8"); break;
0377: case D3DFMT_P8: pstr = TEXT("D3DFMT_P8"); break;
0378: case D3DFMT_L8: pstr = TEXT("D3DFMT_L8"); break;
0379: case D3DFMT_A8L8: pstr = TEXT("D3DFMT_A8L8"); break;
0380: case D3DFMT_A4L4: pstr = TEXT("D3DFMT_A4L4"); break;
0381: case D3DFMT_V8U8: pstr = TEXT("D3DFMT_V8U8"); break;
0382: case D3DFMT_L6V5U5: pstr = TEXT("D3DFMT_L6V5U5"); break;
0383: case D3DFMT_X8L8V8U8: pstr = TEXT("D3DFMT_X8L8V8U8"); break;
0384: case D3DFMT_Q8W8V8U8: pstr = TEXT("D3DFMT_Q8W8V8U8"); break;
0385: case D3DFMT_V16U16: pstr = TEXT("D3DFMT_V16U16"); break;
0386: case D3DFMT_A2W10V10U10: pstr = TEXT("D3DFMT_A2W10V10U10"); break;
0387: case D3DFMT_UYVY: pstr = TEXT("D3DFMT_UYVY"); break;
0388: case D3DFMT_YUY2: pstr = TEXT("D3DFMT_YUY2"); break;
0389: case D3DFMT_DXT1: pstr = TEXT("D3DFMT_DXT1"); break;
0390: case D3DFMT_DXT2: pstr = TEXT("D3DFMT_DXT2"); break;
0391: case D3DFMT_DXT3: pstr = TEXT("D3DFMT_DXT3"); break;
0392: case D3DFMT_DXT4: pstr = TEXT("D3DFMT_DXT4"); break;
0393: case D3DFMT_DXT5: pstr = TEXT("D3DFMT_DXT5"); break;
0394: case D3DFMT_D16_LOCKABLE: pstr = TEXT("D3DFMT_D16_LOCKABLE"); break;
0395: case D3DFMT_D32: pstr = TEXT("D3DFMT_D32"); break;
0396: case D3DFMT_D15S1: pstr = TEXT("D3DFMT_D15S1"); break;
0397: case D3DFMT_D24S8: pstr = TEXT("D3DFMT_D24S8"); break;
0398: case D3DFMT_D24X8: pstr = TEXT("D3DFMT_D24X8"); break;
0399: case D3DFMT_D24X4S4: pstr = TEXT("D3DFMT_D24X4S4"); break;
0400: case D3DFMT_D16: pstr = TEXT("D3DFMT_D16"); break;
0401: case D3DFMT_L16: pstr = TEXT("D3DFMT_L16"); break;
0402: case D3DFMT_VERTEXDATA: pstr = TEXT("D3DFMT_VERTEXDATA"); break;
0403: case D3DFMT_INDEX16: pstr = TEXT("D3DFMT_INDEX16"); break;
0404: case D3DFMT_INDEX32: pstr = TEXT("D3DFMT_INDEX32"); break;
0405: case D3DFMT_Q16W16V16U16: pstr = TEXT("D3DFMT_Q16W16V16U16"); break;
0406: case D3DFMT_MULTI2_ARGB8: pstr = TEXT("D3DFMT_MULTI2_ARGB8"); break;
0407: case D3DFMT_R16F: pstr = TEXT("D3DFMT_R16F"); break;
0408: case D3DFMT_G16R16F: pstr = TEXT("D3DFMT_G16R16F"); break;
0409: case D3DFMT_A16B16G16R16F: pstr = TEXT("D3DFMT_A16B16G16R16F"); break;
0410: case D3DFMT_R32F: pstr = TEXT("D3DFMT_R32F"); break;
0411: case D3DFMT_G32R32F: pstr = TEXT("D3DFMT_G32R32F"); break;
0412: case D3DFMT_A32B32G32R32F: pstr = TEXT("D3DFMT_A32B32G32R32F"); break;
0413: case D3DFMT_CxV8U8: pstr = TEXT("D3DFMT_CxV8U8"); break;
0414: default: pstr = TEXT("Unknown format"); break;
0415: }
0416: if( bWithPrefix || _tcsstr( pstr, TEXT("D3DFMT_") )== NULL )
0417: return pstr;
0418: else
0419: return pstr + lstrlen( TEXT("D3DFMT_") );
0420: }
0421:
0422:
0423:
0424:
0425:
0426:
0427:
0428:
0429: inline D3DXQUATERNION* WINAPI D3DXQuaternionUnitAxisToUnitAxis2
0430: ( D3DXQUATERNION *pOut, const D3DXVECTOR3 *pvFrom, const D3DXVECTOR3 *pvTo)
0431: {
0432: D3DXVECTOR3 vAxis;
0433: D3DXVec3Cross(&vAxis, pvFrom, pvTo);
0434: pOut->x = vAxis.x;
0435: pOut->y = vAxis.y;
0436: pOut->z = vAxis.z;
0437: pOut->w = D3DXVec3Dot( pvFrom, pvTo );
0438: return pOut;
0439: }
0440:
0441:
0442:
0443:
0444:
0445:
0446:
0447:
0448:
0449:
0450: inline D3DXQUATERNION* WINAPI D3DXQuaternionAxisToAxis
0451: ( D3DXQUATERNION *pOut, const D3DXVECTOR3 *pvFrom, const D3DXVECTOR3 *pvTo)
0452: {
0453: D3DXVECTOR3 vA, vB;
0454: D3DXVec3Normalize(&vA, pvFrom);
0455: D3DXVec3Normalize(&vB, pvTo);
0456: D3DXVECTOR3 vHalf(vA + vB);
0457: D3DXVec3Normalize(&vHalf, &vHalf);
0458: return D3DXQuaternionUnitAxisToUnitAxis2(pOut, &vA, &vHalf);
0459: }
0460:
0461:
0462:
0463:
0464:
0465:
0466:
0467:
0468: CD3DArcBall::CD3DArcBall()
0469: {
0470: Init();
0471: }
0472:
0473:
0474:
0475:
0476:
0477:
0478:
0479:
0480: void CD3DArcBall::Init()
0481: {
0482: D3DXQuaternionIdentity( &m_qDown );
0483: D3DXQuaternionIdentity( &m_qNow );
0484: D3DXMatrixIdentity( &m_matRotation );
0485: D3DXMatrixIdentity( &m_matRotationDelta );
0486: D3DXMatrixIdentity( &m_matTranslation );
0487: D3DXMatrixIdentity( &m_matTranslationDelta );
0488: m_bDrag = FALSE;
0489: m_fRadiusTranslation = 1.0f;
0490: m_bRightHanded = FALSE;
0491: }
0492:
0493:
0494:
0495:
0496:
0497:
0498:
0499:
0500: VOID CD3DArcBall::SetWindow( int iWidth, int iHeight, float fRadius )
0501: {
0502:
0503: m_iWidth = iWidth;
0504: m_iHeight = iHeight;
0505: m_fRadius = fRadius;
0506: }
0507:
0508:
0509:
0510:
0511:
0512:
0513:
0514:
0515: D3DXVECTOR3 CD3DArcBall::ScreenToVector( int sx, int sy )
0516: {
0517:
0518: FLOAT x = -(sx - m_iWidth/2) / (m_fRadius*m_iWidth/2);
0519: FLOAT y = (sy - m_iHeight/2) / (m_fRadius*m_iHeight/2);
0520:
0521: if( m_bRightHanded )
0522: {
0523: x = -x;
0524: y = -y;
0525: }
0526:
0527: FLOAT z = 0.0f;
0528: FLOAT mag = x*x + y*y;
0529:
0530: if( mag > 1.0f )
0531: {
0532: FLOAT scale = 1.0f/sqrtf(mag);
0533: x *= scale;
0534: y *= scale;
0535: }
0536: else
0537: z = sqrtf( 1.0f - mag );
0538:
0539:
0540: return D3DXVECTOR3( x, y, z );
0541: }
0542:
0543:
0544:
0545:
0546:
0547:
0548:
0549:
0550: VOID CD3DArcBall::SetRadius( FLOAT fRadius )
0551: {
0552: m_fRadiusTranslation = fRadius;
0553: }
0554:
0555:
0556:
0557:
0558:
0559:
0560:
0561:
0562: LRESULT CD3DArcBall::HandleMouseMessages( HWND hWnd, UINT uMsg, WPARAM wParam,
0563: LPARAM lParam )
0564: {
0565: UNREFERENCED_PARAMETER( hWnd );
0566:
0567: static int iCurMouseX;
0568: static int iCurMouseY;
0569: static D3DXVECTOR3 s_vDown;
0570:
0571:
0572: int iMouseX = GET_X_LPARAM(lParam);
0573: int iMouseY = GET_Y_LPARAM(lParam);
0574:
0575: switch( uMsg )
0576: {
0577: case WM_RBUTTONDOWN:
0578: case WM_MBUTTONDOWN:
0579:
0580: iCurMouseX = iMouseX;
0581: iCurMouseY = iMouseY;
0582: return TRUE;
0583:
0584: case WM_LBUTTONDOWN:
0585:
0586: m_bDrag = TRUE;
0587: s_vDown = ScreenToVector( iMouseX, iMouseY );
0588: m_qDown = m_qNow;
0589: return TRUE;
0590:
0591: case WM_LBUTTONUP:
0592:
0593: m_bDrag = FALSE;
0594: return TRUE;
0595:
0596: case WM_MOUSEMOVE:
0597:
0598: if( MK_LBUTTON&wParam )
0599: {
0600: if( m_bDrag )
0601: {
0602:
0603: D3DXVECTOR3 vCur = ScreenToVector( iMouseX, iMouseY );
0604: D3DXQUATERNION qAxisToAxis;
0605: D3DXQuaternionAxisToAxis(&qAxisToAxis, &s_vDown, &vCur);
0606: m_qNow = m_qDown;
0607: m_qNow *= qAxisToAxis;
0608: D3DXMatrixRotationQuaternion(&m_matRotationDelta, &qAxisToAxis);
0609: }
0610: else
0611: D3DXMatrixIdentity(&m_matRotationDelta);
0612: D3DXMatrixRotationQuaternion(&m_matRotation, &m_qNow);
0613: m_bDrag = TRUE;
0614: }
0615: else if( (MK_RBUTTON&wParam) || (MK_MBUTTON&wParam) )
0616: {
0617:
0618: FLOAT fDeltaX = ( iCurMouseX-iMouseX ) * m_fRadiusTranslation / m_iWidth;
0619: FLOAT fDeltaY = ( iCurMouseY-iMouseY ) * m_fRadiusTranslation / m_iHeight;
0620:
0621: if( wParam & MK_RBUTTON )
0622: {
0623: D3DXMatrixTranslation( &m_matTranslationDelta, -2*fDeltaX, 2*fDeltaY, 0.0f );
0624: D3DXMatrixMultiply( &m_matTranslation, &m_matTranslation, &m_matTranslationDelta );
0625: }
0626: else
0627: {
0628: D3DXMatrixTranslation( &m_matTranslationDelta, 0.0f, 0.0f, 5*fDeltaY );
0629: D3DXMatrixMultiply( &m_matTranslation, &m_matTranslation, &m_matTranslationDelta );
0630: }
0631:
0632:
0633: iCurMouseX = iMouseX;
0634: iCurMouseY = iMouseY;
0635: }
0636: return TRUE;
0637: }
0638:
0639: return FALSE;
0640: }
0641:
0642:
0643:
0644:
0645:
0646:
0647:
0648:
0649: CD3DCamera::CD3DCamera()
0650: {
0651:
0652: D3DXVECTOR3 vEyePt(0.0f,0.0f,0.0f);
0653: D3DXVECTOR3 vLookatPt(0.0f,0.0f,1.0f);
0654: D3DXVECTOR3 vUpVec(0.0f,1.0f,0.0f);
0655: SetViewParams( vEyePt, vLookatPt, vUpVec );
0656:
0657:
0658: SetProjParams( D3DX_PI/4, 1.0f, 1.0f, 1000.0f );
0659: }
0660:
0661:
0662:
0663:
0664:
0665:
0666:
0667:
0668: VOID CD3DCamera::SetViewParams( D3DXVECTOR3 &vEyePt, D3DXVECTOR3& vLookatPt,
0669: D3DXVECTOR3& vUpVec )
0670: {
0671:
0672: m_vEyePt = vEyePt;
0673: m_vLookatPt = vLookatPt;
0674: m_vUpVec = vUpVec;
0675: D3DXVECTOR3 vDir = m_vLookatPt - m_vEyePt;
0676: D3DXVec3Normalize( &m_vView, &vDir );
0677: D3DXVec3Cross( &m_vCross, &m_vView, &m_vUpVec );
0678:
0679: D3DXMatrixLookAtLH( &m_matView, &m_vEyePt, &m_vLookatPt, &m_vUpVec );
0680: D3DXMatrixInverse( &m_matBillboard, NULL, &m_matView );
0681: m_matBillboard._41 = 0.0f;
0682: m_matBillboard._42 = 0.0f;
0683: m_matBillboard._43 = 0.0f;
0684: }
0685:
0686:
0687:
0688:
0689:
0690:
0691:
0692:
0693: VOID CD3DCamera::SetProjParams( FLOAT fFOV, FLOAT fAspect, FLOAT fNearPlane,
0694: FLOAT fFarPlane )
0695: {
0696:
0697: m_fFOV = fFOV;
0698: m_fAspect = fAspect;
0699: m_fNearPlane = fNearPlane;
0700: m_fFarPlane = fFarPlane;
0701:
0702: D3DXMatrixPerspectiveFovLH( &m_matProj, fFOV, fAspect, fNearPlane, fFarPlane );
0703: }
0704: