Files
directx-plane-game/Graphics2/DirectXFramework.cpp
iDunnoDev 7a57c73ac3 Added the camera class
Added the DDS Texture Loading for future use
Added the gamepad class for future use
Added first child method to the scenegraph
Added RGB to intensity and lerp methods to the shared methods class
Added the terrain node class with normals
Fixed issue with submeshnode not passing the world transform to the actual meshes
2022-04-18 22:33:15 +01:00

224 lines
6.9 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;
}
DirectXFramework * DirectXFramework::GetDXFramework()
{
return _dxFramework;
}
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
XMStoreFloat4x4(&_projectionTransformation, XMMatrixPerspectiveFovLH(XM_PIDIV4, (float)GetWindowWidth() / GetWindowHeight(), 1.0f, 1000.0f));
_resourceManager = make_shared<ResourceManager>();
_sceneGraph = make_shared<SceneGraph>();
_camera = make_shared<Camera>();
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();
_camera->Update();
// 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;
}