Problems Initiating DirectX 11

Started by
2 comments, last by Buckeye 9 years, 9 months ago

the code breaks at the pSwapChain->GetBuffer() function when I try to compile it. I believe the swapchain isn't getting created and I am not sure how to fix it sad.png. Also, I did get it to compile one time and for some reason the blue window created didn't respond to me trying to drag it around the screen or close it.

My code:


#include <Windows.h>
#include <D3D11.h>
 
D3D_DRIVER_TYPE pd3dDriverType = D3D_DRIVER_TYPE_HARDWARE;
ID3D11Device* pd3dDevice;
ID3D11DeviceContext* pd3dImmediateContext;
IDXGISwapChain* pSwapChain;
ID3D11Texture2D* pDepthStencilBuffer;
ID3D11RenderTargetView* pRenderTargetView;
ID3D11DepthStencilView* pDepthStencilView;
 
UINT m4xMsaaQuality = 0;
bool enable4xMsaa;
int clientWidth = 800;
int clientHeight = 600;
const float blue[4] = { 0.0f, 0.0f, 1.0f, 0.0f };
 
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
void InitWindow(WNDCLASSEX&, HWND&, HINSTANCE, int);
bool InitDirect3D(HWND&);
 
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                   LPSTR lpCmdLine, int nCmdShow)
{
 
  WNDCLASSEX wc;
  HWND hwnd; 
  MSG msg; 
 
  InitWindow(wc, hwnd, hInstance, nCmdShow);
  InitDirect3D(hwnd);
 
  while (GetMessage(&msg, NULL, 0, 0) > 0)
  {
    if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) {
      TranslateMessage(&msg);
      DispatchMessage(&msg);
    } else {
      pd3dImmediateContext->ClearRenderTargetView(pRenderTargetView, blue);
      pd3dImmediateContext->ClearDepthStencilView(pDepthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL      , 1.0f, 0);
 
      pSwapChain->Present(0, 0);
    }
  }
 
  return msg.wParam; 
}
 
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
  switch (msg)  
  {
  case WM_CLOSE:
    DestroyWindow(hwnd);
    break;
  case WM_DESTROY:
    PostQuitMessage(0);
    break;
  default:
    return DefWindowProc(hwnd, msg, wParam, lParam);
  }
 
  return 0;
}
 
void InitWindow(WNDCLASSEX& wc, HWND& hwnd, HINSTANCE hInstance, int nCmdShow)
{
  wc.cbSize = sizeof(WNDCLASSEX); 
  wc.style = 0;
  wc.lpfnWndProc = WndProc;
  wc.cbClsExtra = 0;
  wc.cbWndExtra = 0;
  wc.hInstance = hInstance;
  wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
  wc.lpszMenuName = NULL;
  wc.lpszClassName = (const char*)"MyWindow";
  wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
 
  hwnd = CreateWindowEx( 
                       WS_EX_CLIENTEDGE,
                      (const char*)"MyWindow",
                      "First Window",
                       WS_OVERLAPPEDWINDOW,
                       CW_USEDEFAULT, CW_USEDEFAULT, clientWidth, clientHeight,
                       NULL, NULL, hInstance, NULL);
 
  ShowWindow(hwnd, nCmdShow); 
  UpdateWindow(hwnd);       
}
 
