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.
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
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
@ 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. –