Files
directx-plane-game/Graphics2/DirectXFramework.cpp
iDunnoDev 65255f1321 Added the ASSIMP library
Added the files provided for the tutorial
Added the SplitMeshNode and SubMeshNode classes
2022-03-18 21:26:31 +00:00

232 lines
7.2 KiB
C++

#include "DirectXFramework.h"
// DirectX libraries that are needed
#pragma comment(lib, "d3d11.lib")
#pragma comment(lib, "d3dcompiler.lib")
DirectXFramework * _dxFramework = nullptr;
DirectXFramework::DirectXFramework() : DirectXFramework(800, 600)
{
}
DirectXFramework::DirectXFramework(unsigned int width, unsigned int height) : Framework(width, height)
{
_dxFramework = this;
// Set default background colour
_backgroundColour[0] = 0.0f;
_backgroundColour[1] = 0.0f;
_backgroundColour[2] = 0.0f;
_backgroundColour[3] = 0.0f;
// Initialise vectors used to create camera. We will move these
// to a separate Camera class later
_eyePosition = XMFLOAT4(0.0f, 20.0f, -90.0f, 0.0f);
_focalPointPosition = XMFLOAT4(0.0f, 20.0f, 0.0f, 0.0f);
_upVector = XMFLOAT4(0.0f, 1.0f, 0.0f, 0.0f);
}
DirectXFramework * DirectXFramework::GetDXFramework()
{
return _dxFramework;
}
XMMATRIX DirectXFramework::GetViewTransformation()
{
return XMLoadFloat4x4(&_viewTransformation);
}
XMMATRIX DirectXFramework::GetProjectionTransformation()
{
return XMLoadFloat4x4(&_projectionTransformation);
}
void DirectXFramework::SetBackgroundColour(XMFLOAT4 backgroundColour)
{
_backgroundColour[0] = backgroundColour.x;
_backgroundColour[1] = backgroundColour.y;
_backgroundColour[2] = backgroundColour.z;
_backgroundColour[3] = backgroundColour.w;
}
void DirectXFramework::CreateSceneGraph()
{
}
void DirectXFramework::UpdateSceneGraph()
{
}
bool DirectXFramework::Initialise()
{
// The call to CoInitializeEx is needed if we are using
// textures since the WIC library used requires it, so we
// take care of initialising it here
if FAILED(CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED))
{
return false;
}
if (!GetDeviceAndSwapChain())
{
return false;
}
OnResize(SIZE_RESTORED);
// Create camera and projection matrices (we will look at how the
// camera matrix is created from vectors later)
XMStoreFloat4x4(&_projectionTransformation, XMMatrixPerspectiveFovLH(XM_PIDIV4, (float)GetWindowWidth() / GetWindowHeight(), 1.0f, 10000.0f));
_resourceManager = make_shared<ResourceManager>();
_sceneGraph = make_shared<SceneGraph>();
CreateSceneGraph();
return _sceneGraph->Initialise();
}
void DirectXFramework::Shutdown()
{
// Required because we called CoInitialize above
_sceneGraph->Shutdown();
CoUninitialize();
}
void DirectXFramework::Update()
{
// Do any updates to the scene graph nodes
UpdateSceneGraph();
// Now apply any updates that have been made to world transformations
// to all the nodes
_sceneGraph->Update(XMMatrixIdentity());
}
void DirectXFramework::Render()
{
// Clear the render target and the depth stencil view
_deviceContext->ClearRenderTargetView(_renderTargetView.Get(), _backgroundColour);
_deviceContext->ClearDepthStencilView(_depthStencilView.Get(), D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
// Now recurse through the scene graph, rendering each object
_sceneGraph->Render();
// Now display the scene
ThrowIfFailed(_swapChain->Present(0, 0));
}
void DirectXFramework::OnResize(WPARAM wParam)
{
// Update view and projection matrices to allow for the window size change
XMStoreFloat4x4(&_viewTransformation, XMMatrixLookAtLH(XMLoadFloat4(&_eyePosition), XMLoadFloat4(&_focalPointPosition), XMLoadFloat4(&_upVector)));
XMStoreFloat4x4(&_projectionTransformation, XMMatrixPerspectiveFovLH(XM_PIDIV4, (float)GetWindowWidth() / GetWindowHeight(), 1.0f, 10000.0f));
// This will free any existing render and depth views (which
// would be the case if the window was being resized)
_renderTargetView = nullptr;
_depthStencilView = nullptr;
_depthStencilBuffer = nullptr;
ThrowIfFailed(_swapChain->ResizeBuffers(1, GetWindowWidth(), GetWindowHeight(), DXGI_FORMAT_R8G8B8A8_UNORM, 0));
// Create a drawing surface for DirectX to render to
ComPtr<ID3D11Texture2D> backBuffer;
ThrowIfFailed(_swapChain->GetBuffer(0, IID_PPV_ARGS(&backBuffer)));
ThrowIfFailed(_device->CreateRenderTargetView(backBuffer.Get(), NULL, _renderTargetView.GetAddressOf()));
// The depth buffer is used by DirectX to ensure
// that pixels of closer objects are drawn over pixels of more
// distant objects.
// First, we need to create a texture (bitmap) for the depth buffer
D3D11_TEXTURE2D_DESC depthBufferTexture = { 0 };
depthBufferTexture.Width = GetWindowWidth();
depthBufferTexture.Height = GetWindowHeight();
depthBufferTexture.ArraySize = 1;
depthBufferTexture.MipLevels = 1;
depthBufferTexture.SampleDesc.Count = 4;
depthBufferTexture.Format = DXGI_FORMAT_D32_FLOAT;
depthBufferTexture.Usage = D3D11_USAGE_DEFAULT;
depthBufferTexture.BindFlags = D3D11_BIND_DEPTH_STENCIL;
// Create the depth buffer.
ComPtr<ID3D11Texture2D> depthBuffer;
ThrowIfFailed(_device->CreateTexture2D(&depthBufferTexture, NULL, depthBuffer.GetAddressOf()));
ThrowIfFailed(_device->CreateDepthStencilView(depthBuffer.Get(), 0, _depthStencilView.GetAddressOf()));
// Bind the render target view buffer and the depth stencil view buffer to the output-merger stage
// of the pipeline.
_deviceContext->OMSetRenderTargets(1, _renderTargetView.GetAddressOf(), _depthStencilView.Get());
// Specify a viewport of the required size
D3D11_VIEWPORT viewPort;
viewPort.Width = static_cast<float>(GetWindowWidth());
viewPort.Height = static_cast<float>(GetWindowHeight());
viewPort.MinDepth = 0.0f;
viewPort.MaxDepth = 1.0f;
viewPort.TopLeftX = 0;
viewPort.TopLeftY = 0;
_deviceContext->RSSetViewports(1, &viewPort);
}
bool DirectXFramework::GetDeviceAndSwapChain()
{
UINT createDeviceFlags = 0;
// We are going to only accept a hardware driver or a WARP
// driver
D3D_DRIVER_TYPE driverTypes[] =
{
D3D_DRIVER_TYPE_HARDWARE,
D3D_DRIVER_TYPE_WARP
};
unsigned int totalDriverTypes = ARRAYSIZE(driverTypes);
D3D_FEATURE_LEVEL featureLevels[] =
{
D3D_FEATURE_LEVEL_11_0
};
unsigned int totalFeatureLevels = ARRAYSIZE(featureLevels);
DXGI_SWAP_CHAIN_DESC swapChainDesc = { 0 };
swapChainDesc.BufferCount = 1;
swapChainDesc.BufferDesc.Width = GetWindowWidth();
swapChainDesc.BufferDesc.Height = GetWindowHeight();
swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
// Set the refresh rate to 0 and let DXGI determine the best option (refer to DXGI best practices)
swapChainDesc.BufferDesc.RefreshRate.Numerator = 0;
swapChainDesc.BufferDesc.RefreshRate.Denominator = 0;
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc.OutputWindow = GetHWnd();
// Start out windowed
swapChainDesc.Windowed = true;
// Enable multi-sampling to give smoother lines (set to 1 if performance becomes an issue)
swapChainDesc.SampleDesc.Count = 4;
swapChainDesc.SampleDesc.Quality = 0;
// Loop through the driver types to determine which one is available to us
D3D_DRIVER_TYPE driverType = D3D_DRIVER_TYPE_UNKNOWN;
for (unsigned int driver = 0; driver < totalDriverTypes && driverType == D3D_DRIVER_TYPE_UNKNOWN; driver++)
{
if (SUCCEEDED(D3D11CreateDeviceAndSwapChain(0,
driverTypes[driver],
0,
createDeviceFlags,
featureLevels,
totalFeatureLevels,
D3D11_SDK_VERSION,
&swapChainDesc,
_swapChain.GetAddressOf(),
_device.GetAddressOf(),
0,
_deviceContext.GetAddressOf()
)))
{
driverType = driverTypes[driver];
}
}
if (driverType == D3D_DRIVER_TYPE_UNKNOWN)
{
// Unable to find a suitable device driver
return false;
}
return true;
}