bool InitDirect3D(HWND& hwnd)
{
  D3D_FEATURE_LEVEL featureLevel;
  HRESULT HR = D3D11CreateDevice(
                                 0,                 
                                 pd3dDriverType,
                                 0,                 
                                 NULL,
                                 NULL, NULL,             
                                 D3D11_SDK_VERSION,
                                 &pd3dDevice,
                                 &featureLevel,
                                 &pd3dImmediateContext);
 

  pd3dDevice->CheckMultisampleQualityLevels(DXGI_FORMAT_R8G8B8A8_UNORM, 4, &m4xMsaaQuality);
 
  DXGI_SWAP_CHAIN_DESC sd;
  sd.BufferDesc.Width = clientWidth;
  sd.BufferDesc.Height = clientHeight;
  sd.BufferDesc.RefreshRate.Numerator = 60;
  sd.BufferDesc.RefreshRate.Denominator = 1;
  sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
  sd.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
  sd.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
  if (enable4xMsaa) {
    sd.SampleDesc.Count = 4;
    sd.SampleDesc.Quality = m4xMsaaQuality - 1;
  } else {
    sd.SampleDesc.Count = 1;
    sd.SampleDesc.Quality = 0;
  }
  sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
  sd.BufferCount = 1;
  sd.OutputWindow = hwnd;
  sd.Windowed = true;
  sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
  sd.Flags = 0;
 
  IDXGIDevice* dxgiDevice = 0;
  pd3dDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice);
 
  IDXGIAdapter* dxgiAdapter = 0;
  dxgiDevice->GetParent(__uuidof(IDXGIAdapter), (void**)&dxgiAdapter);
 
  IDXGIFactory* dxgiFactory = 0;
  dxgiAdapter->GetParent(__uuidof(IDXGIFactory), (void**)&dxgiFactory);
 
  dxgiFactory->CreateSwapChain(pd3dDevice, &sd, &pSwapChain);
 
  dxgiDevice->Release();
  dxgiAdapter->Release();
  dxgiFactory->Release();
 
  ID3D11Texture2D* backBuffer;
  pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), reinterpret_cast<void**>(&backBuffer));
  pd3dDevice->CreateRenderTargetView(backBuffer, 0, &pRenderTargetView);
 
  backBuffer->Release();
 
  D3D11_TEXTURE2D_DESC depthStencilDesc;
  depthStencilDesc.Width = clientWidth;
  depthStencilDesc.Height = clientHeight;
  depthStencilDesc.MipLevels = 1;
  depthStencilDesc.ArraySize = 1;
  depthStencilDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
  if (enable4xMsaa) {
    depthStencilDesc.SampleDesc.Count = 4;
    depthStencilDesc.SampleDesc.Quality = m4xMsaaQuality - 1;
  } else {
    depthStencilDesc.SampleDesc.Count = 1;
    depthStencilDesc.SampleDesc.Quality = 0;
  }
  depthStencilDesc.Usage = D3D11_USAGE_DEFAULT;
  depthStencilDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
  depthStencilDesc.CPUAccessFlags = 0;
  depthStencilDesc.MiscFlags = 0;
 
  pd3dDevice->CreateTexture2D(&depthStencilDesc, 0, &pDepthStencilBuffer);
  pd3dDevice->CreateDepthStencilView(pDepthStencilBuffer, 0, &pDepthStencilView);
 
  pd3dImmediateContext->OMSetRenderTargets(1, &pRenderTargetView, pDepthStencilView);
 
  D3D11_VIEWPORT pScreenViewport;
  pScreenViewport.TopLeftX = 0;
  pScreenViewport.TopLeftY = 0;
  pScreenViewport.Width = static_cast<float>(clientWidth);
  pScreenViewport.Height = static_cast<float>(clientHeight);
  pScreenViewport.MinDepth = 0.0f;
  pScreenViewport.MaxDepth = 1.0f;
 
  pd3dImmediateContext->RSSetViewports(1, &pScreenViewport);
 
  return true;
}
 
Advertisement

You've got several problems.

First: you don't check for any errors and then ask why your code doesn't run as expected. Most functions provide an indication of success or failure. E.g., if CreateWindowEx fails, the returned HWND is NULL. You don't check that. You're catching the HRESULT return from D3D11CreateDevice but you don't check to see if the call was successful. You make a lot of calls throughout without any error checking. Starting now, check all return values to ensure the calls were successful. In addition, when an error occurs, exit the routine gracefully as a favor to the user. Don't just let exceptions be thrown.

Second: you have to register your window class before you can create a window of that class. Before you call CreateWindowEx, call RegisterClassEx(&wc) and check that the call returns a non-zero result.

Third: in your CreateWindowEx call, although you call the variables clientWidth and clientHeight, those values determine the width and height of the window frame, not the client area. If the size of the client area is important, you can call AdjustWindowRectEx to adjust those numbers.

Other comments: your rendering loop is faulty. Try something like:


msg.message = WM_NULL;
while( msg.message != WM_QUIT)
{
   while(PeekMessage(&msg, 0,0,0, PM_REMOVE))
   {
      TranslateMessage(...);
      DispatchMessage(...);
   }
   if(msg.message != WM_QUIT)
   {
      // update the scene
      // render stuff
   }
}

Try making the above changes and post again if you have problems.

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

That fixed it, thank you! :)

Sorry about the error checking. I did have some error checking in place, although probably nowhere near what I should be doing. I know now it was a mistake but I removed the error checks before posting thinking that it would reduce the amount of code people had to read through to help me.


That fixed it,

Which? The RegisterClassEx? wink.png Yeah, you filled out the registration structure, but didn't use it.


I removed the error checks before posting thinking that it would reduce the amount of code people had to read through to help me.

You should always post code as-is. There's been at least one case here on gamedev where the error-checking itself was at fault for the problems!

Glad it's running.

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

This topic is closed to new replies.

Advertisement