1
votes

i am new to directx programing so i started to follow some tutorials online with dx11. I can initialize win32 window and directx11 fine, but when i try to draw triangle window appears and then it freezes my pc so i have to reboot it. I have searched for solution but nothing helps.

Here is my WinMain code:

#include "DXApp.h"
#include<DirectXMath.h>


class App : public DXApp {
public:
App(HINSTANCE hInstance);
~App();

bool Init() override;
void Update(float dt) override;
void Render(float dt) override;

};

int WINAPI WinMain(__in HINSTANCE hInstance, __in_opt HINSTANCE hPrevInstance, __in LPSTR lpCmdLine, __in int nShowCmd) {
App app(hInstance);

if (!app.Init()) return 1;

return app.Run();
}

App::App(HINSTANCE hInstance) : DXApp(hInstance)
{
}

App::~App()
{
}

bool App::Init()
{
return DXApp::Init();
}

void App::Update(float dt)
{
}

    void App::Render(float dt)
{
    immediateContext->ClearRenderTargetView(renderTargetView, DirectX::Colors::CornflowerBlue);
    immediateContext->Draw(3, 0);
    swapChain->Present(0, 0);
}

And my app header and cpp:

DXApp.h:

#pragma once
#include<Windows.h>
#include<string>
#include"DXUtil.h"
#include<d3dcompiler.h>
#pragma comment(lib, "d3dcompiler.lib")
#define WIN32_LEAN_AND_MEAN

class DXApp
{
public:
DXApp(HINSTANCE hInstance);
void cleanUp();
virtual ~DXApp(void);

//MAIN APPLICATION LOOP

int Run();

//FRAMEWORK METHODS

virtual bool Init();
virtual void Update(float dt) = 0;
virtual void Render(float dt) = 0;
virtual LRESULT MsgProc(HWND hwnd, unsigned int msg, WPARAM wParam, LPARAM lParam);

protected:

HWND            hAppWnd;
HINSTANCE       hAppInstance;
unsigned int    ClientWidth;
unsigned int    ClientHeight;
std::string     AppTitle;
DWORD           WindStyle;

//DIRECTX ATTRIBUTES

ID3D11Device*               device;
ID3D11DeviceContext*        immediateContext;
IDXGISwapChain*             swapChain;
ID3D11RenderTargetView*     renderTargetView;
D3D_DRIVER_TYPE             driverType;
D3D_FEATURE_LEVEL           featureLevel;
D3D11_VIEWPORT              viewport;

ID3D11Buffer*               triangleVertBuffer;
ID3D11PixelShader*          pixelShader;
ID3D11VertexShader*         vertexShader;
ID3D10Blob*                 VSBuffer;
ID3D10Blob*                 PSBuffer;
ID3D11InputLayout*          vertLayout;

protected:

//INITIALZE WIN32 WINDOW

bool windowInit();

//INITIALIZE DIRECTX

bool direct3dInit();
};

DXApp.cpp:

#include "DXApp.h"

namespace {

DXApp * g_pApp = nullptr;
}

LRESULT CALLBACK MainWndProc(HWND hwnd, unsigned int msg, WPARAM wParam, LPARAM lParam) {

if (g_pApp) return g_pApp->MsgProc(hwnd, msg, wParam, lParam);
else return DefWindowProc(hwnd, msg, wParam, lParam);
}



//VERTEX

struct Vertex {
Vertex() {}
Vertex(float x, float y, float z) : pos(x, y, z) {}
DirectX::XMFLOAT3 pos;

};

D3D11_INPUT_ELEMENT_DESC layout[] = {
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
};
unsigned int numLayoutElements = ARRAYSIZE(layout);



DXApp::DXApp(HINSTANCE hInstance)
{
hAppInstance = hInstance;
hAppWnd = NULL;
ClientWidth = 1280;
ClientHeight = 720;
AppTitle = "DirectX11 Engine";
WindStyle = WS_OVERLAPPEDWINDOW;
g_pApp = this;

//DIRECTX

device = nullptr;
swapChain = nullptr;
immediateContext = nullptr;
renderTargetView = nullptr;

vertexShader = nullptr;
pixelShader = nullptr;
triangleVertBuffer = nullptr;
VSBuffer = nullptr;
PSBuffer = nullptr;
vertLayout = nullptr;
}

void DXApp::cleanUp()
{
if (immediateContext) immediateContext->ClearState();
Memory::SafeRelease(renderTargetView);
Memory::SafeRelease(immediateContext);
Memory::SafeRelease(swapChain);
Memory::SafeRelease(device);

Memory::SafeRelease(vertLayout);
Memory::SafeRelease(PSBuffer);
Memory::SafeRelease(VSBuffer);
Memory::SafeRelease(triangleVertBuffer);
Memory::SafeRelease(pixelShader);
Memory::SafeRelease(vertexShader);
}


