Advertisement
Guest User

Untitled

a guest
May 24th, 2013
104
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 15.89 KB | None | 0 0
  1. //-----------------------------------------------------------------------------
  2. // Name: dx9u_cgfx_volumetric_lines.cpp
  3. // Author: Adel Amro (adel_w_amro@hotmail.com)
  4. // Last Modified: May 24, 2013 by belfegor
  5. // Description: This sample demonstrates a technique for efficiently drawing
  6. // what is often called volume lines. These are quads oriented
  7. // and textured in such a way to be rendered as though they were
  8. // thick lines. This sample is based on the OpenGL sample from
  9. // Nvidia titled CG Volume Lines. It should work on low end
  10. // cards.
  11. //
  12. // Control Keys: Click and drag to spin the bunch of lines.
  13. // The + and - keys to control line thickness.
  14. // Page Down (PgDn) to cycle through available textures.
  15. // Arrow keys: Move the bunch of lines.
  16. //-----------------------------------------------------------------------------
  17.  
  18.  
  19. # define STRICT
  20. # define WIN32_LEAN_AND_MEAN
  21. #define D3D_DEBUG_INFO 1
  22.  
  23. # include <windows.h>
  24. # include <d3dx9.h>
  25.  
  26. #include <vector>
  27. #include <limits>
  28.  
  29. #ifdef min
  30. #undef min
  31. #endif
  32.  
  33. #ifdef max
  34. #undef max
  35. #endif
  36.  
  37.  
  38. // Instruct the linker to use these libraries.
  39. # pragma comment (lib, "d3d9.lib" )
  40. # pragma comment (lib, "d3dx9d.lib" )
  41.  
  42.  
  43.  
  44. # define ARRAY_SIZE( x ) ( (sizeof((x))/sizeof((x)[0])) )
  45.  
  46. inline FLOAT frand01() { return (FLOAT)rand()/RAND_MAX; }
  47. inline FLOAT frand( float fMin, float fMax ) { return fMin + (fMax - fMin) * ((float)rand()/RAND_MAX); }
  48. inline FLOAT frand() { return (float)rand()/RAND_MAX + rand(); }
  49.  
  50. // Globals
  51.  
  52. const std::size_t maxLinesCnt = 5;
  53. const std::size_t vertsPerLine = 4;
  54. const std::size_t triPerLine = 2;
  55. const std::size_t numVerts = maxLinesCnt * vertsPerLine;
  56.  
  57. struct Line
  58. {
  59. D3DXVECTOR3 pt0;
  60. D3DXVECTOR3 pt1;
  61. };
  62.  
  63. std::vector<Line> vLines;
  64.  
  65.  
  66. // Array of texture file names.
  67. const TCHAR* g_aFileNames[] = {
  68. TEXT( "1d_INNER1.png" ),
  69. TEXT( "1d_INNER2.png" ),
  70. TEXT( "1d_DEBUG.png" ),
  71. TEXT( "1d_DEBUG2.png" ),
  72. TEXT( "1d_glow1.png" )
  73. };
  74.  
  75.  
  76. HWND g_hWnd = NULL;
  77. LPDIRECT3D9 g_pD3D = NULL;
  78. LPDIRECT3DDEVICE9 g_pD3DDevice = NULL;
  79. LPDIRECT3DTEXTURE9 g_pTexture = NULL;
  80. LPD3DXEFFECT g_pEffect = NULL;
  81. D3DXVECTOR3 g_aLines[ maxLinesCnt ];
  82.  
  83.  
  84. INT g_iCurrentTexture = 0;
  85. FLOAT g_fThickness = 1.f;
  86.  
  87.  
  88. FLOAT g_fSpinX = 0.f;
  89. FLOAT g_fSpinY = 0.f;
  90. FLOAT g_fTX = 0.f;
  91. FLOAT g_fTY = 0.f;
  92. FLOAT g_fTZ = 14.f;
  93.  
  94.  
  95.  
  96. D3DXMATRIX g_mProjection;
  97.  
  98.  
  99.  
  100. // The vertex structure we'll be using for line drawing. Each line is defined as two vertices,
  101. // and the vertex shader will create a quad from these two vertices. However, since the vertex
  102. // shader can only process one vertex at a time, we need to store information in each vertex
  103. // about the other vertex (the other end of the line).
  104. struct TVertex
  105. {
  106. D3DXVECTOR3 pos;
  107. D3DXVECTOR3 otherPos;
  108. D3DXVECTOR4 texOffset;
  109. D3DXVECTOR3 thickness;
  110. //static const DWORD FVF = D3DFVF_XYZ | D3DFVF_NORMAL |
  111. // D3DFVF_TEX2 | // D3DFVF_TEX2 specifies we have two sets of texture coordinates.
  112. // D3DFVF_TEXCOORDSIZE4(0) | // This specifies that the first (0th) tex coord set has size 4 floats.
  113. // D3DFVF_TEXCOORDSIZE3(1); // Specifies that second tex coord set has size 2 floats.
  114. };
  115.  
  116. D3DVERTEXELEMENT9 vertexElements[] =
  117. {
  118. {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
  119. {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
  120. {0, 24, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
  121. {0, 40, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
  122. D3DDECL_END()
  123. };
  124.  
  125. LPDIRECT3DVERTEXDECLARATION9 vDeclaration = nullptr;
  126. LPDIRECT3DVERTEXBUFFER9 vBuffer = nullptr;
  127. LPDIRECT3DINDEXBUFFER9 iBuffer = nullptr;
  128.  
  129. // Prototypes
  130. INT WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, INT );
  131. LRESULT CALLBACK WindowProc( HWND, UINT, WPARAM, LPARAM );
  132. HRESULT Init();
  133. VOID ShutDown();
  134. VOID Render();
  135.  
  136.  
  137.  
  138.  
  139. // Application's entry point.
  140. INT WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, INT nShowCmd )
  141. {
  142. WNDCLASSEX winClass;
  143. MSG uMsg;
  144.  
  145. memset(&uMsg,0,sizeof(uMsg));
  146.  
  147. winClass.lpszClassName = TEXT("WC_DX9_VOLUMELINES");
  148. winClass.cbSize = sizeof(WNDCLASSEX);
  149. winClass.style = CS_HREDRAW | CS_VREDRAW;
  150. winClass.lpfnWndProc = WindowProc;
  151. winClass.hInstance = hInstance;
  152. winClass.hIcon = NULL;//LoadIcon(hInstance, (LPCTSTR)IDI_DIRECTX_ICON);
  153. winClass.hIconSm = NULL;//LoadIcon(hInstance, (LPCTSTR)IDI_DIRECTX_ICON);
  154. winClass.hCursor = LoadCursor(NULL, IDC_ARROW);
  155. winClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
  156. winClass.lpszMenuName = NULL;
  157. winClass.cbClsExtra = 0;
  158. winClass.cbWndExtra = 0;
  159.  
  160. if( !RegisterClassEx(&winClass) )
  161. return E_FAIL;
  162.  
  163. RECT rWindow = { 0, 0, 1280, 720 };
  164. AdjustWindowRect( &rWindow, WS_OVERLAPPEDWINDOW, FALSE );
  165.  
  166. g_hWnd = CreateWindowEx( NULL, winClass.lpszClassName,
  167. TEXT("Direct3D (DX9) - Volume Lines"),
  168. WS_OVERLAPPEDWINDOW | WS_VISIBLE,
  169. 0, 0, rWindow.right - rWindow.left,
  170. rWindow.bottom - rWindow.top,
  171. NULL, NULL, hInstance, NULL );
  172.  
  173. if( g_hWnd == NULL )
  174. return E_FAIL;
  175.  
  176. ShowWindow( g_hWnd, nShowCmd );
  177. UpdateWindow( g_hWnd );
  178.  
  179. if( FAILED( Init() ) )
  180. {
  181. MessageBox( g_hWnd, TEXT( "Direct3D initialization failure!" ), TEXT("ERROR!"), MB_OK | MB_ICONSTOP );
  182. return 1;
  183. }
  184.  
  185. while( uMsg.message != WM_QUIT )
  186. {
  187. if( PeekMessage( &uMsg, NULL, 0, 0, PM_REMOVE ) )
  188. {
  189. TranslateMessage( &uMsg );
  190. DispatchMessage( &uMsg );
  191. }
  192. else
  193. Render();
  194. }
  195.  
  196. ShutDown();
  197.  
  198. UnregisterClass( winClass.lpszClassName, winClass.hInstance );
  199.  
  200. return (INT)uMsg.wParam;
  201. }
  202.  
  203. // Initialize the application.
  204. HRESULT Init()
  205. {
  206. HRESULT hr;
  207.  
  208. g_pD3D = Direct3DCreate9( D3D_SDK_VERSION );
  209.  
  210. if( !g_pD3D ) return E_FAIL;
  211.  
  212. D3DDISPLAYMODE d3ddm;
  213.  
  214. g_pD3D->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &d3ddm );
  215.  
  216. D3DPRESENT_PARAMETERS d3dpp;
  217. ZeroMemory( &d3dpp, sizeof(d3dpp) );
  218.  
  219. d3dpp.Windowed = TRUE;
  220. d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
  221. d3dpp.BackBufferFormat = d3ddm.Format;
  222. d3dpp.EnableAutoDepthStencil = TRUE;
  223. d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
  224. d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE; // No need to burn the CPU.
  225. d3dpp.hDeviceWindow = g_hWnd;
  226.  
  227. hr = g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, g_hWnd,
  228. D3DCREATE_HARDWARE_VERTEXPROCESSING,
  229. &d3dpp, &g_pD3DDevice );
  230.  
  231. if( FAILED( hr ) )
  232. return hr;
  233.  
  234. // Load the texture.
  235. hr = D3DXCreateTextureFromFile( g_pD3DDevice, g_aFileNames[0], &g_pTexture );
  236. if( FAILED( hr ) )
  237. return hr;
  238.  
  239. // Load the effect from file.
  240. LPD3DXBUFFER pErrors = NULL;
  241. hr = D3DXCreateEffectFromFile( g_pD3DDevice, TEXT("VolumeLines.fx"), NULL, NULL,
  242. 0, NULL, &g_pEffect, &pErrors );
  243. if( FAILED( hr ) )
  244. {
  245. if( pErrors )
  246. {
  247. MessageBoxA( g_hWnd, (LPCSTR)pErrors->GetBufferPointer(), "Effect error", MB_OK | MB_ICONSTOP );
  248. pErrors->Release();
  249. }
  250. return hr;
  251. }
  252.  
  253. g_pEffect->SetTexture( "lineTexture", g_pTexture );
  254. //g_pEffect->SetTexture( "texture1", g_pTexture );
  255.  
  256.  
  257. // Set up some device states.
  258. D3DXMatrixPerspectiveFovLH( &g_mProjection, 45.f,
  259. (float)d3dpp.BackBufferWidth / (float)d3dpp.BackBufferHeight,
  260. 0.1f, 100.f );
  261.  
  262. g_pD3DDevice->SetTransform( D3DTS_PROJECTION, &g_mProjection );
  263. g_pD3DDevice->SetRenderState( D3DRS_LIGHTING, FALSE );
  264. g_pD3DDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
  265.  
  266. hr = g_pD3DDevice->CreateVertexDeclaration(vertexElements, &vDeclaration);
  267. if(FAILED(hr))
  268. {
  269. MessageBox(0, "CreateVertexDeclaration() failed!", 0, MB_OK);
  270. return E_FAIL;
  271. }
  272.  
  273. D3DPOOL pool = D3DPOOL_DEFAULT;
  274. DWORD usage = D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC;
  275. UINT len = sizeof(TVertex) * numVerts;
  276. hr = g_pD3DDevice->CreateVertexBuffer(len, usage, 0, pool, &vBuffer, nullptr);
  277. if(FAILED(hr))
  278. {
  279. MessageBox(0, "CreateVertexBuffer() failed!", 0, MB_OK);
  280. return E_FAIL;
  281. }
  282.  
  283. D3DFORMAT indFormat = (std::numeric_limits<WORD>::max() < numVerts) ? D3DFMT_INDEX32 : D3DFMT_INDEX16;
  284. std::size_t indBytes = (std::numeric_limits<WORD>::max() < numVerts) ? sizeof(DWORD) : sizeof(WORD);
  285. std::size_t numIndices = maxLinesCnt * triPerLine * 3;
  286. len = indBytes * numIndices;
  287. hr = g_pD3DDevice->CreateIndexBuffer(len, usage, indFormat, pool, &iBuffer, nullptr);
  288. if(FAILED(hr))
  289. {
  290. MessageBox(0, "CreateIndexBuffer() failed!", 0, MB_OK);
  291. return E_FAIL;
  292. }
  293.  
  294. WORD* pIndices = 0;
  295. iBuffer->Lock(0, 0, (LPVOID*)&pIndices, D3DLOCK_DISCARD);
  296. WORD j = 0;
  297. for(WORD i = 0; i < numIndices; i += 6)
  298. {
  299. pIndices[0+i] = 0+j;
  300. pIndices[1+i] = 2+j;
  301. pIndices[2+i] = 1+j;
  302. pIndices[3+i] = 2+j;
  303. pIndices[4+i] = 3+j;
  304. pIndices[5+i] = 1+j;
  305. j += 4;
  306. }
  307. iBuffer->Unlock();
  308.  
  309. // Now create a random list of lines (pairs of vertices) that we will render
  310. srand( GetTickCount() );
  311. //for( UINT i=0; i<ARRAY_SIZE(g_aLines); i++ )
  312. for(std::size_t i = 0; i < maxLinesCnt; ++i)
  313. {
  314. //g_aLines[i].x = frand(-1, 1) * 5.f;
  315. //g_aLines[i].y = frand(-1, 1) * 5.f;
  316. //g_aLines[i].z = frand(-1, 1) * 5.f;
  317. Line l;
  318. l.pt0 = D3DXVECTOR3(frand(-1, 1) * 5.f, frand(-1, 1) * 5.f, frand(-1, 1) * 5.f);
  319. l.pt1 = D3DXVECTOR3(frand(-1, 1) * 5.f, frand(-1, 1) * 5.f, frand(-1, 1) * 5.f);
  320. vLines.push_back(l);
  321. }
  322.  
  323. return S_OK;
  324. }
  325.  
  326.  
  327. // Free all resources.
  328. VOID ShutDown()
  329. {
  330. if(vBuffer) vBuffer->Release();
  331. if(iBuffer) iBuffer->Release();
  332. if(vDeclaration) vDeclaration->Release();
  333. if( g_pTexture ) g_pTexture->Release();
  334. if( g_pEffect ) g_pEffect->Release();
  335. if( g_pD3DDevice ) g_pD3DDevice->Release();
  336. if( g_pD3D ) g_pD3D->Release();
  337. }
  338.  
  339.  
  340. /*VOID RenderLine( D3DXVECTOR3& v0, D3DXVECTOR3& v1 )
  341. {
  342. TVertex vrts[4];
  343. vrts[0].pos = v0; vrts[0].otherPos = v1;
  344. vrts[1].pos = v1; vrts[1].otherPos = v0;
  345. vrts[2].pos = v0; vrts[2].otherPos = v1;
  346. vrts[3].pos = v1; vrts[3].otherPos = v0;
  347.  
  348. vrts[0].thickness = D3DXVECTOR3( -g_fThickness, 0.f, g_fThickness * 0.5f );
  349. vrts[1].thickness = D3DXVECTOR3( g_fThickness, 0.f, g_fThickness * 0.5f );
  350. vrts[2].thickness = D3DXVECTOR3( g_fThickness, 0.f, g_fThickness * 0.5f );
  351. vrts[3].thickness = D3DXVECTOR3( -g_fThickness, 0.f, g_fThickness * 0.5f );
  352.  
  353. vrts[0].texOffset = D3DXVECTOR4( g_fThickness, g_fThickness, 0.f, 0.f );
  354. vrts[1].texOffset = D3DXVECTOR4( g_fThickness, g_fThickness, 0.25f, 0.f );
  355. vrts[2].texOffset = D3DXVECTOR4( g_fThickness, g_fThickness, 0.f, 0.25f );
  356. vrts[3].texOffset = D3DXVECTOR4( g_fThickness, g_fThickness, 0.25f, 0.25f );
  357.  
  358. g_pD3DDevice->DrawPrimitiveUP( D3DPT_TRIANGLESTRIP, 2, vrts, sizeof( TVertex ) );
  359. }*/
  360.  
  361. VOID RenderLines()
  362. {
  363. TVertex* vrts;
  364. vBuffer->Lock(0, 0, (LPVOID*)&vrts, D3DLOCK_DISCARD);
  365. std::size_t numTriDraw = 0u;
  366. std::size_t numVertDraw = 0u;
  367. for(std::size_t i = 0; i < maxLinesCnt; ++i)
  368. {
  369. if( i > maxLinesCnt)
  370. {
  371. vBuffer->Unlock();
  372. g_pD3DDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0,0, numVertDraw, 0, numTriDraw);
  373. vBuffer->Lock(0, 0, (LPVOID*)&vrts, D3DLOCK_DISCARD);
  374. numTriDraw = 0u;
  375. }
  376.  
  377. numTriDraw += triPerLine;
  378. numVertDraw += 4;
  379.  
  380. const D3DXVECTOR3& v0 = vLines[i].pt0;
  381. const D3DXVECTOR3& v1 = vLines[i].pt1;
  382.  
  383. vrts[i*4 + 0].pos = v0; vrts[i*4 + 0].otherPos = v1;
  384. vrts[i*4 + 1].pos = v1; vrts[i*4 + 1].otherPos = v0;
  385. vrts[i*4 + 2].pos = v0; vrts[i*4 + 2].otherPos = v1;
  386. vrts[i*4 + 3].pos = v1; vrts[i*4 + 3].otherPos = v0;
  387.  
  388. vrts[i*4 + 0].thickness = D3DXVECTOR3( -g_fThickness, 0.f, g_fThickness * 0.5f );
  389. vrts[i*4 + 1].thickness = D3DXVECTOR3( g_fThickness, 0.f, g_fThickness * 0.5f );
  390. vrts[i*4 + 2].thickness = D3DXVECTOR3( g_fThickness, 0.f, g_fThickness * 0.5f );
  391. vrts[i*4 + 3].thickness = D3DXVECTOR3( -g_fThickness, 0.f, g_fThickness * 0.5f );
  392.  
  393. vrts[i*4 + 0].texOffset = D3DXVECTOR4( g_fThickness, g_fThickness, 0.f, 0.f );
  394. vrts[i*4 + 1].texOffset = D3DXVECTOR4( g_fThickness, g_fThickness, 0.25f, 0.f );
  395. vrts[i*4 + 2].texOffset = D3DXVECTOR4( g_fThickness, g_fThickness, 0.f, 0.25f );
  396. vrts[i*4 + 3].texOffset = D3DXVECTOR4( g_fThickness, g_fThickness, 0.25f, 0.25f );
  397. }
  398. vBuffer->Unlock();
  399.  
  400. if(numTriDraw > 0u)
  401. {
  402. g_pD3DDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0,0, numVertDraw, 0, numTriDraw);
  403. }
  404. }
  405.  
  406.  
  407. VOID Render()
  408. {
  409.  
  410. g_pD3DDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,70), 1.f, 0 );
  411. if( SUCCEEDED( g_pD3DDevice->BeginScene() ) )
  412. {
  413. D3DXMATRIX mWorld;
  414. D3DXMATRIX mWorldProjection;
  415. D3DXMATRIX mTranslation;
  416. D3DXMATRIX mRotation;
  417.  
  418. D3DXMatrixRotationYawPitchRoll( &mRotation, D3DXToRadian( g_fSpinX ),
  419. D3DXToRadian( g_fSpinY ), 0.f );
  420. D3DXMatrixTranslation( &mTranslation, g_fTX, g_fTY, g_fTZ );//0.f, 0.f, 14.f );
  421. mWorld = mRotation * mTranslation;
  422. mWorldProjection = mWorld * g_mProjection;
  423.  
  424. // We will not be using a viewing transformation, so the view matrix will be identity.
  425. g_pEffect->SetMatrix( "mWV", &mWorld );
  426. g_pEffect->SetMatrix( "mWVP", &mWorldProjection );
  427.  
  428. g_pD3DDevice->SetVertexDeclaration(vDeclaration);
  429. g_pD3DDevice->SetIndices(iBuffer);
  430. g_pD3DDevice->SetStreamSource(0, vBuffer, 0, sizeof(TVertex));
  431.  
  432.  
  433. UINT passes = 0;
  434. if( SUCCEEDED( g_pEffect->Begin( &passes, 0 ) ) )
  435. {
  436. g_pEffect->BeginPass( 0 );
  437.  
  438. RenderLines();
  439.  
  440. //g_pD3DDevice->SetFVF( TVertex::FVF );
  441. //for( UINT i=0; i < ARRAY_SIZE( g_aLines ) / 2; i++ )
  442. // RenderLine( g_aLines[i*2], g_aLines[i*2 + 1] );
  443. g_pEffect->EndPass();
  444. g_pEffect->End();
  445. }
  446.  
  447. g_pD3DDevice->EndScene();
  448. }
  449. g_pD3DDevice->Present( NULL, NULL, NULL, NULL );
  450. }
  451.  
  452. // The message procedure for the main window.
  453. LRESULT CALLBACK WindowProc( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam )
  454. {
  455. static POINT ptLastCursorPos;
  456. static POINT ptCurrentCursorPos;
  457. static BOOL bMousing = FALSE;
  458.  
  459. switch( Msg )
  460. {
  461. case WM_CLOSE:
  462. PostQuitMessage( 0 );
  463. break;
  464.  
  465. case WM_KEYDOWN:
  466. if( wParam == VK_ESCAPE )
  467. PostQuitMessage( 0 );
  468. else if( wParam == VK_NEXT )
  469. {
  470. // Cycle textures.
  471. g_iCurrentTexture = (g_iCurrentTexture+1)%ARRAY_SIZE(g_aFileNames);
  472. g_pTexture->Release();
  473. HRESULT hr = D3DXCreateTextureFromFile( g_pD3DDevice, g_aFileNames[ g_iCurrentTexture ],
  474. &g_pTexture );
  475. if( SUCCEEDED( hr ) )
  476. {
  477. g_pEffect->SetTexture( "lineTexture", g_pTexture );
  478. //g_pEffect->SetTexture( "texture1", g_pTexture );
  479. }
  480. else
  481. {
  482. MessageBox( g_hWnd, TEXT( "Couldn't open texture file!" ), TEXT("ERROR"), MB_OK | MB_ICONSTOP );
  483. PostQuitMessage( 0 );
  484. }
  485. }
  486. else if( wParam == VK_ADD )
  487. g_fThickness += 0.03f;
  488. else if( wParam == VK_SUBTRACT )
  489. g_fThickness -= 0.03f;
  490. else if( wParam == VK_LEFT )
  491. g_fTX += 0.5f;
  492. else if( wParam == VK_RIGHT )
  493. g_fTX -= 0.5f;
  494. else if( wParam == VK_UP )
  495. g_fTZ -= 0.5f;
  496. else if( wParam == VK_DOWN )
  497. g_fTZ += 0.5f;
  498. break;
  499.  
  500.  
  501.  
  502. case WM_LBUTTONDOWN:
  503. ptLastCursorPos.x = ptCurrentCursorPos.x = LOWORD(lParam);
  504. ptLastCursorPos.y = ptCurrentCursorPos.y = HIWORD(lParam);
  505. bMousing = TRUE;
  506.  
  507. // Set capture so we know when the user releases the left button even
  508. // if it's not over the window.
  509. SetCapture( hWnd );
  510. break;
  511.  
  512.  
  513.  
  514. case WM_MOUSELEAVE: // Stop mousing if mouse button is released or cursor leaves window.
  515. case WM_LBUTTONUP:
  516. bMousing = FALSE;
  517. SetCapture( NULL );
  518. break;
  519.  
  520.  
  521. case WM_MOUSEMOVE:
  522. ptCurrentCursorPos.x = LOWORD( lParam );
  523. ptCurrentCursorPos.y = HIWORD( lParam );
  524. if( bMousing )
  525. {
  526. g_fSpinX -= (ptCurrentCursorPos.x - ptLastCursorPos.x) / 3;
  527. g_fSpinY -= (ptCurrentCursorPos.y - ptLastCursorPos.y) / 3;
  528. }
  529. ptLastCursorPos = ptCurrentCursorPos;
  530. break;
  531. }
  532. return DefWindowProc( hWnd, Msg, wParam, lParam );
  533. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement