2017-10-29 24 views
1

Direct3D11을 배우고 있으며 삼각형을 표시하려고하는데 필요한 모든 단계를 수행했지만 아무것도 표시되지 않았습니다. 내의 WinMain 그냥 게임 :: 초기화()와 게임 :: 실행()를 호출Direct3D : 삼각형을 그리려고하지만 아무 것도 표시되지 않습니다.

#include <Windows.h> 
#include <dxgi1_4.h> 
#include <d3d11.h> 
#include <d3dcompiler.h> 
#include "Game.h" 

Game *Game::game = nullptr; 

Game *Game::GetInstance() 
{ 
    if (Game::game == nullptr) 
     Game::game = new Game(); 
    return game; 
} 

Game::Game() 
{ 
} 

Game::~Game() 
{ 
} 

bool Game::Initialize(HINSTANCE hInstance) 
{ 
    if (InitializeWindow(hInstance)) 
     return InitializeDirect3D(); 
    return false; 
} 

bool Game::InitializeWindow(HINSTANCE hInstance) 
{ 
    WNDCLASS windowClass = {}; 
    windowClass.hInstance = hInstance; 
    windowClass.lpfnWndProc = &WndProc; 
    windowClass.lpszClassName = L"wndClass"; 
    windowClass.lpszMenuName = NULL; 
    windowClass.style = CS_HREDRAW | CS_VREDRAW; 
    windowClass.cbClsExtra = 0; 
    windowClass.cbWndExtra = 0; 
    windowClass.hCursor = LoadCursor(NULL, IDC_ARROW); 
    windowClass.hIcon = LoadIcon(NULL, IDI_APPLICATION); 
    windowClass.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH); 
    RegisterClass(&windowClass); 

    mWindow = CreateWindow(L"wndClass", L"DirectX 12 Engine", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, hInstance, 0); 
    if (!mWindow) 
    { 
     MessageBox(0, L"window creation failed", L"ERROR", MB_OK); 
     return false; 
    } 
    ShowWindow(mWindow, SW_SHOW); 
    UpdateWindow(mWindow); 

    return true; 
} 

bool Game::InitializeDirect3D() 
{ 
    HRESULT hr; 

    // create the device and the device context 
    const D3D_FEATURE_LEVEL featureLevels[] = { D3D_FEATURE_LEVEL_11_0 }; 
    D3D_FEATURE_LEVEL featureLevel; 
    hr = D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, 0, D3D11_CREATE_DEVICE_DEBUG, featureLevels, 1, D3D11_SDK_VERSION, &mDevice, &featureLevel, &mDeviceContext); 
    if (FAILED(hr)) 
    { 
     MessageBox(mWindow, L"device creation failed", L"ERROR", MB_OK); 
     return false; 
    } 
    if (featureLevel != D3D_FEATURE_LEVEL_11_0) 
    { 
     MessageBox(mWindow, L"DirectX 11 not supported", L"ERROR", MB_OK); 
     return false; 
    } 

    // query 4X MSAA support 
    mDevice->CheckMultisampleQualityLevels(DXGI_FORMAT_R8G8B8A8_UNORM, 4, &m4xMsaaQuality); 
    if (m4xMsaaQuality <= 0) 
    { 
     MessageBox(mWindow, L"4X MSAA not supported", L"ERROR", MB_OK); 
     return false; 
    } 

    // describe and create the swap chain 
    DXGI_MODE_DESC modeDesc = {}; 
    modeDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; 
    modeDesc.Width = mClientWidth; 
    modeDesc.Height = mClientHeight; 
    modeDesc.RefreshRate.Denominator = 1; 
    modeDesc.RefreshRate.Numerator = 60; 
    modeDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; 
    modeDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; 
    DXGI_SWAP_CHAIN_DESC swapChainDesc = {}; 
    swapChainDesc.BufferDesc = modeDesc; 
    swapChainDesc.BufferCount = 1; 
    swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; 
    swapChainDesc.Flags = 0; 
    swapChainDesc.OutputWindow = mWindow; 
    swapChainDesc.Windowed = true; 
    swapChainDesc.SampleDesc.Count = 4; 
    swapChainDesc.SampleDesc.Quality = m4xMsaaQuality - 1; 
    swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; 

    IDXGIDevice *device = nullptr; 
    mDevice->QueryInterface(IID_PPV_ARGS(&device)); 
    IDXGIAdapter *adapter = nullptr; 
    device->GetParent(IID_PPV_ARGS(&adapter)); 
    IDXGIFactory *factory = nullptr; 
    adapter->GetParent(IID_PPV_ARGS(&factory)); 
    hr = factory->CreateSwapChain(mDevice, &swapChainDesc, &mSwapChain); 
    if (FAILED(hr)) 
    { 
     MessageBox(mWindow, L"swap chain creation failed", L"ERROR", MB_OK); 
     return false; 
    } 

    device->Release(); 
    adapter->Release(); 
    factory->Release(); 

    // create the render target view 
    ID3D11Texture2D *texture = nullptr; 
    mSwapChain->GetBuffer(0, IID_PPV_ARGS(&texture)); 
    mDevice->CreateRenderTargetView(texture, nullptr, &mRenderTargetView); 
    texture->Release(); 

    // bind render target views to output merger stage of graphics pipeline 
    mDeviceContext->OMSetRenderTargets(1, &mRenderTargetView, nullptr); 

    // set the viewport 
    D3D11_VIEWPORT viewport; 
    viewport.TopLeftX = 0.0f; 
    viewport.TopLeftY = 0.0f; 
    viewport.Width = static_cast<float>(mClientWidth); 
    viewport.Height = static_cast<float>(mClientHeight); 
    viewport.MinDepth = 0.0f; 
    viewport.MaxDepth = 1.0f; 
    mDeviceContext->RSSetViewports(1, &viewport); 

    CreateShaders(); 
    CreateBuffers(); 
    CreateInputLayout(); 

    return true; 
} 

bool Game::CreateShaders() 
{ 
    HRESULT hr; 

    // compile shaders 
    ID3DBlob *error; 
    hr = D3DCompileFromFile(L"shaders/VertexShader.hlsl", nullptr, nullptr, "main", "vs_5_0", 0, 0, &mVertexShaderBlob, &error); 
    if (FAILED(hr)) 
    { 
     ErrorBox(L"vertex shader compilation failed"); 
     OutputDebugStringA((LPCSTR)error->GetBufferPointer()); 
     return false; 
    } 
    hr = D3DCompileFromFile(L"shaders/PixelShader.hlsl", nullptr, nullptr, "main", "ps_5_0", 0, 0, &mPixelShaderBlob, &error); 
    if (FAILED(hr)) 
    { 
     ErrorBox(L"pixel shader compilation failed"); 
     OutputDebugStringA((LPCSTR)error->GetBufferPointer()); 
     return false; 
    } 

    // create shaders 
    hr = mDevice->CreateVertexShader(mVertexShaderBlob->GetBufferPointer(), mVertexShaderBlob->GetBufferSize(), nullptr, &mVertexShader); 
    if (FAILED(hr)) 
    { 
     ErrorBox(L"vertex shader creation failed"); 
     return false; 
    } 
    hr = mDevice->CreatePixelShader(mPixelShaderBlob->GetBufferPointer(), mPixelShaderBlob->GetBufferSize(), nullptr, &mPixelShader); 
    if (FAILED(hr)) 
    { 
     ErrorBox(L"pixel shader creation failed"); 
     return false; 
    } 

    return true; 
} 

bool Game::CreateBuffers() 
{ 
    HRESULT hr; 

    // define geometry 
    struct Vertex 
    { 
     float position[3]; 
    }; 
    Vertex vertices[] = { 
     {-0.5f, -0.5f, 0.0f}, 
     {-0.5f, 0.5f, 0.0f}, 
     {0.5f, 0.0f, 0.0f} 
    }; 

    // create vertex buffer 
    D3D11_BUFFER_DESC bufferDesc = {}; 
    bufferDesc.Usage = D3D11_USAGE_DYNAMIC; 
    bufferDesc.ByteWidth = sizeof vertices; 
    bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; 
    bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; 
    bufferDesc.MiscFlags = 0; 
    bufferDesc.StructureByteStride = 0; 

    D3D11_SUBRESOURCE_DATA data = {}; 
    data.pSysMem = vertices; 

    hr = mDevice->CreateBuffer(&bufferDesc, &data, &mVertexBuffer); 
    if (FAILED(hr)) 
    { 
     ErrorBox(L"vertex buffer creation failed"); 
     return false; 
    } 

    return true; 
} 

bool Game::CreateInputLayout() 
{ 
    HRESULT hr; 

    // describe input layout 
    D3D11_INPUT_ELEMENT_DESC inputLayout[] = { 
     {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}, 
    }; 

    // create input layout 
    hr = mDevice->CreateInputLayout(inputLayout, 1, mVertexShaderBlob->GetBufferPointer(), mVertexShaderBlob->GetBufferSize(), &mInputLayout); 
    if (FAILED(hr)) 
    { 
     ErrorBox(L"input layout creation failed"); 
     return false; 
    } 

    return true; 
} 

int Game::Run() 
{ 
    MSG msg; 
    do 
    { 
     if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE) != 0) 
     { 
      TranslateMessage(&msg); 
      DispatchMessage(&msg); 
     } 
     else 
      Draw(); 
    } while (msg.message != WM_QUIT); 

    return (int)msg.wParam; 
} 

