2016-06-04 2 views
0

Я новичок в программировании directx, поэтому я начал следить за некоторыми учебниками онлайн с помощью dx11. Я могу инициализировать окно win32 и directx11 в порядке, но когда я попытаюсь нарисовать треугольное окно, появится, а затем он заморозит мой компьютер, поэтому я должен перезагрузить его. Я искал решение, но ничего не помогает.Windows зависает после попытки визуализации треугольника в 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); 

} 
} 

Thanks for any help.

+1

Ваш пример довольно длинный, сужение проблемы часто помогает найти проблему. Вы можете узнать, как дать хорошие примеры в http://stackoverflow.com/help/mcve. – Jieter

+0

Я знаю только opengl, но быстрый взгляд на это может быть целесообразным более пристальным взглядом на шейдеры. эквивалент segfault по отношению к шейдерам иногда может вызвать много горя, включая замораживание вашей ОС. например, ваш вызов 'VSSetShader', похоже, не имеет правильных аргументов, почему они оба равны 0? снова я не знаю семантики DX, но я думаю, что один из них должен быть 1? Я смотрю [здесь] (https://msdn.microsoft.com/en-us/library/windows/desktop/ff476493%28v=vs.85%29.aspx), я могу ошибаться, но я считаю, что 0 будет обрабатываться как «NULL», и шейдер не будет использоваться? – sjm324

+0

@ sjm324 Спасибо, но VSSetShader в порядке, я не использую какой-либо интерфейс, поэтому оба должны быть равны 0. 0 обрабатывается как NULL, но, как я сказал, в этом случае все в порядке. –

ответ

3

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, или использовать что-то вроде ThrowIfFailed. Это по существу, потому что продолжение за пределами неудачи затруднит отладку истинной причины проблемы.

(2) Включите устройство отладки Direct3D и найдите выход. Кажется, у вас это в ваших отладочных сборках. Вы видите какой-либо вывод в окне отладки?

Очень необычно, чтобы программа зависала вашей системой, но это возможно, если у вас плохой драйвер или неисправное оборудование. Однако, без подробностей, это трудно диагностировать, так как ваша программа является неисправной для начала.

+0

Благодарим вас за консультацию по проверке HRESULT. Проблема заключалась в использовании 'IAGetVertexBuffers' вместо' IASetVertexBuffers'. ОС перестала сбой, но у меня все еще проблема с шейдерами: ** «точка входа не найдена» **. –

+0

Примите ответ и запустите новый вопрос, который включает источник HLSL и ваши вызовы компилятору. –

Смежные вопросы