Advertisement
Guest User

Untitled

a guest
Nov 23rd, 2017
87
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 33.15 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. XMFLOAT3 skybox[] = {
  42. //Front Face
  43. XMFLOAT3(-1.0F, -1.0F, -1.0F),
  44. XMFLOAT3(-1.0F, -1.0F, -1.0F),
  45. XMFLOAT3(-1.0F, -1.0F, -1.0F),
  46.  
  47. XMFLOAT3(-1.0F, -1.0F, -1.0F),
  48. XMFLOAT3(-1.0F, -1.0F, -1.0F),
  49. XMFLOAT3(-1.0F, -1.0F, -1.0F),
  50.  
  51. // Right side face
  52. XMFLOAT3(1.0f, 1.0f, -1.0f),
  53. XMFLOAT3(1.0f, 1.0f, 1.0f),
  54. XMFLOAT3(1.0f, -1.0f, 1.0f),
  55.  
  56. XMFLOAT3(1.0f, -1.0f, 1.0f),
  57. XMFLOAT3(1.0f, -1.0f, -1.0f),
  58. XMFLOAT3(1.0f, 1.0f, -1.0f),
  59.  
  60. // Back face, note that points are in counter clockwise order
  61. XMFLOAT3(-1.0f, -1.0f, 1.0f),
  62. XMFLOAT3(1.0f, -1.0f, 1.0f),
  63. XMFLOAT3(1.0f, 1.0f, 1.0f),
  64.  
  65. XMFLOAT3(1.0f, 1.0f, 1.0f),
  66. XMFLOAT3(-1.0f, 1.0f, 1.0f),
  67. XMFLOAT3(-1.0f, -1.0f, 1.0f),
  68.  
  69. //// Left side face, note that points are in counter clockwise order
  70. XMFLOAT3(-1.0f, 1.0f, 1.0f),
  71. XMFLOAT3(-1.0f, 1.0f, -1.0f),
  72. XMFLOAT3(-1.0f, -1.0f, -1.0f),
  73.  
  74. XMFLOAT3(-1.0f, -1.0f, -1.0f),
  75. XMFLOAT3(-1.0f, -1.0f, 1.0f),
  76. XMFLOAT3(-1.0f, 1.0f, 1.0f),
  77.  
  78. //// Top face
  79. XMFLOAT3(-1.0f, 1.0f, -1.0f),
  80. XMFLOAT3(-1.0f, 1.0f, 1.0f),
  81. XMFLOAT3(1.0f, 1.0f, 1.0f),
  82.  
  83. XMFLOAT3(1.0f, 1.0f, 1.0f),
  84. XMFLOAT3(1.0f, 1.0f, -1.0f),
  85. XMFLOAT3(-1.0f, 1.0f, -1.0f),
  86.  
  87. //// Bottom face, note that points are in counter clockwise order
  88. XMFLOAT3(-1.0f, -1.0f, -1.0f),
  89. XMFLOAT3(1.0f, -1.0f, -1.0f),
  90. XMFLOAT3(1.0f, -1.0f, 1.0f),
  91.  
  92. XMFLOAT3(1.0f, -1.0f, 1.0f),
  93. XMFLOAT3(-1.0f, -1.0f, 1.0f),
  94. XMFLOAT3(-1.0f, -1.0f, -1.0f),
  95. };
  96.  
  97.  
  98. // Template for a vertex and an associated colour
  99. struct Vertex {
  100. XMFLOAT3 pos;
  101. XMFLOAT2 texCoord;
  102.  
  103. Vertex() {
  104. }
  105.  
  106. Vertex(float x, float y, float z, float u, float v) {
  107. pos.x = x;
  108. pos.y = y;
  109. pos.z = z;
  110.  
  111. texCoord.x = u;
  112. texCoord.y = v;
  113. }
  114. };
  115.  
  116. struct ConstantBuffer
  117. {
  118. XMMATRIX mWorld;
  119. XMMATRIX mView;
  120. XMMATRIX mProjection;
  121. };
  122.  
  123. //[3] Dwarf vertex buffer
  124. ID3D11Buffer *dwarfVertexBuffer = NULL;
  125.  
  126.  
  127.  
  128. //[3c] Car vertex buffer
  129. ID3D11Buffer *carVertexBuffer = NULL;
  130.  
  131.  
  132. ID3D11Buffer *constantBuffer = NULL;
  133. ID3D11VertexShader *vertexShader = NULL;
  134. ID3D11PixelShader *pixelShader = NULL;
  135. ID3D11InputLayout *vertexLayout = NULL;
  136.  
  137. //[4] Define the dwarf texture object variables
  138. ID3D11ShaderResourceView *dwarfTex;
  139. ID3D11ShaderResourceView *axeTex;
  140.  
  141.  
  142. //[4c] Define the car texture object variable
  143. ID3D11ShaderResourceView *carTex;
  144.  
  145.  
  146.  
  147. ID3D11SamplerState *sampler;
  148.  
  149. // Stores the cubemap texture
  150. // Stores the cube vertex buffer onto which the cubemap texture is put
  151. ID3D11Buffer *skyboxVertexBuffer = NULL;
  152. // Skybox vertex and pixel shaders. These shaders are different
  153. // to the shaders we've used so far so have to load them separately
  154. ID3D11VertexShader *skyboxVertexShader = NULL;
  155. ID3D11PixelShader *skyboxPixelShader = NULL;
  156.  
  157.  
  158. ID3D11ShaderResourceView *CubeMap;
  159. ID3D11InputLayout *skyboxVertexLayout;
  160.  
  161. ID3D11RasterizerState *rsCullingOff;
  162. ID3D11RasterizerState *rsCullingOn;
  163.  
  164. ID3D11DepthStencilState* DSDepthOff;
  165. ID3D11DepthStencilState* DSDepthOn;
  166.  
  167.  
  168. DWORD frameTime;
  169.  
  170. // MVP Matrices
  171. XMMATRIX matWorld;
  172. XMMATRIX matView;
  173. XMMATRIX matProjection;
  174.  
  175. float camXPos = 0.0f;
  176. float camYPos = 0.0f;
  177. float camZPos = -50.0f;
  178.  
  179. XMVECTOR camTarget = XMVectorSet(0.0f, 0.0f, 0.0f, 0.0f);
  180. XMVECTOR camUp = XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f);
  181.  
  182. float camRotX = 0.0f;
  183. float camRotY = 0.0f;
  184.  
  185. int curMouseXPos, curMouseYPos;
  186.  
  187. int clientMidX, clientMidY;
  188.  
  189. int winMidX, winMidY;
  190. int winLeft, winTop;
  191.  
  192. float rotFactorY = 0.0f;
  193.  
  194. const float MOVE_STEP = 10.0f;
  195. const float ROTATE_STEP = (XM_PI / 6);
  196.  
  197. // To determine mouse movement need to know how far the mouse has moved
  198. int mouseXPos;
  199. int mouseYPos;
  200.  
  201. // Rotation angles for each axis
  202. float RotationY = 0.0f;
  203. float RotationX = 0.0f;
  204. float RotFactorX = 0.01f;
  205. float RotFactorY = 0.01f;
  206.  
  207. float scale = 1.0f;
  208.  
  209. bool Rotating = false;
  210.  
  211. //Position Variables
  212. //float playerX = 0.0f;
  213. //float playerY = 0.0f;
  214. //float playerZ = 0.0f;
  215.  
  216. //Rotation Variables
  217. //float playerYaw = 0.0f;
  218. //float playerPitch = 0.0f;
  219. //float playerRoll = 0.0f;
  220.  
  221.  
  222. const float MOVE_DIST = 5.0f;
  223. const float ROTATION = XM_PI / 45;
  224.  
  225.  
  226.  
  227.  
  228. //[5] Define a variable to store the number of vertices in each dwarf mesh
  229. int *MeshVertices;
  230.  
  231. //[5c] Define a variable to store the number of vertices in the car mesh
  232. int *CarMeshVertices;
  233.  
  234. // Initialise DirectX in the application
  235. // Involves finding a driver suitable for the
  236. // features required by the game
  237. // If there is one, then it is associated
  238. // with the application by use of a back buffer (one or more)
  239. BOOL InitialiseDirectX(HWND hMainWnd, HINSTANCE hCurInstance) {
  240. RECT rectDimensions;
  241. GetClientRect(hMainWnd, &rectDimensions);
  242.  
  243. LONG width = rectDimensions.right - rectDimensions.left;
  244. LONG height = rectDimensions.bottom - rectDimensions.top;
  245.  
  246. RECT rectWindow;
  247. GetWindowRect(hMainWnd, &rectWindow);
  248.  
  249. winTop = rectWindow.top;
  250. winLeft = rectWindow.left;
  251.  
  252. winMidX = (rectWindow.right - rectWindow.left) / 2;
  253. winMidY = (rectWindow.bottom - rectWindow.top) / 2;
  254.  
  255. clientMidX = width / 2;
  256. clientMidY = height / 2;
  257.  
  258. curMouseXPos = clientMidX;
  259. curMouseYPos = clientMidY;
  260.  
  261. SetCursorPos(winLeft + winMidX, winTop + winMidY);
  262.  
  263. rotFactorY = XM_PIDIV2 / width;
  264.  
  265. // Define the feature levels the program
  266. D3D_FEATURE_LEVEL featureLevels[] = { D3D_FEATURE_LEVEL_11_1 };
  267.  
  268. int numFeatureLevels = sizeof(featureLevels) / sizeof(D3D_FEATURE_LEVEL);
  269.  
  270. // Setup the DXGI_SWAP_CHAIN_DESC structure for describing the type of swap chain to be used
  271. DXGI_SWAP_CHAIN_DESC swapChainDesc;
  272. ZeroMemory(&swapChainDesc, sizeof(swapChainDesc));
  273. swapChainDesc.BufferCount = 1;
  274. swapChainDesc.BufferDesc.Width = width;
  275. swapChainDesc.BufferDesc.Height = height;
  276. swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
  277. swapChainDesc.BufferDesc.RefreshRate.Numerator = 60;
  278. swapChainDesc.BufferDesc.RefreshRate.Denominator = 1;
  279. swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
  280. swapChainDesc.OutputWindow = hMainWnd;
  281. swapChainDesc.Windowed = true;
  282. swapChainDesc.SampleDesc.Count = 1;
  283. swapChainDesc.SampleDesc.Quality = 0;
  284.  
  285. int creationFlags = 0;
  286.  
  287. HRESULT result;
  288.  
  289. // Create the device and swap chain for DirectX 11
  290. result = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE,
  291. NULL, NULL, NULL, NULL, D3D11_SDK_VERSION,
  292. &swapChainDesc, &swapChain, &d3dDevice, NULL, &d3dContext);
  293.  
  294. // Check result
  295. if (result != S_OK) {
  296. MessageBox(hMainWnd, TEXT("Failed to initialise DX11!"), szAppClassName, NULL);
  297.  
  298. return false;
  299. }
  300.  
  301. // Create a texture to be used as the back buffer (off screen)
  302. ID3D11Texture2D *backBufferTexture;
  303.  
  304. result = swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID *) &backBufferTexture);
  305.  
  306. if(result != S_OK) {
  307. MessageBox(hMainWnd, L"Failed to get back buffer!", szAppClassName, NULL);
  308.  
  309. return false;
  310. }
  311.  
  312. result = d3dDevice->CreateRenderTargetView(backBufferTexture, 0, &backBuffer);
  313.  
  314. if(backBufferTexture != NULL) {
  315. backBufferTexture->Release();
  316. }
  317.  
  318. if(result != S_OK) {
  319. MessageBox(hMainWnd, L"Failed to get render target!", szAppClassName, NULL);
  320.  
  321. return false;
  322. }
  323.  
  324. //Define Depth/Stencil Buffer
  325. D3D11_TEXTURE2D_DESC depthStencilDesc;
  326. ZeroMemory(&depthStencilDesc, sizeof(D3D11_TEXTURE2D_DESC));
  327.  
  328. // DepthStencil buffer has same dimensions as back buffer which is the same as the client window
  329. depthStencilDesc.Width = width;
  330. depthStencilDesc.Height = height;
  331. depthStencilDesc.MipLevels = 1;
  332. depthStencilDesc.ArraySize = 1;
  333. // Major difference is depth buffer does not store colour information but depth information
  334. depthStencilDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
  335. depthStencilDesc.SampleDesc.Count = 1;
  336. depthStencilDesc.SampleDesc.Quality = 0;
  337. // As it's a texture need to define DirectX usage, would be useful to use D3D11_USAGE_DYNAMIC flag and caputre
  338. // state of depth buffer to examine the values stored.
  339. depthStencilDesc.Usage = D3D11_USAGE_DEFAULT;
  340. depthStencilDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
  341. depthStencilDesc.CPUAccessFlags = 0;
  342. depthStencilDesc.MiscFlags = 0;
  343.  
  344. // Create the texture for the depthstencil buffer
  345. d3dDevice->CreateTexture2D(&depthStencilDesc, NULL, &depthStencilBuffer);
  346. // Create the depthstencil object based on the texture created precious
  347. d3dDevice->CreateDepthStencilView(depthStencilBuffer, NULL, &depthStencilView);
  348.  
  349. // Bind the back buffer and the depthstencil buffer to the OM stage
  350. d3dContext->OMSetRenderTargets( 1, &backBuffer, depthStencilView );
  351.  
  352. D3D11_VIEWPORT viewport;
  353. viewport.Width = static_cast<float>(width);
  354. viewport.Height = static_cast<float>(height);
  355. viewport.MinDepth = 0.0f;
  356. viewport.MaxDepth = 1.0f;
  357. viewport.TopLeftX = 0.0f;
  358. viewport.TopLeftY = 0.0f;
  359.  
  360. d3dContext->RSSetViewports(1, &viewport);
  361.  
  362.  
  363. XMVECTOR camPos = XMVectorSet(camXPos, camYPos, camZPos, 0.0f);
  364. matView = XMMatrixLookAtLH(camPos, camTarget, camUp);
  365.  
  366. matProjection = XMMatrixPerspectiveFovLH( XM_PIDIV4, width / (FLOAT)height,
  367. 1.0f, 100.0f);
  368.  
  369.  
  370. // Initialize the view matrix
  371. //XMVECTOR Eye = XMVectorSet( 0.0f, 3.0f, -10.0f, 0.0f );
  372. //XMVECTOR At = XMVectorSet( 0.0f, 3.0f, 0.0f, 0.0f );
  373. //XMVECTOR Up = XMVectorSet( 0.0f, 1.0f, 0.0f, 0.0f );
  374. //matView = XMMatrixLookAtLH( Eye, At, Up );
  375.  
  376. // Initialize the projection matrix
  377. matProjection = XMMatrixPerspectiveFovLH( XM_PIDIV4, width / (FLOAT)height, 0.01f, 100.0f );
  378.  
  379. return true;
  380. }
  381.  
  382. bool LoadFace(const wchar_t *filename, int faceIdx, ID3D11Texture2D *cubemapTex) {
  383. // Load the texture into a memory
  384. ID3D11ShaderResourceView *faceData;
  385. ID3D11Resource *faceRes;
  386. HRESULT hr = CreateWICTextureFromFile(d3dDevice, d3dContext, filename, &faceRes, &faceData, 0);
  387.  
  388. if (hr != S_OK) {
  389. return false;
  390. }
  391.  
  392. // Get the texture object from the shader resource loaded
  393. ID3D11Texture2D *tex;
  394.  
  395. hr = faceRes->QueryInterface(__uuidof(ID3D11Texture2D), (LPVOID *)&tex);
  396.  
  397. if (hr != S_OK) {
  398. return false;
  399. }
  400.  
  401. D3D11_TEXTURE2D_DESC texDesc;
  402. ZeroMemory(&texDesc, sizeof(D3D11_TEXTURE2D_DESC));
  403. tex->GetDesc(&texDesc);
  404.  
  405. // Copy texture from shader resource to cubemap face specified by faceIdx
  406. D3D11_BOX srcRegion;
  407.  
  408. srcRegion.front = 0;
  409. srcRegion.back = 1;
  410. srcRegion.top = 0;
  411. srcRegion.left = 0;
  412. srcRegion.bottom = texDesc.Height;
  413. srcRegion.right = texDesc.Width;
  414.  
  415. // Determine the subresource object corresponding to the face id
  416. int face = D3D11CalcSubresource(0, faceIdx, 1);
  417. d3dContext->CopySubresourceRegion(cubemapTex, face, 0, 0, 0, faceRes, 0, &srcRegion);
  418.  
  419. // Release the face texture object
  420. faceData->Release();
  421.  
  422. return true;
  423. }
  424.  
  425.  
  426. bool CreateCubemapSkybox(const wchar_t *up_frame,
  427. const wchar_t *down_frame,
  428. const wchar_t *left_frame,
  429. const wchar_t *right_frame,
  430. const wchar_t *front_frame,
  431. const wchar_t *back_frame,
  432. int lengthOfSide) {
  433.  
  434. D3D11_TEXTURE2D_DESC cubemapDesc;
  435. ZeroMemory(&cubemapDesc, sizeof(D3D11_TEXTURE2D_DESC));
  436.  
  437. cubemapDesc.Width = lengthOfSide;
  438. cubemapDesc.Height = lengthOfSide;
  439. cubemapDesc.MipLevels = 1;
  440. cubemapDesc.ArraySize = 6;
  441. cubemapDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
  442. cubemapDesc.SampleDesc.Count = 1;
  443. cubemapDesc.SampleDesc.Quality = 0;
  444. cubemapDesc.Usage = D3D11_USAGE_DEFAULT;
  445. cubemapDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
  446. cubemapDesc.CPUAccessFlags = 0;
  447. cubemapDesc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;
  448.  
  449. ID3D11Texture2D *cubemapBuffer;
  450.  
  451. HRESULT hr = d3dDevice->CreateTexture2D(&cubemapDesc, nullptr, &cubemapBuffer);
  452.  
  453. if (hr != S_OK) {
  454. return false;
  455. }
  456.  
  457. LoadFace(front_frame, 4, cubemapBuffer);
  458.  
  459. D3D11_SHADER_RESOURCE_VIEW_DESC srDesc;
  460. ZeroMemory(&srDesc, sizeof(D3D11_SHADER_RESOURCE_VIEW_DESC));
  461.  
  462. srDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
  463. srDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
  464. srDesc.Texture2D.MostDetailedMip = 0;
  465. srDesc.Texture2D.MipLevels = 1;
  466.  
  467. hr = d3dDevice->CreateShaderResourceView(cubemapBuffer, &srDesc, &CubeMap);
  468.  
  469. if (hr != S_OK) {
  470. return false;
  471. }
  472.  
  473. cubemapBuffer->Release();
  474.  
  475. D3D11_BUFFER_DESC bd;
  476. ZeroMemory(&bd, sizeof(bd));
  477. bd.Usage = D3D11_USAGE_DEFAULT;
  478. bd.ByteWidth = sizeof(XMFLOAT3) * ARRAYSIZE(skybox);
  479. bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
  480. bd.CPUAccessFlags = 0;
  481.  
  482. D3D11_SUBRESOURCE_DATA InitData;
  483. ZeroMemory(&InitData, sizeof(InitData));
  484.  
  485. InitData.pSysMem = skybox;
  486. hr = d3dDevice->CreateBuffer(&bd, &InitData, &skyboxVertexBuffer);
  487. if (hr != S_OK) {
  488. return false;
  489. }
  490.  
  491. }
  492. // Transition from a list of vertices to a final rasterised image.
  493. // In DirectX10 and DirectX11 it is typical to render using shaders, a vertex shader to apply
  494. // a transformation to the vertices and a pixel shader to shade/colour pixels in a list of vertices
  495. bool CreateShaders(HWND hMainWnd) {
  496. // Create the vertex shader first although order does not matter.
  497. // What does matter is shaders were loaded, compiled and then represented in as DirectX objects.
  498. // Otherwise will not get the output we want
  499.  
  500. ID3DBlob *skypVSBlob = NULL;
  501. HRESULT skyhr = D3DReadFileToBlob(L".\\SkyboxVertexShader.cso", &skypVSBlob);
  502. if (skyhr != S_OK)
  503. {
  504. MessageBox(hMainWnd, L"Problem loading skybox vertex shader. Check shader file (SkyboxVertexShader.cso) is in the project directory (sub folder of main solution directory) and shader is valid", szAppClassName, MB_OK);
  505.  
  506. return false;
  507. }
  508.  
  509. ID3DBlob *pVSBlob = NULL;
  510. HRESULT hr = D3DReadFileToBlob( L".\\VertexShader.cso", &pVSBlob);
  511. if( hr != S_OK )
  512. {
  513. 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 );
  514.  
  515. return false;
  516. }
  517.  
  518. // Create the vertex shader in DirectX
  519. hr = d3dDevice->CreateVertexShader( pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), NULL, &vertexShader );
  520. // Check creating vertex shader was successful
  521. if( hr != S_OK )
  522. {
  523. pVSBlob->Release();
  524.  
  525. MessageBox( hMainWnd, L"The vertex shader object cannot be created", szAppClassName, MB_OK );
  526.  
  527. return false;
  528. }
  529.  
  530. D3D11_INPUT_ELEMENT_DESC skybox_layout[] =
  531. {
  532. { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
  533. };
  534.  
  535. UINT numElements = 1;
  536.  
  537. skyhr = d3dDevice->CreateInputLayout(skybox_layout,
  538. numElements,
  539. skypVSBlob->GetBufferPointer(), skypVSBlob->GetBufferSize(), &skyboxVertexLayout);
  540.  
  541. if (skyhr != S_OK) {
  542. MessageBox(hMainWnd, L"Problem creating skybox input layout", szAppClassName, MB_OK);
  543.  
  544. return false;
  545.  
  546. }
  547.  
  548. // Need to tell DirectX how vertices are structured in terms of colour format and order of data, that is individual vertices
  549. // The POSITION is called the semantic name, basically a meaningful identifier used internally to map vertex elements to shader
  550. // parameters. Semantic name text must obey the rules of C identifiers as shader language uses C syntax
  551. D3D11_INPUT_ELEMENT_DESC layout[] =
  552. {
  553. { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
  554. { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
  555. };
  556.  
  557. UINT skynumElements = 3;
  558.  
  559. // Create the input layout for input assembler based on description and the vertex shader to be used
  560. hr = d3dDevice->CreateInputLayout( layout, numElements, pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), &vertexLayout );
  561. // Check layout was created successfully
  562. pVSBlob->Release();
  563. if( hr != S_OK ) {
  564. MessageBox( hMainWnd, L"Problems creating input layout", szAppClassName, MB_OK );
  565.  
  566. return false;
  567. }
  568.  
  569. // Set the input layout for input assembler
  570. d3dContext->IASetInputLayout( vertexLayout );
  571.  
  572. // Compile the pixel shader
  573. ID3DBlob* pPSBlob = NULL;
  574. hr = D3DReadFileToBlob( L".\\PixelShader.cso", &pPSBlob);
  575. // Check pixel shader was loaded successfully
  576. if( hr != S_OK )
  577. {
  578. // 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
  579. 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 );
  580.  
  581. return false;
  582. }
  583.  
  584. // Create the pixel shader in DirectX
  585. hr = d3dDevice->CreatePixelShader( pPSBlob->GetBufferPointer(), pPSBlob->GetBufferSize(), NULL, &pixelShader );
  586. pPSBlob->Release();
  587. // Check creating pixel shader was successful
  588. if( hr != S_OK ) {
  589. MessageBox( hMainWnd, L"The pixel shader object cannot be created", szAppClassName, MB_OK );
  590.  
  591. return false;
  592. }
  593.  
  594. //[6] Load dwarf texture
  595. hr = CreateWICTextureFromFile(d3dDevice, d3dContext, L".\\dwarf.jpg", NULL, &dwarfTex);
  596. if (hr != S_OK) {
  597. MessageBox(hMainWnd, TEXT("Unable to load dwarf texture"), szAppClassName, MB_OK);
  598.  
  599. return false;
  600. }
  601.  
  602.  
  603. //[7] Load axe texture
  604. hr = CreateWICTextureFromFile(d3dDevice, d3dContext, L".\\axe.jpg", NULL, &axeTex);
  605. if (hr != S_OK) {
  606. MessageBox(hMainWnd, TEXT("Unable to load dwarf texture"), szAppClassName, MB_OK);
  607.  
  608. return false;
  609. }
  610.  
  611. //[6c] Load car texture
  612. hr = CreateWICTextureFromFile(d3dDevice, d3dContext, L".\\Car07.jpg", NULL, &carTex);
  613. if (hr != S_OK) {
  614. MessageBox(hMainWnd, TEXT("Unable to load car texture"), szAppClassName, MB_OK);
  615.  
  616. return false;
  617. }
  618.  
  619. D3D11_SAMPLER_DESC sampDesc;
  620. ZeroMemory(&sampDesc, sizeof(sampDesc));
  621. sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
  622. sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
  623. sampDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
  624. sampDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
  625. sampDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
  626. sampDesc.MaxLOD = D3D11_FLOAT32_MAX;
  627.  
  628. hr = d3dDevice->CreateSamplerState(&sampDesc, &sampler);
  629. if(hr != S_OK) {
  630. MessageBox( hMainWnd, TEXT("Unable to create sampler"), szAppClassName, MB_OK );
  631.  
  632. return false;
  633. }
  634.  
  635. // If we've got this far then have valid shaders.
  636. // Return a successful result
  637. return true;
  638. }
  639.  
  640. bool LoadDwarfModel() {
  641. //[8] Create importer object
  642. Assimp::Importer imp;
  643.  
  644.  
  645. //[9] Load model into scene object
  646. const aiScene *pScene = imp.ReadFile(".\\dwarf.x",
  647. aiProcessPreset_TargetRealtime_Fast | aiProcess_ConvertToLeftHanded);
  648. if (!pScene) {
  649. return false;
  650. }
  651.  
  652.  
  653. if (!pScene) {
  654. return false;
  655. }
  656.  
  657. //[10] Create an array to store the individual number of vertices in each mesh
  658. MeshVertices = new int[pScene->mNumMeshes];
  659.  
  660.  
  661. //[11] Calculate the total number of vertices from all meshes
  662. int TotalNumVertices = 0;
  663. for (int MeshIdx = 0; MeshIdx < pScene->mNumMeshes; MeshIdx++) {
  664. const aiMesh *mesh = pScene->mMeshes[MeshIdx];
  665.  
  666. MeshVertices[MeshIdx] = mesh->mNumFaces * 3;
  667.  
  668. TotalNumVertices += mesh->mNumFaces * 3;
  669. }
  670.  
  671.  
  672. //[12] Create an array to store all vertices
  673. Vertex *shape = new Vertex[TotalNumVertices];
  674.  
  675.  
  676.  
  677. //[13] Convert the assimp vertices to ones for DirectX
  678. int vertCount = 0;
  679. for (int MeshIdx = 0; MeshIdx < pScene->mNumMeshes; MeshIdx++) {
  680. const aiMesh *mesh = pScene->mMeshes[MeshIdx];
  681.  
  682. for (int faceIdx = 0; faceIdx < mesh->mNumFaces; faceIdx++) {
  683. const aiFace& face = mesh->mFaces[faceIdx];
  684.  
  685. for (int vertIdx = 0; vertIdx < 3; vertIdx++) {
  686. const aiVector3D *pos = &mesh->mVertices[face.mIndices[vertIdx]];
  687. const aiVector3D *tex = &mesh->mTextureCoords[0][face.mIndices[vertIdx]];
  688.  
  689. shape[vertCount] = Vertex(pos->x, pos->y, pos->z, tex->x, tex->y);
  690. vertCount++;
  691. }
  692. }
  693.  
  694. }
  695.  
  696.  
  697.  
  698. //[14] Define the vertex buffer
  699. D3D11_BUFFER_DESC bd;
  700. ZeroMemory(&bd, sizeof(bd));
  701. bd.Usage = D3D11_USAGE_DEFAULT;
  702. bd.ByteWidth = sizeof(Vertex) * TotalNumVertices;
  703. bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
  704. bd.CPUAccessFlags = 0;
  705.  
  706.  
  707. // Define the source of vertex data in RAM
  708. D3D11_SUBRESOURCE_DATA InitData;
  709. ZeroMemory(&InitData, sizeof(InitData));
  710. InitData.pSysMem = shape;
  711. HRESULT hr = d3dDevice->CreateBuffer(&bd, &InitData, &dwarfVertexBuffer);
  712.  
  713. if (hr != S_OK) {
  714. return false;
  715. }
  716.  
  717.  
  718. //[15] Release memory allocated to shape
  719. delete[] shape;
  720.  
  721.  
  722. // Got this far so model loaded okay
  723. return true;
  724. }
  725.  
  726. bool LoadCarModel() {
  727. //[8] Create importer object
  728. Assimp::Importer imp1;
  729.  
  730.  
  731. //[9] Load model into scene object
  732. const aiScene *pScene = imp1.ReadFile(".\\car07.3DS",
  733. aiProcessPreset_TargetRealtime_Fast | aiProcess_ConvertToLeftHanded);
  734. if (!pScene) {
  735. return false;
  736. }
  737.  
  738.  
  739. if (!pScene) {
  740. return false;
  741. }
  742.  
  743. //[10] Create an array to store the individual number of vertices in each mesh
  744. CarMeshVertices = new int[pScene->mNumMeshes];
  745.  
  746.  
  747. //[11] Calculate the total number of vertices from all meshes
  748. int TotalNumVertices = 0;
  749. for (int MeshIdx = 0; MeshIdx < pScene->mNumMeshes; MeshIdx++) {
  750. const aiMesh *mesh = pScene->mMeshes[MeshIdx];
  751.  
  752. CarMeshVertices[MeshIdx] = mesh->mNumFaces * 3;
  753.  
  754. TotalNumVertices += mesh->mNumFaces * 3;
  755. }
  756.  
  757.  
  758. //[12] Create an array to store all vertices
  759. Vertex *shape1 = new Vertex[TotalNumVertices];
  760.  
  761.  
  762.  
  763. //[13] Convert the assimp vertices to ones for DirectX
  764. int vertCount = 0;
  765. for (int MeshIdx = 0; MeshIdx < pScene->mNumMeshes; MeshIdx++) {
  766. const aiMesh *mesh = pScene->mMeshes[MeshIdx];
  767.  
  768. for (int faceIdx = 0; faceIdx < mesh->mNumFaces; faceIdx++) {
  769. const aiFace& face = mesh->mFaces[faceIdx];
  770.  
  771. for (int vertIdx = 0; vertIdx < 3; vertIdx++) {
  772. const aiVector3D *pos = &mesh->mVertices[face.mIndices[vertIdx]];
  773. const aiVector3D *tex = &mesh->mTextureCoords[0][face.mIndices[vertIdx]];
  774.  
  775. shape1[vertCount] = Vertex(pos->x, pos->y, pos->z, tex->x, tex->y);
  776. vertCount++;
  777. }
  778. }
  779.  
  780. }
  781.  
  782.  
  783.  
  784. //[14] Define the vertex buffer
  785. D3D11_BUFFER_DESC bd;
  786. ZeroMemory(&bd, sizeof(bd));
  787. bd.Usage = D3D11_USAGE_DEFAULT;
  788. bd.ByteWidth = sizeof(Vertex) * TotalNumVertices;
  789. bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
  790. bd.CPUAccessFlags = 0;
  791.  
  792.  
  793. // Define the source of vertex data in RAM
  794. D3D11_SUBRESOURCE_DATA InitData;
  795. ZeroMemory(&InitData, sizeof(InitData));
  796. InitData.pSysMem = shape1;
  797. HRESULT hr = d3dDevice->CreateBuffer(&bd, &InitData, &carVertexBuffer);
  798.  
  799. if (hr != S_OK) {
  800. return false;
  801. }
  802.  
  803.  
  804. //[15] Release memory allocated to shape
  805. delete[] shape1;
  806.  
  807.  
  808. // Got this far so model loaded okay
  809. return true;
  810. }
  811.  
  812. bool CreateMeshes(HWND hMainWnd) {
  813. if (!LoadDwarfModel()) {
  814. MessageBox(hMainWnd, L"Failed to load and create dwarf model", szAppClassName, NULL);
  815.  
  816. return false;
  817. }
  818.  
  819. if (!LoadCarModel()) {
  820. MessageBox(hMainWnd, L"Failed to load and create car model", szAppClassName, NULL);
  821.  
  822. return false;
  823. }
  824.  
  825. // Create the constant buffer
  826. D3D11_BUFFER_DESC bd;
  827. ZeroMemory(&bd, sizeof(D3D11_BUFFER_DESC));
  828. bd.Usage = D3D11_USAGE_DEFAULT;
  829. bd.ByteWidth = sizeof(ConstantBuffer);
  830. bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
  831. bd.CPUAccessFlags = 0;
  832. HRESULT hr = d3dDevice->CreateBuffer( &bd, NULL, &constantBuffer );
  833. if( hr != S_OK ) {
  834. MessageBox(hMainWnd, L"Failed to create constant buffer", szAppClassName, NULL);
  835.  
  836. return false;
  837. }
  838.  
  839. // If we've got this far then have vertice structure in DirectX.
  840. // Return a successful result
  841. return true;
  842. }
  843.  
  844.  
  845. void Update() {
  846. // Does nothing as mouse control is elsewhere
  847. DWORD now = GetTickCount();
  848. DWORD diff = now - frameTime;
  849.  
  850. const float move_step = 10.0f;
  851.  
  852. float forwards_backwards = 0.0f;
  853. float left_right = 0.0f;
  854.  
  855. if (IsKeyDown('W')) {
  856. forwards_backwards = move_step * (diff / 1000.0f);
  857. }
  858.  
  859. if (IsKeyDown('S')) {
  860. forwards_backwards = -move_step * (diff / 1000.0f);
  861. }
  862.  
  863. int deltaX = clientMidX - curMouseXPos;
  864.  
  865. camRotY -= deltaX * rotFactorY;
  866.  
  867. SetCursorPos(winLeft + winMidX, winTop + winMidY);
  868.  
  869. XMMATRIX camMove = XMMatrixTranslation(0.0f, 0.0f, forwards_backwards) *
  870. XMMatrixRotationRollPitchYaw(camRotX, camRotY, 0.0f);
  871.  
  872. XMVECTOR scale, rot, trans;
  873. XMMatrixDecompose(&scale, &rot, &trans, camMove);
  874.  
  875. camXPos += XMVectorGetX(trans);
  876. camYPos += XMVectorGetY(trans);
  877. camZPos += XMVectorGetZ(trans);
  878.  
  879. XMVECTOR camPos = XMVectorSet(camXPos, camYPos, camZPos, 0.0f);
  880.  
  881. XMMATRIX camDist = XMMatrixTranslation(0.0f, 0.0f, 10.0f) *
  882. XMMatrixRotationRollPitchYaw(camRotX, camRotY, 0.0f);
  883.  
  884. XMMatrixDecompose(&scale, &rot, &trans, camDist);
  885.  
  886. camTarget = XMVectorSet(camXPos + XMVectorGetX(trans),
  887. camYPos + XMVectorGetY(trans),
  888. camZPos + XMVectorGetZ(trans), 0.0f);
  889.  
  890. matView = XMMatrixLookAtLH(camPos, camTarget, camUp);
  891.  
  892. frameTime = now;
  893. }
  894.  
  895. // Renders a frame, what does this function do?
  896. void Draw() {
  897. if(d3dContext == NULL) {
  898. return;
  899. }
  900.  
  901. matWorld = XMMatrixIdentity() * XMMatrixScaling(0.3f, 0.3f, 0.3f);
  902.  
  903. matWorld = XMMatrixScaling(0.1f, 0.1f, 0.1f) * XMMatrixRotationY(-RotationY) * XMMatrixTranslation(0.0f, 0.0f, 20.0f);
  904.  
  905. ConstantBuffer cb;
  906.  
  907. matWorld = XMMatrixTranslation(camXPos, camYPos, camZPos);
  908.  
  909. cb.mWorld = XMMatrixTranspose( matWorld );
  910. cb.mView = XMMatrixTranspose( matView );
  911. cb.mProjection = XMMatrixTranspose( matProjection );
  912. d3dContext->UpdateSubresource( constantBuffer, 0, NULL, &cb, 0, 0 );
  913.  
  914. float colour[] = {0.392156f, 0.584313f, 0.929411f, 1.0f};
  915.  
  916. d3dContext->ClearRenderTargetView(backBuffer, colour);
  917. // Clear the depth of depthstencil buffer to 1.0f for new frame
  918. d3dContext->ClearDepthStencilView(depthStencilView, D3D11_CLEAR_DEPTH, 1.0f, 0);
  919.  
  920. // Render a triangle. Not directly from vertices but from applying the shaders
  921. d3dContext->VSSetShader( vertexShader, NULL, 0 );
  922. d3dContext->VSSetConstantBuffers( 0, 1, &constantBuffer );
  923. d3dContext->PSSetShader( pixelShader, NULL, 0 );
  924.  
  925. //[16] Select vertex buffer with all of the mesh vertices
  926. UINT stride = sizeof(Vertex);
  927. UINT offset = 0;
  928. d3dContext->IASetVertexBuffers(0, 1, &dwarfVertexBuffer, &stride, &offset);
  929. d3dContext->IAGetVertexBuffers(0, 1, &skyboxVertexBuffer, &stride, &offset);
  930.  
  931.  
  932. //[11] Set the skybox shaders
  933. // Set up to render skybox, remember skybox has different shaders to
  934. // other models because it uses a cubemap
  935. d3dContext->VSSetShader(skyboxVertexShader, NULL, 0);
  936. d3dContext->PSSetShader(skyboxPixelShader, NULL, 0);
  937. d3dContext->PSSetSamplers(0, 1, &sampler);
  938.  
  939. d3dContext->PSSetShaderResources(1, 1, &CubeMap);
  940.  
  941. d3dContext->IASetInputLayout(skyboxVertexLayout);
  942.  
  943. //UINT stride = sizeof(XMFLOAT3);
  944. //UINT offset = 0;
  945.  
  946.  
  947. d3dContext->OMSetDepthStencilState(DSDepthOff, 0);
  948.  
  949. d3dContext->RSSetState(rsCullingOff);
  950.  
  951. d3dContext->Draw(ARRAYSIZE(skybox), 0);
  952.  
  953. d3dContext->RSSetState(rsCullingOn);
  954. d3dContext->OMSetDepthStencilState(DSDepthOn, 0);
  955.  
  956.  
  957. // Also tell input assembler how the vertices are to be treated.
  958. d3dContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST );
  959.  
  960. // Select the sampler
  961. d3dContext->PSSetSamplers(0, 1, &sampler);
  962.  
  963. ////[17] Select the axe texture first
  964. d3dContext->PSSetShaderResources(1, 1, &axeTex);
  965.  
  966.  
  967.  
  968. ////[18] Draw the axe mesh
  969. d3dContext->Draw(MeshVertices[0], 1);
  970.  
  971.  
  972. ////[19] Select the dwarf texture
  973. d3dContext->PSSetShaderResources(1, 1, &dwarfTex);
  974.  
  975.  
  976. ////[20] Draw the dwarf mesh
  977. d3dContext->Draw(MeshVertices[1], MeshVertices[0]);
  978.  
  979.  
  980. //[16c] Select car vertex buffer into pipeline
  981. d3dContext->IASetVertexBuffers(0, 1, &carVertexBuffer, &stride, &offset);
  982.  
  983.  
  984. //[17c] Select car texture into pipeline
  985. d3dContext->PSSetShaderResources(1, 1, &carTex);
  986.  
  987.  
  988. //[18c] Draw car
  989. d3dContext->Draw(CarMeshVertices[0], CarMeshVertices[0]);
  990.  
  991. // Display frame immediately
  992. swapChain->Present(0,0);
  993. }
  994.  
  995. // Release the resources allocated to application as a result of
  996. // using DirectX
  997. void ShutdownDirectX() {
  998. if(dwarfTex) {
  999. dwarfTex->Release();
  1000. }
  1001.  
  1002. if (axeTex) {
  1003. axeTex->Release();
  1004. }
  1005.  
  1006. if(dwarfVertexBuffer != NULL)
  1007. dwarfVertexBuffer->Release();
  1008.  
  1009. if (carTex) {
  1010. carTex->Release();
  1011. }
  1012.  
  1013. if (carVertexBuffer != NULL)
  1014. carVertexBuffer->Release();
  1015.  
  1016. // Add source code to release car buffer and texture
  1017.  
  1018. if (CubeMap) {
  1019. CubeMap->Release();
  1020. }
  1021.  
  1022. if (rsCullingOn) {
  1023. rsCullingOn->Release();
  1024. }
  1025.  
  1026. if (rsCullingOff) {
  1027. rsCullingOff->Release();
  1028. }
  1029.  
  1030. if (DSDepthOn) {
  1031. DSDepthOn->Release();
  1032. }
  1033.  
  1034. if (DSDepthOff) {
  1035. DSDepthOff->Release();
  1036. }
  1037.  
  1038. if (skyboxVertexBuffer) {
  1039. skyboxVertexBuffer->Release();
  1040. }
  1041.  
  1042. if (skyboxVertexLayout) {
  1043. skyboxVertexLayout->Release();
  1044. }
  1045.  
  1046. if (skyboxPixelShader) {
  1047. skyboxPixelShader->Release();
  1048. }
  1049.  
  1050. if (skyboxVertexBuffer) {
  1051. skyboxVertexBuffer->Release();
  1052. }
  1053.  
  1054.  
  1055.  
  1056.  
  1057. if (sampler) {
  1058. sampler->Release();
  1059. }
  1060.  
  1061.  
  1062. if(vertexShader != NULL)
  1063. vertexShader->Release();
  1064.  
  1065. if(pixelShader != NULL)
  1066. pixelShader->Release();
  1067.  
  1068. if(vertexLayout != NULL)
  1069. vertexLayout->Release();
  1070.  
  1071. if(backBuffer) {
  1072. backBuffer->Release();
  1073. }
  1074.  
  1075. if(depthStencilView) {
  1076. depthStencilView->Release();
  1077. }
  1078.  
  1079. if(depthStencilBuffer) {
  1080. depthStencilBuffer->Release();
  1081. }
  1082.  
  1083. if(swapChain) {
  1084. swapChain->Release();
  1085. }
  1086.  
  1087. if(d3dContext) {
  1088. d3dContext->Release();
  1089. }
  1090.  
  1091. if(d3dDevice) {
  1092. d3dDevice->Release();
  1093.  
  1094. backBuffer = 0;
  1095. swapChain = 0;
  1096. d3dContext = 0;
  1097. d3dDevice = 0;
  1098. }
  1099. }
  1100.  
  1101. int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLineArgs, int nInitialWinShowState) {
  1102. HWND hMainWnd;
  1103. MSG msg = {0};
  1104. // Find out what a WNDCLASS is and what it is used for
  1105. WNDCLASS wndclass;
  1106. wchar_t fps[ 64 ];
  1107. ZeroMemory(fps, 64);
  1108.  
  1109. wndclass.style = CS_HREDRAW | CS_VREDRAW;
  1110. wndclass.lpfnWndProc = WinProc;
  1111. wndclass.cbClsExtra = 0;
  1112. wndclass.cbWndExtra = 0;
  1113. wndclass.hInstance = hInstance;
  1114. wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  1115. wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
  1116. wndclass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
  1117. wndclass.lpszMenuName = NULL;
  1118. wndclass.lpszClassName = szAppClassName;
  1119.  
  1120. // Find out why we have to register the class
  1121. if(!RegisterClass(&wndclass)) {
  1122. MessageBox(NULL, L"Unable to register class for application", szAppClassName, 0);
  1123.  
  1124. return 0;
  1125. }
  1126.  
  1127. // Find out what CreateWindows does
  1128. hMainWnd = CreateWindow(szAppClassName,
  1129. L"Basic Windows Application",
  1130. WS_OVERLAPPEDWINDOW,
  1131. CW_USEDEFAULT,
  1132. CW_USEDEFAULT,
  1133. CW_USEDEFAULT,
  1134. CW_USEDEFAULT,
  1135. NULL,
  1136. NULL,
  1137. hInstance,
  1138. NULL);
  1139.  
  1140. if(!hMainWnd) {
  1141. MessageBox(NULL, L"Unable able to create the application's main window", szAppClassName, 0);
  1142.  
  1143. return 0;
  1144. }
  1145.  
  1146. ShowWindow(hMainWnd, nInitialWinShowState);
  1147.  
  1148. if(!InitialiseDirectX(hMainWnd, hInstance)) {
  1149. MessageBox(NULL, L"Failed to initialise DirectX", szAppClassName, 0);
  1150.  
  1151. return 0;
  1152. }
  1153.  
  1154. // Create shaders
  1155. if(!CreateShaders(hMainWnd)) {
  1156. // Exit program if an error occurred
  1157. return 0;
  1158. }
  1159.  
  1160. // Create the vertices of the triangle in DirectX
  1161. if(!CreateMeshes(hMainWnd)) {
  1162. // Exit program if an error occurred
  1163. return 0;
  1164. }
  1165.  
  1166. if (!CreateCubemapSkybox(L".\\assets\\up.jpg",
  1167. L".\\assets\\down.jpg",
  1168. L".\\assets\\left.jpg",
  1169. L".\\assets\\right.jpg",
  1170. L".\\assets\\front.jpg",
  1171. L".\\assets\\back.jpg", 512)) {
  1172. return 0;
  1173. }
  1174.  
  1175. // Slightly different message loop
  1176. DWORD current = GetTickCount();
  1177. int count = 0;
  1178.  
  1179.  
  1180. InitialiseKeyboardHandler();
  1181.  
  1182.  
  1183.  
  1184. while(msg.message != WM_QUIT) {
  1185. if(PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) {
  1186. TranslateMessage(&msg);
  1187. DispatchMessage(&msg);
  1188. } else {
  1189. Update();
  1190.  
  1191. Draw();
  1192.  
  1193. count++;
  1194.  
  1195. DWORD now = GetTickCount();
  1196. if(now - current > 1000) {
  1197. wsprintf(fps, L"FPS = %d", count);
  1198.  
  1199. SetWindowText(hMainWnd, fps);
  1200.  
  1201. count = 0;
  1202.  
  1203. current = now;
  1204. }
  1205.  
  1206. }
  1207. }
  1208.  
  1209.  
  1210.  
  1211.  
  1212.  
  1213. ShutdownDirectX();
  1214.  
  1215. return 0;
  1216. }
  1217.  
  1218. // Windows message procedure, this responds to user and system generated events
  1219. LRESULT CALLBACK WinProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
  1220. int curMouseXPos, curMouseYPos;
  1221. int zDelta;
  1222.  
  1223. curMouseXPos = (short) LOWORD(lParam);
  1224. curMouseYPos = (short) HIWORD(lParam);
  1225.  
  1226. switch(uMsg) {
  1227. // When the user closes the window by pressing the close button
  1228. // Tell the application to terminate by breaking the windows message loop
  1229.  
  1230.  
  1231.  
  1232. case WM_KEYDOWN:
  1233. ProcessKeyDown(wParam);
  1234. return 0;
  1235.  
  1236. case WM_KEYUP:
  1237. ProcessKeyUp(wParam);
  1238. return 0;
  1239.  
  1240. case WM_MOUSEMOVE:
  1241. curMouseXPos = LOWORD(lParam);
  1242. curMouseYPos = HIWORD(lParam);
  1243.  
  1244. return 0;
  1245.  
  1246. case WM_LBUTTONDOWN:
  1247. SetCapture(hWnd);
  1248. mouseXPos = curMouseXPos;
  1249. mouseYPos = curMouseYPos;
  1250.  
  1251. Rotating = true;
  1252. break;
  1253.  
  1254. case WM_LBUTTONUP:
  1255. ReleaseCapture();
  1256. Rotating = false;
  1257. break;
  1258.  
  1259. case WM_CLOSE:
  1260. PostQuitMessage(0);
  1261. return 0;
  1262. }
  1263.  
  1264. return DefWindowProc(hWnd, uMsg, wParam, lParam);
  1265. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement