首页 文章

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

提问于
浏览
1

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

这是我的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);
}

``
`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);

}
}

谢谢你的帮助 .

1 回答

  • 4

    调试Direct3D程序的第一步是:

    (1) Make sure you are properly checking all HRESULT values. 代码中有很多地方没有检查结果 . 如果Direct3D函数返回void,则可以忽略错误检查 . 否则,您需要使用 SUCCEEDEDFAILED 或使用类似ThrowIfFailed的内容 . 这主要是因为继续超越失败会使调试问题的真正原因变得非常困难 .

    (2) Enable the Direct3D debug device and look for output. 您的调试版本中似乎有这个 . 你在调试窗口看到任何输出吗?

    让程序“挂起”你的系统是非常罕见的,但如果你有一个坏的驱动程序或有故障的硬件,它是可能的 . 但是,如果没有更多细节,由于您的程序开始出现故障,因此很难诊断 .

相关问题