static IDXGIFactory *GetDXGIFactoryFromDevice(ID3D11Device *device) { IDXGIDevice *dxgiDevice = nullptr; HRESULT result = device->QueryInterface(__uuidof(IDXGIDevice), reinterpret_cast<void **>(&dxgiDevice)); if (FAILED(result)) { return nullptr; } IDXGIAdapter *dxgiAdapter = nullptr; result = dxgiDevice->GetParent(__uuidof(IDXGIAdapter), reinterpret_cast<void **>(&dxgiAdapter)); SafeRelease(dxgiDevice); if (FAILED(result)) { return nullptr; } IDXGIFactory *dxgiFactory = nullptr; result = dxgiAdapter->GetParent(__uuidof(IDXGIFactory), reinterpret_cast<void **>(&dxgiFactory)); SafeRelease(dxgiAdapter); if (FAILED(result)) { return nullptr; } return dxgiFactory; }
bool DX11Engine::CreateSwapChain(HWND handle, UINT xSize, UINT ySize) { mXsize = xSize; mYSize = ySize; IDXGIDevice* dxgiDevice = nullptr; HRESULT hr = m_pDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice); if (hr != S_OK) { return false; } IDXGIAdapter* dxgiAdapter = nullptr; hr = dxgiDevice->GetAdapter(&dxgiAdapter); if (hr != S_OK) { return false; } IDXGIFactory1* dxgiFactory1 = nullptr; hr = dxgiAdapter->GetParent(__uuidof(IDXGIFactory1), (void**)&dxgiFactory1); if (hr != S_OK) { return false; } DXGI_SWAP_CHAIN_DESC desc; desc.BufferDesc.Width = xSize; desc.BufferDesc.Height = ySize; desc.BufferDesc.RefreshRate.Numerator = 0; desc.BufferDesc.RefreshRate.Denominator = 1; desc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; desc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; desc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; desc.SampleDesc.Count = 1; desc.SampleDesc.Quality = 0; desc.BufferUsage = DXGI_USAGE_BACK_BUFFER | DXGI_USAGE_RENDER_TARGET_OUTPUT; desc.BufferCount = 2; desc.OutputWindow = handle; desc.Windowed = TRUE; desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; desc.Flags = 0; hr = dxgiFactory1->CreateSwapChain(dxgiDevice, &desc, &m_pSwapChain); if (hr != S_OK) { return false; } dxgiDevice->Release(); dxgiAdapter->Release(); dxgiFactory1->Release(); return true; }
void D3D11RenderWindow::_createSwapChain() { // Fill out a DXGI_SWAP_CHAIN_DESC to describe our swap chain. DXGI_SWAP_CHAIN_DESC sd; sd.BufferDesc.Width = mWidth; sd.BufferDesc.Height = mHeight; 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; // Use 4X MSAA? if (mEnable4xMsaa) { sd.SampleDesc.Count = 4; sd.SampleDesc.Quality = m4xMsaaQuality - 1; } // No MSAA else { sd.SampleDesc.Count = 1; sd.SampleDesc.Quality = 0; } sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; sd.BufferCount = 2; sd.OutputWindow = mhMainWnd; sd.Windowed = true; sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; sd.Flags = 0; // To correctly create the swap chain, we must use the IDXGIFactory that was // used to create the device. If we tried to use a different IDXGIFactory instance // (by calling CreateDXGIFactory), we get an error: "IDXGIFactory::CreateSwapChain: // This function is being called with a device from a different IDXGIFactory." IDXGIDevice* dxgiDevice = 0; HR(md3dDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice)); IDXGIAdapter* dxgiAdapter = 0; HR(dxgiDevice->GetParent(__uuidof(IDXGIAdapter), (void**)&dxgiAdapter)); IDXGIFactory* dxgiFactory = 0; HR(dxgiAdapter->GetParent(__uuidof(IDXGIFactory), (void**)&dxgiFactory)); HR(dxgiFactory->CreateSwapChain(md3dDevice, &sd, &mSwapChain)); ReleaseCOM(dxgiDevice); ReleaseCOM(dxgiAdapter); ReleaseCOM(dxgiFactory); // The remaining steps that need to be carried out for d3d creation // also need to be executed every time the window is resized. So // just call the OnResize method here to avoid code duplication. _updateSwapChain(); }
void D3DContext::InitD3D(HWND hWnd) { m_MSAAEnabled = true; HRESULT hr = D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, m_DebugLayerEnabled ? D3D11_CREATE_DEVICE_DEBUG : D3D11_CREATE_DEVICE_SINGLETHREADED, NULL, NULL, D3D11_SDK_VERSION, &dev, &m_D3DFeatureLevel, &devcon); dev->CheckMultisampleQualityLevels(DXGI_FORMAT_R8G8B8A8_UNORM, 4, &m_MSAAQuality); // assert(m_MSAAQuality > 0); DXGI_SWAP_CHAIN_DESC scd; ZeroMemory(&scd, sizeof(DXGI_SWAP_CHAIN_DESC)); scd.BufferDesc.Width = m_Properties.width; scd.BufferDesc.Height = m_Properties.height; scd.BufferDesc.RefreshRate.Numerator = 60; scd.BufferDesc.RefreshRate.Denominator = 1; scd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; scd.SampleDesc.Count = m_MSAAEnabled ? 4 : 1; scd.SampleDesc.Quality = m_MSAAEnabled ? (m_MSAAQuality - 1) : 0; scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; scd.BufferCount = 3; scd.OutputWindow = hWnd; scd.Windowed = !m_Properties.fullscreen; scd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; scd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; IDXGIDevice* dxgiDevice = 0; IDXGIAdapter* dxgiAdapter = 0; IDXGIFactory* dxgiFactory = 0; dev->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice); dxgiDevice->GetParent(__uuidof(IDXGIAdapter), (void**)&dxgiAdapter); dxgiAdapter->GetParent(__uuidof(IDXGIFactory), (void**)&dxgiFactory); dxgiFactory->CreateSwapChain(dev, &scd, &swapchain); dxgiFactory->Release(); dxgiAdapter->Release(); dxgiDevice->Release(); if (m_DebugLayerEnabled) { dev->QueryInterface(__uuidof(ID3D11Debug), reinterpret_cast<void**>(&m_DebugLayer)); m_DebugLayer->ReportLiveDeviceObjects(D3D11_RLDO_SUMMARY); ID3D11InfoQueue* infoQueue; dev->QueryInterface(__uuidof(ID3D11InfoQueue), reinterpret_cast<void**>(&infoQueue)); D3D11_MESSAGE_ID hide[] = { D3D11_MESSAGE_ID_DEVICE_DRAW_SAMPLER_NOT_SET }; D3D11_INFO_QUEUE_FILTER filter; memset(&filter, 0, sizeof(filter)); filter.DenyList.NumIDs = 1; filter.DenyList.pIDList = hide; infoQueue->AddStorageFilterEntries(&filter); } Resize(); }
bool TRenderDevice::CreateSwapChain(){ IDXGIDevice* device; if (FAILED(Device->QueryInterface(__uuidof(IDXGIDevice), (void**) &device))){ MessageBox(0,L"获取设备接口失败",0,0); return false; } IDXGIAdapter* adapter; if (FAILED(device->GetParent(__uuidof(IDXGIAdapter), (void**) &adapter))){ MessageBox(0,L"获取适配器接口失败",0,0); return false; } IDXGIFactory* factory; if (FAILED(adapter->GetParent(__uuidof(IDXGIFactory), (void**) &factory))){ MessageBox(0,L"获取Factory接口失败",0,0); return false; } DXGI_SWAP_CHAIN_DESC sd; sd.BufferDesc.Width = RenderSize->GetRenderWidth(); sd.BufferDesc.Height = RenderSize->GetRenderHeight(); 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 (MsaaQuality>0){ sd.SampleDesc.Count = MsaaQuality; sd.SampleDesc.Quality = MsaaQuality - 1; }else{ sd.SampleDesc.Count=1; sd.SampleDesc.Quality=0; } sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; sd.BufferCount = 1; sd.OutputWindow = RenderWindow->GetHWnd(); sd.Windowed = true; sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; sd.Flags = 0; if (FAILED(factory->CreateSwapChain(Device, &sd, &SwapChain))){ MessageBox(0,L"创建SwapChain失败",0,0); return false; } device->Release(); adapter->Release(); factory->Release(); return true; }
//************************************************************************************************* // Create the swap chain for the device //************************************************************************************************* SBOOL RenderContext::createSwapChain(HWND clientWindow, SUINT clientWidth, SUINT clientHeight) { // Fill out DXGI swap chain description 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; // Use 4x Msaa if(_4xMsaaEnabled) { sd.SampleDesc.Count = 4; sd.SampleDesc.Quality = _4xMsaaQuality - 1; } // No Msaa else { sd.SampleDesc.Count = 1; sd.SampleDesc.Quality = 0; } sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; sd.BufferCount = 1; sd.OutputWindow = clientWindow; sd.Windowed = true; sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; sd.Flags = 0; // Generate an IDXGI factory to properly initialize the swap chain IDXGIDevice* dxgiDevice = 0; HR(_d3dDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice)); IDXGIAdapter* dxgiAdapter = 0; HR(dxgiDevice->GetParent(__uuidof(IDXGIAdapter), (void**)&dxgiAdapter)); IDXGIFactory* dxgiFactory = 0; HR(dxgiAdapter->GetParent(__uuidof(IDXGIFactory), (void**)&dxgiFactory)); HR(dxgiFactory->CreateSwapChain(_d3dDevice, &sd, &_swapChain)); ReleaseCOM(dxgiDevice); ReleaseCOM(dxgiAdapter); ReleaseCOM(dxgiFactory); return true; }
std::shared_ptr<SwapChain> Device::createSwapChain(const Window& window) { std::shared_ptr<SwapChain> swapChain; IDXGIDevice* dxgiDevice = nullptr; if (SUCCEEDED(m_device->QueryInterface<IDXGIDevice>(&dxgiDevice))) { IDXGIAdapter* adapter = nullptr; if (SUCCEEDED(dxgiDevice->GetAdapter(&adapter))) { IDXGIFactory* dxgiFactory = nullptr; if (SUCCEEDED(adapter->GetParent(__uuidof(IDXGIFactory), reinterpret_cast<void**>(&dxgiFactory)))) { DXGI_SWAP_CHAIN_DESC sd; ZeroMemory(&sd, sizeof(sd)); sd.BufferCount = 1; sd.BufferDesc.Width = window.getWidth(); sd.BufferDesc.Height = window.getHeight(); sd.BufferDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; sd.BufferDesc.RefreshRate.Numerator = 0; sd.BufferDesc.RefreshRate.Denominator = 1; sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; sd.OutputWindow = window.getPlatformData()->getHandle(); sd.SampleDesc.Count = 1; sd.SampleDesc.Quality = 0; sd.Windowed = TRUE; IDXGISwapChain* nativeSwapChain = nullptr; if (SUCCEEDED(dxgiFactory->CreateSwapChain(m_device, &sd, &nativeSwapChain))) { ID3D11Texture2D* backBufferTexture = nullptr; if (SUCCEEDED(nativeSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), reinterpret_cast<void**>(&backBufferTexture)))) { auto texture = std::make_shared<Texture2d>(backBufferTexture); auto backBufferRenderCommandEncoder = createRenderCommandEncoder(1, &texture, nullptr, false); swapChain = std::make_shared<SwapChain>(nativeSwapChain, backBufferRenderCommandEncoder); } dxgiFactory->Release(); } adapter->Release(); } } dxgiDevice->Release(); } return swapChain; }
inline void DisableDXGIWindowChanges(IUnknown* device, HWND window) { IDXGIDevice * pDXGIDevice; ThrowIfFailed(device->QueryInterface(IID_PPV_ARGS(&pDXGIDevice))); IDXGIAdapter * pDXGIAdapter; ThrowIfFailed(pDXGIDevice->GetParent(IID_PPV_ARGS(&pDXGIAdapter))); IDXGIFactory * pIDXGIFactory; ThrowIfFailed(pDXGIAdapter->GetParent(IID_PPV_ARGS(&pIDXGIFactory))); ThrowIfFailed(pIDXGIFactory->MakeWindowAssociation(window, DXGI_MWA_NO_WINDOW_CHANGES | DXGI_MWA_NO_ALT_ENTER)); pIDXGIFactory->Release(); pDXGIAdapter->Release(); pDXGIDevice->Release(); }
static IDXGIFactory* FactoryFromDevice(ID3D11Device *device) { assert(device); IDXGIDevice *dxgiDevice = nullptr; DEBUG_HR(device->QueryInterface(__uuidof(IDXGIDevice), reinterpret_cast<void**>(&dxgiDevice))); IDXGIAdapter *dxgiAdapter = nullptr; DEBUG_HR(dxgiDevice->GetParent(__uuidof(IDXGIAdapter), reinterpret_cast<void**>(&dxgiAdapter))); IDXGIFactory *dxgiFactory = nullptr; DEBUG_HR(dxgiAdapter->GetParent(__uuidof(IDXGIFactory), reinterpret_cast<void**>(&dxgiFactory))); ReleaseCom(dxgiAdapter); ReleaseCom(dxgiDevice); return dxgiFactory; }
//======================================================================== // For specified ID3D10Device returns IDXGIFactory used to create it //======================================================================== IDXGIFactory *getDeviceFactory(ID3D10Device *device) { IDXGIDevice *dxgiDevice = 0; IDXGIAdapter *dxgiAdapter = 0; IDXGIFactory *dxgiFactory = 0; if (SUCCEEDED( device->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice) )) { if (SUCCEEDED( dxgiDevice->GetParent(__uuidof(IDXGIAdapter), (void**)&dxgiAdapter) )) { dxgiAdapter->GetParent(__uuidof(IDXGIFactory), (void**)&dxgiFactory); dxgiAdapter->Release(); } dxgiDevice->Release(); } return dxgiFactory; }
bool Renderer::CreateSwapChain() { // Determine buffer size RECT rect; GetClientRect(hwnd,&rect); // Create swap chain DXGI_SWAP_CHAIN_DESC SwapChainDesc; SwapChainDesc.BufferCount = 1; SwapChainDesc.BufferDesc.Width = rect.right - rect.left; SwapChainDesc.BufferDesc.Height = rect.bottom - rect.top; SwapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; SwapChainDesc.BufferDesc.RefreshRate.Numerator = 60; SwapChainDesc.BufferDesc.RefreshRate.Denominator = 1; // 60/1 = 60 Hz SwapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; SwapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; SwapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; SwapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; SwapChainDesc.OutputWindow = hwnd; SwapChainDesc.SampleDesc.Count = 1; SwapChainDesc.SampleDesc.Quality = 0; // no AA SwapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; SwapChainDesc.Windowed = true; // Obtain DXGI factory that was used to create the device // ??? IDXGIDevice* DXGIDevice; D3DDevice->QueryInterface(__uuidof(IDXGIDevice),(void**)&DXGIDevice); IDXGIAdapter* DXGIAdapter; DXGIDevice->GetParent(__uuidof(IDXGIAdapter),(void**)&DXGIAdapter); IDXGIFactory* DXGIFactory; DXGIAdapter->GetParent(__uuidof(IDXGIFactory),(void**)&DXGIFactory); // Use it if(DXGIFactory->CreateSwapChain(D3DDevice,&SwapChainDesc,&SwapChain) != S_OK) { MessageBox(hwnd,"Error creating swap chain","Error",MB_OK); return false; } // Release unused stuff DXGIDevice->Release(); DXGIAdapter->Release(); DXGIFactory->Release(); return true; }
void DirectXController::Initialize( void ) { WindowController::Get()->Initialize(); WindowController::Get()->OpenWindow(); driverType = D3D_DRIVER_TYPE_HARDWARE; enable4xMsaa = false; msaa4xQuality = 0; device.dx = nullptr; deviceContext.dx = nullptr; swapChain = nullptr; depthStencilBuffer = nullptr; renderTargetView = nullptr; depthStencilView = nullptr; ZeroMemory( &viewport, sizeof(D3D11_VIEWPORT) ); UINT createDeviceFlags = 0; #if defined(_DEBUG) || defined(DEBUG) createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG; #endif D3D_FEATURE_LEVEL requiredFeatureLevel = D3D_FEATURE_LEVEL_11_0; D3D_FEATURE_LEVEL featureLevel; HRESULT hResult = D3D11CreateDevice( NULL, // Adapter driverType, // Driver Type NULL, // Software createDeviceFlags, // Flags &requiredFeatureLevel, // Feature levels 1, // num Feature levels D3D11_SDK_VERSION, // SDK Version &device.dx, // Device &featureLevel, // Feature Level &deviceContext.dx ); // Device Context // Handle any device creation or DirectX version errors if( FAILED(hResult) ) { MessageBox(NULL, L"D3D11CreateDevice Failed", NULL, NULL); //return false; } if( featureLevel != requiredFeatureLevel ) { MessageBox(NULL, L"Direct3D Feature Level 11 unsupported", NULL, NULL); //return false; } // Check for 4X MSAA quality support HR(device.dx->CheckMultisampleQualityLevels( DXGI_FORMAT_R8G8B8A8_UNORM, 4, &msaa4xQuality)); //assert( msaa4xQuality > 0 ); // Potential problem if quality is 0 // set up swap chain DXGI_SWAP_CHAIN_DESC swapChainDesc; ZeroMemory(&swapChainDesc, sizeof(swapChainDesc) ); swapChainDesc.BufferCount = 1; swapChainDesc.BufferDesc.Width = WindowController::Get()->GetWidth();//windowWidth; swapChainDesc.BufferDesc.Height = WindowController::Get()->GetHeight();//windowHeight; swapChainDesc.BufferDesc.RefreshRate.Numerator = 60; swapChainDesc.BufferDesc.RefreshRate.Denominator = 1; swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChainDesc.OutputWindow = Win32Controller::Get()->GetHWnd();//hMainWnd; swapChainDesc.Windowed = true; swapChainDesc.Flags = 0; if( enable4xMsaa ) { // Set up 4x MSAA swapChainDesc.SampleDesc.Count = 4; swapChainDesc.SampleDesc.Quality = msaa4xQuality - 1; } else { // No MSAA swapChainDesc.SampleDesc.Count = 1; swapChainDesc.SampleDesc.Quality = 0; } // To correctly create the swap chain, we must use the IDXGIFactory that // was used to create the device. IDXGIDevice* dxgiDevice = 0; IDXGIAdapter* dxgiAdapter = 0; IDXGIFactory* dxgiFactory = 0; HR(device.dx->QueryInterface( __uuidof(IDXGIDevice), (void**)&dxgiDevice)); HR(dxgiDevice->GetParent( __uuidof(IDXGIAdapter), (void**)&dxgiAdapter)); HR(dxgiAdapter->GetParent( __uuidof(IDXGIFactory), (void**)&dxgiFactory)); // Finally make the swap chain and release the DXGI stuff HR(dxgiFactory->CreateSwapChain(device.dx, &swapChainDesc, &swapChain)); ReleaseCOMobjMacro(dxgiDevice); ReleaseCOMobjMacro(dxgiAdapter); ReleaseCOMobjMacro(dxgiFactory); // The remaining steps also need to happen each time the window // is resized, so just run the OnResize method Resize(); }
bool D3DApp::InitDirect3D() { /* ----------------------------------------- Create the D3D11 Device and DeviceContext ----------------------------------------- */ /* ----------------------- //? D3D11CreateDevice Notes ----------------------- //! Function Signature HRESULT result = D3D11CreateDevice( pAdapter, DriverType, Software, Flags, pFeatureLevels, FeatureLevels, SDKVersion, ppDevice, pFeatureLevel, ppImmediateContext ); //! Parameter Descriptions // The display adapter we want the created device to represent // Notes: Specifying "null" indicates the primary display adapter. //! IDXGIAdapter* pAdapter; // Type of driver our device will represent // Notes: In general, this should always be D3D_DRIVER_TYPE_HARDWARE, unless you need a reference, software, or WARP device. //! D3D_DRIVER_TYPE DriverType; // Software Driver // Notes: This is "null" if using a hardware driver. //! HMODULE Software; // (Optional) Device creation flags // Ex: D3D11_CREATE_DEVICE_DEBUG - Enables the Debug Layer, Direct3D will send debug messages to the VC++ output window. // Ex: D3D11_CREATE_DEVICE_SINGLETHREADED - Improves performance if you guarantee that Direct3D will not be called from multiple threads. //! UINT Flags; // Array of D3D feature levels // Notes: The order indicates the order in which to check for feature level support. // Specifying "null" indicates to choose the greatest feature level supported. //! const D3D_FEATURE_LEVEL* pFeatureLevels; // Size of pFeatureLevels array. // Notes: Specify "0" if you specified "null" for pFeatureLevels. //! UINT FeatureLevels; // Direct3D SDK Version // Notes: While studying this book, always use D3D11_SDK_VERSION. //! UINT SDKVersion; // Returns: Pointer to the device which this function will create //! ID3D11Device** ppDevice; // Returns: The first (highest) supported feature level from pFeatureLevels //! D3D_FEATURE_LEVEL* pFeatureLevel; // Returns: The created device context //! ID3D11DeviceContext** ppImmediateContext; */ UINT CreateDeviceFlags = 0; #if defined(DEBUG) || defined(_DEBUG) CreateDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG; #endif D3D_FEATURE_LEVEL FeatureLevel; HRESULT CreateDeviceResult = D3D11CreateDevice( nullptr, mD3DDriverType, nullptr, CreateDeviceFlags, nullptr, 0, D3D11_SDK_VERSION, &mDevice, &FeatureLevel, &mImmediateContext ); if (FAILED(CreateDeviceResult)) { MessageBox(0, L"D3D11CreateDevice failed.", 0, 0); return false; } if (FeatureLevel != D3D_FEATURE_LEVEL_11_0) { MessageBox(0, L"Direct3D Feature Level 11 unsupported.", 0, 0); return false; } /* ----------------------------------- Check 4X MSAA Quality Level Support ----------------------------------- */ HR(mDevice->CheckMultisampleQualityLevels(DXGI_FORMAT_R8G8B8A8_UNORM, 4, &mMultisampleQuality)); assert(mMultisampleQuality > 0); /* ---------------------------------------------- Describe the characteristics of the swap chain ---------------------------------------------- */ /* -------------------------- //? DXGI_SWAP_CHAIN_DESC Notes -------------------------- //! Structure Signature typedef struct DXGI_SWAP_CHAIN_DESC { DXGI_MODE_DESC BufferDesc; DXGI_SAMPLE_DESC SampleDesc; DXGI_USAGE BufferUsage; UINT BufferCount; HWND OutputWindow; BOOL Windowed; DXGI_SWAP_EFFECT SwapEffect; UINT Flags; } DXGI_SWAP_CHAIN_DESC; //! Member Descriptions // Properties of the back buffer // Notes: The main properties that concern us are the width, height, and pixel format. //! DXGI_MODE_DESC BufferDesc; // Number of multisamples and quality level //! DXGI_SAMPLE_DESC SampleDesc; // Usage of the back buffer // Notes: Specify DXGI_USAGE_RENDER_TARGET_OUTPUT to indicate that the back buffer will be used for rendering. //! DXGI_USAGE BufferUsage; // Number of back buffers in the swap chain // Notes: Use "1" to allocate one back buffer (double buffering) //! UINT BufferCount; // Handle to the window we are rendering to //! HWND OutputWindow; // Notes: "true" indicates windowed-mode, "false" indicates full-screen mode //! BOOL Windowed; // Notes: Specify DXGI_SWAP_EFFECT_DISCARD to let the display driver select the most efficient presentation method //! DXGI_SWAP_EFFECT SwapEffect; // (Optional) flags // Notes: If you use DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH, then when you switch to full-screen mode, the application // will select a display mode that best matches the current back buffer settings. //! UINT Flags; */ DXGI_SWAP_CHAIN_DESC SwapChainDesc; /* -------------------------- //? DXGI_DESC_MODE Notes -------------------------- //! Structure Signature typedef struct DXGI_MODE_DESC { UINT Width; UINT Height; DXGI_RATIONAL RefreshRate; DXGI_FORMAT Format; DXGI_MODE_SCANLINE_ORDER ScanlineOrdering; DXGI_MODE_SCALING Scaling; } DXGI_MODE_DESC; //! Member Descriptions // Window resolution width //! UINT Width; // Window resolution height //! UINT Height; // Refresh rate defined in Hz (Numerator and Denominator) //! DXGI_RATIONAL RefreshRate; // Display format //! DXGI_FORMAT Format; // Scanline Drawing Mode //! DXGI_MODE_SCANLINE_ORDER ScanlineOrdering; // Scaling Mode // Notes: Indicates how an image is stretched to fit the screen resolution. //! DXGI_MODE_SCALING Scaling; */ DXGI_MODE_DESC BackBufferDesc; BackBufferDesc.Width = 800; BackBufferDesc.Height = 600; // Most monitors cannot output more than 24-bit color, so extra precision would be wasted // Even though the monitor cannot output the 8-bit alpha, those bits can be used for other things like effects BackBufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; BackBufferDesc.RefreshRate.Numerator = 60; BackBufferDesc.RefreshRate.Denominator = 1; BackBufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; BackBufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; SwapChainDesc.BufferDesc = BackBufferDesc; if (mEnableMultisample) { SwapChainDesc.SampleDesc.Count = 4; SwapChainDesc.SampleDesc.Quality = mMultisampleQuality - 1; } else { SwapChainDesc.SampleDesc.Count = 1; SwapChainDesc.SampleDesc.Quality = 0; } SwapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; SwapChainDesc.BufferCount = 1; SwapChainDesc.OutputWindow = mMainWindow; SwapChainDesc.Windowed = true; SwapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; SwapChainDesc.Flags = 0; /* --------------------- Create the swap chain --------------------- */ IDXGIDevice* dxgiDevice = 0; mDevice->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(mDevice, &SwapChainDesc, &mSwapChain); ReleaseCOM(dxgiDevice); ReleaseCOM(dxgiAdapter); ReleaseCOM(dxgiFactory); OnResize(); return true; }
void BBWin8Game::CreateD3dDevice(){ CoreWindow ^window=CoreWindow::GetForCurrentThread(); int width=DipsToPixels( window->Bounds.Width ); int height=DipsToPixels( window->Bounds.Height ); #if WINDOWS_8 switch( DisplayProperties::CurrentOrientation ){ case DisplayOrientations::Portrait: case DisplayOrientations::PortraitFlipped: std::swap( width,height ); break; } #endif UINT creationFlags=D3D11_CREATE_DEVICE_BGRA_SUPPORT; #ifdef _DEBUG creationFlags|=D3D11_CREATE_DEVICE_DEBUG; #endif #if WINDOWS_8 D3D_FEATURE_LEVEL featureLevels[]={ D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0, D3D_FEATURE_LEVEL_9_3, D3D_FEATURE_LEVEL_9_2, D3D_FEATURE_LEVEL_9_1 }; #elif WINDOWS_PHONE_8 D3D_FEATURE_LEVEL featureLevels[]={ D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0, D3D_FEATURE_LEVEL_9_3 }; #endif ID3D11Device *device; ID3D11DeviceContext *context; DXASS( D3D11CreateDevice( 0, D3D_DRIVER_TYPE_HARDWARE, 0, creationFlags, featureLevels, ARRAYSIZE(featureLevels), D3D11_SDK_VERSION, &device, &_featureLevel, &context ) ); DXASS( device->QueryInterface( __uuidof( ID3D11Device1 ),(void**)&_d3dDevice ) ); DXASS( context->QueryInterface( __uuidof( ID3D11DeviceContext1 ),(void**)&_d3dContext ) ); device->Release(); context->Release(); //create swap chain if( _swapChain ){ DXASS( _swapChain->ResizeBuffers( 2,width,height,DXGI_FORMAT_B8G8R8A8_UNORM,0 ) ); }else{ #if WINDOWS_8 DXGI_SWAP_CHAIN_DESC1 swapChainDesc={0}; swapChainDesc.Width=width; swapChainDesc.Height=height; swapChainDesc.Format=DXGI_FORMAT_B8G8R8A8_UNORM; swapChainDesc.Stereo=false; swapChainDesc.SampleDesc.Count=1; swapChainDesc.SampleDesc.Quality=0; swapChainDesc.BufferUsage=DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChainDesc.BufferCount=2; swapChainDesc.Scaling=DXGI_SCALING_NONE; swapChainDesc.SwapEffect=DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; swapChainDesc.Flags=0; #elif WINDOWS_PHONE_8 DXGI_SWAP_CHAIN_DESC1 swapChainDesc={0}; swapChainDesc.Width=width; swapChainDesc.Height=height; swapChainDesc.Format=DXGI_FORMAT_B8G8R8A8_UNORM; swapChainDesc.Stereo=false; swapChainDesc.SampleDesc.Count=1; swapChainDesc.SampleDesc.Quality=0; swapChainDesc.BufferUsage=DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChainDesc.BufferCount=1; swapChainDesc.Scaling=DXGI_SCALING_STRETCH; swapChainDesc.SwapEffect=DXGI_SWAP_EFFECT_DISCARD; swapChainDesc.Flags=0; #endif IDXGIDevice1 *dxgiDevice; DXASS( _d3dDevice->QueryInterface( __uuidof( IDXGIDevice1 ),(void**)&dxgiDevice ) ); IDXGIAdapter *dxgiAdapter; DXASS( dxgiDevice->GetAdapter( &dxgiAdapter ) ); IDXGIFactory2 *dxgiFactory; DXASS( dxgiAdapter->GetParent( __uuidof( IDXGIFactory2 ),(void**)&dxgiFactory ) ); DXASS( dxgiFactory->CreateSwapChainForCoreWindow( _d3dDevice,(IUnknown*)window,&swapChainDesc,0,&_swapChain ) ); DXASS( dxgiDevice->SetMaximumFrameLatency( 1 ) ); dxgiFactory->Release(); dxgiAdapter->Release(); dxgiDevice->Release(); } // Create a render target view of the swap chain back buffer. // ID3D11Texture2D *backBuffer; DXASS( _swapChain->GetBuffer( 0,__uuidof( ID3D11Texture2D ),(void**)&backBuffer ) ); DXASS( _d3dDevice->CreateRenderTargetView( backBuffer,0,&_renderTargetView ) ); backBuffer->Release(); /* // Create a depth stencil view // D3D11_TEXTURE2D_DESC dsdesc; ZEROMEM( dsdesc ); dsdesc.Width=width; dsdesc.Height=height; dsdesc.MipLevels=1; dsdesc.ArraySize=1; dsdesc.Format=DXGI_FORMAT_D24_UNORM_S8_UINT; dsdesc.SampleDesc.Count=1; dsdesc.SampleDesc.Quality=0; dsdesc.Usage=D3D11_USAGE_DEFAULT; dsdesc.BindFlags=D3D11_BIND_DEPTH_STENCIL; dsdesc.CpuAccessFlags=0; dsdesc.MiscFlags=0; ID3D11Texture2D *depthStencil; DXASS( _d3dDevice->CreateTexture2D( &dsdesc,0,&depthStencil ) ); DXASS( _d3dDevice->CreateDepthStencilView( depthStencil,0,&_depthStencilView ) ); depthStencil->Release(); */ D3D11_VIEWPORT viewport={ 0,0,width,height,0,1 }; _d3dContext->RSSetViewports( 1,&viewport ); }
bool DirectX11Graphics::Initialise() { if ( _is_initialised ) { //LogError( "F11", "Cannot initialise F11Graphics; F11Graphics is currently initialised." ); return false; } // Return false if no game has been set. if ( !GetGame() ) { //LogError( "F11", "Cannot initialise F11Graphics; F11Graphics has no graphics message listener set." ); return false; } // Get the dimensions of the screen. RECT rectangle; GetClientRect( HWND(GetGame()->GetHWND()), &rectangle ); unsigned int width = rectangle.right - rectangle.left; unsigned int height = rectangle.bottom - rectangle.top; if ( VRIsEnabled() ) { GetGame()->GetVRTextureDimensions( width, height ); } // Use the default adapter and hardware drivers. IDXGIFactory* factory = nullptr; IDXGIAdapter* adapter = nullptr; auto f = CreateDXGIFactory( __uuidof(IDXGIFactory), (void**)&factory ); auto a = factory->EnumAdapters( 0, &adapter ); // Create a debug device if in debug mode. #ifdef _DEBUG unsigned int device_flags = D3D11_CREATE_DEVICE_DEBUG; #else unsigned int device_flags = 0; #endif // Create a swap chain description. DXGI_SWAP_CHAIN_DESC swap_chain_desc; memset( &swap_chain_desc, 0, sizeof(swap_chain_desc) ); swap_chain_desc.BufferDesc.Width = width; swap_chain_desc.BufferDesc.Height = height; swap_chain_desc.BufferDesc.RefreshRate.Numerator = 0; swap_chain_desc.BufferDesc.RefreshRate.Denominator = 1; swap_chain_desc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; //swap_chain_desc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; //swap_chain_desc.BufferDesc.Scaling = DXGI_MODE_SCALING_CENTERED; swap_chain_desc.SampleDesc.Count = 1; swap_chain_desc.SampleDesc.Quality = 0; swap_chain_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swap_chain_desc.BufferCount = 2; swap_chain_desc.OutputWindow = HWND(GetGame()->GetHWND()); swap_chain_desc.Windowed = true; swap_chain_desc.SwapEffect = DXGI_SWAP_EFFECT_SEQUENTIAL; swap_chain_desc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; // Create the swap chain, device and immediate device context. if ( FAILED( D3D11CreateDevice( adapter, adapter ? D3D_DRIVER_TYPE_UNKNOWN : D3D_DRIVER_TYPE_HARDWARE, nullptr, device_flags, nullptr, 0, D3D11_SDK_VERSION, &_device, nullptr, &_immediate_device_context ) ) ) { //LogError( "F11", "Cannot initialise F11Graphics; cannot create device and swapchain." ); return false; } if ( adapter ) { adapter->Release(); } if ( FAILED( factory->CreateSwapChain( _device, &swap_chain_desc, &_swap_chain ) ) ) { return false; } ID3D11Texture2D* backbuffer = nullptr; HRESULT hr = _swap_chain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&backbuffer); if (FAILED(hr)) return false; hr = _device->CreateRenderTargetView(backbuffer, nullptr, &_back_buffer); if (FAILED(hr)) return false; SetWidth( width ); SetHeight( height ); if ( backbuffer ) { backbuffer->Release(); } if ( factory ) { factory->Release(); } if ( VRIsEnabled() ) { { D3D11_BUFFER_DESC cbuffer_desc; cbuffer_desc.ByteWidth = sizeof(OculusBlit_cbuffer); cbuffer_desc.Usage = D3D11_USAGE_DYNAMIC; cbuffer_desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; cbuffer_desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; cbuffer_desc.MiscFlags = 0; cbuffer_desc.StructureByteStride = sizeof(OculusBlit_cbuffer); if ( FAILED( Device()->CreateBuffer( &cbuffer_desc, nullptr, &_oculus_blit_cbuffer ) ) ) { return false; } } _swap_chain->SetFullscreenState( 1, nullptr ); } if (0) { // Get the dxgi factory and disable fullscreen toggling with alt+enter. IDXGIDevice* dxgi_device = nullptr; if ( FAILED( _device->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgi_device) ) ) { //LogError( "F11", "Cannot initialise F11Graphics; cannot get DXGI device." ); return false; } if ( FAILED( dxgi_device->GetParent(__uuidof(IDXGIAdapter), (void **)&adapter) ) ) { //LogError( "F11", "Cannot initialise F11Graphics; cannot get DXGI adapter." ); return false; } IDXGIFactory * factory = nullptr; if ( FAILED( adapter->GetParent(__uuidof(IDXGIFactory), (void **)&factory) ) ) { //LogError( "F11", "Cannot initialise F11Graphics; cannot get DXGI factory." ); return false; } factory->MakeWindowAssociation( HWND(GetGame()->GetHWND()), DXGI_MWA_NO_WINDOW_CHANGES ); dxgi_device->Release(); adapter->Release(); factory->Release(); } // Create the back buffer by resizing //Resize( width, height ); _resources.SetConfig(GetGraphicsSettings()); if ( !_resources.Initialise() ) { return false; } Resize( width, height ); _is_initialised = true; return true; }
bool D3DClass::Initialize(int screenWidth, int screenHeight, bool vsync, HWND hwnd, bool fullscreen, float screenDepth, float screenNear){ HRESULT hr; float fov, screenAspect; m_vsync_enabled = vsync; m_featureLevel = D3D_FEATURE_LEVEL_11_0; D3D_DRIVER_TYPE driverTypes[] = { D3D_DRIVER_TYPE_HARDWARE, D3D_DRIVER_TYPE_WARP, D3D_DRIVER_TYPE_REFERENCE, }; UINT numDriverTypes = ARRAYSIZE(driverTypes); D3D_FEATURE_LEVEL featureLevels[] = { //D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0, }; UINT numFeatureLevels = ARRAYSIZE(featureLevels); for (int driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++){ m_driverType = driverTypes[driverTypeIndex]; hr = D3D11CreateDevice(NULL, m_driverType, NULL, 0, featureLevels, numFeatureLevels, D3D11_SDK_VERSION, &m_device, &m_featureLevel, &m_deviceContext); if (hr == E_INVALIDARG){ hr = D3D11CreateDevice(NULL, m_driverType, NULL, 0, &featureLevels[1], numFeatureLevels - 1, D3D11_SDK_VERSION, &m_device, &m_featureLevel, &m_deviceContext); } if (SUCCEEDED(hr)){ break; } } if (FAILED(hr)){ return false; } IDXGIFactory1* factory = 0; IDXGIDevice* device = 0; hr = m_device->QueryInterface(__uuidof(IDXGIDevice), reinterpret_cast<void**>(&device)); if (SUCCEEDED(hr)){ IDXGIAdapter* adapter = 0; hr = device->GetAdapter(&adapter); if (SUCCEEDED(hr)){ hr = adapter->GetParent(__uuidof(IDXGIFactory1), reinterpret_cast<void**>(&factory)); adapter->Release(); } device->Release(); } if (FAILED(hr)){ return false; } IDXGIFactory2* factory2 = 0; hr = factory->QueryInterface(__uuidof(IDXGIFactory2), reinterpret_cast<void**>(&factory2)); if (factory2){ hr = m_device->QueryInterface(__uuidof(ID3D11Device1), reinterpret_cast<void**>(&m_device1)); if (SUCCEEDED(hr)){ (void)m_deviceContext->QueryInterface(__uuidof(ID3D11DeviceContext1), reinterpret_cast<void**>(&m_deviceContext1)); } DXGI_SWAP_CHAIN_DESC1 sd; ZeroMemory(&sd, sizeof(sd)); sd.Width = screenWidth; sd.Height = screenHeight; sd.Format = DXGI_FORMAT_R8G8B8A8_UNORM; sd.SampleDesc.Count = 1; sd.SampleDesc.Quality = 0; sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; sd.BufferCount = 1; hr = factory2->CreateSwapChainForHwnd(m_device, hwnd, &sd, NULL, NULL, &m_swapChain1); if (SUCCEEDED(hr)){ m_swapChain = NULL; hr = m_swapChain1->QueryInterface(__uuidof(IDXGISwapChain), reinterpret_cast<void**>(&m_swapChain)); } factory2->Release(); } else{ DXGI_SWAP_CHAIN_DESC sd; ZeroMemory(&sd, sizeof(sd)); sd.BufferCount = 1; sd.BufferDesc.Width = screenWidth; sd.BufferDesc.Height = screenHeight; sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; sd.BufferDesc.RefreshRate.Numerator = 60; sd.BufferDesc.RefreshRate.Denominator = 1; sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; sd.OutputWindow = hwnd; sd.SampleDesc.Count = 1; sd.SampleDesc.Quality = 0; sd.Windowed = TRUE; hr = factory->CreateSwapChain(m_device, &sd, &m_swapChain); } factory->MakeWindowAssociation(hwnd, DXGI_MWA_NO_ALT_ENTER); factory->Release(); if (FAILED(hr)){ return false; } ID3D11Texture2D* backBuffer = 0; hr = m_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), reinterpret_cast<void**>(&backBuffer)); if (FAILED(hr)){ return false; } hr = m_device->CreateRenderTargetView(backBuffer, NULL, &m_renderTargetView); backBuffer->Release(); if (FAILED(hr)){ return false; } m_deviceContext->OMSetRenderTargets(1, &m_renderTargetView, NULL); D3D11_TEXTURE2D_DESC depthBufferDesc; ZeroMemory(&depthBufferDesc, sizeof(depthBufferDesc)); depthBufferDesc.Width = screenWidth; depthBufferDesc.Height = screenHeight; depthBufferDesc.MipLevels = 1; depthBufferDesc.ArraySize = 1; depthBufferDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; depthBufferDesc.SampleDesc.Count = 1; depthBufferDesc.SampleDesc.Quality = 0; depthBufferDesc.Usage = D3D11_USAGE_DEFAULT; depthBufferDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL; depthBufferDesc.CPUAccessFlags = 0; depthBufferDesc.MiscFlags = 0; hr = m_device->CreateTexture2D(&depthBufferDesc, NULL, &m_depthStencilBuffer); if (FAILED(hr)){ return false; } D3D11_DEPTH_STENCIL_DESC depthStencilDesc; ZeroMemory(&depthStencilDesc, sizeof(depthStencilDesc)); depthStencilDesc.DepthEnable = true; depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; depthStencilDesc.DepthFunc = D3D11_COMPARISON_LESS; depthStencilDesc.StencilEnable = true; depthStencilDesc.StencilReadMask = 0xFF; depthStencilDesc.StencilWriteMask = 0xFF; depthStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR; depthStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; depthStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR; depthStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; hr = m_device->CreateDepthStencilState(&depthStencilDesc, &m_depthStencilState); if (FAILED(hr)){ return false; } m_deviceContext->OMSetDepthStencilState(m_depthStencilState, 1); D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc; ZeroMemory(&depthStencilViewDesc, sizeof(depthStencilViewDesc)); depthStencilViewDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; depthStencilViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; depthStencilViewDesc.Texture2D.MipSlice = 0; hr = m_device->CreateDepthStencilView(m_depthStencilBuffer, &depthStencilViewDesc, &m_depthStencilView); if (FAILED(hr)){ return false; } m_deviceContext->OMSetRenderTargets(1, &m_renderTargetView, m_depthStencilView); D3D11_RASTERIZER_DESC rasterDesc; rasterDesc.AntialiasedLineEnable = false; rasterDesc.CullMode = D3D11_CULL_BACK; rasterDesc.DepthBias = 0; rasterDesc.DepthBiasClamp = 0.0f; rasterDesc.DepthClipEnable = true; rasterDesc.FillMode = D3D11_FILL_SOLID; rasterDesc.FrontCounterClockwise = false; rasterDesc.MultisampleEnable = false; rasterDesc.ScissorEnable = false; rasterDesc.SlopeScaledDepthBias = 0.0f; hr = m_device->CreateRasterizerState(&rasterDesc, &m_rasterState); if (FAILED(hr)){ return false; } m_deviceContext->RSSetState(m_rasterState); D3D11_VIEWPORT viewport; viewport.Width = (float)screenWidth; viewport.Height = (float)screenHeight; viewport.MinDepth = 0.0f; viewport.MaxDepth = 1.0f; viewport.TopLeftX = 0.0f; viewport.TopLeftY = 0.0f; m_deviceContext->RSSetViewports(1, &viewport); fov = XM_PI / 4.0f; screenAspect = (float)screenWidth / (float)screenHeight; m_projectionMatrix = XMMatrixPerspectiveFovLH(fov, screenAspect, screenNear, screenDepth); m_worldMatrix = XMMatrixIdentity(); m_orthoMatrix = XMMatrixOrthographicLH((float)screenWidth, (float)screenHeight, screenNear, screenDepth); D3D11_DEPTH_STENCIL_DESC depthDisabledStencilDesc; ZeroMemory(&depthDisabledStencilDesc, sizeof(depthDisabledStencilDesc)); depthDisabledStencilDesc.DepthEnable = false; depthDisabledStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; depthDisabledStencilDesc.DepthFunc = D3D11_COMPARISON_LESS; depthDisabledStencilDesc.StencilEnable = true; depthDisabledStencilDesc.StencilReadMask = 0xFF; depthDisabledStencilDesc.StencilWriteMask = 0xFF; depthDisabledStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; depthDisabledStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR; depthDisabledStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; depthDisabledStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; depthDisabledStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; depthDisabledStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR; depthDisabledStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; depthDisabledStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; hr = m_device->CreateDepthStencilState(&depthDisabledStencilDesc, &m_depthDisabledStencilState); if (FAILED(hr)){ return false; } D3D11_BLEND_DESC blendStateDescription; ZeroMemory(&blendStateDescription, sizeof(D3D11_BLEND_DESC)); blendStateDescription.RenderTarget[0].BlendEnable = TRUE; blendStateDescription.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; blendStateDescription.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; blendStateDescription.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; blendStateDescription.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; //blendStateDescription.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_INV_DEST_ALPHA; blendStateDescription.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; // blendStateDescription.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ONE; blendStateDescription.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; blendStateDescription.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; blendStateDescription.RenderTarget[0].RenderTargetWriteMask = 0x0f; hr = m_device->CreateBlendState(&blendStateDescription, &m_alphaEnableBlendingState); if (FAILED(hr)){ return false; } blendStateDescription.RenderTarget[0].BlendEnable = FALSE; hr = m_device->CreateBlendState(&blendStateDescription, &m_alphaDisableBlendingState); if (FAILED(hr)){ return false; } return true; }
bool D3D11Context::Init(HINSTANCE hInst, HWND wnd, std::string *error_message) { hWnd_ = wnd; LoadD3D11Error result = LoadD3D11(); HRESULT hr = E_FAIL; std::vector<std::string> adapterNames; std::string chosenAdapterName; if (result == LoadD3D11Error::SUCCESS) { std::vector<IDXGIAdapter *> adapters; int chosenAdapter = 0; IDXGIFactory * pFactory = nullptr; ptr_CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&pFactory); IDXGIAdapter *pAdapter; for (UINT i = 0; pFactory->EnumAdapters(i, &pAdapter) != DXGI_ERROR_NOT_FOUND; i++) { adapters.push_back(pAdapter); DXGI_ADAPTER_DESC desc; pAdapter->GetDesc(&desc); std::string str = ConvertWStringToUTF8(desc.Description); adapterNames.push_back(str); if (str == g_Config.sD3D11Device) { chosenAdapter = i; } } chosenAdapterName = adapterNames[chosenAdapter]; hr = CreateTheDevice(adapters[chosenAdapter]); for (int i = 0; i < (int)adapters.size(); i++) { adapters[i]->Release(); } } if (FAILED(hr)) { const char *defaultError = "Your GPU does not appear to support Direct3D 11.\n\nWould you like to try again using Direct3D 9 instead?"; I18NCategory *err = GetI18NCategory("Error"); std::wstring error; if (result == LoadD3D11Error::FAIL_NO_COMPILER) { error = ConvertUTF8ToWString(err->T("D3D11CompilerMissing", "D3DCompiler_47.dll not found. Please install. Or press Yes to try again using Direct3D9 instead.")); } else if (result == LoadD3D11Error::FAIL_NO_D3D11) { error = ConvertUTF8ToWString(err->T("D3D11Missing", "Your operating system version does not include D3D11. Please run Windows Update.\n\nPress Yes to try again using Direct3D9 instead.")); } error = ConvertUTF8ToWString(err->T("D3D11NotSupported", defaultError)); std::wstring title = ConvertUTF8ToWString(err->T("D3D11InitializationError", "Direct3D 11 initialization error")); bool yes = IDYES == MessageBox(hWnd_, error.c_str(), title.c_str(), MB_ICONERROR | MB_YESNO); if (yes) { // Change the config to D3D9 and restart. g_Config.iGPUBackend = (int)GPUBackend::DIRECT3D9; g_Config.sFailedGPUBackends.clear(); g_Config.Save("save_d3d9_fallback"); W32Util::ExitAndRestart(); } return false; } if (FAILED(device_->QueryInterface(__uuidof (ID3D11Device1), (void **)&device1_))) { device1_ = nullptr; } if (FAILED(context_->QueryInterface(__uuidof (ID3D11DeviceContext1), (void **)&context1_))) { context1_ = nullptr; } #ifdef _DEBUG if (SUCCEEDED(device_->QueryInterface(__uuidof(ID3D11Debug), (void**)&d3dDebug_))) { if (SUCCEEDED(d3dDebug_->QueryInterface(__uuidof(ID3D11InfoQueue), (void**)&d3dInfoQueue_))) { d3dInfoQueue_->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_CORRUPTION, true); d3dInfoQueue_->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_ERROR, true); d3dInfoQueue_->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_WARNING, true); } } #endif draw_ = Draw::T3DCreateD3D11Context(device_, context_, device1_, context1_, featureLevel_, hWnd_, adapterNames); SetGPUBackend(GPUBackend::DIRECT3D11, chosenAdapterName); bool success = draw_->CreatePresets(); // If we can run D3D11, there's a compiler installed. I think. _assert_msg_(G3D, success, "Failed to compile preset shaders"); int width; int height; GetRes(hWnd_, width, height); // Obtain DXGI factory from device (since we used nullptr for pAdapter above) IDXGIFactory1* dxgiFactory = nullptr; IDXGIDevice* dxgiDevice = nullptr; IDXGIAdapter* adapter = nullptr; hr = device_->QueryInterface(__uuidof(IDXGIDevice), reinterpret_cast<void**>(&dxgiDevice)); if (SUCCEEDED(hr)) { hr = dxgiDevice->GetAdapter(&adapter); if (SUCCEEDED(hr)) { hr = adapter->GetParent(__uuidof(IDXGIFactory1), reinterpret_cast<void**>(&dxgiFactory)); DXGI_ADAPTER_DESC desc; adapter->GetDesc(&desc); adapter->Release(); } dxgiDevice->Release(); } // DirectX 11.0 systems DXGI_SWAP_CHAIN_DESC sd; ZeroMemory(&sd, sizeof(sd)); sd.BufferCount = 1; sd.BufferDesc.Width = width; sd.BufferDesc.Height = height; sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; sd.BufferDesc.RefreshRate.Numerator = 60; sd.BufferDesc.RefreshRate.Denominator = 1; sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; sd.OutputWindow = hWnd_; sd.SampleDesc.Count = 1; sd.SampleDesc.Quality = 0; sd.Windowed = TRUE; hr = dxgiFactory->CreateSwapChain(device_, &sd, &swapChain_); dxgiFactory->MakeWindowAssociation(hWnd_, DXGI_MWA_NO_ALT_ENTER); dxgiFactory->Release(); GotBackbuffer(); return true; }
bool DXApp::InitDirectX() { UINT createDeviceFlags = 0; #if defined(DEBUG) || defined(_DEBUG) createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG; #endif D3D_FEATURE_LEVEL featurelvl; HRESULT hr = D3D11CreateDevice( 0, //default adapter D3D_DRIVER_TYPE_HARDWARE, 0, createDeviceFlags, 0, 0, D3D11_SDK_VERSION, &m_d3dDevice, &featurelvl, &m_d3dImmediateContext); if (FAILED(hr)) { MessageBox(0, L"Creation of Context failed", 0, 0); return false; } if (featurelvl != D3D_FEATURE_LEVEL_11_0) { MessageBox(0, L"DirectX11 not supported", 0, 0); return false; } m_d3dDevice->CheckMultisampleQualityLevels(DXGI_FORMAT_R8G8B8A8_UNORM, 4, &m_4xMsaaQuality); assert(m_4xMsaaQuality > 0); DXGI_SWAP_CHAIN_DESC sd; sd.BufferDesc.Width = m_clientWidth; sd.BufferDesc.Height = m_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 (m_enable4xMsaa) { sd.SampleDesc.Count = 4; sd.SampleDesc.Quality = m_4xMsaaQuality - 1; } else { sd.SampleDesc.Count = 1; sd.SampleDesc.Quality = m_4xMsaaQuality - 1; } sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; sd.BufferCount = 1; sd.OutputWindow =m_mainHandle; sd.Windowed = m_windowed; sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; sd.Flags = 0; IDXGIDevice* dxgiDevice = 0; m_d3dDevice->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(m_d3dDevice, &sd, &m_d3dSwapChain); //NO ALT-ENTER dxgiFactory->MakeWindowAssociation(m_mainHandle, DXGI_MWA_NO_ALT_ENTER); UINT i = 0; IDXGIAdapter* pAdapter; std::vector<IDXGIAdapter*> vAdapters; while (dxgiFactory->EnumAdapters(i, &pAdapter) != DXGI_ERROR_NOT_FOUND) { vAdapters.push_back(pAdapter); //pAdapter->CheckInterfaceSupport(__uuidof(DIRECT3D_VERSION), DIRECT3D_11.0); i++; } //MessageBox(0, LPCWSTR(std::to_string(vAdapters.size()).c_str()), 0, 0); for (auto a : vAdapters)a->Release(); dxgiDevice->Release(); dxgiAdapter->Release(); dxgiFactory->Release(); ID3D11Texture2D* backBuffer; m_d3dSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), reinterpret_cast<void**>(&backBuffer)); m_d3dDevice->CreateRenderTargetView(backBuffer, 0, &m_d3dRenderTargetView); backBuffer->Release(); D3D11_TEXTURE2D_DESC depthStencilDesc; depthStencilDesc.Width = m_clientWidth; depthStencilDesc.Height = m_clientHeight; depthStencilDesc.MipLevels = 1; depthStencilDesc.ArraySize = 1; depthStencilDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; if (m_enable4xMsaa) { depthStencilDesc.SampleDesc.Count = 4; depthStencilDesc.SampleDesc.Quality = m_4xMsaaQuality - 1; } else { depthStencilDesc.SampleDesc.Count = 1; depthStencilDesc.SampleDesc.Quality = m_4xMsaaQuality - 0; } depthStencilDesc.Usage = D3D11_USAGE_DEFAULT; depthStencilDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL; depthStencilDesc.CPUAccessFlags = 0; depthStencilDesc.MiscFlags = 0; m_d3dDevice->CreateTexture2D(&depthStencilDesc, 0, &m_d3dDepthStencilBuffer); m_d3dDevice->CreateDepthStencilView(m_d3dDepthStencilBuffer, 0, &m_d3dDepthStencilView); m_d3dImmediateContext->OMSetRenderTargets(1, &m_d3dRenderTargetView, m_d3dDepthStencilView); D3D11_VIEWPORT vp; vp.TopLeftX = 0.f; vp.TopLeftY = 0.f; vp.Width = static_cast<float>(m_clientWidth); vp.Height = static_cast<float>(m_clientHeight); vp.MinDepth = 0.f; vp.MaxDepth = 0.f; m_d3dImmediateContext->RSSetViewports(1, &vp); return true; }
bool D3DApp::InitDirect3D() { // Create the device and device context. UINT createDeviceFlags = 0; #if defined(DEBUG) || defined(_DEBUG) createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG; #endif D3D_FEATURE_LEVEL featureLevel; HRESULT hr = D3D11CreateDevice( 0, // default adapter md3dDriverType, 0, // no software device createDeviceFlags, 0, 0, // default feature level array D3D11_SDK_VERSION, &md3dDevice, &featureLevel, &md3dImmediateContext); if( FAILED(hr) ) { MessageBox(0, L"D3D11CreateDevice Failed.", 0, 0); return false; } if( featureLevel != D3D_FEATURE_LEVEL_11_0 ) { MessageBox(0, L"Direct3D Feature Level 11 unsupported.", 0, 0); return false; } // Check 4X MSAA quality support for our back buffer format. // All Direct3D 11 capable devices support 4X MSAA for all render // target formats, so we only need to check quality support. HR(md3dDevice->CheckMultisampleQualityLevels( DXGI_FORMAT_R8G8B8A8_UNORM, 4, &m4xMsaaQuality)); assert( m4xMsaaQuality > 0 ); // Fill out a DXGI_SWAP_CHAIN_DESC to describe our swap chain. DXGI_SWAP_CHAIN_DESC sd; ZeroMemory(&sd, sizeof(DXGI_SWAP_CHAIN_DESC)); sd.BufferDesc.Width = mClientWidth; sd.BufferDesc.Height = mClientHeight; sd.Windowed = true; sd.BufferDesc.RefreshRate.Numerator = m_MonitorNumerator; sd.BufferDesc.RefreshRate.Denominator = m_MonitorDenumerator; sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; sd.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; sd.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; // Use 4X MSAA? if( mEnable4xMsaa ) { sd.SampleDesc.Count = 4; sd.SampleDesc.Quality = m4xMsaaQuality-1; } // No MSAA else { sd.SampleDesc.Count = 1; sd.SampleDesc.Quality = 0; } sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; sd.BufferCount = 1; sd.OutputWindow = mhMainWnd; sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; sd.Flags = 0; // To correctly create the swap chain, we must use the IDXGIFactory that was // used to create the device. If we tried to use a different IDXGIFactory instance // (by calling CreateDXGIFactory), we get an error: "IDXGIFactory::CreateSwapChain: // This function is being called with a device from a different IDXGIFactory." IDXGIDevice* dxgiDevice = 0; HR(md3dDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice)); IDXGIAdapter* dxgiAdapter = 0; HR(dxgiDevice->GetParent(__uuidof(IDXGIAdapter), (void**)&dxgiAdapter)); IDXGIFactory* dxgiFactory = 0; HR(dxgiAdapter->GetParent(__uuidof(IDXGIFactory), (void**)&dxgiFactory)); HR(dxgiFactory->CreateSwapChain(md3dDevice, &sd, &mSwapChain)); //Disable Alt-Enter Sequence dxgiFactory->MakeWindowAssociation(mhMainWnd, DXGI_MWA_NO_ALT_ENTER); ReleaseCOM(dxgiDevice); ReleaseCOM(dxgiAdapter); ReleaseCOM(dxgiFactory); // The remaining steps that need to be carried out for d3d creation // also need to be executed every time the window is resized. So // just call the OnResize method here to avoid code duplication. OnResize(); if (mFullScreen){ mSwapChain->SetFullscreenState(true, NULL); } return true; }
//-------------------------------------------------------------------------------------- // Create Direct3D device and swap chain //-------------------------------------------------------------------------------------- HRESULT InitDevice() { HRESULT hr = S_OK; RECT rc; GetClientRect( g_hWnd, &rc ); UINT width = rc.right - rc.left; UINT height = rc.bottom - rc.top; UINT createDeviceFlags = 0; #ifdef _DEBUG createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG; #endif D3D_DRIVER_TYPE driverTypes[] = { D3D_DRIVER_TYPE_HARDWARE, D3D_DRIVER_TYPE_WARP, D3D_DRIVER_TYPE_REFERENCE, }; UINT numDriverTypes = ARRAYSIZE( driverTypes ); D3D_FEATURE_LEVEL featureLevels[] = { D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0, }; UINT numFeatureLevels = ARRAYSIZE( featureLevels ); for( UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++ ) { g_driverType = driverTypes[driverTypeIndex]; hr = D3D11CreateDevice( nullptr, g_driverType, nullptr, createDeviceFlags, featureLevels, numFeatureLevels, D3D11_SDK_VERSION, &g_pd3dDevice, &g_featureLevel, &g_pImmediateContext ); if ( hr == E_INVALIDARG ) { // DirectX 11.0 platforms will not recognize D3D_FEATURE_LEVEL_11_1 so we need to retry without it hr = D3D11CreateDevice( nullptr, g_driverType, nullptr, createDeviceFlags, &featureLevels[1], numFeatureLevels - 1, D3D11_SDK_VERSION, &g_pd3dDevice, &g_featureLevel, &g_pImmediateContext ); } if( SUCCEEDED( hr ) ) break; } if( FAILED( hr ) ) return hr; // Obtain DXGI factory from device (since we used nullptr for pAdapter above) IDXGIFactory1* dxgiFactory = nullptr; { IDXGIDevice* dxgiDevice = nullptr; hr = g_pd3dDevice->QueryInterface( __uuidof(IDXGIDevice), reinterpret_cast<void**>(&dxgiDevice) ); if (SUCCEEDED(hr)) { IDXGIAdapter* adapter = nullptr; hr = dxgiDevice->GetAdapter(&adapter); if (SUCCEEDED(hr)) { hr = adapter->GetParent( __uuidof(IDXGIFactory1), reinterpret_cast<void**>(&dxgiFactory) ); adapter->Release(); } dxgiDevice->Release(); } } if (FAILED(hr)) return hr; // Create swap chain IDXGIFactory2* dxgiFactory2 = nullptr; hr = dxgiFactory->QueryInterface( __uuidof(IDXGIFactory2), reinterpret_cast<void**>(&dxgiFactory2) ); if ( dxgiFactory2 ) { // DirectX 11.1 or later hr = g_pd3dDevice->QueryInterface( __uuidof(ID3D11Device1), reinterpret_cast<void**>(&g_pd3dDevice1) ); if (SUCCEEDED(hr)) { (void) g_pImmediateContext->QueryInterface( __uuidof(ID3D11DeviceContext1), reinterpret_cast<void**>(&g_pImmediateContext1) ); } DXGI_SWAP_CHAIN_DESC1 sd = {}; sd.Width = width; sd.Height = height; sd.Format = DXGI_FORMAT_R8G8B8A8_UNORM; sd.SampleDesc.Count = 1; sd.SampleDesc.Quality = 0; sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; sd.BufferCount = 1; hr = dxgiFactory2->CreateSwapChainForHwnd( g_pd3dDevice, g_hWnd, &sd, nullptr, nullptr, &g_pSwapChain1 ); if (SUCCEEDED(hr)) { hr = g_pSwapChain1->QueryInterface( __uuidof(IDXGISwapChain), reinterpret_cast<void**>(&g_pSwapChain) ); } dxgiFactory2->Release(); } else { // DirectX 11.0 systems DXGI_SWAP_CHAIN_DESC sd = {}; sd.BufferCount = 1; sd.BufferDesc.Width = width; sd.BufferDesc.Height = height; sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; sd.BufferDesc.RefreshRate.Numerator = 60; sd.BufferDesc.RefreshRate.Denominator = 1; sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; sd.OutputWindow = g_hWnd; sd.SampleDesc.Count = 1; sd.SampleDesc.Quality = 0; sd.Windowed = TRUE; hr = dxgiFactory->CreateSwapChain( g_pd3dDevice, &sd, &g_pSwapChain ); } // Note this tutorial doesn't handle full-screen swapchains so we block the ALT+ENTER shortcut dxgiFactory->MakeWindowAssociation( g_hWnd, DXGI_MWA_NO_ALT_ENTER ); dxgiFactory->Release(); if (FAILED(hr)) return hr; // Create a render target view ID3D11Texture2D* pBackBuffer = nullptr; hr = g_pSwapChain->GetBuffer( 0, __uuidof( ID3D11Texture2D ), reinterpret_cast<void**>( &pBackBuffer ) ); if( FAILED( hr ) ) return hr; hr = g_pd3dDevice->CreateRenderTargetView( pBackBuffer, nullptr, &g_pRenderTargetView ); pBackBuffer->Release(); if( FAILED( hr ) ) return hr; g_pImmediateContext->OMSetRenderTargets( 1, &g_pRenderTargetView, nullptr ); // Setup the viewport D3D11_VIEWPORT vp; vp.Width = (FLOAT)width; vp.Height = (FLOAT)height; vp.MinDepth = 0.0f; vp.MaxDepth = 1.0f; vp.TopLeftX = 0; vp.TopLeftY = 0; g_pImmediateContext->RSSetViewports( 1, &vp ); return S_OK; }
// // Initialize all state // DUPL_RETURN OUTPUTMANAGER::InitOutput(HWND Window, INT SingleOutput, _Out_ UINT* OutCount, _Out_ RECT* DeskBounds) { HRESULT hr; // Store window handle m_WindowHandle = Window; // Driver types supported D3D_DRIVER_TYPE DriverTypes[] = { D3D_DRIVER_TYPE_HARDWARE, D3D_DRIVER_TYPE_WARP, D3D_DRIVER_TYPE_REFERENCE, }; UINT NumDriverTypes = ARRAYSIZE(DriverTypes); // Feature levels supported D3D_FEATURE_LEVEL FeatureLevels[] = { D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0, D3D_FEATURE_LEVEL_9_1 }; UINT NumFeatureLevels = ARRAYSIZE(FeatureLevels); D3D_FEATURE_LEVEL FeatureLevel; // Create device for (UINT DriverTypeIndex = 0; DriverTypeIndex < NumDriverTypes; ++DriverTypeIndex) { hr = D3D11CreateDevice(nullptr, DriverTypes[DriverTypeIndex], nullptr, 0, FeatureLevels, NumFeatureLevels, D3D11_SDK_VERSION, &m_Device, &FeatureLevel, &m_DeviceContext); if (SUCCEEDED(hr)) { // Device creation succeeded, no need to loop anymore break; } } if (FAILED(hr)) { return ProcessFailure(m_Device, L"Device creation in OUTPUTMANAGER failed", L"Error", hr, SystemTransitionsExpectedErrors); } // Get DXGI factory IDXGIDevice* DxgiDevice = nullptr; hr = m_Device->QueryInterface(__uuidof(IDXGIDevice), reinterpret_cast<void**>(&DxgiDevice)); if (FAILED(hr)) { return ProcessFailure(nullptr, L"Failed to QI for DXGI Device", L"Error", hr, nullptr); } IDXGIAdapter* DxgiAdapter = nullptr; hr = DxgiDevice->GetParent(__uuidof(IDXGIAdapter), reinterpret_cast<void**>(&DxgiAdapter)); DxgiDevice->Release(); DxgiDevice = nullptr; if (FAILED(hr)) { return ProcessFailure(m_Device, L"Failed to get parent DXGI Adapter", L"Error", hr, SystemTransitionsExpectedErrors); } hr = DxgiAdapter->GetParent(__uuidof(IDXGIFactory2), reinterpret_cast<void**>(&m_Factory)); DxgiAdapter->Release(); DxgiAdapter = nullptr; if (FAILED(hr)) { return ProcessFailure(m_Device, L"Failed to get parent DXGI Factory", L"Error", hr, SystemTransitionsExpectedErrors); } // Register for occlusion status windows message hr = m_Factory->RegisterOcclusionStatusWindow(Window, OCCLUSION_STATUS_MSG, &m_OcclusionCookie); if (FAILED(hr)) { return ProcessFailure(m_Device, L"Failed to register for occlusion message", L"Error", hr, SystemTransitionsExpectedErrors); } // Get window size RECT WindowRect; GetClientRect(m_WindowHandle, &WindowRect); UINT Width = WindowRect.right - WindowRect.left; UINT Height = WindowRect.bottom - WindowRect.top; // Create swapchain for window DXGI_SWAP_CHAIN_DESC1 SwapChainDesc; RtlZeroMemory(&SwapChainDesc, sizeof(SwapChainDesc)); SwapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; SwapChainDesc.BufferCount = 2; SwapChainDesc.Width = Width; SwapChainDesc.Height = Height; SwapChainDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; SwapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; SwapChainDesc.SampleDesc.Count = 1; SwapChainDesc.SampleDesc.Quality = 0; hr = m_Factory->CreateSwapChainForHwnd(m_Device, Window, &SwapChainDesc, nullptr, nullptr, &m_SwapChain); if (FAILED(hr)) { return ProcessFailure(m_Device, L"Failed to create window swapchain", L"Error", hr, SystemTransitionsExpectedErrors); } // Disable the ALT-ENTER shortcut for entering full-screen mode hr = m_Factory->MakeWindowAssociation(Window, DXGI_MWA_NO_ALT_ENTER); if (FAILED(hr)) { return ProcessFailure(m_Device, L"Failed to make window association", L"Error", hr, SystemTransitionsExpectedErrors); } // Create shared texture DUPL_RETURN Return = CreateSharedSurf(SingleOutput, OutCount, DeskBounds); if (Return != DUPL_RETURN_SUCCESS) { return Return; } // Make new render target view Return = MakeRTV(); if (Return != DUPL_RETURN_SUCCESS) { return Return; } // Set view port SetViewPort(Width, Height); // Create the sample state D3D11_SAMPLER_DESC SampDesc; RtlZeroMemory(&SampDesc, sizeof(SampDesc)); SampDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; SampDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP; SampDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP; SampDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; SampDesc.ComparisonFunc = D3D11_COMPARISON_NEVER; SampDesc.MinLOD = 0; SampDesc.MaxLOD = D3D11_FLOAT32_MAX; hr = m_Device->CreateSamplerState(&SampDesc, &m_SamplerLinear); if (FAILED(hr)) { return ProcessFailure(m_Device, L"Failed to create sampler state in OUTPUTMANAGER", L"Error", hr, SystemTransitionsExpectedErrors); } // Create the blend state D3D11_BLEND_DESC BlendStateDesc; BlendStateDesc.AlphaToCoverageEnable = FALSE; BlendStateDesc.IndependentBlendEnable = FALSE; BlendStateDesc.RenderTarget[0].BlendEnable = TRUE; BlendStateDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; BlendStateDesc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; BlendStateDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; BlendStateDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; BlendStateDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; BlendStateDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; BlendStateDesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; hr = m_Device->CreateBlendState(&BlendStateDesc, &m_BlendState); if (FAILED(hr)) { return ProcessFailure(m_Device, L"Failed to create blend state in OUTPUTMANAGER", L"Error", hr, SystemTransitionsExpectedErrors); } // Initialize shaders Return = InitShaders(); if (Return != DUPL_RETURN_SUCCESS) { return Return; } GetWindowRect(m_WindowHandle, &WindowRect); MoveWindow(m_WindowHandle, WindowRect.left, WindowRect.top, (DeskBounds->right - DeskBounds->left) / 2, (DeskBounds->bottom - DeskBounds->top) / 2, TRUE); return Return; }
bool Renderer::Init() { UINT createDeviceFlags = 0; #if defined(DEBUG) || defined(_DEBUG) //createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG; //createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUGGABLE; #endif D3D_FEATURE_LEVEL featureLevel; HRESULT hresult = D3D11CreateDevice(0, _d3dDriverType, 0, createDeviceFlags, 0, 0, D3D11_SDK_VERSION, &_d3dDevice, &featureLevel, &_d3dImmediateContext); if (FAILED(hresult)) { // TODO: Throw exceptions _logger.LogLine(L"Failed to initialize Renderer: Failed to create D3D11CreateDevice."); _logger.LogHResult(hresult); MessageBox(0, L"Failed to initialize Renderer, see log for details.", 0, 0); return false; } if (featureLevel != D3D_FEATURE_LEVEL_11_0) //if (featureLevel != 0xc000) { // TODO: Throw exceptions _logger.LogLine(L"Failed to initialize Renderer: Required D3D feature level 11 not supported."); MessageBox(0, L"Failed to initialize Renderer, see log for details.", 0, 0); return false; } hresult = (_d3dDevice->CheckMultisampleQualityLevels(DXGI_FORMAT_R8G8B8A8_UNORM, 4, &_4xMsaaQuality)); if (FAILED(hresult)) { _logger.LogHResult(hresult); } assert(_4xMsaaQuality > 0); DXGI_SWAP_CHAIN_DESC swapChainDescription; swapChainDescription.BufferDesc.Width = _clientWidth; swapChainDescription.BufferDesc.Height = _clientHeight; swapChainDescription.BufferDesc.RefreshRate.Numerator = 60; swapChainDescription.BufferDesc.RefreshRate.Denominator = 1; swapChainDescription.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; swapChainDescription.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; swapChainDescription.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; if (_enable4xMsaa) { swapChainDescription.SampleDesc.Count = 4; swapChainDescription.SampleDesc.Quality = _4xMsaaQuality - 1; } else { swapChainDescription.SampleDesc.Count = 1; swapChainDescription.SampleDesc.Quality = 0; } swapChainDescription.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChainDescription.BufferCount = 1; swapChainDescription.OutputWindow = _windowHandle; swapChainDescription.Windowed = true; swapChainDescription.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; swapChainDescription.Flags = 0; IDXGIDevice* dxgiDevice = 0; hresult = (_d3dDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice)); if (FAILED(hresult)) { _logger.LogHResult(hresult); } IDXGIAdapter* dxgiAdapter = 0; hresult = (dxgiDevice->GetParent(__uuidof(IDXGIAdapter), (void**)&dxgiAdapter)); if (FAILED(hresult)) { _logger.LogHResult(hresult); } IDXGIFactory* dxgiFactory = 0; hresult = (dxgiAdapter->GetParent(__uuidof(IDXGIFactory), (void**)&dxgiFactory)); if (FAILED(hresult)) { _logger.LogHResult(hresult); } hresult = (dxgiFactory->CreateSwapChain(_d3dDevice, &swapChainDescription, &_swapChain)); if (FAILED(hresult)) { _logger.LogHResult(hresult); } if (dxgiDevice) { dxgiDevice->Release(); dxgiDevice = 0; } if (dxgiAdapter) { dxgiAdapter->Release(); dxgiAdapter = 0; } if (dxgiFactory) { dxgiFactory->Release(); dxgiFactory = 0; } OnResize(); return true; }
void InitializeDirectX() { UINT createDeviceFlags = 0; #if defined(DEBUG) || defined(_DEBUG) createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG; #endif D3D_FEATURE_LEVEL featureLevels[] = { D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0 }; ID3D11Device* direct3DDevice = nullptr; ID3D11DeviceContext* direct3DDeviceContext = nullptr; ThrowIfFailed(D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, createDeviceFlags, featureLevels, ARRAYSIZE(featureLevels), D3D11_SDK_VERSION, &direct3DDevice, &mFeatureLevel, &direct3DDeviceContext), "D3D11CreateDevice() failed"); ThrowIfFailed(direct3DDevice->QueryInterface(__uuidof(ID3D11Device1), reinterpret_cast<void**>(&mDirect3DDevice)), "ID3D11Device::QueryInterface() failed"); ThrowIfFailed(direct3DDeviceContext->QueryInterface(__uuidof(ID3D11DeviceContext1), reinterpret_cast<void**>(&mDirect3DDeviceContext)), "ID3D11Device::QueryInterface() failed"); ReleaseObject(direct3DDevice); ReleaseObject(direct3DDeviceContext); UINT multiSamplingCount = 4; UINT multiSamplingQualityLevels; mDirect3DDevice->CheckMultisampleQualityLevels(DXGI_FORMAT_R8G8B8A8_UNORM, multiSamplingCount, &multiSamplingQualityLevels); if (multiSamplingQualityLevels == 0) { throw GameException("Unsupported multi-sampling quality"); } DXGI_SWAP_CHAIN_DESC1 swapChainDesc; ZeroMemory(&swapChainDesc, sizeof(swapChainDesc)); swapChainDesc.Width = mScreenWidth; swapChainDesc.Height = mScreenHeight; swapChainDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; swapChainDesc.SampleDesc.Count = multiSamplingCount; swapChainDesc.SampleDesc.Quality = multiSamplingQualityLevels - 1; swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChainDesc.BufferCount = 1; swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; IDXGIDevice* dxgiDevice = nullptr; ThrowIfFailed(mDirect3DDevice->QueryInterface(__uuidof(IDXGIDevice), reinterpret_cast<void**>(&dxgiDevice)), "ID3D11Device::QueryInterface() failed"); IDXGIAdapter *dxgiAdapter = nullptr; HRESULT hr; if (FAILED(hr = dxgiDevice->GetParent(__uuidof(IDXGIAdapter), reinterpret_cast<void**>(&dxgiAdapter)))) { ReleaseObject(dxgiDevice); throw GameException("IDXGIDevice::GetParent() failed retrieving adapter.", hr); } IDXGIFactory2* dxgiFactory = nullptr; if (FAILED(hr = dxgiAdapter->GetParent(__uuidof(IDXGIFactory2), reinterpret_cast<void**>(&dxgiFactory)))) { ReleaseObject(dxgiDevice); ReleaseObject(dxgiAdapter); throw GameException("IDXGIAdapter::GetParent() failed retrieving factory.", hr); } DXGI_SWAP_CHAIN_FULLSCREEN_DESC fullScreenDesc; ZeroMemory(&fullScreenDesc, sizeof(fullScreenDesc)); fullScreenDesc.RefreshRate.Numerator = 60; fullScreenDesc.RefreshRate.Denominator = 1; fullScreenDesc.Windowed = true; if (FAILED(hr = dxgiFactory->CreateSwapChainForHwnd(dxgiDevice, mWindowHandle, &swapChainDesc, &fullScreenDesc, nullptr, &mSwapChain))) { ReleaseObject(dxgiDevice); ReleaseObject(dxgiAdapter); ReleaseObject(dxgiFactory); throw GameException("IDXGIDevice::CreateSwapChainForHwnd() failed.", hr); } ReleaseObject(dxgiDevice); ReleaseObject(dxgiAdapter); ReleaseObject(dxgiFactory); ID3D11Texture2D* backBuffer; ThrowIfFailed(mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), reinterpret_cast<void**>(&backBuffer)), "IDXGISwapChain::GetBuffer() failed."); if (FAILED(hr = mDirect3DDevice->CreateRenderTargetView(backBuffer, nullptr, &mRenderTargetView))) { ReleaseObject(backBuffer); throw GameException("IDXGIDevice::CreateRenderTargetView() failed.", hr); } ReleaseObject(backBuffer); D3D11_TEXTURE2D_DESC depthStencilDesc; ZeroMemory(&depthStencilDesc, sizeof(depthStencilDesc)); depthStencilDesc.Width = mScreenWidth; depthStencilDesc.Height = mScreenHeight; depthStencilDesc.MipLevels = 1; depthStencilDesc.ArraySize = 1; depthStencilDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; depthStencilDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL; depthStencilDesc.Usage = D3D11_USAGE_DEFAULT; depthStencilDesc.SampleDesc.Count = multiSamplingCount; depthStencilDesc.SampleDesc.Quality = multiSamplingQualityLevels - 1; ThrowIfFailed(mDirect3DDevice->CreateTexture2D(&depthStencilDesc, nullptr, &mDepthStencilBuffer), "IDXGIDevice::CreateTexture2D() failed."); ThrowIfFailed(mDirect3DDevice->CreateDepthStencilView(mDepthStencilBuffer, nullptr, &mDepthStencilView), "IDXGIDevice::CreateDepthStencilView() failed."); D3D11_VIEWPORT viewport; viewport.TopLeftX = 0.0f; viewport.TopLeftY = 0.0f; viewport.Width = static_cast<float>(mScreenWidth); viewport.Height = static_cast<float>(mScreenHeight); viewport.MinDepth = 0.0f; viewport.MaxDepth = 1.0f; mDirect3DDeviceContext->OMSetRenderTargets(1, &mRenderTargetView, mDepthStencilView); mDirect3DDeviceContext->RSSetViewports(1, &viewport); }
// ´ÙÀÌ·ºÆ® °´Ã¼ ÃʱâÈ // - °¢Á¾±â´ÉÀ» Áö¿øÇϴ°¡ üũÇÏ°í(´ÙÁß »ùÇøµ µî), ½º¿ÒüÀÎ, ÄÄ °´Ã¼ µîÀ» »ý¼º, Á¦°ÅÇÑ´Ù. bool cInitD3D::InitDirect3D() { // µð¹ÙÀ̽º, µð¹ÙÀ̽º ÄÁÅؽºÆ® »ý¼º UINT createDeviceFlags = 0; #if defined(DEBUG) || defined(_DEBUG) createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG; #endif D3D_FEATURE_LEVEL featureLevel; HRESULT hr = D3D11CreateDevice( 0, // default adapter md3dDriverType, 0, // no software device createDeviceFlags, 0, 0, // default feature level array D3D11_SDK_VERSION, &md3dDevice, &featureLevel, &md3dImmediateContext); if (FAILED(hr)) { MessageBox(0, L"D3D11CreateDevice Failed.", 0, 0); return false; } if (featureLevel != D3D_FEATURE_LEVEL_11_0) { MessageBox(0, L"Direct3D Feature Level 11 unsupported.", 0, 0); return false; } // ¹é¹öÆÛ¿¡ 4X MSAA Ç°Áú Áö¿øÀ» È®ÀÎ HR(md3dDevice->CheckMultisampleQualityLevels( DXGI_FORMAT_R8G8B8A8_UNORM, 4, &m4xMsaaQuality)); assert(m4xMsaaQuality > 0); // ½º¿ÒüÀÎ »ý¼º DXGI_SWAP_CHAIN_DESC sd; sd.BufferDesc.Width = mClientWidth; sd.BufferDesc.Height = mClientHeight; 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; // ´ÙÁß »ùÇøµ À¯¹« (Use 4X MSAA?) if (mEnable4xMsaa) { sd.SampleDesc.Count = 4; sd.SampleDesc.Quality = m4xMsaaQuality - 1; } // No MSAA else { sd.SampleDesc.Count = 1; sd.SampleDesc.Quality = 0; } // ¹öÆÛ »ý¼º sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; sd.BufferCount = 1; sd.OutputWindow = mhMainWnd; sd.Windowed = true; sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; sd.Flags = 0; // µð¹ÙÀ̽º »ý¼º IDXGIDevice* dxgiDevice = 0; HR(md3dDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice)); IDXGIAdapter* dxgiAdapter = 0; HR(dxgiDevice->GetParent(__uuidof(IDXGIAdapter), (void**)&dxgiAdapter)); IDXGIFactory* dxgiFactory = 0; HR(dxgiAdapter->GetParent(__uuidof(IDXGIFactory), (void**)&dxgiFactory)); // ½º¿ÒüÀÎ »ý¼º ¹× È®ÀÎ HR(dxgiFactory->CreateSwapChain(md3dDevice, &sd, &mSwapChain)); // ÄÄ °´Ã¼ »èÁ¦ ReleaseCOM(dxgiDevice); ReleaseCOM(dxgiAdapter); ReleaseCOM(dxgiFactory); // â Å©±â Á¶Àý (ÄÚµå Áߺ¹ ÇÇÇϱâ À§ÇØ »ç¿ë) OnResize(); return true; }
//-------------------------------------------------------------------------------------- // Create Direct3D device and swap chain //-------------------------------------------------------------------------------------- HRESULT InitDevice() { HRESULT hr = S_OK; RECT rc; GetClientRect( g_hWnd, &rc ); UINT width = rc.right - rc.left; UINT height = rc.bottom - rc.top; UINT createDeviceFlags = 0; #ifdef _DEBUG createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG; #endif D3D_DRIVER_TYPE driverTypes[] = { D3D_DRIVER_TYPE_HARDWARE, D3D_DRIVER_TYPE_WARP, D3D_DRIVER_TYPE_REFERENCE, }; UINT numDriverTypes = ARRAYSIZE( driverTypes ); D3D_FEATURE_LEVEL featureLevels[] = { D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0, }; UINT numFeatureLevels = ARRAYSIZE( featureLevels ); for( UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++ ) { g_driverType = driverTypes[driverTypeIndex]; hr = D3D11CreateDevice( nullptr, g_driverType, nullptr, createDeviceFlags, featureLevels, numFeatureLevels, D3D11_SDK_VERSION, &g_pd3dDevice, &g_featureLevel, &g_pImmediateContext ); if ( hr == E_INVALIDARG ) { // DirectX 11.0 platforms will not recognize D3D_FEATURE_LEVEL_11_1 so we need to retry without it hr = D3D11CreateDevice( nullptr, g_driverType, nullptr, createDeviceFlags, &featureLevels[1], numFeatureLevels - 1, D3D11_SDK_VERSION, &g_pd3dDevice, &g_featureLevel, &g_pImmediateContext ); } if( SUCCEEDED( hr ) ) break; } if( FAILED( hr ) ) return hr; // Obtain DXGI factory from device (since we used nullptr for pAdapter above) IDXGIFactory1* dxgiFactory = nullptr; { IDXGIDevice* dxgiDevice = nullptr; hr = g_pd3dDevice->QueryInterface( __uuidof(IDXGIDevice), reinterpret_cast<void**>(&dxgiDevice) ); if (SUCCEEDED(hr)) { IDXGIAdapter* adapter = nullptr; hr = dxgiDevice->GetAdapter(&adapter); if (SUCCEEDED(hr)) { hr = adapter->GetParent( __uuidof(IDXGIFactory1), reinterpret_cast<void**>(&dxgiFactory) ); adapter->Release(); } dxgiDevice->Release(); } } if (FAILED(hr)) return hr; // Create swap chain IDXGIFactory2* dxgiFactory2 = nullptr; hr = dxgiFactory->QueryInterface( __uuidof(IDXGIFactory2), reinterpret_cast<void**>(&dxgiFactory2) ); if ( dxgiFactory2 ) { // DirectX 11.1 or later hr = g_pd3dDevice->QueryInterface( __uuidof(ID3D11Device1), reinterpret_cast<void**>(&g_pd3dDevice1) ); if (SUCCEEDED(hr)) { (void) g_pImmediateContext->QueryInterface( __uuidof(ID3D11DeviceContext1), reinterpret_cast<void**>(&g_pImmediateContext1) ); } DXGI_SWAP_CHAIN_DESC1 sd; ZeroMemory(&sd, sizeof(sd)); sd.Width = width; sd.Height = height; sd.Format = DXGI_FORMAT_R8G8B8A8_UNORM; sd.SampleDesc.Count = 1; sd.SampleDesc.Quality = 0; sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; sd.BufferCount = 1; hr = dxgiFactory2->CreateSwapChainForHwnd( g_pd3dDevice, g_hWnd, &sd, nullptr, nullptr, &g_pSwapChain1 ); if (SUCCEEDED(hr)) { hr = g_pSwapChain1->QueryInterface( __uuidof(IDXGISwapChain), reinterpret_cast<void**>(&g_pSwapChain) ); } dxgiFactory2->Release(); } else { // DirectX 11.0 systems DXGI_SWAP_CHAIN_DESC sd; ZeroMemory(&sd, sizeof(sd)); sd.BufferCount = 1; sd.BufferDesc.Width = width; sd.BufferDesc.Height = height; sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; sd.BufferDesc.RefreshRate.Numerator = 60; sd.BufferDesc.RefreshRate.Denominator = 1; sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; sd.OutputWindow = g_hWnd; sd.SampleDesc.Count = 1; sd.SampleDesc.Quality = 0; sd.Windowed = TRUE; hr = dxgiFactory->CreateSwapChain( g_pd3dDevice, &sd, &g_pSwapChain ); } // Note this tutorial doesn't handle full-screen swapchains so we block the ALT+ENTER shortcut dxgiFactory->MakeWindowAssociation( g_hWnd, DXGI_MWA_NO_ALT_ENTER ); dxgiFactory->Release(); if (FAILED(hr)) return hr; // Create a render target view ID3D11Texture2D* pBackBuffer = nullptr; hr = g_pSwapChain->GetBuffer( 0, __uuidof( ID3D11Texture2D ), reinterpret_cast<void**>( &pBackBuffer ) ); if( FAILED( hr ) ) return hr; hr = g_pd3dDevice->CreateRenderTargetView( pBackBuffer, nullptr, &g_pRenderTargetView ); pBackBuffer->Release(); if( FAILED( hr ) ) return hr; // Create depth stencil texture D3D11_TEXTURE2D_DESC descDepth; ZeroMemory( &descDepth, sizeof(descDepth) ); descDepth.Width = width; descDepth.Height = height; descDepth.MipLevels = 1; descDepth.ArraySize = 1; descDepth.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; descDepth.SampleDesc.Count = 1; descDepth.SampleDesc.Quality = 0; descDepth.Usage = D3D11_USAGE_DEFAULT; descDepth.BindFlags = D3D11_BIND_DEPTH_STENCIL; descDepth.CPUAccessFlags = 0; descDepth.MiscFlags = 0; hr = g_pd3dDevice->CreateTexture2D( &descDepth, nullptr, &g_pDepthStencil ); if( FAILED( hr ) ) return hr; // Create the depth stencil view D3D11_DEPTH_STENCIL_VIEW_DESC descDSV; ZeroMemory( &descDSV, sizeof(descDSV) ); descDSV.Format = descDepth.Format; descDSV.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; descDSV.Texture2D.MipSlice = 0; hr = g_pd3dDevice->CreateDepthStencilView( g_pDepthStencil, &descDSV, &g_pDepthStencilView ); if( FAILED( hr ) ) return hr; g_pImmediateContext->OMSetRenderTargets( 1, &g_pRenderTargetView, g_pDepthStencilView ); // Setup the viewport D3D11_VIEWPORT vp; vp.Width = (FLOAT)width; vp.Height = (FLOAT)height; vp.MinDepth = 0.0f; vp.MaxDepth = 1.0f; vp.TopLeftX = 0; vp.TopLeftY = 0; g_pImmediateContext->RSSetViewports( 1, &vp ); // Compile the vertex shader ID3DBlob* pVSBlob = nullptr; hr = CompileShaderFromFile( L"Tutorial07.fx", "VS", "vs_4_0", &pVSBlob ); if( FAILED( hr ) ) { MessageBox( nullptr, L"The FX file cannot be compiled. Please run this executable from the directory that contains the FX file.", L"Error", MB_OK ); return hr; } // Create the vertex shader hr = g_pd3dDevice->CreateVertexShader( pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), nullptr, &g_pVertexShader ); if( FAILED( hr ) ) { pVSBlob->Release(); return hr; } // Define the input layout D3D11_INPUT_ELEMENT_DESC layout[] = { { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }, }; UINT numElements = ARRAYSIZE( layout ); // Create the input layout hr = g_pd3dDevice->CreateInputLayout( layout, numElements, pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), &g_pVertexLayout ); pVSBlob->Release(); if( FAILED( hr ) ) return hr; // Set the input layout g_pImmediateContext->IASetInputLayout( g_pVertexLayout ); // Compile the pixel shader ID3DBlob* pPSBlob = nullptr; hr = CompileShaderFromFile( L"Tutorial07.fx", "PS", "ps_4_0", &pPSBlob ); if( FAILED( hr ) ) { MessageBox( nullptr, L"The FX file cannot be compiled. Please run this executable from the directory that contains the FX file.", L"Error", MB_OK ); return hr; } // Create the pixel shader hr = g_pd3dDevice->CreatePixelShader( pPSBlob->GetBufferPointer(), pPSBlob->GetBufferSize(), nullptr, &g_pPixelShader ); pPSBlob->Release(); if( FAILED( hr ) ) return hr; // Create vertex buffer SimpleVertex vertices[] = { { XMFLOAT3( -1.0f, 1.0f, -1.0f ), XMFLOAT2( 1.0f, 0.0f ) }, { XMFLOAT3( 1.0f, 1.0f, -1.0f ), XMFLOAT2( 0.0f, 0.0f ) }, { XMFLOAT3( 1.0f, 1.0f, 1.0f ), XMFLOAT2( 0.0f, 1.0f ) }, { XMFLOAT3( -1.0f, 1.0f, 1.0f ), XMFLOAT2( 1.0f, 1.0f ) }, { XMFLOAT3( -1.0f, -1.0f, -1.0f ), XMFLOAT2( 0.0f, 0.0f ) }, { XMFLOAT3( 1.0f, -1.0f, -1.0f ), XMFLOAT2( 1.0f, 0.0f ) }, { XMFLOAT3( 1.0f, -1.0f, 1.0f ), XMFLOAT2( 1.0f, 1.0f ) }, { XMFLOAT3( -1.0f, -1.0f, 1.0f ), XMFLOAT2( 0.0f, 1.0f ) }, { XMFLOAT3( -1.0f, -1.0f, 1.0f ), XMFLOAT2( 0.0f, 1.0f ) }, { XMFLOAT3( -1.0f, -1.0f, -1.0f ), XMFLOAT2( 1.0f, 1.0f ) }, { XMFLOAT3( -1.0f, 1.0f, -1.0f ), XMFLOAT2( 1.0f, 0.0f ) }, { XMFLOAT3( -1.0f, 1.0f, 1.0f ), XMFLOAT2( 0.0f, 0.0f ) }, { XMFLOAT3( 1.0f, -1.0f, 1.0f ), XMFLOAT2( 1.0f, 1.0f ) }, { XMFLOAT3( 1.0f, -1.0f, -1.0f ), XMFLOAT2( 0.0f, 1.0f ) }, { XMFLOAT3( 1.0f, 1.0f, -1.0f ), XMFLOAT2( 0.0f, 0.0f ) }, { XMFLOAT3( 1.0f, 1.0f, 1.0f ), XMFLOAT2( 1.0f, 0.0f ) }, { XMFLOAT3( -1.0f, -1.0f, -1.0f ), XMFLOAT2( 0.0f, 1.0f ) }, { XMFLOAT3( 1.0f, -1.0f, -1.0f ), XMFLOAT2( 1.0f, 1.0f ) }, { XMFLOAT3( 1.0f, 1.0f, -1.0f ), XMFLOAT2( 1.0f, 0.0f ) }, { XMFLOAT3( -1.0f, 1.0f, -1.0f ), XMFLOAT2( 0.0f, 0.0f ) }, { XMFLOAT3( -1.0f, -1.0f, 1.0f ), XMFLOAT2( 1.0f, 1.0f ) }, { XMFLOAT3( 1.0f, -1.0f, 1.0f ), XMFLOAT2( 0.0f, 1.0f ) }, { XMFLOAT3( 1.0f, 1.0f, 1.0f ), XMFLOAT2( 0.0f, 0.0f ) }, { XMFLOAT3( -1.0f, 1.0f, 1.0f ), XMFLOAT2( 1.0f, 0.0f ) }, }; D3D11_BUFFER_DESC bd; ZeroMemory( &bd, sizeof(bd) ); bd.Usage = D3D11_USAGE_DEFAULT; bd.ByteWidth = sizeof( SimpleVertex ) * 24; bd.BindFlags = D3D11_BIND_VERTEX_BUFFER; bd.CPUAccessFlags = 0; D3D11_SUBRESOURCE_DATA InitData; ZeroMemory( &InitData, sizeof(InitData) ); InitData.pSysMem = vertices; hr = g_pd3dDevice->CreateBuffer( &bd, &InitData, &g_pVertexBuffer ); if( FAILED( hr ) ) return hr; // Set vertex buffer UINT stride = sizeof( SimpleVertex ); UINT offset = 0; g_pImmediateContext->IASetVertexBuffers( 0, 1, &g_pVertexBuffer, &stride, &offset ); // Create index buffer // Create vertex buffer WORD indices[] = { 3,1,0, 2,1,3, 6,4,5, 7,4,6, 11,9,8, 10,9,11, 14,12,13, 15,12,14, 19,17,16, 18,17,19, 22,20,21, 23,20,22 }; bd.Usage = D3D11_USAGE_DEFAULT; bd.ByteWidth = sizeof( WORD ) * 36; bd.BindFlags = D3D11_BIND_INDEX_BUFFER; bd.CPUAccessFlags = 0; InitData.pSysMem = indices; hr = g_pd3dDevice->CreateBuffer( &bd, &InitData, &g_pIndexBuffer ); if( FAILED( hr ) ) return hr; // Set index buffer g_pImmediateContext->IASetIndexBuffer( g_pIndexBuffer, DXGI_FORMAT_R16_UINT, 0 ); // Set primitive topology g_pImmediateContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST ); // Create the constant buffers bd.Usage = D3D11_USAGE_DEFAULT; bd.ByteWidth = sizeof(CBNeverChanges); bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER; bd.CPUAccessFlags = 0; hr = g_pd3dDevice->CreateBuffer( &bd, nullptr, &g_pCBNeverChanges ); if( FAILED( hr ) ) return hr; bd.ByteWidth = sizeof(CBChangeOnResize); hr = g_pd3dDevice->CreateBuffer( &bd, nullptr, &g_pCBChangeOnResize ); if( FAILED( hr ) ) return hr; bd.ByteWidth = sizeof(CBChangesEveryFrame); hr = g_pd3dDevice->CreateBuffer( &bd, nullptr, &g_pCBChangesEveryFrame ); if( FAILED( hr ) ) return hr; // Load the Texture hr = CreateDDSTextureFromFile( g_pd3dDevice, L"seafloor.dds", nullptr, &g_pTextureRV ); if( FAILED( hr ) ) return hr; // Create the sample state D3D11_SAMPLER_DESC sampDesc; ZeroMemory( &sampDesc, sizeof(sampDesc) ); sampDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP; sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP; sampDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP; sampDesc.ComparisonFunc = D3D11_COMPARISON_NEVER; sampDesc.MinLOD = 0; sampDesc.MaxLOD = D3D11_FLOAT32_MAX; hr = g_pd3dDevice->CreateSamplerState( &sampDesc, &g_pSamplerLinear ); if( FAILED( hr ) ) return hr; // Initialize the world matrices g_World = XMMatrixIdentity(); // Initialize the view matrix XMVECTOR Eye = XMVectorSet( 0.0f, 3.0f, -6.0f, 0.0f ); XMVECTOR At = XMVectorSet( 0.0f, 1.0f, 0.0f, 0.0f ); XMVECTOR Up = XMVectorSet( 0.0f, 1.0f, 0.0f, 0.0f ); g_View = XMMatrixLookAtLH( Eye, At, Up ); CBNeverChanges cbNeverChanges; cbNeverChanges.mView = XMMatrixTranspose( g_View ); g_pImmediateContext->UpdateSubresource( g_pCBNeverChanges, 0, nullptr, &cbNeverChanges, 0, 0 ); // Initialize the projection matrix g_Projection = XMMatrixPerspectiveFovLH( XM_PIDIV4, width / (FLOAT)height, 0.01f, 100.0f ); CBChangeOnResize cbChangesOnResize; cbChangesOnResize.mProjection = XMMatrixTranspose( g_Projection ); g_pImmediateContext->UpdateSubresource( g_pCBChangeOnResize, 0, nullptr, &cbChangesOnResize, 0, 0 ); #ifdef USE_OPENVR // OpenVR. // Loading the SteamVR Runtime vr::EVRInitError eError = vr::VRInitError_None; openvr_system_ = vr::VR_Init(&eError, vr::VRApplication_Scene); if (eError != vr::VRInitError_None) { openvr_system_ = nullptr; ShowMessageBoxAndExit("Unable to init VR runtime: %s", vr::VR_GetVRInitErrorAsEnglishDescription(eError)); } if (!vr::VRCompositor()) { ShowMessageBoxAndExit("Failed to obtain compositor."); } #endif return S_OK; }
bool Direct3D::Initialize(HWND* hWnd) { mcWidth = &Settings->GetData()->mWidth; mcHeight = &Settings->GetData()->mHeight; UINT createDeviceFlags = 0; #if defined(_DEBUG) | (DEBUG) createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG; #endif D3D_FEATURE_LEVEL featureLevel; if( FAILED ( D3D11CreateDevice( nullptr, mDriverType, nullptr, 0, nullptr, 0, D3D11_SDK_VERSION, &mDevice, &featureLevel, &mDevCon))) { cout << "D3D11CreateDevice failed." << endl; return false; } if(featureLevel != D3D_FEATURE_LEVEL_11_0) { cout << "Direct3D feature level 11 unsupported." << endl; return false; } mDevice->CheckMultisampleQualityLevels(DXGI_FORMAT_R8G8B8A8_UNORM, 4, &m4xMSAAQuality); assert(m4xMSAAQuality > 0); DXGI_SWAP_CHAIN_DESC sd = {}; sd.BufferDesc.Width = *mcWidth; sd.BufferDesc.Height = *mcHeight; 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 (mEnable4xMsaa) { 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; // Use back buffer as render target sd.BufferCount = 1; // Number of back buffers to use in swap chain sd.OutputWindow = *hWnd; // Specify window we render into sd.Windowed = !Settings->GetData()->mIsFullscreen; // Windowed mode or full-screen mode sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; // Let display driver select most efficient presentation method sd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; IDXGIDevice* dxgiDevice = nullptr; mDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice); IDXGIAdapter* dxgiAdapter = nullptr; dxgiDevice->GetParent(__uuidof(IDXGIAdapter),(void**)&dxgiAdapter); IDXGIFactory* dxgiFactory = nullptr; dxgiAdapter->GetParent(__uuidof(IDXGIFactory), (void**)&dxgiFactory); dxgiFactory->CreateSwapChain(mDevice, &sd, &mSwapChain); SafeRelease(dxgiDevice); SafeRelease(dxgiAdapter); SafeRelease(dxgiFactory); this->OnResize(); return true; }
// Direct3Dの初期化 HRESULT InitD3D( void ) { HRESULT hr = S_OK; D3D_FEATURE_LEVEL FeatureLevelsRequested[6] = { D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0, D3D_FEATURE_LEVEL_9_3, D3D_FEATURE_LEVEL_9_2, D3D_FEATURE_LEVEL_9_1 }; UINT numLevelsRequested = 6; D3D_FEATURE_LEVEL FeatureLevelsSupported; // デバイス作成 hr = D3D11CreateDevice( NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, FeatureLevelsRequested, numLevelsRequested, D3D11_SDK_VERSION, &g_pd3dDevice, &FeatureLevelsSupported, &g_pImmediateContext ); if( FAILED ( hr ) ) { return hr; } // ファクトリの取得 IDXGIDevice * pDXGIDevice; hr = g_pd3dDevice->QueryInterface( __uuidof( IDXGIDevice ), ( void ** )&pDXGIDevice ); IDXGIAdapter * pDXGIAdapter; hr = pDXGIDevice->GetParent( __uuidof( IDXGIAdapter ), ( void ** )&pDXGIAdapter ); IDXGIFactory * pIDXGIFactory; pDXGIAdapter->GetParent( __uuidof( IDXGIFactory ), ( void ** )&pIDXGIFactory); // スワップチェインの作成 DXGI_SWAP_CHAIN_DESC sd; ZeroMemory( &sd, sizeof( sd ) ); sd.BufferCount = 1; sd.BufferDesc.Width = g_nClientWidth; sd.BufferDesc.Height = g_nClientHeight; sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; sd.BufferDesc.RefreshRate.Numerator = 60; sd.BufferDesc.RefreshRate.Denominator = 1; sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; sd.OutputWindow = g_hWnd; sd.SampleDesc.Count = 1; sd.SampleDesc.Quality = 0; sd.Windowed = TRUE; hr = pIDXGIFactory->CreateSwapChain( g_pd3dDevice, &sd, &g_pSwapChain ); pDXGIDevice->Release(); pDXGIAdapter->Release(); pIDXGIFactory->Release(); if( FAILED ( hr ) ) { return hr; } // レンダリングターゲットの生成 ID3D11Texture2D *pBackBuffer = NULL; D3D11_TEXTURE2D_DESC BackBufferSurfaceDesc; hr = g_pSwapChain->GetBuffer( 0, __uuidof( ID3D11Texture2D ), ( LPVOID* )&pBackBuffer ); if ( FAILED( hr ) ) { MessageBox( NULL, _T( "Can't get backbuffer." ), _T( "Error" ), MB_OK ); return hr; } pBackBuffer->GetDesc( &BackBufferSurfaceDesc ); hr = g_pd3dDevice->CreateRenderTargetView( pBackBuffer, NULL, &g_pRTV ); SAFE_RELEASE( pBackBuffer ); if ( FAILED( hr ) ) { MessageBox( NULL, _T( "Can't create render target view." ), _T( "Error" ), MB_OK ); return hr; } g_pImmediateContext->OMSetRenderTargets( 1, &g_pRTV, NULL ); // ラスタライザの設定 D3D11_RASTERIZER_DESC drd; ZeroMemory( &drd, sizeof( drd ) ); drd.FillMode = D3D11_FILL_SOLID; drd.CullMode = D3D11_CULL_NONE; drd.FrontCounterClockwise = FALSE; drd.DepthClipEnable = TRUE; hr = g_pd3dDevice->CreateRasterizerState( &drd, &g_pRS ); if ( FAILED( hr ) ) { MessageBox( NULL, _T( "Can't create rasterizer state." ), _T( "Error" ), MB_OK ); return hr; } g_pImmediateContext->RSSetState( g_pRS ); // ビューポートの設定 D3D11_VIEWPORT vp; vp.Width = ( FLOAT )g_nClientWidth; vp.Height = ( FLOAT )g_nClientHeight; vp.MinDepth = 0.0f; vp.MaxDepth = 1.0f; vp.TopLeftX = 0.0f; vp.TopLeftY = 0.0f; g_pImmediateContext->RSSetViewports( 1, &vp ); return S_OK; }
//[-------------------------------------------------------] //[ Public methods ] //[-------------------------------------------------------] SwapChain::SwapChain(Direct3D11Renderer &direct3D11Renderer, handle nativeWindowHandle) : ISwapChain(direct3D11Renderer), mDxgiSwapChain(nullptr), mD3D11RenderTargetView(nullptr), mD3D11DepthStencilView(nullptr) { // Get the Direct3D 11 device instance ID3D11Device *d3d11Device = direct3D11Renderer.getD3D11Device(); // Get the native window handle const HWND hWnd = reinterpret_cast<HWND>(nativeWindowHandle); // Get a DXGI factory instance IDXGIFactory1 *dxgiFactory1 = nullptr; { IDXGIDevice *dxgiDevice = nullptr; IDXGIAdapter *dxgiAdapter = nullptr; d3d11Device->QueryInterface(IID_PPV_ARGS(&dxgiDevice)); dxgiDevice->GetAdapter(&dxgiAdapter); dxgiAdapter->GetParent(IID_PPV_ARGS(&dxgiFactory1)); dxgiAdapter->Release(); dxgiDevice->Release(); } // Get the width and height of the given native window and ensure they are never ever zero // -> See "getSafeWidthAndHeight()"-method comments for details long width = 1; long height = 1; { // Get the client rectangle of the given native window RECT rect; ::GetClientRect(hWnd, &rect); // Get the width and height... width = rect.right - rect.left; height = rect.bottom - rect.top; // ... and ensure that none of them is ever zero if (width < 1) { width = 1; } if (height < 1) { height = 1; } } // Create the swap chain DXGI_SWAP_CHAIN_DESC dxgiSwapChainDesc = {}; dxgiSwapChainDesc.BufferCount = 1; dxgiSwapChainDesc.BufferDesc.Width = static_cast<UINT>(width); dxgiSwapChainDesc.BufferDesc.Height = static_cast<UINT>(height); dxgiSwapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; dxgiSwapChainDesc.BufferDesc.RefreshRate.Numerator = 60; dxgiSwapChainDesc.BufferDesc.RefreshRate.Denominator = 1; dxgiSwapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; dxgiSwapChainDesc.OutputWindow = hWnd; dxgiSwapChainDesc.SampleDesc.Count = 1; dxgiSwapChainDesc.SampleDesc.Quality = 0; dxgiSwapChainDesc.Windowed = TRUE; dxgiFactory1->CreateSwapChain(d3d11Device, &dxgiSwapChainDesc, &mDxgiSwapChain); // Disable alt-return for automatic fullscreen state change // -> We handle this manually to have more control over it dxgiFactory1->MakeWindowAssociation(hWnd, DXGI_MWA_NO_ALT_ENTER); // Release our DXGI factory dxgiFactory1->Release(); // Create the Direct3D 11 views if (nullptr != mDxgiSwapChain) { createDirect3D11Views(); } // Assign a default name to the resource for debugging purposes #ifndef DIRECT3D11RENDERER_NO_DEBUG setDebugName("Swap chain"); #endif }
//-------------------------------------------------------------------------------------- // Create Direct3D device and swap chain //-------------------------------------------------------------------------------------- HRESULT InitDevice() { HRESULT hr = S_OK; RECT rc; GetClientRect( g_hWnd, &rc ); UINT width = rc.right - rc.left; UINT height = rc.bottom - rc.top; UINT createDeviceFlags = 0; #ifdef _DEBUG createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG; #endif D3D_DRIVER_TYPE driverTypes[] = { D3D_DRIVER_TYPE_HARDWARE, D3D_DRIVER_TYPE_WARP, D3D_DRIVER_TYPE_REFERENCE, }; UINT numDriverTypes = ARRAYSIZE( driverTypes ); D3D_FEATURE_LEVEL featureLevels[] = { D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0, }; UINT numFeatureLevels = ARRAYSIZE( featureLevels ); for( UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++ ) { g_driverType = driverTypes[driverTypeIndex]; hr = D3D11CreateDevice( nullptr, g_driverType, nullptr, createDeviceFlags, featureLevels, numFeatureLevels, D3D11_SDK_VERSION, &g_pd3dDevice, &g_featureLevel, &g_pImmediateContext ); if ( hr == E_INVALIDARG ) { // DirectX 11.0 platforms will not recognize D3D_FEATURE_LEVEL_11_1 so we need to retry without it hr = D3D11CreateDevice( nullptr, g_driverType, nullptr, createDeviceFlags, &featureLevels[1], numFeatureLevels - 1, D3D11_SDK_VERSION, &g_pd3dDevice, &g_featureLevel, &g_pImmediateContext ); } if( SUCCEEDED( hr ) ) break; } if( FAILED( hr ) ) return hr; // Obtain DXGI factory from device (since we used nullptr for pAdapter above) IDXGIFactory1* dxgiFactory = nullptr; { IDXGIDevice* dxgiDevice = nullptr; hr = g_pd3dDevice->QueryInterface( __uuidof(IDXGIDevice), reinterpret_cast<void**>(&dxgiDevice) ); if (SUCCEEDED(hr)) { IDXGIAdapter* adapter = nullptr; hr = dxgiDevice->GetAdapter(&adapter); if (SUCCEEDED(hr)) { hr = adapter->GetParent( __uuidof(IDXGIFactory1), reinterpret_cast<void**>(&dxgiFactory) ); adapter->Release(); } dxgiDevice->Release(); } } if (FAILED(hr)) return hr; // Create swap chain IDXGIFactory2* dxgiFactory2 = nullptr; hr = dxgiFactory->QueryInterface( __uuidof(IDXGIFactory2), reinterpret_cast<void**>(&dxgiFactory2) ); if ( dxgiFactory2 ) { // DirectX 11.1 or later hr = g_pd3dDevice->QueryInterface( __uuidof(ID3D11Device1), reinterpret_cast<void**>(&g_pd3dDevice1) ); if (SUCCEEDED(hr)) { (void) g_pImmediateContext->QueryInterface( __uuidof(ID3D11DeviceContext1), reinterpret_cast<void**>(&g_pImmediateContext1) ); } DXGI_SWAP_CHAIN_DESC1 sd; ZeroMemory(&sd, sizeof(sd)); sd.Width = width; sd.Height = height; sd.Format = DXGI_FORMAT_R8G8B8A8_UNORM; sd.SampleDesc.Count = 1; sd.SampleDesc.Quality = 0; sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; sd.BufferCount = 1; hr = dxgiFactory2->CreateSwapChainForHwnd( g_pd3dDevice, g_hWnd, &sd, nullptr, nullptr, &g_pSwapChain1 ); if (SUCCEEDED(hr)) { hr = g_pSwapChain1->QueryInterface( __uuidof(IDXGISwapChain), reinterpret_cast<void**>(&g_pSwapChain) ); } dxgiFactory2->Release(); } else { // DirectX 11.0 systems DXGI_SWAP_CHAIN_DESC sd; ZeroMemory(&sd, sizeof(sd)); sd.BufferCount = 1; sd.BufferDesc.Width = width; sd.BufferDesc.Height = height; sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; sd.BufferDesc.RefreshRate.Numerator = 60; sd.BufferDesc.RefreshRate.Denominator = 1; sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; sd.OutputWindow = g_hWnd; sd.SampleDesc.Count = 1; sd.SampleDesc.Quality = 0; sd.Windowed = TRUE; hr = dxgiFactory->CreateSwapChain( g_pd3dDevice, &sd, &g_pSwapChain ); } // Note this tutorial doesn't handle full-screen swapchains so we block the ALT+ENTER shortcut dxgiFactory->MakeWindowAssociation( g_hWnd, DXGI_MWA_NO_ALT_ENTER ); dxgiFactory->Release(); if (FAILED(hr)) return hr; // Create a render target view ID3D11Texture2D* pBackBuffer = nullptr; hr = g_pSwapChain->GetBuffer( 0, __uuidof( ID3D11Texture2D ), reinterpret_cast<void**>( &pBackBuffer ) ); if( FAILED( hr ) ) return hr; hr = g_pd3dDevice->CreateRenderTargetView( pBackBuffer, nullptr, &g_pRenderTargetView ); pBackBuffer->Release(); if( FAILED( hr ) ) return hr; g_pImmediateContext->OMSetRenderTargets( 1, &g_pRenderTargetView, nullptr ); // Setup the viewport D3D11_VIEWPORT vp; vp.Width = (FLOAT)width; vp.Height = (FLOAT)height; vp.MinDepth = 0.0f; vp.MaxDepth = 1.0f; vp.TopLeftX = 0; vp.TopLeftY = 0; g_pImmediateContext->RSSetViewports( 1, &vp ); // Compile the vertex shader ID3DBlob* pVSBlob = nullptr; hr = CompileShaderFromFile( L"Tutorial02.fx", "VS", "vs_4_0", &pVSBlob ); if( FAILED( hr ) ) { MessageBox( nullptr, "The FX file cannot be compiled. Please run this executable from the directory that contains the FX file.", "Error", MB_OK ); return hr; } // Create the vertex shader hr = g_pd3dDevice->CreateVertexShader( pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), nullptr, &g_pVertexShader ); if( FAILED( hr ) ) { pVSBlob->Release(); return hr; } // Define the input layout D3D11_INPUT_ELEMENT_DESC layout[] = { { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, }; UINT numElements = ARRAYSIZE( layout ); // Create the input layout hr = g_pd3dDevice->CreateInputLayout( layout, numElements, pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), &g_pVertexLayout ); pVSBlob->Release(); if( FAILED( hr ) ) return hr; // Set the input layout g_pImmediateContext->IASetInputLayout( g_pVertexLayout ); // Compile the pixel shader ID3DBlob* pPSBlob = nullptr; hr = CompileShaderFromFile( L"Tutorial02.fx", "PS", "ps_4_0", &pPSBlob ); if( FAILED( hr ) ) { MessageBox( nullptr, "The FX file cannot be compiled. Please run this executable from the directory that contains the FX file.", "Error", MB_OK ); return hr; } // Create the pixel shader hr = g_pd3dDevice->CreatePixelShader( pPSBlob->GetBufferPointer(), pPSBlob->GetBufferSize(), nullptr, &g_pPixelShader ); pPSBlob->Release(); if( FAILED( hr ) ) return hr; // Create vertex buffer SimpleVertex vertices[] = { XMFLOAT3( 0.0f, 0.5f, 0.5f ), XMFLOAT3( 0.5f, -0.5f, 0.5f ), XMFLOAT3( -0.5f, -0.5f, 0.5f ), }; D3D11_BUFFER_DESC bd; ZeroMemory( &bd, sizeof(bd) ); bd.Usage = D3D11_USAGE_DEFAULT; bd.ByteWidth = sizeof( SimpleVertex ) * 3; bd.BindFlags = D3D11_BIND_VERTEX_BUFFER; bd.CPUAccessFlags = 0; D3D11_SUBRESOURCE_DATA InitData; ZeroMemory( &InitData, sizeof(InitData) ); InitData.pSysMem = vertices; hr = g_pd3dDevice->CreateBuffer( &bd, &InitData, &g_pVertexBuffer ); if( FAILED( hr ) ) return hr; // Set vertex buffer UINT stride = sizeof( SimpleVertex ); UINT offset = 0; g_pImmediateContext->IASetVertexBuffers( 0, 1, &g_pVertexBuffer, &stride, &offset ); // Set primitive topology g_pImmediateContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST ); return S_OK; }
// // FUNCTION: GraphicsDeviceInterface::Initialize() // // PURPOSE: Initializes Direct3D // bool GraphicsDeviceInterface::Initialize(HWND hWnd, WindowSize* wind) { HRESULT hResult; // Clear the struct ZeroMemory(&scd, sizeof(DXGI_SWAP_CHAIN_DESC)); // Set the swap chain values scd.BufferCount = 1; // one back buffer scd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; // use 32 bit color scd.BufferDesc.Width = wind->getWidth(); // set width using windowSize object scd.BufferDesc.Height = wind->getHeight(); // set height using windowSize object scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; // swap chain is output scd.OutputWindow = hWnd; // window to render into scd.SampleDesc.Count = 4; // use 4 multisamples for antialiasing scd.Windowed = wind->getWindowed(); // Sets windowed mode scd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; // Allow full-screen switching // Create the device, context, and swap chain hResult = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, NULL, //D3D_FEATURE_LEVEL_10_0, NULL, NULL, D3D11_SDK_VERSION, &scd, &m_Swapchain, &m_Device, NULL, &m_Context); if (hResult != S_OK) { return FALSE; } // Retrieves the IDXGIFactory that created "m_Device" IDXGIDevice *pDXGIDevice; m_Device->QueryInterface(__uuidof(IDXGIDevice), (void **)&pDXGIDevice); IDXGIAdapter *pDXGIAdapter; pDXGIDevice->GetParent(__uuidof(IDXGIAdapter), (void **)&pDXGIAdapter); IDXGIFactory *pDXGIFactory; pDXGIAdapter->GetParent(__uuidof(IDXGIFactory), (void **)&pDXGIFactory); // Disables the use of Alt-Enter to switch between fullscreen/windowed pDXGIFactory->MakeWindowAssociation(hWnd, DXGI_MWA_NO_ALT_ENTER); // Resized the target (window or screen resolution) and back buffers m_Swapchain->ResizeTarget(&scd.BufferDesc); m_Swapchain->ResizeBuffers(0, 0, 0, DXGI_FORMAT_UNKNOWN, scd.Flags); // Get the back buffer address ID3D11Texture1D *pBackBuffer; m_Swapchain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer); // Use the back buffer address to create a render target m_Device->CreateRenderTargetView(pBackBuffer, NULL, &m_BackBuffer); pBackBuffer->Release(); D3D11_TEXTURE2D_DESC depthBufferDesc; D3D11_DEPTH_STENCIL_DESC depthStencilDesc; D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc; D3D11_RASTERIZER_DESC rasterDesc; ZeroMemory(&depthBufferDesc, sizeof(depthBufferDesc)); depthBufferDesc.Width = wind->getWidth(); depthBufferDesc.Height = wind->getHeight(); depthBufferDesc.MipLevels = 1; depthBufferDesc.ArraySize = 1; depthBufferDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; depthBufferDesc.SampleDesc.Count = 4; depthBufferDesc.SampleDesc.Quality = 0; depthBufferDesc.Usage = D3D11_USAGE_DEFAULT; depthBufferDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL; depthBufferDesc.CPUAccessFlags = 0; depthBufferDesc.MiscFlags = 0; m_Device->CreateTexture2D(&depthBufferDesc, NULL, &m_DepthStencilBuffer); // Initialize the description of the stencil state. ZeroMemory(&depthStencilDesc, sizeof(depthStencilDesc)); // Set up the description of the stencil state. depthStencilDesc.DepthEnable = true; depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; depthStencilDesc.DepthFunc = D3D11_COMPARISON_LESS; depthStencilDesc.StencilEnable = true; depthStencilDesc.StencilReadMask = 0xFF; depthStencilDesc.StencilWriteMask = 0xFF; // Stencil operations if pixel is front-facing. depthStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR; depthStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; // Stencil operations if pixel is back-facing. depthStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR; depthStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; m_Device->CreateDepthStencilState(&depthStencilDesc, &m_DepthStencilState); m_Context->OMSetDepthStencilState(m_DepthStencilState, 1); // Initailze the depth stencil view. ZeroMemory(&depthStencilViewDesc, sizeof(depthStencilViewDesc)); // Set up the depth stencil view description. depthStencilViewDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; depthStencilViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; depthStencilViewDesc.Texture2D.MipSlice = 0; m_Device->CreateDepthStencilView(m_DepthStencilBuffer, NULL, &m_DepthStencilView); // set the render target as the back buffer m_Context->OMSetRenderTargets(1, &m_BackBuffer, m_DepthStencilView); // Set the viewport using windowSize object D3D11_VIEWPORT viewport; ZeroMemory(&viewport, sizeof(D3D11_VIEWPORT)); viewport.TopLeftX = 0; viewport.TopLeftY = 0; viewport.MinDepth = 0.0f; viewport.MaxDepth = 1.0f; viewport.Width = (float)wind->getWidth(); viewport.Height = (float)wind->getHeight(); m_Context->RSSetViewports(1, &viewport); // Setup the projection matrix. float fieldOfView = (float)D3DX_PI / 4.0f; float screenAspect = (float)wind->getWidth() / (float)wind->getHeight(); // TODO: Make constants for screen depth and screen near. // Create the projection matrix for 3D rendering. D3DXMatrixPerspectiveFovLH(&m_projMatrix, fieldOfView, screenAspect, 0.1f, 1000.0f); InitPipeline(); InitGraphics(); return TRUE; }