|
@@ -14,12 +14,16 @@
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
|
#include <Windows.h>
|
|
|
+#include <shellapi.h>
|
|
|
+#include <stdexcept>
|
|
|
#include <windowsx.h>
|
|
|
#include <d3d11_1.h>
|
|
|
#include <dxgi1_2.h>
|
|
|
#include <DirectXMath.h>
|
|
|
#include <d3dcompiler.h>
|
|
|
#include "ModelLoader.h"
|
|
|
+#include "UTFConverter.h"
|
|
|
+#include "SafeRelease.hpp"
|
|
|
|
|
|
#pragma comment (lib, "d3d11.lib")
|
|
|
#pragma comment (lib, "Dxgi.lib")
|
|
@@ -27,6 +31,10 @@
|
|
|
#pragma comment (lib, "dxguid.lib")
|
|
|
|
|
|
using namespace DirectX;
|
|
|
+using namespace AssimpSamples::SharedCode;
|
|
|
+
|
|
|
+#define VERTEX_SHADER_FILE L"VertexShader.hlsl"
|
|
|
+#define PIXEL_SHADER_FILE L"PixelShader.hlsl"
|
|
|
|
|
|
// ------------------------------------------------------------
|
|
|
// Structs
|
|
@@ -45,29 +53,32 @@ struct ConstantBuffer {
|
|
|
|
|
|
const char g_szClassName[] = "directxWindowClass";
|
|
|
|
|
|
+static std::string g_ModelPath;
|
|
|
|
|
|
UINT width, height;
|
|
|
-HWND hwnd;
|
|
|
+HWND hwnd = nullptr;
|
|
|
|
|
|
// ------------------------------------------------------------
|
|
|
// DirectX Variables
|
|
|
// ------------------------------------------------------------
|
|
|
D3D_DRIVER_TYPE g_driverType = D3D_DRIVER_TYPE_NULL;
|
|
|
D3D_FEATURE_LEVEL g_featureLevel = D3D_FEATURE_LEVEL_11_0;
|
|
|
-ID3D11Device *dev;
|
|
|
-ID3D11Device1 *dev1;
|
|
|
-ID3D11DeviceContext *devcon;
|
|
|
-ID3D11DeviceContext1 *devcon1;
|
|
|
-IDXGISwapChain *swapchain;
|
|
|
-IDXGISwapChain1 *swapchain1;
|
|
|
-ID3D11RenderTargetView *backbuffer;
|
|
|
-ID3D11VertexShader *pVS;
|
|
|
-ID3D11PixelShader *pPS;
|
|
|
-ID3D11InputLayout *pLayout;
|
|
|
-ID3D11Buffer *pConstantBuffer;
|
|
|
-ID3D11Texture2D *g_pDepthStencil;
|
|
|
-ID3D11DepthStencilView *g_pDepthStencilView;
|
|
|
-ID3D11SamplerState *TexSamplerState;
|
|
|
+ID3D11Device *dev = nullptr;
|
|
|
+ID3D11Device1 *dev1 = nullptr;
|
|
|
+ID3D11DeviceContext *devcon = nullptr;
|
|
|
+ID3D11DeviceContext1 *devcon1 = nullptr;
|
|
|
+IDXGISwapChain *swapchain = nullptr;
|
|
|
+IDXGISwapChain1 *swapchain1 = nullptr;
|
|
|
+ID3D11RenderTargetView *backbuffer = nullptr;
|
|
|
+ID3D11VertexShader *pVS = nullptr;
|
|
|
+ID3D11PixelShader *pPS = nullptr;
|
|
|
+ID3D11InputLayout *pLayout = nullptr;
|
|
|
+ID3D11Buffer *pConstantBuffer = nullptr;
|
|
|
+ID3D11Texture2D *g_pDepthStencil = nullptr;
|
|
|
+ID3D11DepthStencilView *g_pDepthStencilView = nullptr;
|
|
|
+ID3D11SamplerState *TexSamplerState = nullptr;
|
|
|
+ID3D11RasterizerState *rasterstate = nullptr;
|
|
|
+ID3D11Debug* d3d11debug = nullptr;
|
|
|
|
|
|
XMMATRIX m_World;
|
|
|
XMMATRIX m_View;
|
|
@@ -91,7 +102,7 @@ void Throwanerror(LPCSTR errormessage);
|
|
|
// Our Model
|
|
|
// ------------------------------------------------------------
|
|
|
|
|
|
-ModelLoader *ourModel;
|
|
|
+ModelLoader *ourModel = nullptr;
|
|
|
|
|
|
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
|
{
|
|
@@ -109,9 +120,42 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
|
|
- LPSTR lpCmdLine, int nCmdShow)
|
|
|
+int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
|
|
+ LPWSTR lpCmdLine, int nCmdShow)
|
|
|
{
|
|
|
+ int argc;
|
|
|
+ LPWSTR* argv = CommandLineToArgvW(GetCommandLineW(), &argc);
|
|
|
+ if (!argv) {
|
|
|
+ MessageBox(NULL,
|
|
|
+ TEXT("An error occured while reading command line arguments."),
|
|
|
+ TEXT("Error!"),
|
|
|
+ MB_ICONERROR | MB_OK);
|
|
|
+ return EXIT_FAILURE;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Free memory allocated from CommandLineToArgvW.
|
|
|
+ auto free_command_line_allocated_memory = [&argv]() {
|
|
|
+ if (argv) {
|
|
|
+ LocalFree(argv);
|
|
|
+ argv = nullptr;
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ // Ensure that a model file has been specified.
|
|
|
+ if (argc < 2) {
|
|
|
+ MessageBox(NULL,
|
|
|
+ TEXT("No model file specified. The program will now close."),
|
|
|
+ TEXT("Error!"),
|
|
|
+ MB_ICONERROR | MB_OK);
|
|
|
+ free_command_line_allocated_memory();
|
|
|
+ return EXIT_FAILURE;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Retrieve the model file path.
|
|
|
+ g_ModelPath = UTFConverter(argv[1]).str();
|
|
|
+
|
|
|
+ free_command_line_allocated_memory();
|
|
|
+
|
|
|
WNDCLASSEX wc;
|
|
|
MSG msg;
|
|
|
|
|
@@ -160,26 +204,35 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
|
|
width = wr.right - wr.left;
|
|
|
height = wr.bottom - wr.top;
|
|
|
|
|
|
- InitD3D(hInstance, hwnd);
|
|
|
+ try {
|
|
|
+ InitD3D(hInstance, hwnd);
|
|
|
|
|
|
- while (true)
|
|
|
- {
|
|
|
-
|
|
|
- if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
|
|
|
+ while (true)
|
|
|
{
|
|
|
- TranslateMessage(&msg);
|
|
|
- DispatchMessage(&msg);
|
|
|
|
|
|
- if (msg.message == WM_QUIT)
|
|
|
- break;
|
|
|
- }
|
|
|
+ if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
|
|
|
+ {
|
|
|
+ TranslateMessage(&msg);
|
|
|
+ DispatchMessage(&msg);
|
|
|
|
|
|
- RenderFrame();
|
|
|
- }
|
|
|
+ if (msg.message == WM_QUIT)
|
|
|
+ break;
|
|
|
+ }
|
|
|
|
|
|
- CleanD3D();
|
|
|
+ RenderFrame();
|
|
|
+ }
|
|
|
|
|
|
- return msg.wParam;
|
|
|
+ CleanD3D();
|
|
|
+ return static_cast<int>(msg.wParam);
|
|
|
+ } catch (const std::exception& e) {
|
|
|
+ MessageBox(hwnd, e.what(), TEXT("Error!"), MB_ICONERROR | MB_OK);
|
|
|
+ CleanD3D();
|
|
|
+ return EXIT_FAILURE;
|
|
|
+ } catch (...) {
|
|
|
+ MessageBox(hwnd, TEXT("Caught an unknown exception."), TEXT("Error!"), MB_ICONERROR | MB_OK);
|
|
|
+ CleanD3D();
|
|
|
+ return EXIT_FAILURE;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
void InitD3D(HINSTANCE hinstance, HWND hWnd)
|
|
@@ -227,6 +280,12 @@ void InitD3D(HINSTANCE hinstance, HWND hWnd)
|
|
|
if (FAILED(hr))
|
|
|
Throwanerror("Directx Device Creation Failed!");
|
|
|
|
|
|
+#if _DEBUG
|
|
|
+ hr = dev->QueryInterface(IID_PPV_ARGS(&d3d11debug));
|
|
|
+ if (FAILED(hr))
|
|
|
+ OutputDebugString(TEXT("Failed to retrieve DirectX 11 debug interface.\n"));
|
|
|
+#endif
|
|
|
+
|
|
|
UINT m4xMsaaQuality;
|
|
|
dev->CheckMultisampleQualityLevels(
|
|
|
DXGI_FORMAT_R8G8B8A8_UNORM, 4, &m4xMsaaQuality);
|
|
@@ -348,7 +407,6 @@ void InitD3D(HINSTANCE hinstance, HWND hWnd)
|
|
|
devcon->OMSetRenderTargets(1, &backbuffer, g_pDepthStencilView);
|
|
|
|
|
|
D3D11_RASTERIZER_DESC rasterDesc;
|
|
|
- ID3D11RasterizerState *rasterState;
|
|
|
rasterDesc.AntialiasedLineEnable = false;
|
|
|
rasterDesc.CullMode = D3D11_CULL_BACK;
|
|
|
rasterDesc.DepthBias = 0;
|
|
@@ -360,8 +418,8 @@ void InitD3D(HINSTANCE hinstance, HWND hWnd)
|
|
|
rasterDesc.ScissorEnable = false;
|
|
|
rasterDesc.SlopeScaledDepthBias = 0.0f;
|
|
|
|
|
|
- dev->CreateRasterizerState(&rasterDesc, &rasterState);
|
|
|
- devcon->RSSetState(rasterState);
|
|
|
+ dev->CreateRasterizerState(&rasterDesc, &rasterstate);
|
|
|
+ devcon->RSSetState(rasterstate);
|
|
|
|
|
|
D3D11_VIEWPORT viewport;
|
|
|
ZeroMemory(&viewport, sizeof(D3D11_VIEWPORT));
|
|
@@ -381,19 +439,38 @@ void InitD3D(HINSTANCE hinstance, HWND hWnd)
|
|
|
|
|
|
void CleanD3D(void)
|
|
|
{
|
|
|
- swapchain->SetFullscreenState(FALSE, NULL);
|
|
|
-
|
|
|
- ourModel->Close();
|
|
|
- g_pDepthStencil->Release();
|
|
|
- g_pDepthStencilView->Release();
|
|
|
- pLayout->Release();
|
|
|
- pVS->Release();
|
|
|
- pPS->Release();
|
|
|
- pConstantBuffer->Release();
|
|
|
- swapchain->Release();
|
|
|
- backbuffer->Release();
|
|
|
- dev->Release();
|
|
|
- devcon->Release();
|
|
|
+ if (swapchain)
|
|
|
+ swapchain->SetFullscreenState(FALSE, NULL);
|
|
|
+
|
|
|
+ if (ourModel) {
|
|
|
+ ourModel->Close();
|
|
|
+ delete ourModel;
|
|
|
+ ourModel = nullptr;
|
|
|
+ }
|
|
|
+ SafeRelease(TexSamplerState);
|
|
|
+ SafeRelease(pConstantBuffer);
|
|
|
+ SafeRelease(pLayout);
|
|
|
+ SafeRelease(pVS);
|
|
|
+ SafeRelease(pPS);
|
|
|
+ SafeRelease(rasterstate);
|
|
|
+ SafeRelease(g_pDepthStencilView);
|
|
|
+ SafeRelease(g_pDepthStencil);
|
|
|
+ SafeRelease(backbuffer);
|
|
|
+ SafeRelease(swapchain);
|
|
|
+ SafeRelease(swapchain1);
|
|
|
+ SafeRelease(devcon1);
|
|
|
+ SafeRelease(dev1);
|
|
|
+ SafeRelease(devcon);
|
|
|
+#if _DEBUG
|
|
|
+ if (d3d11debug) {
|
|
|
+ OutputDebugString(TEXT("Dumping DirectX 11 live objects.\n"));
|
|
|
+ d3d11debug->ReportLiveDeviceObjects(D3D11_RLDO_DETAIL);
|
|
|
+ SafeRelease(d3d11debug);
|
|
|
+ } else {
|
|
|
+ OutputDebugString(TEXT("Unable to dump live objects: no DirectX 11 debug interface available.\n"));
|
|
|
+ }
|
|
|
+#endif
|
|
|
+ SafeRelease(dev);
|
|
|
}
|
|
|
|
|
|
void RenderFrame(void)
|
|
@@ -431,8 +508,10 @@ void RenderFrame(void)
|
|
|
void InitPipeline()
|
|
|
{
|
|
|
ID3DBlob *VS, *PS;
|
|
|
- CompileShaderFromFile(L"VertexShader.hlsl", 0, "main", "vs_4_0", &VS);
|
|
|
- CompileShaderFromFile(L"PixelShader.hlsl", 0, "main", "ps_4_0", &PS);
|
|
|
+ if(FAILED(CompileShaderFromFile(SHADER_PATH VERTEX_SHADER_FILE, 0, "main", "vs_4_0", &VS)))
|
|
|
+ Throwanerror(UTFConverter(L"Failed to compile shader from file " VERTEX_SHADER_FILE).c_str());
|
|
|
+ if(FAILED(CompileShaderFromFile(SHADER_PATH PIXEL_SHADER_FILE, 0, "main", "ps_4_0", &PS)))
|
|
|
+ Throwanerror(UTFConverter(L"Failed to compile shader from file " PIXEL_SHADER_FILE).c_str());
|
|
|
|
|
|
dev->CreateVertexShader(VS->GetBufferPointer(), VS->GetBufferSize(), NULL, &pVS);
|
|
|
dev->CreatePixelShader(PS->GetBufferPointer(), PS->GetBufferSize(), NULL, &pPS);
|
|
@@ -485,7 +564,7 @@ void InitGraphics()
|
|
|
m_View = XMMatrixLookAtLH(Eye, At, Up);
|
|
|
|
|
|
ourModel = new ModelLoader;
|
|
|
- if (!ourModel->Load(hwnd, dev, devcon, "Models/myModel.fbx"))
|
|
|
+ if (!ourModel->Load(hwnd, dev, devcon, g_ModelPath))
|
|
|
Throwanerror("Model couldn't be loaded");
|
|
|
}
|
|
|
|
|
@@ -514,5 +593,5 @@ HRESULT CompileShaderFromFile(LPCWSTR pFileName, const D3D_SHADER_MACRO* pDefine
|
|
|
|
|
|
void Throwanerror(LPCSTR errormessage)
|
|
|
{
|
|
|
- MessageBox(hwnd, errormessage, "Error!", MB_ICONERROR | MB_OK);
|
|
|
-}
|
|
|
+ throw std::runtime_error(errormessage);
|
|
|
+}
|