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;
- // Terrain Vertex Template
- struct Vertex {
- XMFLOAT3 pos;
- XMFLOAT2 texCoord;
- Vertex(XMFLOAT3 xyz, XMFLOAT2 uv) {
- pos = xyz;
- texCoord = uv;
- }
- Vertex() {
- pos = XMFLOAT3(0.0f, 0.0f, 0.0f);
- texCoord = XMFLOAT2(0.0f, 0.0f);
- }
- };
- //Model Vertex Template
- struct Vertex1 {
- XMFLOAT3 pos;
- XMFLOAT2 texCoord;
- Vertex1() {
- }
- Vertex1(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 *terrainVertexBuffer = NULL;
- ID3D11Buffer *terrainIndexBuffer = NULL;
- int NumIndices;
- ID3D11ShaderResourceView *terrainTex;
- 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;
- // MVP Matrices
- XMMATRIX matWorld;
- XMMATRIX matView;
- XMMATRIX matProjection;
- //Camera position
- float camXPos = 0.0f;
- float camYPos = 10.0f;
- float camZPos = 10.0f;
- XMVECTOR camTarget = XMVectorSet(0.0f, 0.0f, 0.0f, 0.0f);
- XMVECTOR camUp = XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f);
- //Camera rotation
- 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;
- DWORD frameTime;
- //[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
- BOOL InitialiseDirectX(HWND hMainWnd, HINSTANCE hCurInstance) {
- RECT rectDimensions;
- GetClientRect(hMainWnd, &rectDimensions);
- // CREATE MOUSE CURSOR VARIABLES FOR USE IN CAMERA //
- 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) - 12;
- 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;
- }
- // CREATE ALL SHADERS //
- bool CreateShaders(HWND hMainWnd) {
- 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;
- }
- // 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 numElements = 2;
- // 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;
- }
- // TEXTURES //
- //Load
- hr = CreateWICTextureFromFile(d3dDevice, d3dContext, L".\\terrain-texture2.jpg", 0, &terrainTex, 0);
- //[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".\\Alien Slime.png", 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;
- }
- // CUSTOM HEIGHTMAP //
- void LoadHeightMap(const char *filename, float MaxHeight, Vertex **mesh) {
- // This example expects a texture file of 256 pixels width and height
- // More flexible version would obtain the width and height from
- // file and create terrain from this data as terrain vertices
- // map onto pixel data
- // Also presumes height map is 24 bit texture file
- const int Size = 256;
- FILE *file_ptr = fopen(filename, "rb");
- if (file_ptr == NULL) {
- return;
- }
- // Read the file's header information
- // so we can create a buffer to hold the pixel colour data
- BITMAPFILEHEADER bmHeader;
- BITMAPINFOHEADER bmInfo;
- fread(&bmHeader, sizeof(BITMAPFILEHEADER), 1, file_ptr);
- fread(&bmInfo, sizeof(BITMAPINFOHEADER), 1, file_ptr);
- // Move file pointer to start of pixel colour data
- fseek(file_ptr, bmHeader.bfOffBits, SEEK_SET);
- // Work out number of bytes per pixel for array
- int NumBytesPerPixel = bmInfo.biBitCount / 8;
- // Calculate maximum colour value up 2^24 colour
- float MaxColourVal = (float)pow(2.0f, min(24.0f, (float)bmInfo.biBitCount));
- // Create array for pixel data
- unsigned char *pixel_data = new unsigned char[Size * Size * NumBytesPerPixel];
- // Read pixel data from file into memory
- fread(pixel_data, sizeof(unsigned char), Size * Size * NumBytesPerPixel, file_ptr);
- // Release the file
- fclose(file_ptr);
- //[13] Modify each vertex's y component based on the pixel value in proportion to max colour value
- // in the corresponding pixel
- int idx = 0;
- Vertex *vertArray = *mesh;
- for (int row = 0; row < Size; row++) {
- for (int col = 0; col < Size; col++) {
- int pixel_val = pixel_data[idx * NumBytesPerPixel]
- + (pixel_data[(idx * NumBytesPerPixel) + 1] << 8)
- + (pixel_data[(idx * NumBytesPerPixel) + 2] << 16);
- vertArray[idx].pos.y = MaxHeight * (pixel_val / MaxColourVal);
- idx++;
- }
- }
- // Release pixel data as don't need it any more
- delete[] pixel_data;
- }
- // CREATE TERRAIN MESH //
- void CreateTerrainMesh(int NumVertices, Vertex **mesh, int *TotalNumVert, int **indices, int *NumIndices)
- {
- *NumIndices = (NumVertices - 1) * (NumVertices - 1) * 6;
- *indices = new int[*NumIndices];
- int *p = *indices;
- p[0] = 0;
- p[1] = NumVertices;
- p[2] = NumVertices + 1;
- p[3] = NumVertices + 1;
- p[4] = 1;
- p[5] = 0;
- int NextRow = (NumVertices - 1) * 6;
- for (int idx = 6; idx < *NumIndices; idx++) {
- if (idx % NextRow == 0) {
- p[idx] = (idx / NextRow) *NumVertices;
- p[idx + 1] = p[idx] + NumVertices;
- p[idx + 2] = p[idx + 1] + 1;
- p[idx + 3] = p[idx + 2];
- p[idx + 4] = p[idx] + 1;
- p[idx + 5] = p[idx];
- idx += 5;
- }
- else {
- p[idx] = p[idx - 6] + 1;
- }
- }
- *TotalNumVert = NumVertices * NumVertices;
- *mesh = new Vertex[*TotalNumVert];
- float step = 2.0f / NumVertices;
- float xPos = -1.0f;
- float zPos = -1.0f;
- float uvStep = 1.0f / NumVertices;
- float u = 0.0f;
- float v = 0.0f;
- int idx = 0;
- Vertex *vertArray = *mesh;
- for (int row = 0; row < NumVertices; row++) {
- for (int col = 0; col < NumVertices; col++) {
- vertArray[idx] = Vertex(XMFLOAT3(xPos, 0.0f, zPos), XMFLOAT2(u, v));
- xPos += step;
- u += uvStep;
- idx++;
- }
- u = 0.0f;
- v += uvStep;
- xPos = -1.0f;
- zPos += step;
- }
- }
- // LOAD DWARF MODEL //
- 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
- Vertex1 *shape = new Vertex1[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] = Vertex1(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(Vertex1) * 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(".\\Alien Slime.blend",
- 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
- Vertex1 *shape1 = new Vertex1[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] = Vertex1(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(Vertex1) * 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) {
- // LOAD DWARF MODEL //
- if (!LoadDwarfModel()) {
- MessageBox(hMainWnd, L"Failed to load and create dwarf model", szAppClassName, NULL);
- return false;
- }
- // LOAD CAR MODEL //
- if (!LoadCarModel()) {
- MessageBox(hMainWnd, L"Failed to load and create car model", szAppClassName, NULL);
- return false;
- }
- // TERRAIN //
- Vertex *terrainVertices;
- int *terrainIndices;
- int NumVert;
- CreateTerrainMesh(256, &terrainVertices, &NumVert, &terrainIndices, &NumIndices);
- LoadHeightMap(".\\terrain-heightmap 24bit.bmp", 2.0f, &terrainVertices);
- D3D11_BUFFER_DESC bdt;
- ZeroMemory(&bdt, sizeof(bdt));
- bdt.Usage = D3D11_USAGE_IMMUTABLE;
- bdt.ByteWidth = sizeof(Vertex) * NumVert;
- bdt.BindFlags = D3D11_BIND_VERTEX_BUFFER;
- bdt.CPUAccessFlags = 0;
- D3D11_SUBRESOURCE_DATA InitData;
- ZeroMemory(&InitData, sizeof(InitData) );
- InitData.pSysMem = terrainVertices; HRESULT hrt = d3dDevice->CreateBuffer(&bdt, &InitData, &terrainVertexBuffer);
- ZeroMemory(&bdt, sizeof(bdt));
- bdt.Usage = D3D11_USAGE_IMMUTABLE;
- bdt.ByteWidth = sizeof(int) * NumIndices;
- bdt.BindFlags = D3D11_BIND_INDEX_BUFFER;
- bdt.CPUAccessFlags = 0;
- ZeroMemory(&InitData, sizeof(InitData));
- InitData.pSysMem = terrainIndices;
- hrt = d3dDevice->CreateBuffer(&bdt, &InitData, &terrainIndexBuffer);
- delete[] terrainVertices;
- delete[] terrainIndices;
- // 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() {
- // MOUSE & KEYBOARD CONTROLS //
- 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;
- }
- //Player model
- matWorld = XMMatrixIdentity() * XMMatrixScaling(0.3f, 0.3f, 0.3f) *
- XMMatrixRotationRollPitchYaw(playerPitch, playerYaw, playerRoll) *
- XMMatrixTranslation(playerX, playerY, playerZ);
- matWorld = XMMatrixScaling(0.1f, 0.1f, 0.1f) * XMMatrixRotationY(-RotationY) * XMMatrixTranslation(0.0f, 0.0f, 20.0f);
- ConstantBuffer cb;
- 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);
- // 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);
- // TERRAIN //
- //Scale terrain based on matrix scaling values
- matWorld = XMMatrixScaling(50.0f, 5.0f, 100.0f) *XMMatrixIdentity();
- cb.mWorld = XMMatrixTranspose(matWorld);
- d3dContext->UpdateSubresource(constantBuffer, 0, NULL, &cb, 0, 0);
- UINT stridet = sizeof(Vertex);
- UINT offsett = 0;
- d3dContext->IASetVertexBuffers(0, 1, &terrainVertexBuffer, &stridet, &offsett);
- //Set Terrain Index buffer
- d3dContext->IASetIndexBuffer(terrainIndexBuffer, DXGI_FORMAT_R32_UINT, 0);
- d3dContext->PSSetShaderResources(1, 1, &terrainTex);
- d3dContext->DrawIndexed(NumIndices, 0, 0);
- ////[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 (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;
- }
- // 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