Advertisement
Guest User

Untitled

a guest
Nov 23rd, 2017
67
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 25.75 KB | None | 0 0
  1. #include <windows.h>
  2. #include <d3d11.h>
  3. #include <d3dcompiler.h>
  4. #include <DirectXMath.h>
  5. #include <stdio.h>
  6. #include <WICTextureLoader.h>
  7. #include "keyprocessor.h"
  8.  
  9. //[1] Add the assimp libraries
  10. #include <assimp/Importer.hpp>
  11. #include <assimp/postprocess.h>
  12. #include <assimp/scene.h>
  13.  
  14.  
  15. using namespace DirectX;
  16.  
  17. #pragma comment(lib, "d3d11.lib")
  18. #pragma comment(lib, "d3dcompiler.lib")
  19. #pragma comment(lib, "DirectXTK.lib")
  20.  
  21. //[2] Add the assimp library
  22. #pragma comment(lib, "assimp-vc140-mt.lib")
  23.  
  24. // Window class name
  25. static wchar_t szAppClassName[] = L"AssImpEx";
  26.  
  27. // Forward definition of Windows procedure, necessary as Windows Procedure is defined last and
  28. // C++ requires identifiers are declared before use
  29. LRESULT CALLBACK WinProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  30.  
  31. // DirectX objects
  32. ID3D11Device *d3dDevice;
  33. ID3D11DeviceContext *d3dContext;
  34. IDXGISwapChain *swapChain;
  35. ID3D11RenderTargetView *backBuffer;
  36.  
  37. // Depth buffer texture and object
  38. ID3D11Texture2D* depthStencilBuffer;
  39. ID3D11DepthStencilView* depthStencilView;
  40.  
  41.  
  42.  
  43. // Template for a vertex and an associated colour
  44. struct Vertex {
  45. XMFLOAT3 pos;
  46. XMFLOAT2 texCoord;
  47.  
  48. Vertex() {
  49. }
  50.  
  51. Vertex(float x, float y, float z, float u, float v) {
  52. pos.x = x;
  53. pos.y = y;
  54. pos.z = z;
  55.  
  56. texCoord.x = u;
  57. texCoord.y = v;
  58. }
  59. };
  60.  
  61. struct ConstantBuffer
  62. {
  63. XMMATRIX mWorld;
  64. XMMATRIX mView;
  65. XMMATRIX mProjection;
  66. };
  67.  
  68. //[3] Dwarf vertex buffer
  69. ID3D11Buffer *dwarfVertexBuffer = NULL;
  70.  
  71.  
  72.  
  73. //[3c] Car vertex buffer
  74. ID3D11Buffer *carVertexBuffer = NULL;
  75.  
  76.  
  77. ID3D11Buffer *constantBuffer = NULL;
  78. ID3D11VertexShader *vertexShader = NULL;
  79. ID3D11PixelShader *pixelShader = NULL;
  80. ID3D11InputLayout *vertexLayout = NULL;
  81.  
  82. //[4] Define the dwarf texture object variables
  83. ID3D11ShaderResourceView *dwarfTex;
  84. ID3D11ShaderResourceView *axeTex;
  85.  
  86.  
  87. //[4c] Define the car texture object variable
  88. ID3D11ShaderResourceView *carTex;
  89.  
  90.  
  91. ID3D11SamplerState *sampler;
  92.  
  93. // MVP Matrices
  94. XMMATRIX matWorld;
  95. XMMATRIX matView;
  96. XMMATRIX matProjection;
  97.  
  98. float camXPos = 0.0f;
  99. float camYPos = 0.0f;
  100. float camZPos = -50.0f;
  101.  
  102. XMVECTOR camTarget = XMVectorSet(0.0f, 0.0f, 0.0f, 0.0f);
  103. XMVECTOR camUp = XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f);
  104.  
  105. float camRotX = 0.0f;
  106. float camRotY = 0.0f;
  107.  
  108. int curMouseXPos, curMouseYPos;
  109.  
  110. int clientMidX, clientMidY;
  111.  
  112. int winMidX, winMidY;
  113. int winLeft, winTop;
  114.  
  115. float rotFactorY = 0.0f;
  116.  
  117. const float MOVE_STEP = 10.0f;
  118. const float ROTATE_STEP = (XM_PI / 6);
  119.  
  120. // To determine mouse movement need to know how far the mouse has moved
  121. int mouseXPos;
  122. int mouseYPos;
  123.  
  124. // Rotation angles for each axis
  125. float RotationY = 0.0f;
  126. float RotationX = 0.0f;
  127. float RotFactorX = 0.01f;
  128. float RotFactorY = 0.01f;
  129.  
  130. float scale = 1.0f;
  131.  
  132. bool Rotating = false;
  133.  
  134. //Position Variables
  135. //float playerX = 0.0f;
  136. //float playerY = 0.0f;
  137. //float playerZ = 0.0f;
  138.  
  139. //Rotation Variables
  140. //float playerYaw = 0.0f;
  141. //float playerPitch = 0.0f;
  142. //float playerRoll = 0.0f;
  143.  
  144.  
  145. const float MOVE_DIST = 5.0f;
  146. const float ROTATION = XM_PI / 45;
  147.  
  148. DWORD frameTime;
  149.  
  150.  
  151. //[5] Define a variable to store the number of vertices in each dwarf mesh
  152. int *MeshVertices;
  153.  
  154. //[5c] Define a variable to store the number of vertices in the car mesh
  155. int *CarMeshVertices;
  156.  
  157. // Initialise DirectX in the application
  158. // Involves finding a driver suitable for the
  159. // features required by the game
  160. // If there is one, then it is associated
  161. // with the application by use of a back buffer (one or more)
  162. BOOL InitialiseDirectX(HWND hMainWnd, HINSTANCE hCurInstance) {
  163. RECT rectDimensions;
  164. GetClientRect(hMainWnd, &rectDimensions);
  165.  
  166. LONG width = rectDimensions.right - rectDimensions.left;
  167. LONG height = rectDimensions.bottom - rectDimensions.top;
  168.  
  169. RECT rectWindow;
  170. GetWindowRect(hMainWnd, &rectWindow);
  171.  
  172. winTop = rectWindow.top;
  173. winLeft = rectWindow.left;
  174.  
  175. winMidX = (rectWindow.right - rectWindow.left) / 2;
  176. winMidY = (rectWindow.bottom - rectWindow.top) / 2;
  177.  
  178. clientMidX = width / 2;
  179. clientMidY = height / 2;
  180.  
  181. curMouseXPos = clientMidX;
  182. curMouseYPos = clientMidY;
  183.  
  184. SetCursorPos(winLeft + winMidX, winTop + winMidY);
  185.  
  186. rotFactorY = XM_PIDIV2 / width;
  187.  
  188. // Define the feature levels the program
  189. D3D_FEATURE_LEVEL featureLevels[] = { D3D_FEATURE_LEVEL_11_1 };
  190.  
  191. int numFeatureLevels = sizeof(featureLevels) / sizeof(D3D_FEATURE_LEVEL);
  192.  
  193. // Setup the DXGI_SWAP_CHAIN_DESC structure for describing the type of swap chain to be used
  194. DXGI_SWAP_CHAIN_DESC swapChainDesc;
  195. ZeroMemory(&swapChainDesc, sizeof(swapChainDesc));
  196. swapChainDesc.BufferCount = 1;
  197. swapChainDesc.BufferDesc.Width = width;
  198. swapChainDesc.BufferDesc.Height = height;
  199. swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
  200. swapChainDesc.BufferDesc.RefreshRate.Numerator = 60;
  201. swapChainDesc.BufferDesc.RefreshRate.Denominator = 1;
  202. swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
  203. swapChainDesc.OutputWindow = hMainWnd;
  204. swapChainDesc.Windowed = true;
  205. swapChainDesc.SampleDesc.Count = 1;
  206. swapChainDesc.SampleDesc.Quality = 0;
  207.  
  208. int creationFlags = 0;
  209.  
  210. HRESULT result;
  211.  
  212. // Create the device and swap chain for DirectX 11
  213. result = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE,
  214. NULL, NULL, NULL, NULL, D3D11_SDK_VERSION,
  215. &swapChainDesc, &swapChain, &d3dDevice, NULL, &d3dContext);
  216.  
  217. // Check result
  218. if (result != S_OK) {
  219. MessageBox(hMainWnd, TEXT("Failed to initialise DX11!"), szAppClassName, NULL);
  220.  
  221. return false;
  222. }
  223.  
  224. // Create a texture to be used as the back buffer (off screen)
  225. ID3D11Texture2D *backBufferTexture;
  226.  
  227. result = swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID *) &backBufferTexture);
  228.  
  229. if(result != S_OK) {
  230. MessageBox(hMainWnd, L"Failed to get back buffer!", szAppClassName, NULL);
  231.  
  232. return false;
  233. }
  234.  
  235. result = d3dDevice->CreateRenderTargetView(backBufferTexture, 0, &backBuffer);
  236.  
  237. if(backBufferTexture != NULL) {
  238. backBufferTexture->Release();
  239. }
  240.  
  241. if(result != S_OK) {
  242. MessageBox(hMainWnd, L"Failed to get render target!", szAppClassName, NULL);
  243.  
  244. return false;
  245. }
  246.  
  247. //Define Depth/Stencil Buffer
  248. D3D11_TEXTURE2D_DESC depthStencilDesc;
  249. ZeroMemory(&depthStencilDesc, sizeof(D3D11_TEXTURE2D_DESC));
  250.  
  251. // DepthStencil buffer has same dimensions as back buffer which is the same as the client window
  252. depthStencilDesc.Width = width;
  253. depthStencilDesc.Height = height;
  254. depthStencilDesc.MipLevels = 1;
  255. depthStencilDesc.ArraySize = 1;
  256. // Major difference is depth buffer does not store colour information but depth information
  257. depthStencilDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
  258. depthStencilDesc.SampleDesc.Count = 1;
  259. depthStencilDesc.SampleDesc.Quality = 0;
  260. // As it's a texture need to define DirectX usage, would be useful to use D3D11_USAGE_DYNAMIC flag and caputre
  261. // state of depth buffer to examine the values stored.
  262. depthStencilDesc.Usage = D3D11_USAGE_DEFAULT;
  263. depthStencilDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
  264. depthStencilDesc.CPUAccessFlags = 0;
  265. depthStencilDesc.MiscFlags = 0;
  266.  
  267. // Create the texture for the depthstencil buffer
  268. d3dDevice->CreateTexture2D(&depthStencilDesc, NULL, &depthStencilBuffer);
  269. // Create the depthstencil object based on the texture created precious
  270. d3dDevice->CreateDepthStencilView(depthStencilBuffer, NULL, &depthStencilView);
  271.  
  272. // Bind the back buffer and the depthstencil buffer to the OM stage
  273. d3dContext->OMSetRenderTargets( 1, &backBuffer, depthStencilView );
  274.  
  275. D3D11_VIEWPORT viewport;
  276. viewport.Width = static_cast<float>(width);
  277. viewport.Height = static_cast<float>(height);
  278. viewport.MinDepth = 0.0f;
  279. viewport.MaxDepth = 1.0f;
  280. viewport.TopLeftX = 0.0f;
  281. viewport.TopLeftY = 0.0f;
  282.  
  283. d3dContext->RSSetViewports(1, &viewport);
  284.  
  285.  
  286. XMVECTOR camPos = XMVectorSet(camXPos, camYPos, camZPos, 0.0f);
  287. matView = XMMatrixLookAtLH(camPos, camTarget, camUp);
  288.  
  289. matProjection = XMMatrixPerspectiveFovLH( XM_PIDIV4, width / (FLOAT)height,
  290. 1.0f, 100.0f);
  291.  
  292.  
  293. // Initialize the view matrix
  294. XMVECTOR Eye = XMVectorSet( 0.0f, 3.0f, -10.0f, 0.0f );
  295. XMVECTOR At = XMVectorSet( 0.0f, 3.0f, 0.0f, 0.0f );
  296. XMVECTOR Up = XMVectorSet( 0.0f, 1.0f, 0.0f, 0.0f );
  297. matView = XMMatrixLookAtLH( Eye, At, Up );
  298.  
  299. // Initialize the projection matrix
  300. matProjection = XMMatrixPerspectiveFovLH( XM_PIDIV4, width / (FLOAT)height, 0.01f, 100.0f );
  301.  
  302. return true;
  303. }
  304.  
  305. // Transition from a list of vertices to a final rasterised image.
  306. // In DirectX10 and DirectX11 it is typical to render using shaders, a vertex shader to apply
  307. // a transformation to the vertices and a pixel shader to shade/colour pixels in a list of vertices
  308. bool CreateShaders(HWND hMainWnd) {
  309. // Create the vertex shader first although order does not matter.
  310. // What does matter is shaders were loaded, compiled and then represented in as DirectX objects.
  311. // Otherwise will not get the output we want
  312.  
  313. ID3DBlob *pVSBlob = NULL;
  314. HRESULT hr = D3DReadFileToBlob( L".\\VertexShader.cso", &pVSBlob);
  315. if( hr != S_OK )
  316. {
  317. MessageBox( hMainWnd, L"Problem loading vertex shader. Check shader file (VertexShader.cso) is in the project directory (sub folder of main solution directory) and shader is valid", szAppClassName, MB_OK );
  318.  
  319. return false;
  320. }
  321.  
  322. // Create the vertex shader in DirectX
  323. hr = d3dDevice->CreateVertexShader( pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), NULL, &vertexShader );
  324. // Check creating vertex shader was successful
  325. if( hr != S_OK )
  326. {
  327. pVSBlob->Release();
  328.  
  329. MessageBox( hMainWnd, L"The vertex shader object cannot be created", szAppClassName, MB_OK );
  330.  
  331. return false;
  332. }
  333.  
  334. // Need to tell DirectX how vertices are structured in terms of colour format and order of data, that is individual vertices
  335. // The POSITION is called the semantic name, basically a meaningful identifier used internally to map vertex elements to shader
  336. // parameters. Semantic name text must obey the rules of C identifiers as shader language uses C syntax
  337. D3D11_INPUT_ELEMENT_DESC layout[] =
  338. {
  339. { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
  340. { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
  341. };
  342.  
  343. UINT numElements = 2;
  344.  
  345. // Create the input layout for input assembler based on description and the vertex shader to be used
  346. hr = d3dDevice->CreateInputLayout( layout, numElements, pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), &vertexLayout );
  347. // Check layout was created successfully
  348. pVSBlob->Release();
  349. if( hr != S_OK ) {
  350. MessageBox( hMainWnd, L"Problems creating input layout", szAppClassName, MB_OK );
  351.  
  352. return false;
  353. }
  354.  
  355. // Set the input layout for input assembler
  356. d3dContext->IASetInputLayout( vertexLayout );
  357.  
  358. // Compile the pixel shader
  359. ID3DBlob* pPSBlob = NULL;
  360. hr = D3DReadFileToBlob( L".\\PixelShader.cso", &pPSBlob);
  361. // Check pixel shader was loaded successfully
  362. if( hr != S_OK )
  363. {
  364. // If program has got this far then the problem is more likely to be in shader file, e.g. mistyped name, or wrong shader version
  365. MessageBox( hMainWnd, L"Problem loading pixel shader. Check shader file (PixelShader.cso) is in the project directory (sub folder of main solution directory) and shader is valid", szAppClassName, MB_OK );
  366.  
  367. return false;
  368. }
  369.  
  370. // Create the pixel shader in DirectX
  371. hr = d3dDevice->CreatePixelShader( pPSBlob->GetBufferPointer(), pPSBlob->GetBufferSize(), NULL, &pixelShader );
  372. pPSBlob->Release();
  373. // Check creating pixel shader was successful
  374. if( hr != S_OK ) {
  375. MessageBox( hMainWnd, L"The pixel shader object cannot be created", szAppClassName, MB_OK );
  376.  
  377. return false;
  378. }
  379.  
  380. //[6] Load dwarf texture
  381. hr = CreateWICTextureFromFile(d3dDevice, d3dContext, L".\\dwarf.jpg", NULL, &dwarfTex);
  382. if (hr != S_OK) {
  383. MessageBox(hMainWnd, TEXT("Unable to load dwarf texture"), szAppClassName, MB_OK);
  384.  
  385. return false;
  386. }
  387.  
  388.  
  389. //[7] Load axe texture
  390. hr = CreateWICTextureFromFile(d3dDevice, d3dContext, L".\\axe.jpg", NULL, &axeTex);
  391. if (hr != S_OK) {
  392. MessageBox(hMainWnd, TEXT("Unable to load dwarf texture"), szAppClassName, MB_OK);
  393.  
  394. return false;
  395. }
  396.  
  397. //[6c] Load car texture
  398. hr = CreateWICTextureFromFile(d3dDevice, d3dContext, L".\\Car07.jpg", NULL, &carTex);
  399. if (hr != S_OK) {
  400. MessageBox(hMainWnd, TEXT("Unable to load car texture"), szAppClassName, MB_OK);
  401.  
  402. return false;
  403. }
  404.  
  405. D3D11_SAMPLER_DESC sampDesc;
  406. ZeroMemory(&sampDesc, sizeof(sampDesc));
  407. sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
  408. sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
  409. sampDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
  410. sampDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
  411. sampDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
  412. sampDesc.MaxLOD = D3D11_FLOAT32_MAX;
  413.  
  414. hr = d3dDevice->CreateSamplerState(&sampDesc, &sampler);
  415. if(hr != S_OK) {
  416. MessageBox( hMainWnd, TEXT("Unable to create sampler"), szAppClassName, MB_OK );
  417.  
  418. return false;
  419. }
  420.  
  421. // If we've got this far then have valid shaders.
  422. // Return a successful result
  423. return true;
  424. }
  425.  
  426. bool LoadDwarfModel() {
  427. //[8] Create importer object
  428. Assimp::Importer imp;
  429.  
  430.  
  431. //[9] Load model into scene object
  432. const aiScene *pScene = imp.ReadFile(".\\dwarf.x",
  433. aiProcessPreset_TargetRealtime_Fast | aiProcess_ConvertToLeftHanded);
  434. if (!pScene) {
  435. return false;
  436. }
  437.  
  438.  
  439. if (!pScene) {
  440. return false;
  441. }
  442.  
  443. //[10] Create an array to store the individual number of vertices in each mesh
  444. MeshVertices = new int[pScene->mNumMeshes];
  445.  
  446.  
  447. //[11] Calculate the total number of vertices from all meshes
  448. int TotalNumVertices = 0;
  449. for (int MeshIdx = 0; MeshIdx < pScene->mNumMeshes; MeshIdx++) {
  450. const aiMesh *mesh = pScene->mMeshes[MeshIdx];
  451.  
  452. MeshVertices[MeshIdx] = mesh->mNumFaces * 3;
  453.  
  454. TotalNumVertices += mesh->mNumFaces * 3;
  455. }
  456.  
  457.  
  458. //[12] Create an array to store all vertices
  459. Vertex *shape = new Vertex[TotalNumVertices];
  460.  
  461.  
  462.  
  463. //[13] Convert the assimp vertices to ones for DirectX
  464. int vertCount = 0;
  465. for (int MeshIdx = 0; MeshIdx < pScene->mNumMeshes; MeshIdx++) {
  466. const aiMesh *mesh = pScene->mMeshes[MeshIdx];
  467.  
  468. for (int faceIdx = 0; faceIdx < mesh->mNumFaces; faceIdx++) {
  469. const aiFace& face = mesh->mFaces[faceIdx];
  470.  
  471. for (int vertIdx = 0; vertIdx < 3; vertIdx++) {
  472. const aiVector3D *pos = &mesh->mVertices[face.mIndices[vertIdx]];
  473. const aiVector3D *tex = &mesh->mTextureCoords[0][face.mIndices[vertIdx]];
  474.  
  475. shape[vertCount] = Vertex(pos->x, pos->y, pos->z, tex->x, tex->y);
  476. vertCount++;
  477. }
  478. }
  479.  
  480. }
  481.  
  482.  
  483.  
  484. //[14] Define the vertex buffer
  485. D3D11_BUFFER_DESC bd;
  486. ZeroMemory(&bd, sizeof(bd));
  487. bd.Usage = D3D11_USAGE_DEFAULT;
  488. bd.ByteWidth = sizeof(Vertex) * TotalNumVertices;
  489. bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
  490. bd.CPUAccessFlags = 0;
  491.  
  492.  
  493. // Define the source of vertex data in RAM
  494. D3D11_SUBRESOURCE_DATA InitData;
  495. ZeroMemory(&InitData, sizeof(InitData));
  496. InitData.pSysMem = shape;
  497. HRESULT hr = d3dDevice->CreateBuffer(&bd, &InitData, &dwarfVertexBuffer);
  498.  
  499. if (hr != S_OK) {
  500. return false;
  501. }
  502.  
  503.  
  504. //[15] Release memory allocated to shape
  505. delete[] shape;
  506.  
  507.  
  508. // Got this far so model loaded okay
  509. return true;
  510. }
  511.  
  512. bool LoadCarModel() {
  513. //[8] Create importer object
  514. Assimp::Importer imp1;
  515.  
  516.  
  517. //[9] Load model into scene object
  518. const aiScene *pScene = imp1.ReadFile(".\\car07.3DS",
  519. aiProcessPreset_TargetRealtime_Fast | aiProcess_ConvertToLeftHanded);
  520. if (!pScene) {
  521. return false;
  522. }
  523.  
  524.  
  525. if (!pScene) {
  526. return false;
  527. }
  528.  
  529. //[10] Create an array to store the individual number of vertices in each mesh
  530. CarMeshVertices = new int[pScene->mNumMeshes];
  531.  
  532.  
  533. //[11] Calculate the total number of vertices from all meshes
  534. int TotalNumVertices = 0;
  535. for (int MeshIdx = 0; MeshIdx < pScene->mNumMeshes; MeshIdx++) {
  536. const aiMesh *mesh = pScene->mMeshes[MeshIdx];
  537.  
  538. CarMeshVertices[MeshIdx] = mesh->mNumFaces * 3;
  539.  
  540. TotalNumVertices += mesh->mNumFaces * 3;
  541. }
  542.  
  543.  
  544. //[12] Create an array to store all vertices
  545. Vertex *shape1 = new Vertex[TotalNumVertices];
  546.  
  547.  
  548.  
  549. //[13] Convert the assimp vertices to ones for DirectX
  550. int vertCount = 0;
  551. for (int MeshIdx = 0; MeshIdx < pScene->mNumMeshes; MeshIdx++) {
  552. const aiMesh *mesh = pScene->mMeshes[MeshIdx];
  553.  
  554. for (int faceIdx = 0; faceIdx < mesh->mNumFaces; faceIdx++) {
  555. const aiFace& face = mesh->mFaces[faceIdx];
  556.  
  557. for (int vertIdx = 0; vertIdx < 3; vertIdx++) {
  558. const aiVector3D *pos = &mesh->mVertices[face.mIndices[vertIdx]];
  559. const aiVector3D *tex = &mesh->mTextureCoords[0][face.mIndices[vertIdx]];
  560.  
  561. shape1[vertCount] = Vertex(pos->x, pos->y, pos->z, tex->x, tex->y);
  562. vertCount++;
  563. }
  564. }
  565.  
  566. }
  567.  
  568.  
  569.  
  570. //[14] Define the vertex buffer
  571. D3D11_BUFFER_DESC bd;
  572. ZeroMemory(&bd, sizeof(bd));
  573. bd.Usage = D3D11_USAGE_DEFAULT;
  574. bd.ByteWidth = sizeof(Vertex) * TotalNumVertices;
  575. bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
  576. bd.CPUAccessFlags = 0;
  577.  
  578.  
  579. // Define the source of vertex data in RAM
  580. D3D11_SUBRESOURCE_DATA InitData;
  581. ZeroMemory(&InitData, sizeof(InitData));
  582. InitData.pSysMem = shape1;
  583. HRESULT hr = d3dDevice->CreateBuffer(&bd, &InitData, &carVertexBuffer);
  584.  
  585. if (hr != S_OK) {
  586. return false;
  587. }
  588.  
  589.  
  590. //[15] Release memory allocated to shape
  591. delete[] shape1;
  592.  
  593.  
  594. // Got this far so model loaded okay
  595. return true;
  596. }
  597.  
  598. bool CreateMeshes(HWND hMainWnd) {
  599. if (!LoadDwarfModel()) {
  600. MessageBox(hMainWnd, L"Failed to load and create dwarf model", szAppClassName, NULL);
  601.  
  602. return false;
  603. }
  604.  
  605. if (!LoadCarModel()) {
  606. MessageBox(hMainWnd, L"Failed to load and create car model", szAppClassName, NULL);
  607.  
  608. return false;
  609. }
  610.  
  611. // Create the constant buffer
  612. D3D11_BUFFER_DESC bd;
  613. ZeroMemory(&bd, sizeof(D3D11_BUFFER_DESC));
  614. bd.Usage = D3D11_USAGE_DEFAULT;
  615. bd.ByteWidth = sizeof(ConstantBuffer);
  616. bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
  617. bd.CPUAccessFlags = 0;
  618. HRESULT hr = d3dDevice->CreateBuffer( &bd, NULL, &constantBuffer );
  619. if( hr != S_OK ) {
  620. MessageBox(hMainWnd, L"Failed to create constant buffer", szAppClassName, NULL);
  621.  
  622. return false;
  623. }
  624.  
  625. // If we've got this far then have vertice structure in DirectX.
  626. // Return a successful result
  627. return true;
  628. }
  629.  
  630.  
  631. void Update() {
  632. // Does nothing as mouse control is elsewhere
  633. DWORD now = GetTickCount();
  634. DWORD diff = now - frameTime;
  635.  
  636. const float move_step = 10.0f;
  637.  
  638. float forwards_backwards = 0.0f;
  639. float left_right = 0.0f;
  640.  
  641. if (IsKeyDown('W')) {
  642. forwards_backwards = move_step * (diff / 1000.0f);
  643. }
  644.  
  645. if (IsKeyDown('S')) {
  646. forwards_backwards = -move_step * (diff / 1000.0f);
  647. }
  648.  
  649. int deltaX = clientMidX - curMouseXPos;
  650.  
  651. camRotY -= deltaX * rotFactorY;
  652.  
  653. SetCursorPos(winLeft + winMidX, winTop + winMidY);
  654.  
  655. XMMATRIX camMove = XMMatrixTranslation(0.0f, 0.0f, forwards_backwards) *
  656. XMMatrixRotationRollPitchYaw(camRotX, camRotY, 0.0f);
  657.  
  658. XMVECTOR scale, rot, trans;
  659. XMMatrixDecompose(&scale, &rot, &trans, camMove);
  660.  
  661. camXPos += XMVectorGetX(trans);
  662. camYPos += XMVectorGetY(trans);
  663. camZPos += XMVectorGetZ(trans);
  664.  
  665. XMVECTOR camPos = XMVectorSet(camXPos, camYPos, camZPos, 0.0f);
  666.  
  667. XMMATRIX camDist = XMMatrixTranslation(0.0f, 0.0f, 10.0f) *
  668. XMMatrixRotationRollPitchYaw(camRotX, camRotY, 0.0f);
  669.  
  670. XMMatrixDecompose(&scale, &rot, &trans, camDist);
  671.  
  672. camTarget = XMVectorSet(camXPos + XMVectorGetX(trans),
  673. camYPos + XMVectorGetY(trans),
  674. camZPos + XMVectorGetZ(trans), 0.0f);
  675.  
  676. matView = XMMatrixLookAtLH(camPos, camTarget, camUp);
  677.  
  678. frameTime = now;
  679. }
  680.  
  681. // Renders a frame, what does this function do?
  682. void Draw() {
  683. if(d3dContext == NULL) {
  684. return;
  685. }
  686.  
  687. matWorld = XMMatrixIdentity() * XMMatrixScaling(0.3f, 0.3f, 0.3f);
  688.  
  689. matWorld = XMMatrixScaling(0.1f, 0.1f, 0.1f) * XMMatrixRotationY(-RotationY) * XMMatrixTranslation(0.0f, 0.0f, 20.0f);
  690.  
  691. ConstantBuffer cb;
  692. cb.mWorld = XMMatrixTranspose( matWorld );
  693. cb.mView = XMMatrixTranspose( matView );
  694. cb.mProjection = XMMatrixTranspose( matProjection );
  695. d3dContext->UpdateSubresource( constantBuffer, 0, NULL, &cb, 0, 0 );
  696.  
  697. float colour[] = {0.392156f, 0.584313f, 0.929411f, 1.0f};
  698.  
  699. d3dContext->ClearRenderTargetView(backBuffer, colour);
  700. // Clear the depth of depthstencil buffer to 1.0f for new frame
  701. d3dContext->ClearDepthStencilView(depthStencilView, D3D11_CLEAR_DEPTH, 1.0f, 0);
  702.  
  703. // Render a triangle. Not directly from vertices but from applying the shaders
  704. d3dContext->VSSetShader( vertexShader, NULL, 0 );
  705. d3dContext->VSSetConstantBuffers( 0, 1, &constantBuffer );
  706. d3dContext->PSSetShader( pixelShader, NULL, 0 );
  707.  
  708. //[16] Select vertex buffer with all of the mesh vertices
  709. UINT stride = sizeof(Vertex);
  710. UINT offset = 0;
  711. d3dContext->IASetVertexBuffers(0, 1, &dwarfVertexBuffer, &stride, &offset);
  712.  
  713.  
  714.  
  715. // Also tell input assembler how the vertices are to be treated.
  716. d3dContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST );
  717.  
  718. // Select the sampler
  719. d3dContext->PSSetSamplers(0, 1, &sampler);
  720.  
  721. ////[17] Select the axe texture first
  722. d3dContext->PSSetShaderResources(1, 1, &axeTex);
  723.  
  724.  
  725.  
  726. ////[18] Draw the axe mesh
  727. d3dContext->Draw(MeshVertices[0], 1);
  728.  
  729.  
  730. ////[19] Select the dwarf texture
  731. d3dContext->PSSetShaderResources(1, 1, &dwarfTex);
  732.  
  733.  
  734. ////[20] Draw the dwarf mesh
  735. d3dContext->Draw(MeshVertices[1], MeshVertices[0]);
  736.  
  737.  
  738. //[16c] Select car vertex buffer into pipeline
  739. d3dContext->IASetVertexBuffers(0, 1, &carVertexBuffer, &stride, &offset);
  740.  
  741.  
  742. //[17c] Select car texture into pipeline
  743. d3dContext->PSSetShaderResources(1, 1, &carTex);
  744.  
  745.  
  746. //[18c] Draw car
  747. d3dContext->Draw(CarMeshVertices[0], CarMeshVertices[0]);
  748.  
  749. // Display frame immediately
  750. swapChain->Present(0,0);
  751. }
  752.  
  753. // Release the resources allocated to application as a result of
  754. // using DirectX
  755. void ShutdownDirectX() {
  756. if(dwarfTex) {
  757. dwarfTex->Release();
  758. }
  759.  
  760. if (axeTex) {
  761. axeTex->Release();
  762. }
  763.  
  764. if(dwarfVertexBuffer != NULL)
  765. dwarfVertexBuffer->Release();
  766.  
  767. if (carTex) {
  768. carTex->Release();
  769. }
  770.  
  771. if (carVertexBuffer != NULL)
  772. carVertexBuffer->Release();
  773.  
  774. // Add source code to release car buffer and texture
  775.  
  776. if (sampler) {
  777. sampler->Release();
  778. }
  779.  
  780.  
  781. if(vertexShader != NULL)
  782. vertexShader->Release();
  783.  
  784. if(pixelShader != NULL)
  785. pixelShader->Release();
  786.  
  787. if(vertexLayout != NULL)
  788. vertexLayout->Release();
  789.  
  790. if(backBuffer) {
  791. backBuffer->Release();
  792. }
  793.  
  794. if(depthStencilView) {
  795. depthStencilView->Release();
  796. }
  797.  
  798. if(depthStencilBuffer) {
  799. depthStencilBuffer->Release();
  800. }
  801.  
  802. if(swapChain) {
  803. swapChain->Release();
  804. }
  805.  
  806. if(d3dContext) {
  807. d3dContext->Release();
  808. }
  809.  
  810. if(d3dDevice) {
  811. d3dDevice->Release();
  812.  
  813. backBuffer = 0;
  814. swapChain = 0;
  815. d3dContext = 0;
  816. d3dDevice = 0;
  817. }
  818. }
  819.  
  820. int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLineArgs, int nInitialWinShowState) {
  821. HWND hMainWnd;
  822. MSG msg = {0};
  823. // Find out what a WNDCLASS is and what it is used for
  824. WNDCLASS wndclass;
  825. wchar_t fps[ 64 ];
  826. ZeroMemory(fps, 64);
  827.  
  828. wndclass.style = CS_HREDRAW | CS_VREDRAW;
  829. wndclass.lpfnWndProc = WinProc;
  830. wndclass.cbClsExtra = 0;
  831. wndclass.cbWndExtra = 0;
  832. wndclass.hInstance = hInstance;
  833. wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  834. wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
  835. wndclass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
  836. wndclass.lpszMenuName = NULL;
  837. wndclass.lpszClassName = szAppClassName;
  838.  
  839. // Find out why we have to register the class
  840. if(!RegisterClass(&wndclass)) {
  841. MessageBox(NULL, L"Unable to register class for application", szAppClassName, 0);
  842.  
  843. return 0;
  844. }
  845.  
  846. // Find out what CreateWindows does
  847. hMainWnd = CreateWindow(szAppClassName,
  848. L"Basic Windows Application",
  849. WS_OVERLAPPEDWINDOW,
  850. CW_USEDEFAULT,
  851. CW_USEDEFAULT,
  852. CW_USEDEFAULT,
  853. CW_USEDEFAULT,
  854. NULL,
  855. NULL,
  856. hInstance,
  857. NULL);
  858.  
  859. if(!hMainWnd) {
  860. MessageBox(NULL, L"Unable able to create the application's main window", szAppClassName, 0);
  861.  
  862. return 0;
  863. }
  864.  
  865. ShowWindow(hMainWnd, nInitialWinShowState);
  866.  
  867. if(!InitialiseDirectX(hMainWnd, hInstance)) {
  868. MessageBox(NULL, L"Failed to initialise DirectX", szAppClassName, 0);
  869.  
  870. return 0;
  871. }
  872.  
  873. // Create shaders
  874. if(!CreateShaders(hMainWnd)) {
  875. // Exit program if an error occurred
  876. return 0;
  877. }
  878.  
  879. // Create the vertices of the triangle in DirectX
  880. if(!CreateMeshes(hMainWnd)) {
  881. // Exit program if an error occurred
  882. return 0;
  883. }
  884.  
  885. // Slightly different message loop
  886. DWORD current = GetTickCount();
  887. int count = 0;
  888.  
  889.  
  890. InitialiseKeyboardHandler();
  891.  
  892.  
  893.  
  894. while(msg.message != WM_QUIT) {
  895. if(PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) {
  896. TranslateMessage(&msg);
  897. DispatchMessage(&msg);
  898. } else {
  899. Update();
  900.  
  901. Draw();
  902.  
  903. count++;
  904.  
  905. DWORD now = GetTickCount();
  906. if(now - current > 1000) {
  907. wsprintf(fps, L"FPS = %d", count);
  908.  
  909. SetWindowText(hMainWnd, fps);
  910.  
  911. count = 0;
  912.  
  913. current = now;
  914. }
  915.  
  916. }
  917. }
  918.  
  919.  
  920.  
  921.  
  922.  
  923. ShutdownDirectX();
  924.  
  925. return 0;
  926. }
  927.  
  928. // Windows message procedure, this responds to user and system generated events
  929. LRESULT CALLBACK WinProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
  930. int curMouseXPos, curMouseYPos;
  931. int zDelta;
  932.  
  933. curMouseXPos = (short) LOWORD(lParam);
  934. curMouseYPos = (short) HIWORD(lParam);
  935.  
  936. switch(uMsg) {
  937. // When the user closes the window by pressing the close button
  938. // Tell the application to terminate by breaking the windows message loop
  939.  
  940.  
  941.  
  942. case WM_KEYDOWN:
  943. ProcessKeyDown(wParam);
  944. return 0;
  945.  
  946. case WM_KEYUP:
  947. ProcessKeyUp(wParam);
  948. return 0;
  949.  
  950. case WM_MOUSEMOVE:
  951. curMouseXPos = LOWORD(lParam);
  952. curMouseYPos = HIWORD(lParam);
  953.  
  954. return 0;
  955.  
  956. case WM_LBUTTONDOWN:
  957. SetCapture(hWnd);
  958. mouseXPos = curMouseXPos;
  959. mouseYPos = curMouseYPos;
  960.  
  961. Rotating = true;
  962. break;
  963.  
  964. case WM_LBUTTONUP:
  965. ReleaseCapture();
  966. Rotating = false;
  967. break;
  968.  
  969. case WM_CLOSE:
  970. PostQuitMessage(0);
  971. return 0;
  972. }
  973.  
  974. return DefWindowProc(hWnd, uMsg, wParam, lParam);
  975. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement