Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <windows.h>
- #include <d3d11.h>
- #include <d3dcompiler.h>
- #include <DirectXMath.h>
- #include <stdio.h>
- #include <WICTextureLoader.h>
- #include "keyprocessor.h"
- //[1] Add the assimp libraries
- #include <assimp/Importer.hpp>
- #include <assimp/postprocess.h>
- #include <assimp/scene.h>
- using namespace DirectX;
- #pragma comment(lib, "d3d11.lib")
- #pragma comment(lib, "d3dcompiler.lib")
- #pragma comment(lib, "DirectXTK.lib")
- //[2] Add the assimp library
- #pragma comment(lib, "assimp-vc140-mt.lib")
- // Window class name
- static wchar_t szAppClassName[] = L"AssImpEx";
- // Forward definition of Windows procedure, necessary as Windows Procedure is defined last and
- // C++ requires identifiers are declared before use
- LRESULT CALLBACK WinProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
- // DirectX objects
- ID3D11Device *d3dDevice;
- ID3D11DeviceContext *d3dContext;
- IDXGISwapChain *swapChain;
- ID3D11RenderTargetView *backBuffer;
- // Depth buffer texture and object
- ID3D11Texture2D* depthStencilBuffer;
- ID3D11DepthStencilView* depthStencilView;
- XMFLOAT3 skybox[] = {
- //Front Face
- XMFLOAT3(-1.0F, -1.0F, -1.0F),
- XMFLOAT3(-1.0F, -1.0F, -1.0F),
- XMFLOAT3(-1.0F, -1.0F, -1.0F),
- XMFLOAT3(-1.0F, -1.0F, -1.0F),
- XMFLOAT3(-1.0F, -1.0F, -1.0F),
- XMFLOAT3(-1.0F, -1.0F, -1.0F),
- // Right side face
- XMFLOAT3(1.0f, 1.0f, -1.0f),
- XMFLOAT3(1.0f, 1.0f, 1.0f),
- XMFLOAT3(1.0f, -1.0f, 1.0f),
- XMFLOAT3(1.0f, -1.0f, 1.0f),
- XMFLOAT3(1.0f, -1.0f, -1.0f),
- XMFLOAT3(1.0f, 1.0f, -1.0f),
- // Back face, note that points are in counter clockwise order
- XMFLOAT3(-1.0f, -1.0f, 1.0f),
- XMFLOAT3(1.0f, -1.0f, 1.0f),
- XMFLOAT3(1.0f, 1.0f, 1.0f),
- XMFLOAT3(1.0f, 1.0f, 1.0f),
- XMFLOAT3(-1.0f, 1.0f, 1.0f),
- XMFLOAT3(-1.0f, -1.0f, 1.0f),
- //// Left side face, note that points are in counter clockwise order
- XMFLOAT3(-1.0f, 1.0f, 1.0f),
- XMFLOAT3(-1.0f, 1.0f, -1.0f),
- XMFLOAT3(-1.0f, -1.0f, -1.0f),
- XMFLOAT3(-1.0f, -1.0f, -1.0f),
- XMFLOAT3(-1.0f, -1.0f, 1.0f),
- XMFLOAT3(-1.0f, 1.0f, 1.0f),
- //// Top face
- XMFLOAT3(-1.0f, 1.0f, -1.0f),
- XMFLOAT3(-1.0f, 1.0f, 1.0f),
- XMFLOAT3(1.0f, 1.0f, 1.0f),
- XMFLOAT3(1.0f, 1.0f, 1.0f),
- XMFLOAT3(1.0f, 1.0f, -1.0f),
- XMFLOAT3(-1.0f, 1.0f, -1.0f),
- //// Bottom face, note that points are in counter clockwise order
- XMFLOAT3(-1.0f, -1.0f, -1.0f),
- XMFLOAT3(1.0f, -1.0f, -1.0f),
- XMFLOAT3(1.0f, -1.0f, 1.0f),
- XMFLOAT3(1.0f, -1.0f, 1.0f),
- XMFLOAT3(-1.0f, -1.0f, 1.0f),
- XMFLOAT3(-1.0f, -1.0f, -1.0f),
- };
- // Template for a vertex and an associated colour
- struct Vertex {
- XMFLOAT3 pos;
- XMFLOAT2 texCoord;
- Vertex() {
- }
- Vertex(float x, float y, float z, float u, float v) {
- pos.x = x;
- pos.y = y;
- pos.z = z;
- texCoord.x = u;
- texCoord.y = v;
- }
- };
- struct ConstantBuffer
- {
- XMMATRIX mWorld;
- XMMATRIX mView;
- XMMATRIX mProjection;
- };
- //[3] Dwarf vertex buffer
- ID3D11Buffer *dwarfVertexBuffer = NULL;
- //[3c] Car vertex buffer
- ID3D11Buffer *carVertexBuffer = NULL;
- ID3D11Buffer *constantBuffer = NULL;
- ID3D11VertexShader *vertexShader = NULL;
- ID3D11PixelShader *pixelShader = NULL;
- ID3D11InputLayout *vertexLayout = NULL;
- //[4] Define the dwarf texture object variables
- ID3D11ShaderResourceView *dwarfTex;
- ID3D11ShaderResourceView *axeTex;
- //[4c] Define the car texture object variable
- ID3D11ShaderResourceView *carTex;
- ID3D11SamplerState *sampler;
- // Stores the cubemap texture
- // Stores the cube vertex buffer onto which the cubemap texture is put
- ID3D11Buffer *skyboxVertexBuffer = NULL;
- // Skybox vertex and pixel shaders. These shaders are different
- // to the shaders we've used so far so have to load them separately
- ID3D11VertexShader *skyboxVertexShader = NULL;
- ID3D11PixelShader *skyboxPixelShader = NULL;
- ID3D11ShaderResourceView *CubeMap;
- ID3D11InputLayout *skyboxVertexLayout;
- ID3D11RasterizerState *rsCullingOff;
- ID3D11RasterizerState *rsCullingOn;
- ID3D11DepthStencilState* DSDepthOff;
- ID3D11DepthStencilState* DSDepthOn;
- DWORD frameTime;
- // MVP Matrices
- XMMATRIX matWorld;
- XMMATRIX matView;
- XMMATRIX matProjection;
- float camXPos = 0.0f;
- float camYPos = 0.0f;
- float camZPos = -50.0f;
- XMVECTOR camTarget = XMVectorSet(0.0f, 0.0f, 0.0f, 0.0f);
- XMVECTOR camUp = XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f);
- float camRotX = 0.0f;
- float camRotY = 0.0f;
- int curMouseXPos, curMouseYPos;
- int clientMidX, clientMidY;
- int winMidX, winMidY;
- int winLeft, winTop;
- float rotFactorY = 0.0f;
- const float MOVE_STEP = 10.0f;
- const float ROTATE_STEP = (XM_PI / 6);
- // To determine mouse movement need to know how far the mouse has moved
- int mouseXPos;
- int mouseYPos;
- // Rotation angles for each axis
- float RotationY = 0.0f;
- float RotationX = 0.0f;
- float RotFactorX = 0.01f;
- float RotFactorY = 0.01f;
- float scale = 1.0f;
- bool Rotating = false;
- //Position Variables
- //float playerX = 0.0f;
- //float playerY = 0.0f;
- //float playerZ = 0.0f;
- //Rotation Variables
- //float playerYaw = 0.0f;
- //float playerPitch = 0.0f;
- //float playerRoll = 0.0f;
- const float MOVE_DIST = 5.0f;
- const float ROTATION = XM_PI / 45;
- //[5] Define a variable to store the number of vertices in each dwarf mesh
- int *MeshVertices;
- //[5c] Define a variable to store the number of vertices in the car mesh
- int *CarMeshVertices;
- // Initialise DirectX in the application
- // Involves finding a driver suitable for the
- // features required by the game
- // If there is one, then it is associated
- // with the application by use of a back buffer (one or more)
- BOOL InitialiseDirectX(HWND hMainWnd, HINSTANCE hCurInstance) {
- RECT rectDimensions;
- GetClientRect(hMainWnd, &rectDimensions);
- LONG width = rectDimensions.right - rectDimensions.left;
- LONG height = rectDimensions.bottom - rectDimensions.top;
- RECT rectWindow;
- GetWindowRect(hMainWnd, &rectWindow);
- winTop = rectWindow.top;
- winLeft = rectWindow.left;
- winMidX = (rectWindow.right - rectWindow.left) / 2;
- winMidY = (rectWindow.bottom - rectWindow.top) / 2;
- clientMidX = width / 2;
- clientMidY = height / 2;
- curMouseXPos = clientMidX;
- curMouseYPos = clientMidY;
- SetCursorPos(winLeft + winMidX, winTop + winMidY);
- rotFactorY = XM_PIDIV2 / width;
- // Define the feature levels the program
- D3D_FEATURE_LEVEL featureLevels[] = { D3D_FEATURE_LEVEL_11_1 };
- int numFeatureLevels = sizeof(featureLevels) / sizeof(D3D_FEATURE_LEVEL);
- // Setup the DXGI_SWAP_CHAIN_DESC structure for describing the type of swap chain to be used
- DXGI_SWAP_CHAIN_DESC swapChainDesc;
- ZeroMemory(&swapChainDesc, sizeof(swapChainDesc));
- swapChainDesc.BufferCount = 1;
- swapChainDesc.BufferDesc.Width = width;
- swapChainDesc.BufferDesc.Height = height;
- swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
- swapChainDesc.BufferDesc.RefreshRate.Numerator = 60;
- swapChainDesc.BufferDesc.RefreshRate.Denominator = 1;
- swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
- swapChainDesc.OutputWindow = hMainWnd;
- swapChainDesc.Windowed = true;
- swapChainDesc.SampleDesc.Count = 1;
- swapChainDesc.SampleDesc.Quality = 0;
- int creationFlags = 0;
- HRESULT result;
- // Create the device and swap chain for DirectX 11
- result = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE,
- NULL, NULL, NULL, NULL, D3D11_SDK_VERSION,
- &swapChainDesc, &swapChain, &d3dDevice, NULL, &d3dContext);
- // Check result
- if (result != S_OK) {
- MessageBox(hMainWnd, TEXT("Failed to initialise DX11!"), szAppClassName, NULL);
- return false;
- }
- // Create a texture to be used as the back buffer (off screen)
- ID3D11Texture2D *backBufferTexture;
- result = swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID *) &backBufferTexture);
- if(result != S_OK) {
- MessageBox(hMainWnd, L"Failed to get back buffer!", szAppClassName, NULL);
- return false;
- }
- result = d3dDevice->CreateRenderTargetView(backBufferTexture, 0, &backBuffer);
- if(backBufferTexture != NULL) {
- backBufferTexture->Release();
- }
- if(result != S_OK) {
- MessageBox(hMainWnd, L"Failed to get render target!", szAppClassName, NULL);
- return false;
- }
- //Define Depth/Stencil Buffer
- D3D11_TEXTURE2D_DESC depthStencilDesc;
- ZeroMemory(&depthStencilDesc, sizeof(D3D11_TEXTURE2D_DESC));
- // DepthStencil buffer has same dimensions as back buffer which is the same as the client window
- depthStencilDesc.Width = width;
- depthStencilDesc.Height = height;
- depthStencilDesc.MipLevels = 1;
- depthStencilDesc.ArraySize = 1;
- // Major difference is depth buffer does not store colour information but depth information
- depthStencilDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
- depthStencilDesc.SampleDesc.Count = 1;
- depthStencilDesc.SampleDesc.Quality = 0;
- // As it's a texture need to define DirectX usage, would be useful to use D3D11_USAGE_DYNAMIC flag and caputre
- // state of depth buffer to examine the values stored.
- depthStencilDesc.Usage = D3D11_USAGE_DEFAULT;
- depthStencilDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
- depthStencilDesc.CPUAccessFlags = 0;
- depthStencilDesc.MiscFlags = 0;
- // Create the texture for the depthstencil buffer
- d3dDevice->CreateTexture2D(&depthStencilDesc, NULL, &depthStencilBuffer);
- // Create the depthstencil object based on the texture created precious
- d3dDevice->CreateDepthStencilView(depthStencilBuffer, NULL, &depthStencilView);
- // Bind the back buffer and the depthstencil buffer to the OM stage
- d3dContext->OMSetRenderTargets( 1, &backBuffer, depthStencilView );
- D3D11_VIEWPORT viewport;
- viewport.Width = static_cast<float>(width);
- viewport.Height = static_cast<float>(height);
- viewport.MinDepth = 0.0f;
- viewport.MaxDepth = 1.0f;
- viewport.TopLeftX = 0.0f;
- viewport.TopLeftY = 0.0f;
- d3dContext->RSSetViewports(1, &viewport);
- XMVECTOR camPos = XMVectorSet(camXPos, camYPos, camZPos, 0.0f);
- matView = XMMatrixLookAtLH(camPos, camTarget, camUp);
- matProjection = XMMatrixPerspectiveFovLH( XM_PIDIV4, width / (FLOAT)height,
- 1.0f, 100.0f);
- // Initialize the view matrix
- //XMVECTOR Eye = XMVectorSet( 0.0f, 3.0f, -10.0f, 0.0f );
- //XMVECTOR At = XMVectorSet( 0.0f, 3.0f, 0.0f, 0.0f );
- //XMVECTOR Up = XMVectorSet( 0.0f, 1.0f, 0.0f, 0.0f );
- //matView = XMMatrixLookAtLH( Eye, At, Up );
- // Initialize the projection matrix
- matProjection = XMMatrixPerspectiveFovLH( XM_PIDIV4, width / (FLOAT)height, 0.01f, 100.0f );
- return true;
- }
- bool LoadFace(const wchar_t *filename, int faceIdx, ID3D11Texture2D *cubemapTex) {
- // Load the texture into a memory
- ID3D11ShaderResourceView *faceData;
- ID3D11Resource *faceRes;
- HRESULT hr = CreateWICTextureFromFile(d3dDevice, d3dContext, filename, &faceRes, &faceData, 0);
- if (hr != S_OK) {
- return false;
- }
- // Get the texture object from the shader resource loaded
- ID3D11Texture2D *tex;
- hr = faceRes->QueryInterface(__uuidof(ID3D11Texture2D), (LPVOID *)&tex);
- if (hr != S_OK) {
- return false;
- }
- D3D11_TEXTURE2D_DESC texDesc;
- ZeroMemory(&texDesc, sizeof(D3D11_TEXTURE2D_DESC));
- tex->GetDesc(&texDesc);
- // Copy texture from shader resource to cubemap face specified by faceIdx
- D3D11_BOX srcRegion;
- srcRegion.front = 0;
- srcRegion.back = 1;
- srcRegion.top = 0;
- srcRegion.left = 0;
- srcRegion.bottom = texDesc.Height;
- srcRegion.right = texDesc.Width;
- // Determine the subresource object corresponding to the face id
- int face = D3D11CalcSubresource(0, faceIdx, 1);
- d3dContext->CopySubresourceRegion(cubemapTex, face, 0, 0, 0, faceRes, 0, &srcRegion);
- // Release the face texture object
- faceData->Release();
- return true;
- }
- bool CreateCubemapSkybox(const wchar_t *up_frame,
- const wchar_t *down_frame,
- const wchar_t *left_frame,
- const wchar_t *right_frame,
- const wchar_t *front_frame,
- const wchar_t *back_frame,
- int lengthOfSide) {
- D3D11_TEXTURE2D_DESC cubemapDesc;
- ZeroMemory(&cubemapDesc, sizeof(D3D11_TEXTURE2D_DESC));
- cubemapDesc.Width = lengthOfSide;
- cubemapDesc.Height = lengthOfSide;
- cubemapDesc.MipLevels = 1;
- cubemapDesc.ArraySize = 6;
- cubemapDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
- cubemapDesc.SampleDesc.Count = 1;
- cubemapDesc.SampleDesc.Quality = 0;
- cubemapDesc.Usage = D3D11_USAGE_DEFAULT;
- cubemapDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
- cubemapDesc.CPUAccessFlags = 0;
- cubemapDesc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;
- ID3D11Texture2D *cubemapBuffer;
- HRESULT hr = d3dDevice->CreateTexture2D(&cubemapDesc, nullptr, &cubemapBuffer);
- if (hr != S_OK) {
- return false;
- }
- LoadFace(front_frame, 4, cubemapBuffer);
- D3D11_SHADER_RESOURCE_VIEW_DESC srDesc;
- ZeroMemory(&srDesc, sizeof(D3D11_SHADER_RESOURCE_VIEW_DESC));
- srDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
- srDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
- srDesc.Texture2D.MostDetailedMip = 0;
- srDesc.Texture2D.MipLevels = 1;
- hr = d3dDevice->CreateShaderResourceView(cubemapBuffer, &srDesc, &CubeMap);
- if (hr != S_OK) {
- return false;
- }
- cubemapBuffer->Release();
- D3D11_BUFFER_DESC bd;
- ZeroMemory(&bd, sizeof(bd));
- bd.Usage = D3D11_USAGE_DEFAULT;
- bd.ByteWidth = sizeof(XMFLOAT3) * ARRAYSIZE(skybox);
- bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
- bd.CPUAccessFlags = 0;
- D3D11_SUBRESOURCE_DATA InitData;
- ZeroMemory(&InitData, sizeof(InitData));
- InitData.pSysMem = skybox;
- hr = d3dDevice->CreateBuffer(&bd, &InitData, &skyboxVertexBuffer);
- if (hr != S_OK) {
- return false;
- }
- }
- // Transition from a list of vertices to a final rasterised image.
- // In DirectX10 and DirectX11 it is typical to render using shaders, a vertex shader to apply
- // a transformation to the vertices and a pixel shader to shade/colour pixels in a list of vertices
- bool CreateShaders(HWND hMainWnd) {
- // Create the vertex shader first although order does not matter.
- // What does matter is shaders were loaded, compiled and then represented in as DirectX objects.
- // Otherwise will not get the output we want
- ID3DBlob *skypVSBlob = NULL;
- HRESULT skyhr = D3DReadFileToBlob(L".\\SkyboxVertexShader.cso", &skypVSBlob);
- if (skyhr != S_OK)
- {
- 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);
- return false;
- }
- ID3DBlob *pVSBlob = NULL;
- HRESULT hr = D3DReadFileToBlob( L".\\VertexShader.cso", &pVSBlob);
- if( hr != S_OK )
- {
- 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 );
- return false;
- }
- // Create the vertex shader in DirectX
- hr = d3dDevice->CreateVertexShader( pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), NULL, &vertexShader );
- // Check creating vertex shader was successful
- if( hr != S_OK )
- {
- pVSBlob->Release();
- MessageBox( hMainWnd, L"The vertex shader object cannot be created", szAppClassName, MB_OK );
- return false;
- }
- D3D11_INPUT_ELEMENT_DESC skybox_layout[] =
- {
- { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
- };
- UINT numElements = 1;
- skyhr = d3dDevice->CreateInputLayout(skybox_layout,
- numElements,
- skypVSBlob->GetBufferPointer(), skypVSBlob->GetBufferSize(), &skyboxVertexLayout);
- if (skyhr != S_OK) {
- MessageBox(hMainWnd, L"Problem creating skybox input layout", szAppClassName, MB_OK);
- return false;
- }
- // Need to tell DirectX how vertices are structured in terms of colour format and order of data, that is individual vertices
- // The POSITION is called the semantic name, basically a meaningful identifier used internally to map vertex elements to shader
- // parameters. Semantic name text must obey the rules of C identifiers as shader language uses C syntax
- D3D11_INPUT_ELEMENT_DESC layout[] =
- {
- { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
- { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
- };
- UINT skynumElements = 3;
- // Create the input layout for input assembler based on description and the vertex shader to be used
- hr = d3dDevice->CreateInputLayout( layout, numElements, pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), &vertexLayout );
- // Check layout was created successfully
- pVSBlob->Release();
- if( hr != S_OK ) {
- MessageBox( hMainWnd, L"Problems creating input layout", szAppClassName, MB_OK );
- return false;
- }
- // Set the input layout for input assembler
- d3dContext->IASetInputLayout( vertexLayout );
- // Compile the pixel shader
- ID3DBlob* pPSBlob = NULL;
- hr = D3DReadFileToBlob( L".\\PixelShader.cso", &pPSBlob);
- // Check pixel shader was loaded successfully
- if( hr != S_OK )
- {
- // 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
- 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 );
- return false;
- }
- // Create the pixel shader in DirectX
- hr = d3dDevice->CreatePixelShader( pPSBlob->GetBufferPointer(), pPSBlob->GetBufferSize(), NULL, &pixelShader );
- pPSBlob->Release();
- // Check creating pixel shader was successful
- if( hr != S_OK ) {
- MessageBox( hMainWnd, L"The pixel shader object cannot be created", szAppClassName, MB_OK );
- return false;
- }
- //[6] Load dwarf texture
- hr = CreateWICTextureFromFile(d3dDevice, d3dContext, L".\\dwarf.jpg", NULL, &dwarfTex);
- if (hr != S_OK) {
- MessageBox(hMainWnd, TEXT("Unable to load dwarf texture"), szAppClassName, MB_OK);
- return false;
- }
- //[7] Load axe texture
- hr = CreateWICTextureFromFile(d3dDevice, d3dContext, L".\\axe.jpg", NULL, &axeTex);
- if (hr != S_OK) {
- MessageBox(hMainWnd, TEXT("Unable to load dwarf texture"), szAppClassName, MB_OK);
- return false;
- }
- //[6c] Load car texture
- hr = CreateWICTextureFromFile(d3dDevice, d3dContext, L".\\Car07.jpg", NULL, &carTex);
- if (hr != S_OK) {
- MessageBox(hMainWnd, TEXT("Unable to load car texture"), szAppClassName, MB_OK);
- return false;
- }
- D3D11_SAMPLER_DESC sampDesc;
- ZeroMemory(&sampDesc, sizeof(sampDesc));
- sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
- sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
- sampDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
- sampDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
- sampDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
- sampDesc.MaxLOD = D3D11_FLOAT32_MAX;
- hr = d3dDevice->CreateSamplerState(&sampDesc, &sampler);
- if(hr != S_OK) {
- MessageBox( hMainWnd, TEXT("Unable to create sampler"), szAppClassName, MB_OK );
- return false;
- }
- // If we've got this far then have valid shaders.
- // Return a successful result
- return true;
- }
- bool LoadDwarfModel() {
- //[8] Create importer object
- Assimp::Importer imp;
- //[9] Load model into scene object
- const aiScene *pScene = imp.ReadFile(".\\dwarf.x",
- aiProcessPreset_TargetRealtime_Fast | aiProcess_ConvertToLeftHanded);
- if (!pScene) {
- return false;
- }
- if (!pScene) {
- return false;
- }
- //[10] Create an array to store the individual number of vertices in each mesh
- MeshVertices = new int[pScene->mNumMeshes];
- //[11] Calculate the total number of vertices from all meshes
- int TotalNumVertices = 0;
- for (int MeshIdx = 0; MeshIdx < pScene->mNumMeshes; MeshIdx++) {
- const aiMesh *mesh = pScene->mMeshes[MeshIdx];
- MeshVertices[MeshIdx] = mesh->mNumFaces * 3;
- TotalNumVertices += mesh->mNumFaces * 3;
- }
- //[12] Create an array to store all vertices
- Vertex *shape = new Vertex[TotalNumVertices];
- //[13] Convert the assimp vertices to ones for DirectX
- int vertCount = 0;
- for (int MeshIdx = 0; MeshIdx < pScene->mNumMeshes; MeshIdx++) {
- const aiMesh *mesh = pScene->mMeshes[MeshIdx];
- for (int faceIdx = 0; faceIdx < mesh->mNumFaces; faceIdx++) {
- const aiFace& face = mesh->mFaces[faceIdx];
- for (int vertIdx = 0; vertIdx < 3; vertIdx++) {
- const aiVector3D *pos = &mesh->mVertices[face.mIndices[vertIdx]];
- const aiVector3D *tex = &mesh->mTextureCoords[0][face.mIndices[vertIdx]];
- shape[vertCount] = Vertex(pos->x, pos->y, pos->z, tex->x, tex->y);
- vertCount++;
- }
- }
- }
- //[14] Define the vertex buffer
- D3D11_BUFFER_DESC bd;
- ZeroMemory(&bd, sizeof(bd));
- bd.Usage = D3D11_USAGE_DEFAULT;
- bd.ByteWidth = sizeof(Vertex) * TotalNumVertices;
- bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
- bd.CPUAccessFlags = 0;
- // Define the source of vertex data in RAM
- D3D11_SUBRESOURCE_DATA InitData;
- ZeroMemory(&InitData, sizeof(InitData));
- InitData.pSysMem = shape;
- HRESULT hr = d3dDevice->CreateBuffer(&bd, &InitData, &dwarfVertexBuffer);
- if (hr != S_OK) {
- return false;
- }
- //[15] Release memory allocated to shape
- delete[] shape;
- // Got this far so model loaded okay
- return true;
- }
- bool LoadCarModel() {
- //[8] Create importer object
- Assimp::Importer imp1;
- //[9] Load model into scene object
- const aiScene *pScene = imp1.ReadFile(".\\car07.3DS",
- aiProcessPreset_TargetRealtime_Fast | aiProcess_ConvertToLeftHanded);
- if (!pScene) {
- return false;
- }
- if (!pScene) {
- return false;
- }
- //[10] Create an array to store the individual number of vertices in each mesh
- CarMeshVertices = new int[pScene->mNumMeshes];
- //[11] Calculate the total number of vertices from all meshes
- int TotalNumVertices = 0;
- for (int MeshIdx = 0; MeshIdx < pScene->mNumMeshes; MeshIdx++) {
- const aiMesh *mesh = pScene->mMeshes[MeshIdx];
- CarMeshVertices[MeshIdx] = mesh->mNumFaces * 3;
- TotalNumVertices += mesh->mNumFaces * 3;
- }
- //[12] Create an array to store all vertices
- Vertex *shape1 = new Vertex[TotalNumVertices];
- //[13] Convert the assimp vertices to ones for DirectX
- int vertCount = 0;
- for (int MeshIdx = 0; MeshIdx < pScene->mNumMeshes; MeshIdx++) {
- const aiMesh *mesh = pScene->mMeshes[MeshIdx];
- for (int faceIdx = 0; faceIdx < mesh->mNumFaces; faceIdx++) {
- const aiFace& face = mesh->mFaces[faceIdx];
- for (int vertIdx = 0; vertIdx < 3; vertIdx++) {
- const aiVector3D *pos = &mesh->mVertices[face.mIndices[vertIdx]];
- const aiVector3D *tex = &mesh->mTextureCoords[0][face.mIndices[vertIdx]];
- shape1[vertCount] = Vertex(pos->x, pos->y, pos->z, tex->x, tex->y);
- vertCount++;
- }
- }
- }
- //[14] Define the vertex buffer
- D3D11_BUFFER_DESC bd;
- ZeroMemory(&bd, sizeof(bd));
- bd.Usage = D3D11_USAGE_DEFAULT;
- bd.ByteWidth = sizeof(Vertex) * TotalNumVertices;
- bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
- bd.CPUAccessFlags = 0;
- // Define the source of vertex data in RAM
- D3D11_SUBRESOURCE_DATA InitData;
- ZeroMemory(&InitData, sizeof(InitData));
- InitData.pSysMem = shape1;
- HRESULT hr = d3dDevice->CreateBuffer(&bd, &InitData, &carVertexBuffer);
- if (hr != S_OK) {
- return false;
- }
- //[15] Release memory allocated to shape
- delete[] shape1;
- // Got this far so model loaded okay
- return true;
- }
- bool CreateMeshes(HWND hMainWnd) {
- if (!LoadDwarfModel()) {
- MessageBox(hMainWnd, L"Failed to load and create dwarf model", szAppClassName, NULL);
- return false;
- }
- if (!LoadCarModel()) {
- MessageBox(hMainWnd, L"Failed to load and create car model", szAppClassName, NULL);
- return false;
- }
- // Create the constant buffer
- D3D11_BUFFER_DESC bd;
- ZeroMemory(&bd, sizeof(D3D11_BUFFER_DESC));
- bd.Usage = D3D11_USAGE_DEFAULT;
- bd.ByteWidth = sizeof(ConstantBuffer);
- bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
- bd.CPUAccessFlags = 0;
- HRESULT hr = d3dDevice->CreateBuffer( &bd, NULL, &constantBuffer );
- if( hr != S_OK ) {
- MessageBox(hMainWnd, L"Failed to create constant buffer", szAppClassName, NULL);
- return false;
- }
- // If we've got this far then have vertice structure in DirectX.
- // Return a successful result
- return true;
- }
- void Update() {
- // Does nothing as mouse control is elsewhere
- DWORD now = GetTickCount();
- DWORD diff = now - frameTime;
- const float move_step = 10.0f;
- float forwards_backwards = 0.0f;
- float left_right = 0.0f;
- if (IsKeyDown('W')) {
- forwards_backwards = move_step * (diff / 1000.0f);
- }
- if (IsKeyDown('S')) {
- forwards_backwards = -move_step * (diff / 1000.0f);
- }
- int deltaX = clientMidX - curMouseXPos;
- camRotY -= deltaX * rotFactorY;
- SetCursorPos(winLeft + winMidX, winTop + winMidY);
- XMMATRIX camMove = XMMatrixTranslation(0.0f, 0.0f, forwards_backwards) *
- XMMatrixRotationRollPitchYaw(camRotX, camRotY, 0.0f);
- XMVECTOR scale, rot, trans;
- XMMatrixDecompose(&scale, &rot, &trans, camMove);
- camXPos += XMVectorGetX(trans);
- camYPos += XMVectorGetY(trans);
- camZPos += XMVectorGetZ(trans);
- XMVECTOR camPos = XMVectorSet(camXPos, camYPos, camZPos, 0.0f);
- XMMATRIX camDist = XMMatrixTranslation(0.0f, 0.0f, 10.0f) *
- XMMatrixRotationRollPitchYaw(camRotX, camRotY, 0.0f);
- XMMatrixDecompose(&scale, &rot, &trans, camDist);
- camTarget = XMVectorSet(camXPos + XMVectorGetX(trans),
- camYPos + XMVectorGetY(trans),
- camZPos + XMVectorGetZ(trans), 0.0f);
- matView = XMMatrixLookAtLH(camPos, camTarget, camUp);
- frameTime = now;
- }
- // Renders a frame, what does this function do?
- void Draw() {
- if(d3dContext == NULL) {
- return;
- }
- matWorld = XMMatrixIdentity() * XMMatrixScaling(0.3f, 0.3f, 0.3f);
- matWorld = XMMatrixScaling(0.1f, 0.1f, 0.1f) * XMMatrixRotationY(-RotationY) * XMMatrixTranslation(0.0f, 0.0f, 20.0f);
- ConstantBuffer cb;
- matWorld = XMMatrixTranslation(camXPos, camYPos, camZPos);
- cb.mWorld = XMMatrixTranspose( matWorld );
- cb.mView = XMMatrixTranspose( matView );
- cb.mProjection = XMMatrixTranspose( matProjection );
- d3dContext->UpdateSubresource( constantBuffer, 0, NULL, &cb, 0, 0 );
- float colour[] = {0.392156f, 0.584313f, 0.929411f, 1.0f};
- d3dContext->ClearRenderTargetView(backBuffer, colour);
- // Clear the depth of depthstencil buffer to 1.0f for new frame
- d3dContext->ClearDepthStencilView(depthStencilView, D3D11_CLEAR_DEPTH, 1.0f, 0);
- // Render a triangle. Not directly from vertices but from applying the shaders
- d3dContext->VSSetShader( vertexShader, NULL, 0 );
- d3dContext->VSSetConstantBuffers( 0, 1, &constantBuffer );
- d3dContext->PSSetShader( pixelShader, NULL, 0 );
- //[16] Select vertex buffer with all of the mesh vertices
- UINT stride = sizeof(Vertex);
- UINT offset = 0;
- d3dContext->IASetVertexBuffers(0, 1, &dwarfVertexBuffer, &stride, &offset);
- d3dContext->IAGetVertexBuffers(0, 1, &skyboxVertexBuffer, &stride, &offset);
- //[11] Set the skybox shaders
- // Set up to render skybox, remember skybox has different shaders to
- // other models because it uses a cubemap
- d3dContext->VSSetShader(skyboxVertexShader, NULL, 0);
- d3dContext->PSSetShader(skyboxPixelShader, NULL, 0);
- d3dContext->PSSetSamplers(0, 1, &sampler);
- d3dContext->PSSetShaderResources(1, 1, &CubeMap);
- d3dContext->IASetInputLayout(skyboxVertexLayout);
- //UINT stride = sizeof(XMFLOAT3);
- //UINT offset = 0;
- d3dContext->OMSetDepthStencilState(DSDepthOff, 0);
- d3dContext->RSSetState(rsCullingOff);
- d3dContext->Draw(ARRAYSIZE(skybox), 0);
- d3dContext->RSSetState(rsCullingOn);
- d3dContext->OMSetDepthStencilState(DSDepthOn, 0);
- // Also tell input assembler how the vertices are to be treated.
- d3dContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST );
- // Select the sampler
- d3dContext->PSSetSamplers(0, 1, &sampler);
- ////[17] Select the axe texture first
- d3dContext->PSSetShaderResources(1, 1, &axeTex);
- ////[18] Draw the axe mesh
- d3dContext->Draw(MeshVertices[0], 1);
- ////[19] Select the dwarf texture
- d3dContext->PSSetShaderResources(1, 1, &dwarfTex);
- ////[20] Draw the dwarf mesh
- d3dContext->Draw(MeshVertices[1], MeshVertices[0]);
- //[16c] Select car vertex buffer into pipeline
- d3dContext->IASetVertexBuffers(0, 1, &carVertexBuffer, &stride, &offset);
- //[17c] Select car texture into pipeline
- d3dContext->PSSetShaderResources(1, 1, &carTex);
- //[18c] Draw car
- d3dContext->Draw(CarMeshVertices[0], CarMeshVertices[0]);
- // Display frame immediately
- swapChain->Present(0,0);
- }
- // Release the resources allocated to application as a result of
- // using DirectX
- void ShutdownDirectX() {
- if(dwarfTex) {
- dwarfTex->Release();
- }
- if (axeTex) {
- axeTex->Release();
- }
- if(dwarfVertexBuffer != NULL)
- dwarfVertexBuffer->Release();
- if (carTex) {
- carTex->Release();
- }
- if (carVertexBuffer != NULL)
- carVertexBuffer->Release();
- // Add source code to release car buffer and texture
- if (CubeMap) {
- CubeMap->Release();
- }
- if (rsCullingOn) {
- rsCullingOn->Release();
- }
- if (rsCullingOff) {
- rsCullingOff->Release();
- }
- if (DSDepthOn) {
- DSDepthOn->Release();
- }
- if (DSDepthOff) {
- DSDepthOff->Release();
- }
- if (skyboxVertexBuffer) {
- skyboxVertexBuffer->Release();
- }
- if (skyboxVertexLayout) {
- skyboxVertexLayout->Release();
- }
- if (skyboxPixelShader) {
- skyboxPixelShader->Release();
- }
- if (skyboxVertexBuffer) {
- skyboxVertexBuffer->Release();
- }
- if (sampler) {
- sampler->Release();
- }
- if(vertexShader != NULL)
- vertexShader->Release();
- if(pixelShader != NULL)
- pixelShader->Release();
- if(vertexLayout != NULL)
- vertexLayout->Release();
- if(backBuffer) {
- backBuffer->Release();
- }
- if(depthStencilView) {
- depthStencilView->Release();
- }
- if(depthStencilBuffer) {
- depthStencilBuffer->Release();
- }
- if(swapChain) {
- swapChain->Release();
- }
- if(d3dContext) {
- d3dContext->Release();
- }
- if(d3dDevice) {
- d3dDevice->Release();
- backBuffer = 0;
- swapChain = 0;
- d3dContext = 0;
- d3dDevice = 0;
- }
- }
- int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLineArgs, int nInitialWinShowState) {
- HWND hMainWnd;
- MSG msg = {0};
- // Find out what a WNDCLASS is and what it is used for
- WNDCLASS wndclass;
- wchar_t fps[ 64 ];
- ZeroMemory(fps, 64);
- wndclass.style = CS_HREDRAW | CS_VREDRAW;
- wndclass.lpfnWndProc = WinProc;
- wndclass.cbClsExtra = 0;
- wndclass.cbWndExtra = 0;
- wndclass.hInstance = hInstance;
- wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
- wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
- wndclass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
- wndclass.lpszMenuName = NULL;
- wndclass.lpszClassName = szAppClassName;
- // Find out why we have to register the class
- if(!RegisterClass(&wndclass)) {
- MessageBox(NULL, L"Unable to register class for application", szAppClassName, 0);
- return 0;
- }
- // Find out what CreateWindows does
- hMainWnd = CreateWindow(szAppClassName,
- L"Basic Windows Application",
- WS_OVERLAPPEDWINDOW,
- CW_USEDEFAULT,
- CW_USEDEFAULT,
- CW_USEDEFAULT,
- CW_USEDEFAULT,
- NULL,
- NULL,
- hInstance,
- NULL);
- if(!hMainWnd) {
- MessageBox(NULL, L"Unable able to create the application's main window", szAppClassName, 0);
- return 0;
- }
- ShowWindow(hMainWnd, nInitialWinShowState);
- if(!InitialiseDirectX(hMainWnd, hInstance)) {
- MessageBox(NULL, L"Failed to initialise DirectX", szAppClassName, 0);
- return 0;
- }
- // Create shaders
- if(!CreateShaders(hMainWnd)) {
- // Exit program if an error occurred
- return 0;
- }
- // Create the vertices of the triangle in DirectX
- if(!CreateMeshes(hMainWnd)) {
- // Exit program if an error occurred
- return 0;
- }
- if (!CreateCubemapSkybox(L".\\assets\\up.jpg",
- L".\\assets\\down.jpg",
- L".\\assets\\left.jpg",
- L".\\assets\\right.jpg",
- L".\\assets\\front.jpg",
- L".\\assets\\back.jpg", 512)) {
- return 0;
- }
- // Slightly different message loop
- DWORD current = GetTickCount();
- int count = 0;
- InitialiseKeyboardHandler();
- while(msg.message != WM_QUIT) {
- if(PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- } else {
- Update();
- Draw();
- count++;
- DWORD now = GetTickCount();
- if(now - current > 1000) {
- wsprintf(fps, L"FPS = %d", count);
- SetWindowText(hMainWnd, fps);
- count = 0;
- current = now;
- }
- }
- }
- ShutdownDirectX();
- return 0;
- }
- // Windows message procedure, this responds to user and system generated events
- LRESULT CALLBACK WinProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
- int curMouseXPos, curMouseYPos;
- int zDelta;
- curMouseXPos = (short) LOWORD(lParam);
- curMouseYPos = (short) HIWORD(lParam);
- switch(uMsg) {
- // When the user closes the window by pressing the close button
- // Tell the application to terminate by breaking the windows message loop
- case WM_KEYDOWN:
- ProcessKeyDown(wParam);
- return 0;
- case WM_KEYUP:
- ProcessKeyUp(wParam);
- return 0;
- case WM_MOUSEMOVE:
- curMouseXPos = LOWORD(lParam);
- curMouseYPos = HIWORD(lParam);
- return 0;
- case WM_LBUTTONDOWN:
- SetCapture(hWnd);
- mouseXPos = curMouseXPos;
- mouseYPos = curMouseYPos;
- Rotating = true;
- break;
- case WM_LBUTTONUP:
- ReleaseCapture();
- Rotating = false;
- break;
- case WM_CLOSE:
- PostQuitMessage(0);
- return 0;
- }
- return DefWindowProc(hWnd, uMsg, wParam, lParam);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement