2016-06-04 1 views
0

Je suis nouveau à la programmation directx donc j'ai commencé à suivre quelques tutoriels en ligne avec dx11. Je peux initialiser win32 window et directx11 bien, mais quand j'essaie de dessiner une fenêtre triangulaire apparaît et puis il fige mon pc alors je dois le redémarrer. J'ai cherché une solution mais rien n'y fait.Windows se fige après avoir essayé de rendre le triangle en directx11

Voici mon code 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

Votre exemple est assez long, réduire le problème aide souvent à trouver le problème. Vous pouvez apprendre à donner de bons exemples dans http://stackoverflow.com/help/mcve – Jieter

+0

Je ne connais que opengl, mais un coup d'œil rapide sur ce que les shaders pourraient valoir la peine d'examiner de plus près. l'équivalent d'une faute de frappe aux shaders peut parfois causer beaucoup de chagrin, y compris le gel de votre système d'exploitation. Par exemple, votre appel à 'VSSetShader' ne semble pas avoir les bons arguments, pourquoi sont-ils tous les deux 0? encore une fois je ne connais pas la sémantique de DX, mais je pense que l'un d'entre eux devrait être un 1? Je regarde [ici] (https://msdn.microsoft.com/en-us/library/windows/desktop/ff476493%28v=vs.85%29.aspx), je pourrais être malentendu mais je crois que 0 sera être traité comme 'NULL' et le shader ne sera pas utilisé? – sjm324

+0

@ sjm324 Merci, mais VSSetShader est ok, je n'utilise pas d'interface donc les deux devraient être 0. 0 est considéré comme NULL, mais comme je l'ai dit c'est OK dans ce cas. –

Répondre

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 ou utiliser quelque chose comme ThrowIfFailed. C'est essentiellement parce que continuer au-delà d'un échec va rendre très difficile de déboguer la véritable cause du problème.

(2) Activez le périphérique de débogage Direct3D et recherchez la sortie. Vous semblez l'avoir dans vos versions de débogage. Voyez-vous une sortie dans la fenêtre de débogage?

Il est très inhabituel qu'un programme «bloque» votre système, mais cela est possible si vous avez un mauvais pilote ou un matériel défectueux. Sans plus de détails, cependant, il est difficile de diagnostiquer puisque votre programme est défectueux pour commencer.

+0

Merci pour le conseil sur vérifier HRESULT. Le problème était en utilisant 'IAGetVertexBuffers' au lieu de' IASetVertexBuffers'. OS a arrêté de s'écraser mais j'ai toujours un problème avec les shaders: ** "entrypoint not found" **. –

+0

Acceptez la réponse et lancez une nouvelle question qui inclut la source HLSL et vos appels au compilateur. –