DXApp::~DXApp()
{
//DIRECTX CLEANUP
if (immediateContext) immediateContext->ClearState();
Memory::SafeRelease(renderTargetView);
Memory::SafeRelease(immediateContext);
Memory::SafeRelease(swapChain);
Memory::SafeRelease(device);

Memory::SafeRelease(vertLayout);
Memory::SafeRelease(PSBuffer);
Memory::SafeRelease(VSBuffer);
Memory::SafeRelease(triangleVertBuffer);
Memory::SafeRelease(pixelShader);
Memory::SafeRelease(vertexShader);
}


int DXApp::Run() {

MSG msg = { 0 };
while (WM_QUIT != msg.message) {
    if (PeekMessage(&msg, NULL, NULL, NULL, PM_REMOVE)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    else {
        Update(0.0f);

        Render(0.0f);
    }
}
return static_cast<int>(msg.wParam);
}

bool DXApp::Init()
{
if (!windowInit()) {
    return false;
}

if (!direct3dInit()) {
    return false;
}

return true;
}

bool DXApp::windowInit()
{
WNDCLASSEX wcex;
ZeroMemory(&wcex, sizeof(WNDCLASSEX));

wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.hInstance = hAppInstance;
wcex.lpfnWndProc = MainWndProc;
wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)GetStockObject(NULL_BRUSH);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = "DXAPPWNDCLASS";
wcex.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

if (!RegisterClassEx(&wcex)) {
    OutputDebugString("\nFAILED TO CREATE WINDOW CLASS!!\n");
    return false;
}

RECT r = { 0, 0, ClientWidth, ClientHeight };
AdjustWindowRect(&r, WindStyle, false);

unsigned int width = r.right - r.left;
unsigned int height = r.bottom - r.top;

unsigned int x = GetSystemMetrics(SM_CXSCREEN) / 2 - width / 2;
unsigned int y = GetSystemMetrics(SM_CYSCREEN) / 2 - height / 2;

hAppWnd = CreateWindow("DXAPPWNDCLASS", AppTitle.c_str(), WindStyle, x, y, width, height, NULL, NULL, hAppInstance, NULL);
if (!hAppWnd) {
    OutputDebugString("\nFAILED TO CREATE WINDOW!!\n");
    return false;
}

ShowWindow(hAppWnd, SW_SHOW);
return true;
}

//DIRECTX INITIALIZATION

