Fixed SimpleTexturedDirectX11 sample.

- Removed OpenGL/Glut references in SimpleTexturedDirectX11 CMakeFile
- Moved UTFConverter from SimpleTexturedOpenGL to its own file to be able to reuse it.
- Added compile definition SHADER_PATH to allow to locate the shader files in CMakeFile
- Fixed compile warnings
- Made global pointers null to help prevent dangling references.
- Added missing members initialization in class constructors.
- Removed references to missing model "Models/mymodel.fbx"
- Fixed error when extracting model file directory
- Added missing device context assignment in ModelLoader Load method
- Fixed memory leak caused by variable 'ourModel' not deleted.
- Removed call to dev->Release() in ModelLoader.cpp
- Adjusted Release() calls in reverse order when cleaning up D3D
- Made Throwanerror implementation throw an error instead of displaying a message box
- Fixed leaking D3D resources
- Added a pointer to an ID3D11Debug to dump live objects.
This commit is contained in:
Marc-Antoine Lortie
2020-03-06 10:26:51 -05:00
parent 0201fc57dc
commit aa8a6122ce
10 changed files with 386 additions and 109 deletions

View File

@@ -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);
if (msg.message == WM_QUIT)
break;
}
RenderFrame();
}
RenderFrame();
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;
}
CleanD3D();
return msg.wParam;
}
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);
if (swapchain)
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 (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);
}