Matrices.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  1. //-----------------------------------------------------------------------------
  2. // File: Matrices.cpp
  3. //
  4. // Desc: Now that we know how to create a device and render some 2D vertices,
  5. // this tutorial goes the next step and renders 3D geometry. To deal with
  6. // 3D geometry we need to introduce the use of 4x4 Matrices to transform
  7. // the geometry with translations, rotations, scaling, and setting up our
  8. // camera.
  9. //
  10. // Geometry is defined in model space. We can move it (translation),
  11. // rotate it (rotation), or stretch it (scaling) using a world transform.
  12. // The geometry is then said to be in world space. Next, we need to
  13. // position the camera, or eye point, somewhere to look at the geometry.
  14. // Another transform, via the view matrix, is used, to position and
  15. // rotate our view. With the geometry then in view space, our last
  16. // transform is the projection transform, which "projects" the 3D scene
  17. // into our 2D viewport.
  18. //
  19. // Note that in this tutorial, we are introducing the use of D3DX, which
  20. // is a set of helper utilities for D3D. In this case, we are using some
  21. // of D3DX's useful matrix initialization functions. To use D3DX, simply
  22. // include <d3dx9.h> and link with d3dx9.lib.
  23. //
  24. // Copyright (c) Microsoft Corporation. All rights reserved.
  25. //-----------------------------------------------------------------------------
  26. // RakNet: Logger includes. Include before Windows.h
  27. #include "SQLiteClientLoggerPlugin.h"
  28. #include "PacketizedTCP.h"
  29. #include "DX9_BackbufferGrabber.h"
  30. #include <Windows.h>
  31. #include <mmsystem.h>
  32. #include <d3dx9.h>
  33. #pragma warning( disable : 4996 ) // disable deprecated warning
  34. #include <strsafe.h>
  35. #pragma warning( default : 4996 )
  36. //-----------------------------------------------------------------------------
  37. // Global variables
  38. //-----------------------------------------------------------------------------
  39. LPDIRECT3D9 g_pD3D = NULL; // Used to create the D3DDevice
  40. LPDIRECT3DDEVICE9 g_pd3dDevice = NULL; // Our rendering device
  41. LPDIRECT3DVERTEXBUFFER9 g_pVB = NULL; // Buffer to hold vertices
  42. // A structure for our custom vertex type
  43. struct CUSTOMVERTEX
  44. {
  45. FLOAT x, y, z; // The untransformed, 3D position for the vertex
  46. DWORD color; // The vertex color
  47. };
  48. // Our custom FVF, which describes our custom vertex structure
  49. #define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE)
  50. //-----------------------------------------------------------------------------
  51. // Name: InitD3D()
  52. // Desc: Initializes Direct3D
  53. //-----------------------------------------------------------------------------
  54. HRESULT InitD3D( HWND hWnd )
  55. {
  56. // Create the D3D object.
  57. if( NULL == ( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )
  58. return E_FAIL;
  59. // Set up the structure used to create the D3DDevice
  60. D3DPRESENT_PARAMETERS d3dpp;
  61. ZeroMemory( &d3dpp, sizeof( d3dpp ) );
  62. d3dpp.Windowed = TRUE;
  63. d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
  64. // KevinJ: Used known backbuffer format of 4 bytes per pixel, and let us lock the backbuffer
  65. d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8; // D3DFMT_UNKNOWN;
  66. d3dpp.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
  67. // Create the D3DDevice
  68. if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
  69. D3DCREATE_SOFTWARE_VERTEXPROCESSING,
  70. &d3dpp, &g_pd3dDevice ) ) )
  71. {
  72. return E_FAIL;
  73. }
  74. // Turn off culling, so we see the front and back of the triangle
  75. g_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
  76. // Turn off D3D lighting, since we are providing our own vertex colors
  77. g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE );
  78. return S_OK;
  79. }
  80. //-----------------------------------------------------------------------------
  81. // Name: InitGeometry()
  82. // Desc: Creates the scene geometry
  83. //-----------------------------------------------------------------------------
  84. HRESULT InitGeometry()
  85. {
  86. // Initialize three vertices for rendering a triangle
  87. // ARGB
  88. CUSTOMVERTEX g_Vertices[] =
  89. {
  90. { -1.0f,-1.0f, 0.0f, 0xffff0000, },
  91. { 1.0f,-1.0f, 0.0f, 0xff0000ff, },
  92. { 0.0f, 1.0f, 0.0f, 0xffffffff, },
  93. // { -1.0f,-1.0f, 0.0f, 0xffff0000, },
  94. // { 1.0f,-1.0f, 0.0f, 0xffff0000, },
  95. // { 0.0f, 1.0f, 0.0f, 0xffff0000, },
  96. };
  97. // Create the vertex buffer.
  98. if( FAILED( g_pd3dDevice->CreateVertexBuffer( 3 * sizeof( CUSTOMVERTEX ),
  99. 0, D3DFVF_CUSTOMVERTEX,
  100. D3DPOOL_DEFAULT, &g_pVB, NULL ) ) )
  101. {
  102. return E_FAIL;
  103. }
  104. // Fill the vertex buffer.
  105. VOID* pVertices;
  106. if( FAILED( g_pVB->Lock( 0, sizeof( g_Vertices ), ( void** )&pVertices, 0 ) ) )
  107. return E_FAIL;
  108. memcpy( pVertices, g_Vertices, sizeof( g_Vertices ) );
  109. g_pVB->Unlock();
  110. return S_OK;
  111. }
  112. //-----------------------------------------------------------------------------
  113. // Name: Cleanup()
  114. // Desc: Releases all previously initialized objects
  115. //-----------------------------------------------------------------------------
  116. VOID Cleanup()
  117. {
  118. if( g_pVB != NULL )
  119. g_pVB->Release();
  120. if( g_pd3dDevice != NULL )
  121. g_pd3dDevice->Release();
  122. if( g_pD3D != NULL )
  123. g_pD3D->Release();
  124. }
  125. //-----------------------------------------------------------------------------
  126. // Name: SetupMatrices()
  127. // Desc: Sets up the world, view, and projection transform Matrices.
  128. //-----------------------------------------------------------------------------
  129. VOID SetupMatrices()
  130. {
  131. // For our world matrix, we will just rotate the object about the y-axis.
  132. D3DXMATRIXA16 matWorld;
  133. // Set up the rotation matrix to generate 1 full rotation (2*PI radians)
  134. // every 1000 ms. To avoid the loss of precision inherent in very high
  135. // floating point numbers, the system time is modulated by the rotation
  136. // period before conversion to a radian angle.
  137. UINT iTime = timeGetTime() % 1000;
  138. FLOAT fAngle = iTime * ( 2.0f * D3DX_PI ) / 1000.0f;
  139. // D3DXMatrixRotationY( &matWorld, fAngle );
  140. // g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
  141. // Set up our view matrix. A view matrix can be defined given an eye point,
  142. // a point to lookat, and a direction for which way is up. Here, we set the
  143. // eye five units back along the z-axis and up three units, look at the
  144. // origin, and define "up" to be in the y-direction.
  145. D3DXVECTOR3 vEyePt( 0.0f, 3.0f,-5.0f );
  146. D3DXVECTOR3 vLookatPt( 0.0f, 0.0f, 0.0f );
  147. D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f );
  148. D3DXMATRIXA16 matView;
  149. D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec );
  150. g_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );
  151. // For the projection matrix, we set up a perspective transform (which
  152. // transforms geometry from 3D view space to 2D viewport space, with
  153. // a perspective divide making objects smaller in the distance). To build
  154. // a perpsective transform, we need the field of view (1/4 pi is common),
  155. // the aspect ratio, and the near and far clipping planes (which define at
  156. // what distances geometry should be no longer be rendered).
  157. D3DXMATRIXA16 matProj;
  158. D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI / 4, 1.0f, 1.0f, 100.0f );
  159. g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );
  160. }
  161. //-----------------------------------------------------------------------------
  162. // Name: Render()
  163. // Desc: Draws the scene
  164. //-----------------------------------------------------------------------------
  165. VOID Render()
  166. {
  167. // Clear the backbuffer to a black color
  168. g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB( 0, 0, 0 ), 1.0f, 0 );
  169. // Begin the scene
  170. if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
  171. {
  172. // Setup the world, view, and projection Matrices
  173. SetupMatrices();
  174. // Render the vertex buffer contents
  175. g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof( CUSTOMVERTEX ) );
  176. g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
  177. g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 1 );
  178. // End the scene
  179. g_pd3dDevice->EndScene();
  180. }
  181. // Present the backbuffer contents to the display
  182. g_pd3dDevice->Present( NULL, NULL, NULL, NULL );
  183. }
  184. //-----------------------------------------------------------------------------
  185. // Name: MsgProc()
  186. // Desc: The window's message handler
  187. //-----------------------------------------------------------------------------
  188. LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
  189. {
  190. switch( msg )
  191. {
  192. case WM_DESTROY:
  193. Cleanup();
  194. PostQuitMessage( 0 );
  195. return 0;
  196. }
  197. return DefWindowProc( hWnd, msg, wParam, lParam );
  198. }
  199. //-----------------------------------------------------------------------------
  200. // Name: WinMain()
  201. // Desc: The application's entry point
  202. //-----------------------------------------------------------------------------
  203. INT WINAPI wWinMain( HINSTANCE hInst, HINSTANCE, LPWSTR, INT )
  204. {
  205. // Register the window class
  206. WNDCLASSEX wc =
  207. {
  208. sizeof( WNDCLASSEX ), CS_CLASSDC, MsgProc, 0L, 0L,
  209. GetModuleHandle( NULL ), NULL, NULL, NULL, NULL,
  210. L"D3D Tutorial", NULL
  211. };
  212. RegisterClassEx( &wc );
  213. // Connect to the server if it is running, to store screenshots
  214. RakNet::PacketizedTCP packetizedTCP;
  215. RakNet::SQLiteClientLoggerPlugin loggerPlugin;
  216. packetizedTCP.AttachPlugin(&loggerPlugin);
  217. packetizedTCP.Start(0,0);
  218. loggerPlugin.SetServerParameters(packetizedTCP.Connect("127.0.0.1", 38123, true), "d3dvideo.sqlite");
  219. loggerPlugin.SetMemoryConstraint(8000000);
  220. DX9_BackbufferGrabber backbufferGrabber;
  221. // Create the application's window
  222. HWND hWnd = CreateWindow( L"D3D Tutorial", L"D3D Tutorial 03: Matrices",
  223. WS_OVERLAPPEDWINDOW, 100, 100, 512, 512,
  224. NULL, NULL, hInst, NULL );
  225. DWORD timeSinceLastLog, timeSinceLastTick, lastLogTime=0;
  226. float lastFps;
  227. timeSinceLastTick=0;
  228. // Initialize Direct3D
  229. if( SUCCEEDED( InitD3D( hWnd ) ) )
  230. {
  231. // Create the scene geometry
  232. if( SUCCEEDED( InitGeometry() ) )
  233. {
  234. // Show the window
  235. ShowWindow( hWnd, SW_SHOWDEFAULT );
  236. UpdateWindow( hWnd );
  237. // Start backbuffer grabber
  238. backbufferGrabber.InitBackbufferGrabber(g_pd3dDevice, 256, 256);
  239. // Enter the message loop
  240. MSG msg;
  241. ZeroMemory( &msg, sizeof( msg ) );
  242. while( msg.message != WM_QUIT )
  243. {
  244. if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
  245. {
  246. TranslateMessage( &msg );
  247. DispatchMessage( &msg );
  248. }
  249. else
  250. {
  251. Render();
  252. timeSinceLastLog=timeGetTime()-lastLogTime;
  253. if (packetizedTCP.GetConnectionCount()>0 && timeSinceLastLog>30)
  254. {
  255. RakNet::RGBImageBlob blob;
  256. backbufferGrabber.LockBackbufferCopy(&blob);
  257. RakAssert(blob.data!=0);
  258. rakSqlLog("Screenshots", "screenshot", ( &blob ));
  259. static bool saveToDiskOnce=true;
  260. if (saveToDiskOnce)
  261. {
  262. blob.SaveToTGA("MatricesDemoFirstFrame.tga");
  263. saveToDiskOnce=false;
  264. }
  265. backbufferGrabber.ReleaseBackbufferCopy();
  266. }
  267. float fps;
  268. if (timeSinceLastTick!=0)
  269. {
  270. DWORD elapsedTime = timeGetTime()-timeSinceLastTick;
  271. if (elapsedTime==0)
  272. fps=lastFps;
  273. else
  274. fps = 1000.0f / (float) elapsedTime;
  275. }
  276. else
  277. {
  278. fps=0;
  279. }
  280. lastFps = fps;
  281. timeSinceLastTick=timeGetTime();
  282. rakSqlLog("FPS", "FPS", ( fps ));
  283. loggerPlugin.IncrementAutoTickCount();
  284. }
  285. }
  286. }
  287. }
  288. UnregisterClass( L"D3D Tutorial", wc.hInstance );
  289. return 0;
  290. }
粤ICP备19079148号