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>
- //[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;
- //Model Vertex Template
- 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
- //Triangle Direct X data/objects
- 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
- // This DirectX object stores the data from the background texture file
- // This DirectX object is used to map texture data onto triangle
- ID3D11SamplerState *sampler;
- XMMATRIX matWorld;
- XMMATRIX matView;
- XMMATRIX matProjection;
- int mouseXPos;
- int mouseYPos;
- float RotationY = 0.0f;
- float RotationX = 0.0f;
- float RotFactorX = 0.01f;
- float RotFactorY = 0.01f;
- float scale = 1.0f;
- bool Rotating = false;
- //[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
- // 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;
- D3D_FEATURE_LEVEL featureLevels[] = { D3D_FEATURE_LEVEL_11_1 };
- int numFeatureLevels = sizeof(featureLevels) / sizeof(D3D_FEATURE_LEVEL);
- 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;
- }
- 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;
- depthStencilDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
- depthStencilDesc.SampleDesc.Count = 1;
- depthStencilDesc.SampleDesc.Quality = 0;
- 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);
- d3dDevice->CreateDepthStencilView(depthStencilBuffer, NULL, &depthStencilView);
- 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 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);
- matProjection = XMMatrixPerspectiveFovLH(XM_PIDIV4, width / (FLOAT)height, 0.01f, 100.0f);
- return true;
- }
- 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;
- }
- hr = d3dDevice->CreateVertexShader(pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), NULL, &vertexShader);
- 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 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;
- hr = d3dDevice->CreateInputLayout(layout, numElements, pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), &vertexLayout);
- pVSBlob->Release();
- if (hr != S_OK) {
- MessageBox(hMainWnd, L"Problems creating input layout", szAppClassName, MB_OK);
- return false;
- }
- d3dContext->IASetInputLayout(vertexLayout);
- ID3DBlob* pPSBlob = NULL;
- hr = D3DReadFileToBlob(L".\\PixelShader.cso", &pPSBlob);
- 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 axe texture"), szAppClassName, MB_OK);
- return false;
- }
- //[6c] Load car texture
- 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;
- }
- 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;
- }
- //[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() {
- //[7c] Create importer object
- //[8c] Load model into scene object
- //[10c] Calculate the total number of vertices from all meshes
- // Store calculated number of vertices in a global variable for drawing later
- //[11c] Create an array to accommodate all vertices
- //[12c] Convert the assimp vertices to ones for DirectX
- //[13c] Define the vertex buffer
- // Define the source of vertex data in RAM
- //[14c] Release memory allocated to shape
- // 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;
- }
- 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 craete constant buffer", szAppClassName, NULL);
- return false;
- }
- return true;
- }
- void Update() {
- }
- void Draw() {
- if (d3dContext == NULL) {
- return;
- }
- 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);
- d3dContext->ClearDepthStencilView(depthStencilView, D3D11_CLEAR_DEPTH, 1.0f, 0);
- 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->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
- 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], 0);
- ////[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
- //[17c] Select car texture into pipeline
- //[18c] Draw car
- //Display frame immediately
- swapChain->Present(0, 0);
- }
- void ShutdownDirectX() {
- if (dwarfTex) {
- dwarfTex->Release();
- }
- if (axeTex) {
- axeTex->Release();
- }
- if (dwarfVertexBuffer != NULL)
- dwarfVertexBuffer->Release();
- //Direct X Release
- if (sampler) {
- sampler->Release();
- }
- if (vertexShader != NULL)
- vertexShader->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 };
- 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;
- if (!RegisterClass(&wndclass)) {
- MessageBox(NULL, L"Unable to register class for application", szAppClassName, 0);
- return 0;
- }
- hMainWnd = CreateWindow(szAppClassName,
- L"DirectX Application",
- WS_OVERLAPPEDWINDOW,
- CW_USEDEFAULT,
- CW_USEDEFAULT,
- CW_USEDEFAULT,
- CW_USEDEFAULT,
- NULL,
- NULL,
- hInstance,
- NULL);
- if (!hMainWnd) {
- MessageBox(NULL, L"Unable 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;
- }
- if (!CreateShaders(hMainWnd)) {
- return 0;
- }
- if (!CreateMeshes(hMainWnd)) {
- return 0;
- }
- DWORD current = GetTickCount();
- int count = 0;
- 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;
- }
- 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) {
- case WM_MOUSEMOVE:
- if (Rotating) {
- RotationY += -(curMouseXPos - mouseXPos) * RotFactorY;
- if (RotationY < 0) {
- RotationY = 2 * XM_PI - RotationY;
- }
- RotationX += -(curMouseYPos - mouseYPos) * RotFactorX;
- if (RotationX < 0) {
- RotationX = 2 * XM_PI - RotationX;
- }
- }
- mouseXPos = curMouseXPos;
- mouseYPos = curMouseYPos;
- break;
- 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