Windows 尝试在 directx11 中渲染三角形后冻结

Windows freezes after trying to render triangle in directx11

我是 directx 编程的新手,所以我开始使用 dx11 在线学习一些教程。 我可以很好地初始化 win32 window 和 directx11,但是当我尝试绘制三角形时 window 出现,然后它冻结了我的电脑,所以我必须重新启动它。我已经搜索了解决方案,但没有任何帮助。

这是我的 WinMain 代码:

#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);
}

</p> <p>还有我的应用头文件和 cpp:</p> <p><strong>DXApp.h:</strong></p> <pre><code>#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);

}
}

感谢您的帮助。

调试 Direct3D 程序的第一步是:

(1) 确保您正确检查了所有 HRESULT 值。 您的代码中有很多地方没有检查结果。如果 Direct3D 函数 returns 无效,则可以忽略错误检查。否则,您需要使用 SUCCEEDEDFAILEDThrowIfFailed 之类的东西。这主要是因为在失败之后继续进行下去会使调试问题的真正原因变得非常困难。

(2) 启用 Direct3D 调试设备并查找输出。 您的调试版本中似乎有它。您在调试 window 中看到任何输出了吗?

您的系统中有一个程序 'hang' 是极不寻常的,但如果您的驱动程序或硬件有问题,则有可能。但是,如果没有更多详细信息,则很难诊断,因为您的程序一开始就有问题。