// custom vertex format 
struct Vertex 
{ 
    float position[3]; 
    unsigned char color[4]; 
}; 

void Game::Draw() 
{ 
    const float color[] = { 0.0f, 1.0f, 0.0f, 1.0f }; 
    mDeviceContext->ClearRenderTargetView(mRenderTargetView, color); 

    // set shaders 
    mDeviceContext->VSSetShader(mVertexShader, nullptr, 0); 
    mDeviceContext->PSSetShader(mPixelShader, nullptr, 0); 

    // set vertex buffer 
    UINT stride = sizeof(Vertex); 
    UINT offset = 0; 
    mDeviceContext->IASetVertexBuffers(0, 1, &mVertexBuffer, &stride, &offset); 

    // set input layout 
    mDeviceContext->IASetInputLayout(mInputLayout); 

    // set primitive topology 
    mDeviceContext->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); 

    // draw 
    mDeviceContext->Draw(3, 0); 
    mSwapChain->Present(0, 0); 
} 

LRESULT CALLBACK Game::GameWndProc(HWND window, UINT msg, WPARAM wParam, LPARAM lParam) 
{ 
    switch (msg) 
    { 
     case WM_LBUTTONDOWN: 
      MessageBox(mWindow, L"left mouse button clicked", L"CLICK", MB_OK); 
      return 0; 
     case WM_RBUTTONDOWN: 
      MessageBox(mWindow, L"right mouse button clicked", L"CLICK", MB_OK); 
      return 0; 
     case WM_CLOSE: 
      if (MessageBox(mWindow, L"are you sure you want to quit?", L"QUIT", MB_YESNO) == IDYES) 
       PostQuitMessage(0); 
      return 0; 
     default: 
      return DefWindowProc(window, msg, wParam, lParam); 
    } 
} 

LRESULT CALLBACK WndProc(HWND window, UINT msg, WPARAM wParam, LPARAM lParam) 
{ 
    return Game::GetInstance()->GameWndProc(window, msg, wParam, lParam); 
} 

void ErrorBox(wchar_t *message) 
{ 
    MessageBox(Game::GetInstance()->mWindow, message, L"ERROR", MB_OK); 
} 

: 다음은 내 코드입니다. 꼭지점 셰이더는 정점의 위치 만 출력하고 픽셀 셰이더는 흰색 단색 픽셀 조각을 그리지 만 녹색 화면 만 얻습니다.

먼저 DirectX12를 사용해 보았지만 API의 복잡성으로 인해 겁에 질 렸습니다. 그래서 DirectX11로 무언가를 그리는 법을 배웠습니다. 그런 다음 D3D1을 고려할 것입니다. (저는 OpenGL 재치 SDL에 대해 잘 알고 있습니다. 그리고 그걸로 간단한 게임을 만들었지 만, DirectX 초기화가 붙어 있습니다.)

+0

를 사용하여 디버그 쉐이더에 비주얼 스튜디오 디버거에서 실행할 때 – Asesh

+1

을 사용하면 출력 창에 디버그 장치에서 어떤 진단 출력을받을 수 있나요 단? –

+0

이 코드에는 DirectX 11에 대한 일반적인 온라인 자습서에있는 많은 기본 오류가 있지만 (드로잉을 방지 할 수있는 확실한 것은 없습니다.) 귀하의 쉐이더는 유사하게 보이고 전체 프로젝트에 대한 링크를 포함시키지 마십시오 .TW, 표준 [튜토리얼] (https://github.com/walbourn/directx-sdk-samples/tree/master/Direct3D11Tutorials)가 실행되며 [DirectX Tool Kit 튜토리얼] (https://github.com/Microsoft/DirectXTK/wiki/Getting-Started)을 참고하십시오 –

답변

-1

[번역] 시도 설정 래스터 라이저 상태 :

ID3D11RasterizerState* rs = 0; 
D3D11_RASTERIZER_DESC r; 
r.AntialiasedLineEnable = false; 
r.CullMode = D3D11_CULL_BACK; 
r.DepthBias = 0; 
r.DepthBiasClamp = 0.0f; 
r.DepthClipEnable = true; 
r.FillMode = D3D11_FILL_MODE::D3D11_FILL_SOLID; 
r.FrontCounterClockwise = true; 
r.MultisampleEnable = false; 
r.ScissorEnable = false; 
r.SlopeScaledDepthBias = 0.0f; 
/*if (FAILED(*/device->CreateRasterizerState(&r,&rs); 
d3dcontext->RSSetState(rs); 
+0

정점의 감기 순서는 시계 방향이므로 아무 문제가 없습니다. 어쨌든 성명서는 질문에 대답하지 않습니다. – Asesh

+0

It ~ 될 것입니다 rth가''D3D11_CULL_NONE''을 시도해 볼 수 있습니다. –