我是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 回答
调试Direct3D程序的第一步是:
(1) Make sure you are properly checking all HRESULT values. 代码中有很多地方没有检查结果 . 如果Direct3D函数返回void,则可以忽略错误检查 . 否则,您需要使用
SUCCEEDED
,FAILED
或使用类似ThrowIfFailed的内容 . 这主要是因为继续超越失败会使调试问题的真正原因变得非常困难 .(2) Enable the Direct3D debug device and look for output. 您的调试版本中似乎有这个 . 你在调试窗口看到任何输出吗?
让程序“挂起”你的系统是非常罕见的,但如果你有一个坏的驱动程序或有故障的硬件,它是可能的 . 但是,如果没有更多细节,由于您的程序开始出现故障,因此很难诊断 .