bool DXApp::direct3dInit()
{
unsigned int createDeviceFlags = 0;

#ifdef DEBUG
createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif // DEBUG

D3D_DRIVER_TYPE driverTypes[] = {

    D3D_DRIVER_TYPE_HARDWARE,
    D3D_DRIVER_TYPE_WARP,
    D3D_DRIVER_TYPE_REFERENCE
};

unsigned int numDriverTypes = ARRAYSIZE(driverTypes);

D3D_FEATURE_LEVEL featureLevels[] = {

    D3D_FEATURE_LEVEL_11_0,
    D3D_FEATURE_LEVEL_10_1,
    D3D_FEATURE_LEVEL_10_0,
    D3D_FEATURE_LEVEL_9_3
};

unsigned int numFeatureLevels = ARRAYSIZE(featureLevels);

DXGI_SWAP_CHAIN_DESC swapDesc;
ZeroMemory(&swapDesc, sizeof(DXGI_SWAP_CHAIN_DESC));

swapDesc.BufferCount = 1;
swapDesc.BufferDesc.Width = ClientWidth;
swapDesc.BufferDesc.Height = ClientHeight;
swapDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
swapDesc.BufferDesc.RefreshRate.Numerator = 60;
swapDesc.BufferDesc.RefreshRate.Denominator = 1;
swapDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapDesc.OutputWindow = hAppWnd;
swapDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
swapDesc.Windowed = true;
swapDesc.SampleDesc.Count = 1;
swapDesc.SampleDesc.Quality = 0;
swapDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;

HRESULT result;
for (int i = 0; i < numDriverTypes; ++i) {
    result = D3D11CreateDeviceAndSwapChain(NULL, driverTypes[i], NULL, createDeviceFlags, featureLevels, numFeatureLevels, 
        D3D11_SDK_VERSION, &swapDesc, &swapChain, &device, &featureLevel, &immediateContext);

    if (SUCCEEDED(result)) {
        driverType = driverTypes[i];
        break;
    }

    if (FAILED(result)) {
        OutputDebugString("FAILED TO CREATE DX11 DEVICE!!");
        return false;
    }
}

//RENDER TARGET VIEW
ID3D11Texture2D* backBufferTex = 0;
swapChain->GetBuffer(NULL, __uuidof(ID3D11Texture2D), reinterpret_cast<void**>(&backBufferTex));
device->CreateRenderTargetView(backBufferTex, nullptr, &renderTargetView);

//BIND RENDER TARGET VIEW
immediateContext->OMSetRenderTargets(1, &renderTargetView, nullptr);

//COMPILE SHADERS FROM FILE
result = D3DCompileFromFile(L"VertexShader.hlsl", 0, 0, "vertexShader", "vs_4_0", 0, 0, &VSBuffer, &VSBuffer);
result = D3DCompileFromFile(L"PixelShader.hlsl", 0, 0, "pixelShader", "ps_4_0", 0, 0, &PSBuffer, &PSBuffer);

//CREATE SHADER OBJECTS
result = device->CreateVertexShader(VSBuffer->GetBufferPointer(), VSBuffer->GetBufferSize(), 0, &vertexShader);
result = device->CreatePixelShader(PSBuffer->GetBufferPointer(), PSBuffer->GetBufferSize(), 0, &pixelShader);

//SET SHADERS
immediateContext->VSSetShader(vertexShader, 0, 0);
immediateContext->PSSetShader(pixelShader, 0, 0);

//CREATE VERTEX BUFFER
Vertex v[] = {
    Vertex(0.0f, 0.5f, 0.5f),
    Vertex(0.5f, -0.5f, 0.5f),
    Vertex(-0.5f, 0.5f, 0.5f),
};

D3D11_BUFFER_DESC vertexBufferDesc;
ZeroMemory(&vertexBufferDesc, sizeof(D3D11_BUFFER_DESC));

vertexBufferDesc.Usage = D3D11_USAGE_DEFAULT;
vertexBufferDesc.ByteWidth = sizeof(Vertex) * 3;
vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
vertexBufferDesc.CPUAccessFlags = 0;
vertexBufferDesc.MiscFlags = 0;

D3D11_SUBRESOURCE_DATA vertexBufferData;
ZeroMemory(&vertexBufferData, sizeof(vertexBufferData));
vertexBufferData.pSysMem = v;

result = device->CreateBuffer(&vertexBufferDesc, &vertexBufferData, &triangleVertBuffer);

//SET VERTEX BUFFER
unsigned int stride = sizeof(Vertex);
unsigned int offset = 0;
immediateContext->IAGetVertexBuffers(0, 1, &triangleVertBuffer, &stride, &offset);

//CREATE INPUT LAYOUT
device->CreateInputLayout(layout, numLayoutElements, VSBuffer->GetBufferPointer(), VSBuffer->GetBufferSize(), &vertLayout);

//SET INPUT LAYOUT
immediateContext->IASetInputLayout(vertLayout);

//SET PRIMITIVE TOPOLOGY
immediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

//VIEWPORT CREATION
ZeroMemory(&viewport, sizeof(D3D11_VIEWPORT));

viewport.Width = static_cast<float>(ClientWidth);
viewport.Height = static_cast<float>(ClientHeight);
viewport.TopLeftX = 0;
viewport.TopLeftY = 0;
viewport.MinDepth = 0.0f;
viewport.MaxDepth = 1.0f;

//SET VIEWPORT
immediateContext->RSSetViewports(1, &viewport);


return true;

}




//MESSAGES

LRESULT DXApp::MsgProc(HWND hwnd, unsigned int msg, WPARAM wParam, LPARAM lParam)
{
switch (msg) {
case WM_DESTROY:
    PostQuitMessage(0);
    return 0;
default:
    return DefWindowProc(hwnd, msg, wParam, lParam);

}
}

Thanks for any help.

1
Your example is quite long, narrowing down the problem often helps to find the issue. You can learn how to give good examples in stackoverflow.com/help/mcve - Jieter
i only know opengl, but a quick glance over this the shaders might be worth taking a closer look at. the equivalent of a segfault wrt to shaders can sometimes cause a lot of grief, including freezing your OS. for example your call to VSSetShader doesn't seem to have the right arguments, why are they both 0? again i don't know the semantics of DX, but I think one of those should be a 1? i'm looking here, i could be misunderstanding but I believe 0 will be treated as NULL and the shader won't be used? - svenevs
@sjm324 Thanks, but VSSetShader is ok, i am not using any interface so both should be 0. 0 is treated as NULL, but as i said it's ok in this case. - Boris Djurdjevic

1 Answers

4
votes

The first steps in debugging a Direct3D program are:

(1) Make sure you are properly checking all HRESULT values. There are numerous places in your code where you are failing to check the result. If the Direct3D function returns a void, you can ignore error checking. Otherwise you need to use SUCCEEDED, FAILED, or use something like ThrowIfFailed. This is essentially because continuing beyond a failure is going to make it very hard to debug the true cause of the problem.

(2) Enable the Direct3D debug device and look for output. You appear to have that in your debug builds. Do you see any output in the debug window?

It is highly unusual to have a program 'hang' your system, but it is possible if you have a bad driver or faulty hardware. Without more details, however, it's difficult to diagnose since your program is faulty to begin with.