// Create Direct3D device and swap chain HRESULT InitDevice(HWND wnd) { HRESULT hr = S_OK; // Get window size RECT rc; GetClientRect(wnd, &rc); UINT width = rc.right - rc.left; UINT height = rc.bottom - rc.top; // Create D3D11 device and swap chain UINT createDeviceFlags = 0; #ifdef _DEBUG createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG; #endif ZeroMemory(&g_SwapChainDesc, sizeof(g_SwapChainDesc)); g_SwapChainDesc.BufferCount = 1; g_SwapChainDesc.BufferDesc.Width = width; g_SwapChainDesc.BufferDesc.Height = height; g_SwapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; g_SwapChainDesc.BufferDesc.RefreshRate.Numerator = 0; g_SwapChainDesc.BufferDesc.RefreshRate.Denominator = 0; g_SwapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; g_SwapChainDesc.OutputWindow = wnd; g_SwapChainDesc.SampleDesc.Count = 4; g_SwapChainDesc.SampleDesc.Quality = 0; g_SwapChainDesc.Windowed = TRUE; g_SwapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; // Try to create a hardware accelerated device with multisample antialiasing first hr = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, createDeviceFlags, NULL, 0, D3D11_SDK_VERSION, &g_SwapChainDesc, &g_SwapChain, &g_D3DDev, NULL, &g_D3DDevCtx); if (FAILED(hr)) { // If failed, try without antialiasing g_SwapChainDesc.SampleDesc.Count = 1; hr = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, createDeviceFlags, NULL, 0, D3D11_SDK_VERSION, &g_SwapChainDesc, &g_SwapChain, &g_D3DDev, NULL, &g_D3DDevCtx); if (FAILED(hr)) { // If failed, try to create a reference device hr = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_REFERENCE, NULL, createDeviceFlags, NULL, 0, D3D11_SDK_VERSION, &g_SwapChainDesc, &g_SwapChain, &g_D3DDev, NULL, &g_D3DDevCtx); if (SUCCEEDED(hr)) MessageBox(wnd, L"No DX11 hardware acceleration found.\nSwitching to REFERENCE driver (very slow).", L"Warning", MB_OK|MB_ICONWARNING); else return hr; } } // Create a render target and depth-stencil view ID3D11Texture2D *backBuffer = NULL, *dsBuffer = NULL; hr = g_SwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&backBuffer); if (FAILED(hr)) return hr; hr = g_D3DDev->CreateRenderTargetView(backBuffer, NULL, &g_RenderTargetView); backBuffer->Release(); if (FAILED(hr)) return hr; g_DepthStencilDesc.Width = width; g_DepthStencilDesc.Height = height; g_DepthStencilDesc.MipLevels = 1; g_DepthStencilDesc.ArraySize = 1; g_DepthStencilDesc.Format = DXGI_FORMAT_D16_UNORM; g_DepthStencilDesc.SampleDesc = g_SwapChainDesc.SampleDesc; g_DepthStencilDesc.Usage = D3D11_USAGE_DEFAULT; g_DepthStencilDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL; g_DepthStencilDesc.CPUAccessFlags = 0; g_DepthStencilDesc.MiscFlags = 0; hr = g_D3DDev->CreateTexture2D(&g_DepthStencilDesc, NULL, &dsBuffer); if (FAILED(hr)) return hr; hr = g_D3DDev->CreateDepthStencilView(dsBuffer, NULL, &g_DepthStencilView); dsBuffer->Release(); if (FAILED(hr)) return hr; g_D3DDevCtx->OMSetRenderTargets(1, &g_RenderTargetView, g_DepthStencilView); // 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_D3DDevCtx->RSSetViewports(1, &vp); return S_OK; }
bool DX11Render::Initialize(int screenWidth, int screenHeight, bool fullscreen, HWND hwnd) { HRESULT result; IDXGIFactory* factory; IDXGIAdapter* adapter; IDXGIOutput* adapterOutput; unsigned int numModes, numerator, denominator, stringLength; DXGI_MODE_DESC* displayModeList; DXGI_ADAPTER_DESC adapterDesc; int error; DXGI_SWAP_CHAIN_DESC swapChainDesc; D3D_FEATURE_LEVEL featureLevel; ID3D11Texture2D* backBufferPtr; D3D11_TEXTURE2D_DESC depthBufferDesc; D3D11_DEPTH_STENCIL_DESC depthStencilDesc; D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc; D3D11_RASTERIZER_DESC rasterDesc; D3D11_VIEWPORT viewport; float fieldOfView, screenAspect; m_vsync_enabled = VSYNC_ENABLED; //Dx Graphics interface factory result = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&factory); if(FAILED(result)) return false; //Factory is used to create adapter result = factory->EnumAdapters(0, &adapter); if(FAILED(result)) return false; //Enumerate the adapter output (monitor) result = adapter->EnumOutputs(0, &adapterOutput); if(FAILED(result)) return false; //Get # modes that fit format result = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, NULL); if(FAILED(result)) return false; //create list for display modes displayModeList = new DXGI_MODE_DESC[numModes]; if(!displayModeList) return false; //fill mode list result = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, displayModeList); if(FAILED(result)) return false; //go through list and find one that matches current monitor settings for(unsigned int i = 0; i < numModes; i++) { if(displayModeList[i].Width == (unsigned int)screenWidth) { if(displayModeList[i].Height == (unsigned int)screenHeight) { numerator = displayModeList[i].RefreshRate.Numerator; denominator = displayModeList[i].RefreshRate.Denominator; } } } //Get adapter desc. result = adapter->GetDesc(&adapterDesc); if(FAILED(result)) return false; //Get MB of video card m_videoCardMemory = (int)(adapterDesc.DedicatedVideoMemory / 1024 / 1024); //Convert Video Card desc to char array error = wcstombs_s(&stringLength, m_videoCardDescription, 128, adapterDesc.Description, 128); if(error != 0) return false; //release video card data delete [] displayModeList; displayModeList = 0; //Not needed, will go out of scope right after? adapterOutput->Release(); adapterOutput = 0; //Not needed, will go out of scope right after? adapter->Release(); adapter = 0; //Not needed, will go out of scope right after? factory->Release(); factory = 0; //Not needed, will go out of scope right after? //init swap chain ZeroMemory(&swapChainDesc, sizeof(swapChainDesc)); swapChainDesc.BufferCount = 1; swapChainDesc.BufferDesc.Width = screenWidth; swapChainDesc.BufferDesc.Height = screenHeight; swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; if(m_vsync_enabled) { swapChainDesc.BufferDesc.RefreshRate.Numerator = numerator; swapChainDesc.BufferDesc.RefreshRate.Denominator = denominator; } else { swapChainDesc.BufferDesc.RefreshRate.Numerator = 0; swapChainDesc.BufferDesc.RefreshRate.Denominator = 1; } //set scan line and scaling swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; //set buffer usage swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; //set handle swapChainDesc.OutputWindow = hwnd; //turn multisample off swapChainDesc.SampleDesc.Count = 1; swapChainDesc.SampleDesc.Quality = 0; //set fullscreen if(fullscreen) swapChainDesc.Windowed = false; else swapChainDesc.Windowed = true; //set swap effect swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; //dont set flags swapChainDesc.Flags = 0; //set dx level featureLevel = D3D_FEATURE_LEVEL_11_0; //Create the swap chain, d3d device and device context result = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, &featureLevel, 1, D3D11_SDK_VERSION, &swapChainDesc, &m_swapChain, &m_device, NULL, &m_deviceContext); if(FAILED(result)) return false; //get pointer to back buffer result = m_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&backBufferPtr); if(FAILED(result)) return false; //create render target result = m_device->CreateRenderTargetView(backBufferPtr, NULL, &m_renderTargetView); if(FAILED(result)) return false; //release pointer to back buffer backBufferPtr->Release(); backBufferPtr = 0; //Setup depth buffer desc. 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; //create depth buffer result = m_device->CreateTexture2D(&depthBufferDesc, NULL, &m_depthStencilBuffer); if(FAILED(result)) return false; //setup depth stencil desc. 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; // 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; //create depth stencil result = m_device->CreateDepthStencilState(&depthStencilDesc, &m_depthStencilState); if(FAILED(result)) return false; //set the depth stencil state m_deviceContext->OMSetDepthStencilState(m_depthStencilState, 1); //create stencil view desc ZeroMemory(&depthStencilViewDesc, sizeof(depthStencilViewDesc)); depthStencilViewDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; depthStencilViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; depthStencilViewDesc.Texture2D.MipSlice = 0; //create depth stencil view result = m_device->CreateDepthStencilView(m_depthStencilBuffer, &depthStencilViewDesc, &m_depthStencilView); if(FAILED(result)) return false; //bind render target view and depth stencil buffer to output m_deviceContext->OMSetRenderTargets(1, &m_renderTargetView, m_depthStencilView); //create raster control desc. 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; //create raster state result = m_device->CreateRasterizerState(&rasterDesc, &m_rasterState); if(FAILED(result)) return false; //now set state m_deviceContext->RSSetState(m_rasterState); //setup 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; //create viewport m_deviceContext->RSSetViewports(1, &viewport); //setup projetion matrix fieldOfView = (float)D3DX_PI / 4.0f; screenAspect = (float)screenWidth / (float)screenHeight; //create projection matrix D3DXMatrixPerspectiveFovLH(&m_projectionMatrix, fieldOfView, screenAspect, SCREEN_NEAR, SCREEN_DEPTH); //create world matrix D3DXMatrixIdentity(&m_worldMatrix); //create orthogonal projection matrix D3DXMatrixOrthoLH(&m_orthoMatrix, (float)screenWidth, (float)screenHeight, SCREEN_NEAR, SCREEN_DEPTH); //Tell someone we did well MessageManager::Instance()->NotifyHandlers(DEFAULT_MSG, "Default:\t DX11Renderer Init Complete."); return true; }
// this will Initialize DirectX graphics and its window void TSRD3D11GraphicsSubSystem::InitGraphics( TSRScreenMode& _mode ) { DXGI_SWAP_CHAIN_DESC SwapChainDesc; ZeroMemory( &SwapChainDesc, sizeof( SwapChainDesc ) ); unsigned int uiNumSamples = _mode.m_uiSamplesCountForMSAA; if ( uiNumSamples == 0 ) { uiNumSamples = 1; } D3D_RTV_DIMENSION RenderTargetViewDimension = D3D_RTV_DIMENSION_TEXTURE2D; D3D_DSV_DIMENSION DepthStencilViewDimension = D3D_DSV_DIMENSION_TEXTURE2D; if ( uiNumSamples > 1 ) { RenderTargetViewDimension = D3D_RTV_DIMENSION_TEXTURE2DMS; DepthStencilViewDimension = D3D_DSV_DIMENSION_TEXTURE2DMS; } if ( _mode.m_bBackBufferUsesDesktopResolution ) { m_uiBackBufferWidth = GetSystemMetrics( SM_CXFULLSCREEN ); m_uiBackBufferHeight = GetSystemMetrics( SM_CYFULLSCREEN ); } else { m_uiBackBufferWidth = TSRSystem()->m_DisplayMode.m_uiWidth; m_uiBackBufferHeight = TSRSystem()->m_DisplayMode.m_uiHeight; } SwapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; SwapChainDesc.BufferDesc.Width = m_uiBackBufferWidth; SwapChainDesc.BufferDesc.Height = m_uiBackBufferHeight; SwapChainDesc.BufferDesc.RefreshRate.Denominator = 60; SwapChainDesc.BufferDesc.RefreshRate.Numerator = 1; // SwapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_CENTERED; // SwapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_PROGRESSIVE; SwapChainDesc.SampleDesc.Count = uiNumSamples; SwapChainDesc.SampleDesc.Quality = 0; SwapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_BACK_BUFFER; SwapChainDesc.BufferCount = 1; SwapChainDesc.OutputWindow = SystemWin32()->GetMainHWND(); SwapChainDesc.Windowed = TSRSystem()->m_DisplayMode.m_bIsWindowed ? TRUE : FALSE; SwapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; SwapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; /*UINT uiNumAdapters = 0; IDXGIAdapter* pAdapter; std::vector <IDXGIAdapter*> vAdapters; std::vector <DXGI_ADAPTER_DESC> vAdapterDescriptors; DXGI_ADAPTER_DESC adapterDesc; IDXGIFactory * pFactory; HRESULT hrr = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)(&pFactory) ); while(pFactory->EnumAdapters(uiNumAdapters, &pAdapter) != DXGI_ERROR_NOT_FOUND) { vAdapters.push_back(pAdapter); pAdapter->GetDesc( &adapterDesc ); vAdapterDescriptors.push_back( adapterDesc ); ++uiNumAdapters; } */ unsigned int uiDeviceCreationFlags = 0; #ifdef _DEBUG /// onwindows 10, deubg flag results in crash, so disabling it for now uiDeviceCreationFlags = 0;//D3D_CREATE_DEVICE_DEBUG; #endif #ifdef D3D10_RENDERER HRESULT hr = D3D10CreateDeviceAndSwapChain( NULL, D3D10_DRIVER_TYPE_HARDWARE, NULL, uiDeviceCreationFlags, D3D10_SDK_VERSION, &SwapChainDesc, &m_pSwapChain, &m_pD3DDevice ); #endif #ifdef D3D11_RENDERER D3D_FEATURE_LEVEL featureLevels[] = { 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 numFeatureLevels = ARRAYSIZE( featureLevels ); HRESULT hr = D3D11CreateDeviceAndSwapChain( NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, uiDeviceCreationFlags, featureLevels, numFeatureLevels, D3D11_SDK_VERSION, &SwapChainDesc, &m_pSwapChain, &m_pD3DDevice, &m_FeatureLevel, &m_pD3DDeviceContext ); #endif // Create a render target view ID3DTexture2D* pBuffer; hr = m_pSwapChain->GetBuffer( 0, __uuidof( ID3DTexture2D ), ( LPVOID* ) &pBuffer ); if( FAILED( hr ) ) { assert( 0 && "Failed to get the back buffer from the swap chain" ); } D3D_RENDER_TARGET_VIEW_DESC DescRT; DescRT.Format = DXGI_FORMAT_R8G8B8A8_UNORM; DescRT.ViewDimension = RenderTargetViewDimension; DescRT.Texture2D.MipSlice = 0; hr = m_pD3DDevice->CreateRenderTargetView( pBuffer, &DescRT, &m_pColorBufferView ); pBuffer->Release(); if( FAILED( hr ) ) { assert( 0 && "Failed to create render target view" ); } // Create depth stencil texture D3D_TEXTURE2D_DESC descDepth; descDepth.Width = m_uiBackBufferWidth; descDepth.Height = m_uiBackBufferHeight; descDepth.MipLevels = 1; descDepth.ArraySize = 1; descDepth.Format = DXGI_FORMAT_D32_FLOAT; descDepth.SampleDesc.Count = uiNumSamples; descDepth.SampleDesc.Quality = 0; descDepth.Usage = D3D_USAGE_DEFAULT; descDepth.BindFlags = D3D_BIND_DEPTH_STENCIL; descDepth.CPUAccessFlags = 0; descDepth.MiscFlags = 0; hr = m_pD3DDevice->CreateTexture2D( &descDepth, NULL, &m_pDepthStencil ); if ( FAILED( hr ) ) { assert( 0 && "Failed to create the depth stencil target" ); } // Create the depth stencil view D3D_DEPTH_STENCIL_VIEW_DESC descDSV; ZeroMemory( &descDSV, sizeof( D3D_DEPTH_STENCIL_VIEW_DESC ) ); descDSV.Format = descDepth.Format; descDSV.ViewDimension = DepthStencilViewDimension; descDSV.Texture2D.MipSlice = 0; hr = m_pD3DDevice->CreateDepthStencilView( m_pDepthStencil, &descDSV, &m_pDepthStencilView ); if ( FAILED( hr ) ) { assert( 0 && "Failed to create the depth stencil view" ); } m_pActiveColorBufferViews[ 0 ] = m_pColorBufferView; m_pActiveColorBufferViews[ 1 ] = NULL; m_pActiveColorBufferViews[ 2 ] = NULL; m_pActiveColorBufferViews[ 3 ] = NULL; m_pActiveDepthStencilView = m_pDepthStencilView; GetDeviceContext()->OMSetRenderTargets( 1, m_pActiveColorBufferViews, m_pActiveDepthStencilView ); // set the projection matrix accordingly Resize( _mode.m_uiWidth, _mode.m_uiHeight ); m_pColorBufferTexture = pBuffer; /// Create staging selection buffer texture D3D_TEXTURE2D_DESC descSelectionBuffer; descSelectionBuffer.Width = m_uiBackBufferWidth; descSelectionBuffer.Height = m_uiBackBufferHeight; descSelectionBuffer.MipLevels = 1; descSelectionBuffer.ArraySize = 1; descSelectionBuffer.Format = DXGI_FORMAT_R8G8B8A8_UNORM; descSelectionBuffer.SampleDesc.Count = 1;//uiNumSamples; descSelectionBuffer.SampleDesc.Quality = 0; descSelectionBuffer.Usage = D3D_USAGE_STAGING; descSelectionBuffer.BindFlags = 0; descSelectionBuffer.CPUAccessFlags = D3D_CPU_ACCESS_READ ; descSelectionBuffer.MiscFlags = 0; hr = m_pD3DDevice->CreateTexture2D( &descSelectionBuffer, NULL, &m_pCpuBackBufferCopy ); if ( FAILED( hr ) ) { assert( 0 && "Failed to create the selection buffer" ); } m_pQueryIdleGPU = NULL; D3D_QUERY_DESC queryDesc; queryDesc.MiscFlags = 0; queryDesc.Query = D3D_QUERY_EVENT; m_pD3DDevice->CreateQuery( &queryDesc, &m_pQueryIdleGPU ); #ifdef D3D10_RENDERER TSRPrintln( "D3D10 initialized successfully" ); #endif #ifdef D3D11_RENDERER TSRPrintln( "D3D11 initialized successfully" ); #endif #ifdef D3D10_RENDERER TSRPrintln( "D3D10 initialized successfully" ); #endif }
//----------------------------------------------------------------------------- // Initialize // Performs any API specific initialization tasks (wind order, etc) //----------------------------------------------------------------------------- Result CD3DDevice::Initialize( CWindow* pWindow ) { HRESULT hr = S_OK; HWND hWnd = static_cast<HWND>( pWindow->GetWindow() ); // Get the actual client size of the window RECT rcClient; GetClientRect( hWnd, &rcClient ); unsigned int nWidth = rcClient.right - rcClient.left; unsigned int nHeight = rcClient.bottom - rcClient.top; // TODO: Don't use these hardcoded values int nAACount = 1, nAAQuality = 0; bool bWindowed = true; ///////////////////////////////////////// // Create the swap chain description DXGI_SWAP_CHAIN_DESC tSwapChainDesc = {0}; tSwapChainDesc.BufferCount = 2; // buffer count tSwapChainDesc.BufferDesc.Width = nWidth; // width of the window tSwapChainDesc.BufferDesc.Height = nHeight; // height of the window tSwapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; // Back buffer format // TODO: Don't hardcode this tSwapChainDesc.BufferDesc.RefreshRate.Numerator = 60; // Refresh rate tSwapChainDesc.BufferDesc.RefreshRate.Denominator = 1; // Refresh rate tSwapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; // Its a render target! tSwapChainDesc.OutputWindow = hWnd; // Window to attach to tSwapChainDesc.SampleDesc.Count = nAACount; // AA count tSwapChainDesc.SampleDesc.Quality = nAAQuality; // AA quality tSwapChainDesc.Windowed = bWindowed; // Windowed!! Yay! tSwapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; // TODO: Fix the fullscreen 'ding'. // DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH isn't what causes it... ///////////////////////////////////////// // Create the DX device D3D_FEATURE_LEVEL FeatureLevel; unsigned int nFlags = 0; #ifdef DEBUG nFlags |= D3D11_CREATE_DEVICE_DEBUG; #endif hr = D3D11CreateDeviceAndSwapChain( 0, // physical adapter to try D3D_DRIVER_TYPE_HARDWARE, // TODO: Add support for software/warp 0, // TODO: Add support for software/warp nFlags, // Creation flags NULL, // Feature levels to try 0, // Number of feature levels D3D11_SDK_VERSION, // The SDK version &tSwapChainDesc, // The Swap chain description &m_pSwapChain, // The swap chain &m_pDevice, // the device &FeatureLevel, // The feature level being used &m_pContext ); // The context! if( FAILED( hr ) ) { // TODO: Handle gracefully ASSERT( FALSE ); MessageBox( 0, L"Could not create DX device/swap chain", L"Error", 0 ); return rResultFailure; } /////////////////////////////////////////////// // Do any feature level specific stuff switch( FeatureLevel ) { case D3D_FEATURE_LEVEL_11_0: { strcpy( m_szVSProfile, "vs_5_0" ); strcpy( m_szPSProfile, "ps_5_0" ); break; } case D3D_FEATURE_LEVEL_10_1: { strcpy( m_szVSProfile, "vs_4_1" ); strcpy( m_szPSProfile, "ps_4_1" ); break; } case D3D_FEATURE_LEVEL_10_0: { strcpy( m_szVSProfile, "vs_4_0" ); strcpy( m_szPSProfile, "ps_4_0" ); break; } case D3D_FEATURE_LEVEL_9_3: { strcpy( m_szVSProfile, "vs_3_0" ); strcpy( m_szPSProfile, "ps_3_0" ); break; } default: { break; } }; // Resize everything Resize( nWidth, nHeight ); // Create the rasterizer states D3D11_RASTERIZER_DESC rd; Memset( &rd, 0, sizeof(rd) ); // Solid rd.CullMode = D3D11_CULL_BACK; rd.FillMode = D3D11_FILL_SOLID; rd.DepthClipEnable = TRUE; hr = m_pDevice->CreateRasterizerState( &rd, &m_pSolidRasterizerState ); // wireframe rd.FillMode = D3D11_FILL_WIREFRAME; rd.CullMode = D3D11_CULL_NONE; hr = m_pDevice->CreateRasterizerState( &rd, &m_pWireframeRasterizerState ); ////////////////////////////////////////// // Create depth states D3D11_DEPTH_STENCIL_DESC dsd; dsd.DepthEnable = true; dsd.StencilEnable = false; dsd.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; dsd.DepthFunc = D3D11_COMPARISON_LESS_EQUAL; hr = m_pDevice->CreateDepthStencilState( &dsd, &m_pDepthWriteTest ); ASSERT( hr == S_OK ); dsd.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO; hr = m_pDevice->CreateDepthStencilState( &dsd, &m_pDepthNoWriteTest ); ASSERT( hr == S_OK ); dsd.DepthEnable = false; dsd.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; hr = m_pDevice->CreateDepthStencilState( &dsd, &m_pDepthWriteNoTest ); ASSERT( hr == S_OK ); dsd.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO; hr = m_pDevice->CreateDepthStencilState( &dsd, &m_pDepthNoWriteNoTest ); ASSERT( hr == S_OK ); ////////////////////////////////////////// // Blend states D3D11_BLEND_DESC bd = { 0 }; bd.AlphaToCoverageEnable = false; bd.IndependentBlendEnable = false; bd.RenderTarget[0].RenderTargetWriteMask = 0; hr = m_pDevice->CreateBlendState( &bd, &m_pColorDisableBlendState ); ASSERT( hr == S_OK ); bd.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; hr = m_pDevice->CreateBlendState( &bd, &m_pColorEnableBlendState ); ASSERT( hr == S_OK ); return rResultSuccess; }
bool CGameFramework::CreateDirect3DDisplay() { RECT rcClient; ::GetClientRect(m_hWnd, &rcClient); m_nWndClientWidth = rcClient.right - rcClient.left; m_nWndClientHeight = rcClient.bottom - rcClient.top; UINT dwCreateDeviceFlags = 0; #ifdef _DEBUG dwCreateDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG; #endif //디바이스를 생성하기 위하여 시도할 드라이버 유형의 순서를 나타낸다. D3D_DRIVER_TYPE d3dDriverTypes[] = { D3D_DRIVER_TYPE_HARDWARE, D3D_DRIVER_TYPE_WARP, D3D_DRIVER_TYPE_REFERENCE }; UINT nDriverTypes = sizeof(d3dDriverTypes) / sizeof(D3D10_DRIVER_TYPE); //디바이스를 생성하기 위하여 시도할 특성 레벨의 순서를 나타낸다. D3D_FEATURE_LEVEL d3dFeatureLevels[] = { D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0 }; UINT nFeatureLevels = sizeof(d3dFeatureLevels) / sizeof(D3D_FEATURE_LEVEL); //생성할 스왑 체인을 서술하는 구조체이다. DXGI_SWAP_CHAIN_DESC dxgiSwapChainDesc; ::ZeroMemory(&dxgiSwapChainDesc, sizeof(dxgiSwapChainDesc)); dxgiSwapChainDesc.BufferCount = 1; dxgiSwapChainDesc.BufferDesc.Width = m_nWndClientWidth; dxgiSwapChainDesc.BufferDesc.Height = m_nWndClientHeight; 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 = m_hWnd; dxgiSwapChainDesc.SampleDesc.Count = 1; dxgiSwapChainDesc.SampleDesc.Quality = 0; dxgiSwapChainDesc.Windowed = TRUE; D3D_DRIVER_TYPE nd3dDriverType = D3D_DRIVER_TYPE_NULL; D3D_FEATURE_LEVEL nd3dFeatureLevel = D3D_FEATURE_LEVEL_11_0; HRESULT hResult = S_OK; //디바이스의 드라이버 유형과 특성 레벨을 지원하는 디바이스와 스왑 체인을 생성한다. 고수준의 디바이스 생성을 시도하고 실패하면 다음 수준의 디바이스를 생성한다. for (UINT i = 0; i < nDriverTypes; i++) { nd3dDriverType = d3dDriverTypes[i]; if (SUCCEEDED(hResult = D3D11CreateDeviceAndSwapChain(NULL, nd3dDriverType, NULL, dwCreateDeviceFlags, d3dFeatureLevels, nFeatureLevels, D3D11_SDK_VERSION, &dxgiSwapChainDesc, &m_pDXGISwapChain, &m_pd3dDevice, &nd3dFeatureLevel, &m_pd3dDeviceContext))) break; } if (!m_pDXGISwapChain || !m_pd3dDevice || !m_pd3dDeviceContext) return(false); //렌더 타겟 뷰를 생성하는 함수를 호출한다. if (!CreateRenderTargetView()) return(false); return(true); }
// this function initializes and prepares Direct3D for use void InitD3D(HWND hWnd) { // create a struct to hold information about the swap chain DXGI_SWAP_CHAIN_DESC scd; // clear out the struct for use ZeroMemory(&scd, sizeof(DXGI_SWAP_CHAIN_DESC)); // fill the swap chain description struct scd.BufferCount = 1; // one back buffer scd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; // use 32-bit color scd.BufferDesc.Width = SCREEN_WIDTH; // set the back buffer width scd.BufferDesc.Height = SCREEN_HEIGHT; // set the back buffer height scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; // how swap chain is to be used scd.OutputWindow = hWnd; // the window to be used scd.SampleDesc.Count = 4; // how many multisamples scd.Windowed = TRUE; // windowed/full-screen mode scd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; // allow full-screen switching // create a device, device context and swap chain using the information in the scd struct D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, NULL, NULL, NULL, D3D11_SDK_VERSION, &scd, &swapchain, &dev, NULL, &devcon); // create the depth buffer texture D3D11_TEXTURE2D_DESC texd; ZeroMemory(&texd, sizeof(texd)); texd.Width = SCREEN_WIDTH; texd.Height = SCREEN_HEIGHT; texd.ArraySize = 1; texd.MipLevels = 1; texd.SampleDesc.Count = 4; texd.Format = DXGI_FORMAT_D32_FLOAT; texd.BindFlags = D3D11_BIND_DEPTH_STENCIL; ID3D11Texture2D *pDepthBuffer; dev->CreateTexture2D(&texd, NULL, &pDepthBuffer); // create the depth buffer D3D11_DEPTH_STENCIL_VIEW_DESC dsvd; ZeroMemory(&dsvd, sizeof(dsvd)); dsvd.Format = DXGI_FORMAT_D32_FLOAT; dsvd.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMS; dev->CreateDepthStencilView(pDepthBuffer, &dsvd, &zbuffer); pDepthBuffer->Release(); // get the address of the back buffer ID3D11Texture2D *pBackBuffer; swapchain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer); // use the back buffer address to create the render target dev->CreateRenderTargetView(pBackBuffer, NULL, &backbuffer); pBackBuffer->Release(); // set the render target as the back buffer devcon->OMSetRenderTargets(1, &backbuffer, zbuffer); // Set the viewport D3D11_VIEWPORT viewport; ZeroMemory(&viewport, sizeof(D3D11_VIEWPORT)); viewport.TopLeftX = 0; viewport.TopLeftY = 0; viewport.Width = SCREEN_WIDTH; viewport.Height = SCREEN_HEIGHT; viewport.MinDepth = 0; // the closest an object can be on the depth buffer is 0.0 viewport.MaxDepth = 1; // the farthest an object can be on the depth buffer is 1.0 devcon->RSSetViewports(1, &viewport); InitPipeline(); InitGraphics(); }
GraphicsLayer::GraphicsLayer(HWND in_hWnd, UINT in_bbWidth, UINT in_bbHeight) throw(Exception) { // if (s_pMainLayer) { throw Exception("Graphics layer already initialized"); } s_pMainLayer = this; // Fill out swap chain desc DXGI_SWAP_CHAIN_DESC swapChainDesc; ZeroMemory(&swapChainDesc, sizeof(swapChainDesc)); // Double buffering swapChainDesc.BufferCount = 1; // Backbuffer attributes swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; swapChainDesc.BufferDesc.Width = in_bbWidth; swapChainDesc.BufferDesc.Height = in_bbHeight; swapChainDesc.BufferDesc.RefreshRate.Numerator = 60; swapChainDesc.BufferDesc.RefreshRate.Denominator = 1; // Buffer usage swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChainDesc.OutputWindow = in_hWnd; // No multi-sampling swapChainDesc.SampleDesc.Count = 1; swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; swapChainDesc.Windowed = TRUE; // Required feature levels D3D_FEATURE_LEVEL featureLevels[] = {D3D_FEATURE_LEVEL_10_0, D3D_FEATURE_LEVEL_11_0}; UINT numLevels = sizeof(featureLevels)/sizeof(D3D_FEATURE_LEVEL); // Attempt to create device and swap chain if (FAILED(D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, 0, D3D11_CREATE_DEVICE_DEBUG, featureLevels, numLevels, D3D11_SDK_VERSION, &swapChainDesc, &m_pSwapChain, &m_pDevice, &m_featureLevel, &m_pImmediateContext ))) { throw Exception("Couldn't create device and swap chain"); } // Retrieve default render target ID3D11Texture2D* pBackBuffer = NULL; if (FAILED(m_pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&pBackBuffer))) { throw Exception("Couldn't retrieve back buffer"); } // Create default render target view if (FAILED(m_pDevice->CreateRenderTargetView(pBackBuffer, NULL, &m_pDefaultRT))) { throw Exception("Couldn't create default render target view"); } // Release back buffer pBackBuffer->Release(); // Create depth-stencil texture D3D11_TEXTURE2D_DESC depthTextureDesc; ZeroMemory(&depthTextureDesc, sizeof(depthTextureDesc)); depthTextureDesc.ArraySize = 1; depthTextureDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL; depthTextureDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; depthTextureDesc.Height = in_bbHeight; depthTextureDesc.Width = in_bbWidth; depthTextureDesc.MipLevels = 1; depthTextureDesc.SampleDesc.Count = 1; depthTextureDesc.Usage = D3D11_USAGE_DEFAULT; if (FAILED(m_pDevice->CreateTexture2D(&depthTextureDesc, NULL, &m_pDepthTexture))) { throw Exception("Couldn't create default depth-stencil"); } // Create depth-stencil view D3D11_DEPTH_STENCIL_VIEW_DESC depthViewDesc; ZeroMemory(&depthViewDesc, sizeof(depthViewDesc)); depthViewDesc.Format = depthTextureDesc.Format; depthViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; depthViewDesc.Texture2D.MipSlice = 0; if (FAILED(m_pDevice->CreateDepthStencilView(m_pDepthTexture, &depthViewDesc, &m_pDefaultDS))) { throw Exception("Couldn't create default depth-stencil view"); } // Set default render targte and depth stencil m_pImmediateContext->OMSetRenderTargets(1, &m_pDefaultRT, m_pDefaultDS); // Set viewport to cover the whole backbuffer D3D11_VIEWPORT viewport; viewport.TopLeftX = viewport.TopLeftY = 0.f; viewport.MinDepth = 0.f; viewport.MaxDepth = 1.f; viewport.Width = in_bbWidth; viewport.Height = in_bbHeight; m_pImmediateContext->RSSetViewports(1, &viewport); }
void System::InitGraphics() { D3D_FEATURE_LEVEL _FeatureLevel = D3D_FEATURE_LEVEL::D3D_FEATURE_LEVEL_11_0; D3D_FEATURE_LEVEL _FeatureLevelOut; DXGI_SWAP_CHAIN_DESC _Desc; ZeroMemory(&_Desc, sizeof(_Desc)); _Desc.BufferCount = 1; _Desc.BufferDesc.Format = DXGI_FORMAT::DXGI_FORMAT_R8G8B8A8_UNORM; _Desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; _Desc.OutputWindow = m_Window; _Desc.Windowed = true; _Desc.SampleDesc.Count = 4; HRESULT _HR = D3D11CreateDeviceAndSwapChain(nullptr, D3D_DRIVER_TYPE::D3D_DRIVER_TYPE_HARDWARE, nullptr, 0, // D3D11_CREATE_DEVICE_FLAG::D3D11_CREATE_DEVICE_DEBUG, &_FeatureLevel, 1, D3D11_SDK_VERSION, &_Desc, &m_pSwapChain, &m_pDevice, &_FeatureLevelOut, &m_pDeviceContext); // ID3D11Texture2D : Textur // ID3D11ShaderResourceView : Objekt um aus der Textur zu lesen // ID3D11RenderTargetView : Objekt um in die Textur zu schreiben // BackBuffer (Farbinformation des "Bildes") ID3D11Texture2D* m_pBackbufferTexture = nullptr; m_pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&m_pBackbufferTexture); m_pDevice->CreateRenderTargetView(m_pBackbufferTexture, nullptr, &m_pBackBuffer); // DepthBuffer (Tiefeninformation des "Bildes") ID3D11Texture2D* _pDepthBuffer = nullptr; D3D11_TEXTURE2D_DESC _DBDesc; ZeroMemory(&_DBDesc, sizeof(_DBDesc)); _DBDesc.ArraySize = 1; _DBDesc.MipLevels = 1; _DBDesc.Height = 600; _DBDesc.Width = 800; _DBDesc.SampleDesc.Count = 4; _DBDesc.Format = DXGI_FORMAT::DXGI_FORMAT_D32_FLOAT; _DBDesc.BindFlags = D3D11_BIND_FLAG::D3D11_BIND_DEPTH_STENCIL; m_pDevice->CreateTexture2D(&_DBDesc, nullptr, &_pDepthBuffer); D3D11_DEPTH_STENCIL_VIEW_DESC _DSVDesc; ZeroMemory(&_DSVDesc, sizeof(_DSVDesc)); _DSVDesc.ViewDimension = D3D11_DSV_DIMENSION::D3D11_DSV_DIMENSION_TEXTURE2DMS; _DSVDesc.Format = DXGI_FORMAT::DXGI_FORMAT_D32_FLOAT; m_pDevice->CreateDepthStencilView(_pDepthBuffer, &_DSVDesc, &m_pDepthStencilView); m_pDeviceContext->OMSetRenderTargets(1, &m_pBackBuffer, m_pDepthStencilView); D3D11_VIEWPORT _Viewport; _Viewport.TopLeftX = 0; _Viewport.TopLeftY = 0; _Viewport.Width = 800; _Viewport.Height = 600; _Viewport.MinDepth = 0; _Viewport.MaxDepth = 1; m_pDeviceContext->RSSetViewports(1, &_Viewport); }
void RenderSystem::init_device() { ////////////////////////Create buffer desc//////////////////////////// DXGI_MODE_DESC bufferDesc; ZeroMemory(&bufferDesc, sizeof(DXGI_MODE_DESC)); bufferDesc.Width = m_ScreenWidth; bufferDesc.Height = m_ScreenHeight; bufferDesc.RefreshRate.Numerator = 60; bufferDesc.RefreshRate.Denominator = 1; bufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; bufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; bufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; //Create swapChain Desc DXGI_SWAP_CHAIN_DESC swapChainDesc; ZeroMemory(&swapChainDesc, sizeof(DXGI_SWAP_CHAIN_DESC)); swapChainDesc.BufferDesc = bufferDesc; swapChainDesc.SampleDesc.Count = 1; swapChainDesc.SampleDesc.Quality = 0; swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChainDesc.BufferCount = 1; swapChainDesc.OutputWindow = GetHwnd(); swapChainDesc.Windowed = TRUE; swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; /////////////////////////////////////////////////////////////////////////// HRESULT hr; //Create the double buffer chain hr = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, NULL, NULL, NULL, D3D11_SDK_VERSION, &swapChainDesc, &m_pSwapChain, &m_pD3D11Device, NULL, &m_pD3D11DeviceContext); //DebugHR(hr); //Create back buffer, buffer also is a texture ID3D11Texture2D *pBackBuffer; hr = m_pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&pBackBuffer); hr = m_pD3D11Device->CreateRenderTargetView(pBackBuffer, NULL, &m_pRenderTargetView); pBackBuffer->Release(); //DebugHR(hr); ///////////////////// Set up the description of the depth buffer.//////////////////////// D3D11_TEXTURE2D_DESC depthBufferDesc; ZeroMemory(&depthBufferDesc, sizeof(depthBufferDesc)); depthBufferDesc.Width = m_ScreenWidth; depthBufferDesc.Height = m_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; // Create the texture for the depth buffer using the filled out description. hr = m_pD3D11Device->CreateTexture2D(&depthBufferDesc, NULL, &m_pDepthStencilBuffer); //DebugHR(hr); //////////////////////////// initialize the description of the stencil state./////////////////////////////////////////////// D3D11_DEPTH_STENCIL_DESC depthStencilDesc; ZeroMemory(&depthStencilDesc, sizeof(depthStencilDesc)); depthStencilDesc.DepthEnable = true; depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; depthStencilDesc.DepthFunc = D3D11_COMPARISON_LESS_EQUAL; 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; // Create the depth stencil state. hr = m_pD3D11Device->CreateDepthStencilState(&depthStencilDesc, &m_pDepthStencilState); //DebugHR(hr); // initialize the depth stencil view. 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_pD3D11Device->CreateDepthStencilView(m_pDepthStencilBuffer.Get(), &depthStencilViewDesc, &m_pDepthStencilView); //DebugHR(hr); /////////////////////////////////////////////////////////////////////////////////////////// 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; // Create the rasterizer state from the description we just filled out. hr = m_pD3D11Device->CreateRasterizerState(&rasterDesc, &m_pRasterState); DebugHR(hr); /////////////////////////////////////////////////////////////////////////////// unsigned int numModes, i, numerator, denominator, stringLength; IDXGIFactory* factory; IDXGIAdapter* adapter; IDXGISurface *surface; DXGI_ADAPTER_DESC adapterDesc; // Create a DirectX graphics interface factory. CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&factory); // Use the factory to create an adapter for the primary graphics interface (video card). factory->EnumAdapters(0, &adapter); adapter->GetDesc(&adapterDesc); m_videoCardMemory = (int)(adapterDesc.DedicatedVideoMemory / 1024 / 1024); // Convert the name of the video card to a character array and store it. m_videoCardInfo = std::wstring(L"Video Card :") + adapterDesc.Description; }
HRESULT Graphics::InitDirect3D(HWND hWndMain) { HRESULT hr = S_OK;; int screenWidth = WINDOW_WIDTH; int screenHeight = WINDOW_Height; UINT createDeviceFlags = 0; #ifdef _DEBUG createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG; #endif D3D_DRIVER_TYPE driverType; D3D_DRIVER_TYPE driverTypes[] = { D3D_DRIVER_TYPE_HARDWARE, D3D_DRIVER_TYPE_REFERENCE, }; UINT numDriverTypes = sizeof(driverTypes) / sizeof(driverTypes[0]); 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 = hWndMain; sd.SampleDesc.Count = 1; sd.SampleDesc.Quality = 0; sd.Windowed = TRUE; D3D_FEATURE_LEVEL featureLevelsToTry[] = { D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0 }; D3D_FEATURE_LEVEL initiatedFeatureLevel; D3D_FEATURE_LEVEL featureLevel; featureLevel = D3D_FEATURE_LEVEL_11_0; for( UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++ ) { driverType = driverTypes[driverTypeIndex]; hr = D3D11CreateDeviceAndSwapChain( NULL, driverType, NULL, 0, featureLevelsToTry, ARRAYSIZE(featureLevelsToTry), D3D11_SDK_VERSION, &sd, &m_SwapChain, &m_Device, &initiatedFeatureLevel, &m_DeviceContext); if( SUCCEEDED( hr ) ) break; } if( FAILED(hr) ) return hr; // Create a render target view ID3D11Texture2D* pBackBuffer; hr = m_SwapChain->GetBuffer( 0, __uuidof( ID3D11Texture2D ), (LPVOID*)&pBackBuffer ); if( FAILED(hr) ) return hr; hr = m_Device->CreateRenderTargetView( pBackBuffer, NULL, &m_RenderTargetView ); pBackBuffer->Release(); if( FAILED(hr) ) return hr; // Create depth stencil texture D3D11_TEXTURE2D_DESC descDepth; descDepth.Width = screenWidth; descDepth.Height = screenHeight; descDepth.MipLevels = 1; descDepth.ArraySize = 1; descDepth.Format = DXGI_FORMAT_D32_FLOAT; 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 = m_Device->CreateTexture2D( &descDepth, NULL, &m_DepthStencil ); 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 = m_Device->CreateDepthStencilView(m_DepthStencil, &descDSV, &m_DepthStencilView ); if( FAILED(hr) ) return hr; m_DeviceContext->OMSetRenderTargets(1, &m_RenderTargetView, m_DepthStencilView ); // Setup the viewport vp.Width = (float)screenWidth; vp.Height = (float)screenHeight; vp.MinDepth = 0.0f; vp.MaxDepth = 1.0f; vp.TopLeftX = 0; vp.TopLeftY = 0; m_DeviceContext->RSSetViewports( 1, &vp ); Effects::InitAll(m_Device); return S_OK; }
//-------------------------------------------------------------------------------------- // 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_0, D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0, }; UINT numFeatureLevels = ARRAYSIZE(featureLevels); 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; for (UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++) { g_driverType = driverTypes[driverTypeIndex]; hr = D3D11CreateDeviceAndSwapChain(NULL, g_driverType, NULL, createDeviceFlags, featureLevels, numFeatureLevels, D3D11_SDK_VERSION, &sd, &g_pSwapChain, &m_pd3dDevice, &g_featureLevel, &m_DeviceContext); if (SUCCEEDED(hr)) { break; } } if (FAILED(hr)) { return hr; } // Create a render target view ID3D11Texture2D* pBackBuffer = NULL; hr = g_pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer); if (FAILED(hr)) { return hr; } hr = m_pd3dDevice->CreateRenderTargetView(pBackBuffer, NULL, &m_pRenderTargetView); pBackBuffer->Release(); if (FAILED(hr)) { return hr; } m_DeviceContext->OMSetRenderTargets(1, &m_pRenderTargetView, NULL); // 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; m_DeviceContext->RSSetViewports(1, &vp); return S_OK; }
//-------------------------------------------------------------------------------------- // Direct3Dデバイスとスワップチェーン //-------------------------------------------------------------------------------------- HRESULT InitDevice() { HRESULT hr = S_OK; UINT createDeviceFlags = 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_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 numFeatureLevels = ARRAYSIZE( featureLevels ); //スワップチェーンの設定 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; //Direct3Dデバイスの作成とスワップチェーンの作成 for( UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++ ) { g_driverType = driverTypes[driverTypeIndex]; hr = D3D11CreateDeviceAndSwapChain( NULL, g_driverType, NULL, createDeviceFlags, featureLevels, numFeatureLevels, D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice, &g_featureLevel, &g_pImmediateContext ); if( SUCCEEDED( hr ) ) break; } if( FAILED( hr ) ) return hr; //レンダーターゲットビュー ID3D11Texture2D* pBackBuffer = NULL; hr = g_pSwapChain->GetBuffer( 0, __uuidof( ID3D11Texture2D ), ( LPVOID* )&pBackBuffer ); if( FAILED( hr ) ) return hr; hr = g_pd3dDevice->CreateRenderTargetView( pBackBuffer, NULL, &g_pRenderTargetView ); pBackBuffer->Release(); if( FAILED( hr ) ) return hr; //深度バッファ作成(ステンシル) 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, NULL, &g_pDepthStencil ); if( FAILED( hr ) ) return hr; //ステンシルビューの作成 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 ); //ビューポートの設定 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 ); //頂点シェーダーをコンパイル ID3DBlob* pVSBlob = NULL; hr = CompileShaderFromFile( "SimpleShader.hlsl", "VS", "vs_4_0", &pVSBlob ); if( FAILED( hr ) ) { MessageBox( NULL,"頂点シェーダーを読み込めませんでした。", "Error", MB_OK ); return hr; } //頂点シェーダーから頂点シェーダのオブジェクトを作成 hr = g_pd3dDevice->CreateVertexShader( pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), NULL, &g_pVertexShader ); if( FAILED( hr ) ) { pVSBlob->Release(); return hr; } //頂点のインプットレイアウトを定義 D3D11_INPUT_ELEMENT_DESC layout[] = { { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 28, D3D11_INPUT_PER_VERTEX_DATA, 0 }, }; UINT numElements = ARRAYSIZE( layout ); //インプットレイアウトの作成 hr = g_pd3dDevice->CreateInputLayout( layout, numElements, pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), &g_pVertexLayout ); pVSBlob->Release();pVSBlob = NULL; if( FAILED( hr ) ) return hr; //インプットレイアウトのセット g_pImmediateContext->IASetInputLayout( g_pVertexLayout ); //ピクセルシェーダーをコンパイル ID3DBlob* pPSBlob = NULL; hr = CompileShaderFromFile("SimpleShader.hlsl", "PS", "ps_4_0", &pPSBlob ); if( FAILED( hr ) ) { MessageBox( NULL,"頂点シェーダーを読み込めませんでした。", "Error", MB_OK ); return hr; } //ピクセルシェーダーからピクセルシェーダのオブジェクトを作成 hr = g_pd3dDevice->CreatePixelShader( pPSBlob->GetBufferPointer(), pPSBlob->GetBufferSize(), NULL, &g_pPixelShader ); pPSBlob->Release(); if( FAILED( hr ) ) return hr; //頂点バッファの作成 SimpleVertex vertices[] = { { XMFLOAT3( -1.0f, 1.0f, -1.0f ), XMFLOAT4( 1.0f, 0.0f, 0.0f, 1.0f ), XMFLOAT2( 0.0f, 0.0f ) }, { XMFLOAT3( 1.0f, 1.0f, -1.0f ), XMFLOAT4( 1.0f, 1.0f, 0.0f, 1.0f ), XMFLOAT2( 1.0f, 0.0f ) }, { XMFLOAT3( 1.0f, 1.0f, 1.0f ), XMFLOAT4( 0.0f, 1.0f, 0.0f, 1.0f ), XMFLOAT2( 1.0f, 1.0f ) }, { XMFLOAT3( -1.0f, 1.0f, 1.0f ), XMFLOAT4( 1.0f, 1.0f, 0.0f, 1.0f ), XMFLOAT2( 0.0f, 1.0f ) }, { XMFLOAT3( -1.0f, -1.0f, -1.0f ), XMFLOAT4( 1.0f, 1.0f, 1.0f, 1.0f ), XMFLOAT2( 0.0f, 0.0f ) }, { XMFLOAT3( 1.0f, -1.0f, -1.0f ), XMFLOAT4( 1.0f, 1.0f, 1.0f, 1.0f ), XMFLOAT2( 1.0f, 0.0f ) }, { XMFLOAT3( 1.0f, -1.0f, 1.0f ), XMFLOAT4( 1.0f, 1.0f, 1.0f, 1.0f ), XMFLOAT2( 1.0f, 1.0f ) }, { XMFLOAT3( -1.0f, -1.0f, 1.0f ), XMFLOAT4( 1.0f, 1.0f, 1.0f, 1.0f ), XMFLOAT2( 0.0f, 1.0f ) }, { XMFLOAT3( -1.0f, -1.0f, 1.0f ), XMFLOAT4( 0.0f, 0.0f, 1.0f, 1.0f ), XMFLOAT2( 0.0f, 0.0f ) }, { XMFLOAT3( -1.0f, -1.0f, -1.0f ), XMFLOAT4( 0.0f, 1.0f, 1.0f, 1.0f ), XMFLOAT2( 1.0f, 0.0f ) }, { XMFLOAT3( -1.0f, 1.0f, -1.0f ), XMFLOAT4( 0.0f, 1.0f, 0.0f, 1.0f ), XMFLOAT2( 1.0f, 1.0f ) }, { XMFLOAT3( -1.0f, 1.0f, 1.0f ), XMFLOAT4( 0.0f, 1.0f, 1.0f, 1.0f ), XMFLOAT2( 0.0f, 1.0f ) }, { XMFLOAT3( 1.0f, -1.0f, 1.0f ), XMFLOAT4( 0.5f, 0.5f, 0.5f, 1.0f ), XMFLOAT2( 0.0f, 0.0f ) }, { XMFLOAT3( 1.0f, -1.0f, -1.0f ), XMFLOAT4( 0.5f, 0.5f, 0.5f, 1.0f ), XMFLOAT2( 1.0f, 0.0f ) }, { XMFLOAT3( 1.0f, 1.0f, -1.0f ), XMFLOAT4( 0.5f, 0.5f, 0.5f, 1.0f ), XMFLOAT2( 1.0f, 1.0f ) }, { XMFLOAT3( 1.0f, 1.0f, 1.0f ), XMFLOAT4( 0.5f, 0.5f, 0.5f, 1.0f ), XMFLOAT2( 0.0f, 1.0f ) }, { XMFLOAT3( -1.0f, -1.0f, -1.0f ), XMFLOAT4( 1.0f, 1.0f, 1.0f, 1.0f ), XMFLOAT2( 0.0f, 0.0f ) }, { XMFLOAT3( 1.0f, -1.0f, -1.0f ), XMFLOAT4( 1.0f, 1.0f, 1.0f, 1.0f ), XMFLOAT2( 1.0f, 0.0f ) }, { XMFLOAT3( 1.0f, 1.0f, -1.0f ), XMFLOAT4( 1.0f, 1.0f, 1.0f, 1.0f ), XMFLOAT2( 1.0f, 1.0f ) }, { XMFLOAT3( -1.0f, 1.0f, -1.0f ), XMFLOAT4( 1.0f, 1.0f, 1.0f, 1.0f ), XMFLOAT2( 0.0f, 1.0f ) }, { XMFLOAT3( -1.0f, -1.0f, 1.0f ), XMFLOAT4( 1.0f, 0.0f, 0.0f, 1.0f ), XMFLOAT2( 0.0f, 0.0f ) }, { XMFLOAT3( 1.0f, -1.0f, 1.0f ), XMFLOAT4( 0.0f, 1.0f, 0.0f, 1.0f ), XMFLOAT2( 1.0f, 0.0f ) }, { XMFLOAT3( 1.0f, 1.0f, 1.0f ), XMFLOAT4( 0.0f, 0.0f, 1.0f, 1.0f ), XMFLOAT2( 1.0f, 1.0f ) }, { XMFLOAT3( -1.0f, 1.0f, 1.0f ), XMFLOAT4( 0.0f, 0.0f, 0.0f, 1.0f ), XMFLOAT2( 0.0f, 1.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; //インデックスバッファの作成 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; // 36 vertices needed for 12 triangles in a triangle list 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; // コンスタントバッファの作成 bd.Usage = D3D11_USAGE_DEFAULT; bd.ByteWidth = sizeof(ConstantBuffer); bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER; bd.CPUAccessFlags = 0; hr = g_pd3dDevice->CreateBuffer( &bd, NULL, &g_pConstantBuffer ); if( FAILED( hr ) ) return hr; //画像をテクスチャにロード hr = D3DX11CreateShaderResourceViewFromFile( g_pd3dDevice, "suwako.png", NULL, NULL, &g_pTextureRV, NULL ); if( FAILED( hr ) ) return hr; //サンプラーステートの作成 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; //行列の設定 // ワールド行列は単位行列 g_World = XMMatrixIdentity(); //ビュー行列の定義 XMVECTOR Eye = XMVectorSet( 0.0f, 1.0f, -5.0f, 0.0f ); //カメラの位置 XMVECTOR At = XMVectorSet( 0.0f, 0.0f, 0.0f, 0.0f ); //カメラの注視先 XMVECTOR Up = XMVectorSet( 0.0f, 1.0f, 0.0f, 0.0f ); //カメラの真上のベクトル g_View = XMMatrixLookAtLH( Eye, At, Up ); //プロジェクション行列 g_Projection = XMMatrixPerspectiveFovLH( XM_PIDIV2, WIDTH / (FLOAT)HEIGHT, 0.01f, 100.0f ); InitOculusRiftObjects(); return S_OK; }
bool Prism::DirectX::D3DSwapChainSetup() { DXGI_SWAP_CHAIN_DESC swapChainDesc; ZeroMemory(&swapChainDesc, sizeof(DXGI_SWAP_CHAIN_DESC)); swapChainDesc.BufferCount = 1; swapChainDesc.BufferDesc.Width = mySetupInfo.myScreenWidth; swapChainDesc.BufferDesc.Height = mySetupInfo.myScreenHeight; swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; swapChainDesc.BufferDesc.RefreshRate.Numerator = 60; swapChainDesc.BufferDesc.RefreshRate.Denominator = 1; swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_SHADER_INPUT; swapChainDesc.OutputWindow = myHWND; swapChainDesc.SampleDesc.Count = 1; swapChainDesc.Windowed = true; HRESULT result = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, #ifdef RELEASE_BUILD NULL, #else D3D11_CREATE_DEVICE_DEBUG, #endif NULL, NULL, D3D11_SDK_VERSION, &swapChainDesc, &mySwapChain, &myDevice, NULL, &myContext); if (FAILED(result)) { return false; } #ifdef _DEBUG myDebugInterface = nullptr; result = myDevice->QueryInterface(__uuidof(ID3D11Debug), (void**)&myDebugInterface); if (FAILED(result)) { DL_ASSERT("[DirectX]: Failed to Query DebugInterface"); return false; } myInfoQueue = nullptr; if (FAILED(myDebugInterface->QueryInterface(__uuidof(ID3D11InfoQueue), (void**)&myInfoQueue))) { DL_ASSERT("[DirectX]: Failed to Query InfoQueue"); return false; } myInfoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_CORRUPTION, true); myInfoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_ERROR, true); D3D11_MESSAGE_ID hide[] = { D3D11_MESSAGE_ID_DEVICE_PSSETSHADERRESOURCES_HAZARD, D3D11_MESSAGE_ID_DEVICE_OMSETRENDERTARGETS_HAZARD // Add more message IDs here as needed }; D3D11_INFO_QUEUE_FILTER filter; memset(&filter, 0, sizeof(filter)); filter.DenyList.NumIDs = _countof(hide); filter.DenyList.pIDList = hide; myInfoQueue->AddStorageFilterEntries(&filter); myInfoQueue->Release(); #endif return TRUE; }
// WinMain int APIENTRY _tWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow ) { HRESULT hr; // ウィンドウクラスを登録 WNDCLASSEX wcex = { sizeof( WNDCLASSEX ), // cbSize CS_HREDRAW | CS_VREDRAW, // style WndProc, // lpfnWndProc 0, // cbClsExtra 0, // cbWndExtra hInstance, // hInstance NULL, // hIcon NULL, // hCursor ( HBRUSH )( COLOR_WINDOW + 1 ), // hbrBackGround NULL, // lpszMenuName g_className, // lpszClassName NULL // hIconSm }; if ( ! RegisterClassEx( &wcex ) ) { MessageBox( NULL, _T( "失敗: RegisterClassEx()" ), _T( "エラー" ), MB_OK | MB_ICONERROR ); return 0; } dtprintf( _T( "RegisterClassEx: ok\n" ) ); // ウィンドウサイズを計算 RECT r = { 0, 0, 800, 450 }; // 800x450 (16:9) if ( ! AdjustWindowRect( &r, WS_OVERLAPPEDWINDOW, FALSE ) ) { MessageBox( NULL, _T( "失敗: AdjustWindowRect()" ), _T( "エラー" ), MB_OK | MB_ICONERROR ); return 0; } dtprintf( _T( "AdjustWindowRect: ok (%d, %d)-(%d, %d)\n" ), r.left, r.top, r.right, r.bottom ); // ウィンドウ生成 HWND hWnd; hWnd = CreateWindow( g_className, g_windowName, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, r.right - r.left, r.bottom - r.top, NULL, NULL, hInstance, NULL ); if ( hWnd == NULL ) { MessageBox( NULL, _T( "失敗: CreateWindow()" ), _T( "エラー" ), MB_OK | MB_ICONERROR ); return 0; } dtprintf( _T( "CreateWindow: ok\n" ) ); // ウィンドウ表示 ShowWindow(hWnd, nCmdShow); dtprintf( _T( "ShowWindow: ok\n" ) ); // スワップチェイン設定 DXGI_SWAP_CHAIN_DESC scDesc = { { 1280, // BufferDesc.Width 720, // BufferDesc.Height { 60, // BufferDesc.RefreshRate.Numerator 1 // BufferDesc.RefreshRate.Denominator }, DXGI_FORMAT_R16G16B16A16_FLOAT, // BufferDesc.Format DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED, // BufferDesc.ScanlineOrdering DXGI_MODE_SCALING_CENTERED // BufferDesc.Scaling }, { 1, // SampleDesc.Count 0 // SampleDesc.Quality }, DXGI_USAGE_RENDER_TARGET_OUTPUT, // BufferUsage 1, // BufferCount hWnd, // OutputWindow TRUE, // Windowed DXGI_SWAP_EFFECT_DISCARD, // SwapEffect DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH // Flags }; // Direct3D11 デバイス・デバイスコンテキスト・スワップチェーンを生成 ID3D11Device * pDevice = NULL; ID3D11DeviceContext * pDeviceContext = NULL; IDXGISwapChain * pSwapChain = NULL; D3D_FEATURE_LEVEL feature; hr = D3D11CreateDeviceAndSwapChain( NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, NULL, 0, D3D11_SDK_VERSION, &scDesc, &pSwapChain, &pDevice, &feature, &pDeviceContext ); if ( FAILED( hr ) ) { MessageBox( NULL, _T( "失敗: D3D11CreateDeviceAndSwapChain()" ), _T( "エラー" ), MB_OK | MB_ICONERROR ); return 0; } dtprintf( _T( "D3D11CreateDeviceAndSwapChain: ok (pDevice: 0x%p, pDeviceContext: 0x%p, pSwapChain: 0x%p, feature: 0x%4x)\n" ), pDevice, pDeviceContext, pSwapChain, ( int ) feature ); // バックバッファテクスチャを取得 ID3D11Texture2D * pBackBuffer = NULL; hr = pSwapChain->GetBuffer( 0, __uuidof( pBackBuffer ), reinterpret_cast< void ** >( &pBackBuffer ) ); if ( FAILED( hr ) ) { MessageBox( NULL, _T( "失敗: IDXGISwapChain::GetBuffer()" ), _T( "エラー" ), MB_OK | MB_ICONERROR ); return 0; } dtprintf( _T( "IDXGISwapChain::GetBuffer: ok (pBackBuffer: 0x%p)\n" ), pBackBuffer ); // レンダーターゲットビューを生成 ID3D11RenderTargetView * pRenderTargetView = NULL; hr = pDevice->CreateRenderTargetView( pBackBuffer, NULL, &pRenderTargetView ); if ( FAILED( hr ) ) { MessageBox( NULL, _T( "失敗: ID3D11Device::CreateRenderTargetView()" ), _T( "エラー" ), MB_OK | MB_ICONERROR ); return 0; } dtprintf( _T( "ID3D11Device::CreateRenderTargetView: ok (pRenderTargetView: 0x%p)\n" ), pRenderTargetView ); // デプス・ステンシルバッファとなるテクスチャを生成 D3D11_TEXTURE2D_DESC depthStencilBufferDesc = { 1280, // Width 720, // Height 1, // MipLevels 1, // ArraySize DXGI_FORMAT_D32_FLOAT, // Format { 1, // SampleDesc.Count 0 // SampleDesc.Quality }, D3D11_USAGE_DEFAULT, // Usage D3D11_BIND_DEPTH_STENCIL, // BindFlags 0, // CPUAccessFlags 0 // MiscFlags }; ID3D11Texture2D * pDepthStencilBuffer = NULL; hr = pDevice->CreateTexture2D( &depthStencilBufferDesc, NULL, &pDepthStencilBuffer ); if ( FAILED( hr ) ) { MessageBox( NULL, _T( "失敗: ID3D11Device::CreateTexture2D()" ), _T( "エラー" ), MB_OK | MB_ICONERROR ); return 0; } dtprintf( _T( "ID3D11Device::CreateTexture2D: ok (pDepthStencilBuffer: 0x%p)\n" ), pDepthStencilBuffer ); // デプス・ステンシルビューを生成 ID3D11DepthStencilView * pDepthStencilView = NULL; hr = pDevice->CreateDepthStencilView( pDepthStencilBuffer, NULL, &pDepthStencilView ); if ( FAILED( hr ) ) { MessageBox( NULL, _T( "失敗: ID3D11Device::CreateDepthStencilView()" ), _T( "エラー" ), MB_OK | MB_ICONERROR ); return 0; } dtprintf( _T( "ID3D11Device::CreateDepthStencilView: ok (pDepthStencilView: 0x%p)\n" ), pDepthStencilView ); // レンダーターゲットビューとデプス・ステンシルビューをバインド ID3D11RenderTargetView * pRenderTargetViews[] = { pRenderTargetView }; pDeviceContext->OMSetRenderTargets( 1, pRenderTargetViews, pDepthStencilView ); dtprintf( _T( "ID3D11DeviceContext::OMSetRenderTargets: ok\n" ) ); // バックバッファはもうここでは使わない COM_SAFE_RELEASE( pBackBuffer ); // ビューポートをバインド D3D11_VIEWPORT viewport = { 0.0f, // TopLeftX 0.0f, // TopLeftY 1280.0f, // Width 720.0f, // Height 0.0f, // MinDepth 1.0f // MaxDepth }; pDeviceContext->RSSetViewports( 1, &viewport ); dtprintf( _T( "ID3D11DeviceContext::RSSetViewports: ok\n" ) ); // Metasequoia モデル変換データ読み込み // fread の引数 path/to/exported_data を、エクスポートしたモデルデータファイルに変更してください。 FILE *fp; unsigned int vertices_count = 0; unsigned int faces_count = 0; float * metasequoiaVertices = NULL; unsigned int * metasequoiaIndices = NULL; if ( ( fp = fopen( "path/to/exported_data", "rb" ) ) == NULL ) { MessageBox( NULL, _T( "失敗: fopen()" ), _T( "エラー" ), MB_OK | MB_ICONERROR ); return 0; } // 頂点数 fread( &vertices_count, sizeof( unsigned int ), 1, fp ); // メモリ確保・読み込み metasequoiaVertices = new float[ 6 * vertices_count ]; fread( metasequoiaVertices, sizeof( float ) * 6, vertices_count, fp ); // 面数 fread( &faces_count, sizeof( unsigned int ), 1, fp ); // メモリ確保・読み込み metasequoiaIndices = new unsigned int[ 3 * faces_count ]; fread( metasequoiaIndices, sizeof( unsigned int ) * 3, faces_count, fp ); // モデル表示用の頂点バッファを生成 D3D11_BUFFER_DESC metasequoiaVertexBufferDesc = { sizeof( float ) * 6 * vertices_count, // ByteWidth D3D11_USAGE_DEFAULT, // Usage D3D11_BIND_VERTEX_BUFFER, // BindFlags 0, // CPUAccessFlags 0, // MiscFlags 0 // StructureByteStride }; D3D11_SUBRESOURCE_DATA metasequoiaVertexResourceData = { metasequoiaVertices }; ID3D11Buffer * pMetasequoiaVertexBuffer = NULL; hr = pDevice->CreateBuffer( &metasequoiaVertexBufferDesc, &metasequoiaVertexResourceData, &pMetasequoiaVertexBuffer ); if ( FAILED( hr ) ) { MessageBox( NULL, _T( "失敗: ID3D11Device::CreateBuffer()" ), _T( "エラー" ), MB_OK | MB_ICONERROR ); return 0; } dtprintf( _T( "ID3D11Device::CreateBuffer: ok (pMetasequoiaVertexBuffer: 0x%p)\n" ), pMetasequoiaVertexBuffer ); // モデル表示用のインデックスバッファを生成 D3D11_BUFFER_DESC metasequoiaIndexBufferDesc = { sizeof( unsigned int ) * 3 * faces_count, // ByteWidth D3D11_USAGE_DEFAULT, // Usage D3D11_BIND_INDEX_BUFFER, // BindFlags 0, // CPUAccessFlags 0, // MiscFlags 0 // StructureByteStride }; D3D11_SUBRESOURCE_DATA metasequoiaIndexResourceData = { metasequoiaIndices }; ID3D11Buffer * pMetasequoiaIndexBuffer = NULL; hr = pDevice->CreateBuffer( &metasequoiaIndexBufferDesc, &metasequoiaIndexResourceData, &pMetasequoiaIndexBuffer ); if ( FAILED( hr ) ) { MessageBox( NULL, _T( "失敗: ID3D11Device::CreateBuffer()" ), _T( "エラー" ), MB_OK | MB_ICONERROR ); return 0; } dtprintf( _T( "ID3D11Device::CreateBuffer: ok (pMetasequoiaIndexBuffer: 0x%p)\n" ), pMetasequoiaIndexBuffer ); // モデル表示用のインデックスバッファをバインド pDeviceContext->IASetIndexBuffer( pMetasequoiaIndexBuffer, DXGI_FORMAT_R32_UINT, 0 ); dtprintf( _T( "ID3D11DeviceContext::IASetIndexBuffer: ok\n" ) ); // 3 軸線の頂点データ float triaxialVertices[ 12 ][ 7 ] = { // Xaxis Yaxis Zaxis 赤 緑 青 Alpha { 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f }, // x 軸正方向 { 200.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f }, { 0.0f, 0.0f, 0.0f, 0.2f, 0.0f, 0.0f, 1.0f }, // x 軸負方向 { -200.0f, 0.0f, 0.0f, 0.2f, 0.0f, 0.0f, 1.0f }, { 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f }, // y 軸正方向 { 0.0f, 500.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f }, { 0.0f, 0.0f, 0.0f, 0.0f, 0.2f, 0.0f, 1.0f }, // y 軸負方向 { 0.0f, -500.0f, 0.0f, 0.0f, 0.2f, 0.0f, 1.0f }, { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f }, // z 軸正方向 { 0.0f, 0.0f, 100.0f, 0.0f, 0.0f, 1.0f, 1.0f }, { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.2f, 1.0f }, // z 軸負方向 { 0.0f, 0.0f, -100.0f, 0.0f, 0.0f, 0.2f, 1.0f } }; // 3 軸線の頂点バッファを生成 D3D11_BUFFER_DESC triaxialVertexBufferDesc = { sizeof( triaxialVertices ), // ByteWidth D3D11_USAGE_DEFAULT, // Usage D3D11_BIND_VERTEX_BUFFER, // BindFlags 0, // CPUAccessFlags 0, // MiscFlags 0 // StructureByteStride }; D3D11_SUBRESOURCE_DATA triaxialVertexResourceData = { triaxialVertices }; ID3D11Buffer * pTriaxialVertexBuffer = NULL; hr = pDevice->CreateBuffer( &triaxialVertexBufferDesc, &triaxialVertexResourceData, &pTriaxialVertexBuffer ); if ( FAILED( hr ) ) { MessageBox( NULL, _T( "失敗: ID3D11Device::CreateBuffer()" ), _T( "エラー" ), MB_OK | MB_ICONERROR ); return 0; } dtprintf( _T( "ID3D11Device::CreateBuffer: ok (pTriaxialVertexBuffer: 0x%p)\n" ), pTriaxialVertexBuffer ); // 頂点シェーダ用の定数バッファを作成 D3D11_BUFFER_DESC VSConstantBufferDesc = { sizeof( D3DXMATRIX ) * 3, // ByteWidth D3D11_USAGE_DYNAMIC, // Usage D3D11_BIND_CONSTANT_BUFFER, // BindFlags D3D11_CPU_ACCESS_WRITE, // CPUAccessFlags 0, // MiscFlags 0 // StructureByteStride }; ID3D11Buffer * pVSConstantBuffer = NULL; hr = pDevice->CreateBuffer( &VSConstantBufferDesc, NULL, &pVSConstantBuffer ); if ( FAILED( hr ) ) { MessageBox( NULL, _T( "失敗: ID3D11Device::CreateBuffer()" ), _T( "エラー" ), MB_OK | MB_ICONERROR ); return 0; } dtprintf( _T( "ID3D11Device::CreateBuffer: ok (pVSConstantBuffer: 0x%p)\n" ), pVSConstantBuffer ); // 定数バッファをバインド pDeviceContext->VSSetConstantBuffers( 0, 1, &pVSConstantBuffer ); dtprintf( _T( "ID3D11DeviceContext::VSSetConstantBuffers: ok\n" ) ); // 3 軸線表示用の頂点シェーダを作成 ID3D11VertexShader * pTriaxialVertexShader = NULL; hr = pDevice->CreateVertexShader( g_vs_perspective, sizeof( g_vs_perspective ), NULL, &pTriaxialVertexShader ); if ( FAILED( hr ) ) { MessageBox( NULL, _T( "失敗: ID3D11Device::CreateVertexShader()" ), _T( "エラー" ), MB_OK | MB_ICONERROR ); return 0; } dtprintf( _T( "ID3D11Device::CreateVertexShader: ok (pTriaxialVertexShader: 0x%p)\n" ), pTriaxialVertexShader ); // モデル表示用の頂点シェーダを作成 ID3D11VertexShader * pMetasequoiaVertexShader = NULL; hr = pDevice->CreateVertexShader( g_vs_metasequoiaNormal, sizeof( g_vs_metasequoiaNormal ), NULL, &pMetasequoiaVertexShader ); if ( FAILED( hr ) ) { MessageBox( NULL, _T( "失敗: ID3D11Device::CreateVertexShader()" ), _T( "エラー" ), MB_OK | MB_ICONERROR ); return 0; } dtprintf( _T( "ID3D11Device::CreateVertexShader: ok (pMetasequoiaVertexShader: 0x%p)\n" ), pMetasequoiaVertexShader ); // ピクセルシェーダを作成 ID3D11PixelShader * pPixelShader = NULL; hr = pDevice->CreatePixelShader( g_ps_constant, sizeof( g_ps_constant ), NULL, &pPixelShader ); if ( FAILED( hr ) ) { MessageBox( NULL, _T( "失敗: ID3D11Device::CreatePixelShader()" ), _T( "エラー" ), MB_OK | MB_ICONERROR ); return 0; } dtprintf( _T( "ID3D11Device::CreatePixelShader: ok (pPixelShader: 0x%p)\n" ), pPixelShader ); // シェーダをバインド pDeviceContext->VSSetShader( NULL, NULL, 0 ); // pDeviceContext->VSSetShader( pVertexShader, NULL, 0 ); // dtprintf( _T( "ID3D11DeviceContext::VSSetShader: ok\n" ) ); pDeviceContext->PSSetShader( pPixelShader, NULL, 0 ); dtprintf( _T( "ID3D11DeviceContext::PSSetShader: ok\n" ) ); pDeviceContext->GSSetShader( NULL, NULL, 0 ); pDeviceContext->HSSetShader( NULL, NULL, 0 ); pDeviceContext->DSSetShader( NULL, NULL, 0 ); // 3 軸線表示用の入力レイアウトを作成 D3D11_INPUT_ELEMENT_DESC triaxialVerticesDesc[] = { { "IN_POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "IN_COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, sizeof(float)*3, D3D11_INPUT_PER_VERTEX_DATA, 0 } }; ID3D11InputLayout * pTriaxialInputLayout = NULL; hr = pDevice->CreateInputLayout( triaxialVerticesDesc, 2, g_vs_perspective, sizeof( g_vs_perspective ), &pTriaxialInputLayout ); if ( FAILED( hr ) ) { MessageBox( NULL, _T( "失敗: ID3D11Device::CreateInputLayout()" ), _T( "エラー" ), MB_OK | MB_ICONERROR ); return 0; } dtprintf( _T( "ID3D11Device::CreateInputLayout: ok (pTriaxialInputLayout: 0x%p)\n" ), pTriaxialInputLayout ); // モデル表示用の入力レイアウトを作成 D3D11_INPUT_ELEMENT_DESC metasequoiaVerticesDesc[] = { { "IN_POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "IN_NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, sizeof(float)*3, D3D11_INPUT_PER_VERTEX_DATA, 0 } }; ID3D11InputLayout * pMetasequoiaInputLayout = NULL; hr = pDevice->CreateInputLayout( metasequoiaVerticesDesc, 2, g_vs_metasequoiaNormal, sizeof( g_vs_metasequoiaNormal ), &pMetasequoiaInputLayout ); if ( FAILED( hr ) ) { MessageBox( NULL, _T( "失敗: ID3D11Device::CreateInputLayout()" ), _T( "エラー" ), MB_OK | MB_ICONERROR ); return 0; } dtprintf( _T( "ID3D11Device::CreateInputLayout: ok (pMetasequoiaInputLayout: 0x%p)\n" ), pMetasequoiaInputLayout ); // ラスタライザステートを生成 D3D11_RASTERIZER_DESC rasterizerStateDesc = { D3D11_FILL_SOLID, // FillMode // D3D11_FILL_WIREFRAME, // FillMode (ワイヤーフレーム表示) // D3D11_CULL_BACK, // CullMode D3D11_CULL_NONE, // CullMode (カリングなし) FALSE, // FrontCounterClockwise 0, // DepthBias 0.0f, // DepthBiasClamp 0.0f, // SlopeScaledDepthBias TRUE, // DepthClipEnable FALSE, // ScissorEnable FALSE, // MultisampleEnable FALSE // AntialiasedLineEnable }; ID3D11RasterizerState * pRasterizerState = NULL; hr = pDevice->CreateRasterizerState( &rasterizerStateDesc, &pRasterizerState ); if ( FAILED( hr ) ) { MessageBox( NULL, _T( "失敗: ID3D11Device::CreateRasterizerState()" ), _T( "エラー" ), MB_OK | MB_ICONERROR ); return 0; } dtprintf( _T( "ID3D11Device::CreateRasterizerState: ok (pRasterizerState: 0x%p)\n" ), pRasterizerState ); // ラスタライザステートをバインド pDeviceContext->RSSetState( pRasterizerState ); dtprintf( _T( "ID3D11DeviceContext::RSSetState: ok\n" ) ); // デプス・ステンシルステートを生成 D3D11_DEPTH_STENCIL_DESC depthStencilStateDesc = { TRUE, // DepthEnable D3D11_DEPTH_WRITE_MASK_ALL, // DepthWriteMask D3D11_COMPARISON_LESS, // DepthFunc FALSE, // StencilEnable D3D11_DEFAULT_STENCIL_READ_MASK, // StencilReadMask D3D11_DEFAULT_STENCIL_WRITE_MASK, // StencilWriteMask { D3D11_STENCIL_OP_KEEP, // FrontFace.StencilFailOp D3D11_STENCIL_OP_KEEP, // FrontFace.StencilDepthFailOp D3D11_STENCIL_OP_KEEP, // FrontFace.StencilPassOp D3D11_COMPARISON_ALWAYS // FrontFace.StencilFunc }, { D3D11_STENCIL_OP_KEEP, // BackFace.StencilFailOp D3D11_STENCIL_OP_KEEP, // BackFace.StencilDepthFailOp D3D11_STENCIL_OP_KEEP, // BackFace.StencilPassOp D3D11_COMPARISON_ALWAYS // BackFace.StencilFunc } }; ID3D11DepthStencilState * pDepthStencilState = NULL; hr = pDevice->CreateDepthStencilState( &depthStencilStateDesc, &pDepthStencilState ); if ( FAILED( hr ) ) { MessageBox( NULL, _T( "失敗: ID3D11Device::CreateDepthStencilState()" ), _T( "エラー" ), MB_OK | MB_ICONERROR ); return 0; } dtprintf( _T( "ID3D11Device::CreateDepthStencilState: ok (pDepthStencilState: 0x%p)\n" ), pDepthStencilState ); // デプス・ステンシルステートをバインド pDeviceContext->OMSetDepthStencilState( pDepthStencilState, 0 ); dtprintf( _T( "ID3D11DeviceContext::OMSetDepthStencilState: ok\n" ) ); MSG msg; while ( 1 ) { // メッセージを取得 if ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ) { if ( msg.message == WM_QUIT ) { dtprintf( _T( "PeekMessage: WM_QUIT\n" ) ); break; } // メッセージ処理 DispatchMessage( &msg ); } else { HRESULT hr; static unsigned int count = 0; float theta = ( count++ / 200.0f ) * ( 3.141593f / 2.0f ); // World-View-Projection 行列をそれぞれ生成 D3DXMATRIX world, view, projection; D3DXMatrixIdentity( &world ); const D3DXVECTOR3 eye( 500.0f * 1.414214f * -cosf( theta ), 100.0f, 500.0f * 1.414214f * sinf( theta ) ); const D3DXVECTOR3 at( 0.0f, -50.0f, 0.0f ); const D3DXVECTOR3 up( 0.0f, 1.0f, 0.0f ); D3DXMatrixLookAtRH( &view, &eye, &at, &up ); D3DXMatrixPerspectiveFovRH( &projection, 3.141593f / 4.0f, 1280.0f / 720.0f, 1.0f, 10000.0f ); // 頂点シェーダ用定数バッファへアクセス D3D11_MAPPED_SUBRESOURCE mapped; hr = pDeviceContext->Map( pVSConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped ); if ( SUCCEEDED( hr ) ) { D3DXMATRIX * mapped_m = static_cast< D3DXMATRIX * >( mapped.pData ); mapped_m[0] = world; mapped_m[1] = view; mapped_m[2] = projection; // 後始末 pDeviceContext->Unmap( pVSConstantBuffer, 0 ); } // レンダーターゲットビューをクリア const float clear[ 4 ] = { 0.0f, 0.25f, 0.5f, 1.0f }; // RGBA pDeviceContext->ClearRenderTargetView( pRenderTargetView, clear ); // デプス・ステンシルビューをクリア pDeviceContext->ClearDepthStencilView( pDepthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0 ); ///// 3 軸線の描画 // 頂点バッファをバインド UINT strides[] = { sizeof( float ) * 7 }; UINT offsets[] = { 0 }; pDeviceContext->IASetVertexBuffers( 0, 1, &pTriaxialVertexBuffer, strides, offsets ); // プリミティブタイプを設定 pDeviceContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_LINELIST ); // 頂点シェーダをバインド pDeviceContext->VSSetShader( pTriaxialVertexShader, NULL, 0 ); // 入力レイアウトをバインド pDeviceContext->IASetInputLayout( pTriaxialInputLayout ); // 描画 pDeviceContext->Draw( 12, 0 ); ///// モデルの描画 // 頂点バッファをバインド strides[0] = sizeof( float ) * 6; pDeviceContext->IASetVertexBuffers( 0, 1, &pMetasequoiaVertexBuffer, strides, offsets ); // プリミティブタイプを設定 pDeviceContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST ); // 頂点シェーダをバインド pDeviceContext->VSSetShader( pMetasequoiaVertexShader, NULL, 0 ); // 入力レイアウトをバインド pDeviceContext->IASetInputLayout( pMetasequoiaInputLayout ); // 描画 pDeviceContext->DrawIndexed( 3 * faces_count, 0, 0 ); pSwapChain->Present( 1, 0 ); // ちょっとだけ待つ Sleep( 5 ); } } // シェーダをアンバインド pDeviceContext->VSSetShader( NULL, NULL, 0 ); pDeviceContext->PSSetShader( NULL, NULL, 0 ); // デバイス・リソース解放 COM_SAFE_RELEASE( pDepthStencilState ); COM_SAFE_RELEASE( pRasterizerState ); COM_SAFE_RELEASE( pMetasequoiaInputLayout ); COM_SAFE_RELEASE( pTriaxialInputLayout ); COM_SAFE_RELEASE( pPixelShader ); COM_SAFE_RELEASE( pMetasequoiaVertexShader ); COM_SAFE_RELEASE( pTriaxialVertexShader ); COM_SAFE_RELEASE( pVSConstantBuffer ); COM_SAFE_RELEASE( pTriaxialVertexBuffer ); COM_SAFE_RELEASE( pMetasequoiaIndexBuffer ); COM_SAFE_RELEASE( pMetasequoiaVertexBuffer ); COM_SAFE_RELEASE( pDepthStencilView ); COM_SAFE_RELEASE( pDepthStencilBuffer ); COM_SAFE_RELEASE( pRenderTargetView ); COM_SAFE_RELEASE( pSwapChain ); COM_SAFE_RELEASE( pDeviceContext ); COM_SAFE_RELEASE( pDevice ); // メモリ解放 delete [] metasequoiaVertices; delete [] metasequoiaIndices; return msg.wParam; }
BOOL CSGRenderEngineDX11::InitDevice(HWND hWnd,int nDeviceWidth,int nDeviceHeight) { HRESULT hr = S_OK; UINT nCreateDeviceFlags = 0; #ifdef _DEBUG nCreateDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG; #endif D3D_DRIVER_TYPE eDriveType[] = { D3D_DRIVER_TYPE_HARDWARE, D3D_DRIVER_TYPE_SOFTWARE, D3D_DRIVER_TYPE_REFERENCE }; UINT nDriverTypeNum = ARRAYSIZE(eDriveType); D3D_FEATURE_LEVEL eFeatureLevel[] = { D3D_FEATURE_LEVEL_10_0, D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_11_0 }; UINT nFeatureNum = ARRAYSIZE(eFeatureLevel); DXGI_SWAP_CHAIN_DESC swapchainDesc; ZeroMemory(&swapchainDesc,sizeof(swapchainDesc)); swapchainDesc.BufferCount = 1; swapchainDesc.BufferDesc.Width = nDeviceWidth; swapchainDesc.BufferDesc.Height = nDeviceHeight; swapchainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; swapchainDesc.BufferDesc.RefreshRate.Numerator = 60; swapchainDesc.BufferDesc.RefreshRate.Denominator = 1; swapchainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swapchainDesc.SampleDesc.Count = 1; swapchainDesc.SampleDesc.Quality = 0; swapchainDesc.OutputWindow = hWnd; swapchainDesc.Windowed = TRUE; for(int i = 0; i< nDriverTypeNum; i++) { D3D_DRIVER_TYPE eType = eDriveType[i]; D3D_FEATURE_LEVEL eLevel; hr = D3D11CreateDeviceAndSwapChain(NULL,eType, NULL,nCreateDeviceFlags, eFeatureLevel,nFeatureNum, D3D11_SDK_VERSION,&swapchainDesc, &m_p11SwapChain,&m_p11Device, &eLevel,&m_p11DeviceContext); if(SUCCEEDED(hr)) break; } if(FAILED(hr)) return FALSE; // RenderTargetView ID3D11Texture2D* p2DTexBuffer = NULL; m_p11SwapChain->GetBuffer(0,__uuidof(ID3D11Texture2D),(void**)&p2DTexBuffer); hr = m_p11Device->CreateRenderTargetView((ID3D11Resource*)p2DTexBuffer,NULL,&m_p11TargetView); p2DTexBuffer->Release(); if(FAILED(hr)) return FALSE; m_p11DeviceContext->OMSetRenderTargets(1,&m_p11TargetView,NULL); D3D11_VIEWPORT vpD3D11; vpD3D11.TopLeftX = 0.f; vpD3D11.TopLeftY = 0.f; vpD3D11.Width = nDeviceWidth; vpD3D11.Height = nDeviceHeight; vpD3D11.MinDepth = 0.f; vpD3D11.MaxDepth = 1.f; m_p11DeviceContext->RSSetViewports(1,&vpD3D11); return TRUE; }
/*------------------------------------------- Direct3D初期化 --------------------------------------------*/ HRESULT InitDirect3D(void) { // ウインドウのクライアント エリア RECT rc; GetClientRect(g_hWindow, &rc); UINT width = rc.right - rc.left; UINT height = rc.bottom - rc.top; // デバイスとスワップ チェインの作成 DXGI_SWAP_CHAIN_DESC sd; ZeroMemory(&sd, sizeof(sd)); // 構造体の値を初期化 sd.BufferCount = 3; // バック バッファ数 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.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_PROGRESSIVE; // スキャンライン sd.BufferDesc.Scaling = DXGI_MODE_SCALING_CENTERED; // スケーリング sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; // バック バッファの使用法 sd.OutputWindow = g_hWindow; // 関連付けるウインドウ sd.SampleDesc.Count = 1; // マルチ サンプルの数 sd.SampleDesc.Quality = 0; // マルチ サンプルのクオリティ sd.Windowed = TRUE; // ウインドウ モード sd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; // モード自動切り替え #if defined(DEBUG) || defined(_DEBUG) UINT createDeviceFlags = D3D11_CREATE_DEVICE_DEBUG; #else UINT createDeviceFlags = 0; #endif // ハードウェア・デバイスを作成 HRESULT hr = D3D11CreateDeviceAndSwapChain( NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, createDeviceFlags, g_pFeatureLevels, g_FeatureLevels, D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pD3DDevice, &g_FeatureLevelsSupported, &g_pImmediateContext); if(FAILED(hr)) { // WARPデバイスを作成 hr = D3D11CreateDeviceAndSwapChain( NULL, D3D_DRIVER_TYPE_WARP, NULL, createDeviceFlags, g_pFeatureLevels, g_FeatureLevels, D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pD3DDevice, &g_FeatureLevelsSupported, &g_pImmediateContext); if(FAILED(hr)) { // リファレンス・デバイスを作成 hr = D3D11CreateDeviceAndSwapChain( NULL, D3D_DRIVER_TYPE_REFERENCE, NULL, createDeviceFlags, g_pFeatureLevels, g_FeatureLevels, D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pD3DDevice, &g_FeatureLevelsSupported, &g_pImmediateContext); if(FAILED(hr)) { return DXTRACE_ERR(L"InitDirect3D D3D11CreateDeviceAndSwapChain", hr); } } } // ********************************************************** // シェーダのコンパイル hr = CreateShaderObj(); if (FAILED(hr)) return DXTRACE_ERR(L"InitDirect3D CreateShaderObj", hr); hr = CreateShaderShadow(); if (FAILED(hr)) return DXTRACE_ERR(L"InitDirect3D CreateShaderShadow", hr); // ********************************************************** // 定数バッファの定義 D3D11_BUFFER_DESC cBufferDesc; cBufferDesc.Usage = D3D11_USAGE_DYNAMIC; // 動的(ダイナミック)使用法 cBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; // 定数バッファ cBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; // CPUから書き込む cBufferDesc.MiscFlags = 0; cBufferDesc.StructureByteStride = 0; // 定数バッファの作成 cBufferDesc.ByteWidth = sizeof(cbCBuffer); // バッファ・サイズ hr = g_pD3DDevice->CreateBuffer(&cBufferDesc, NULL, &g_pCBuffer); if (FAILED(hr)) return DXTRACE_ERR(L"InitDirect3D g_pD3DDevice->CreateBuffer", hr); // ********************************************************** // ブレンド・ステート・オブジェクトの作成 D3D11_BLEND_DESC BlendState; ZeroMemory(&BlendState, sizeof(D3D11_BLEND_DESC)); BlendState.AlphaToCoverageEnable = FALSE; BlendState.IndependentBlendEnable = FALSE; BlendState.RenderTarget[0].BlendEnable = FALSE; BlendState.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; hr = g_pD3DDevice->CreateBlendState(&BlendState, &g_pBlendState); if (FAILED(hr)) return DXTRACE_ERR(L"InitDirect3D g_pD3DDevice->CreateBlendState", hr); // ********************************************************** // 深度/ステンシル・ステート・オブジェクトの作成 D3D11_DEPTH_STENCIL_DESC DepthStencil; DepthStencil.DepthEnable = TRUE; // 深度テストあり DepthStencil.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; // 書き込む DepthStencil.DepthFunc = D3D11_COMPARISON_LESS; // 手前の物体を描画 DepthStencil.StencilEnable = FALSE; // ステンシル・テストなし DepthStencil.StencilReadMask = 0xff; // ステンシル読み込みマスク。 DepthStencil.StencilWriteMask = 0xff; // ステンシル書き込みマスク。 // 面が表を向いている場合のステンシル・テストの設定 DepthStencil.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; // 維持 DepthStencil.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; // 維持 DepthStencil.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; // 維持 DepthStencil.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; // 常に成功 // 面が裏を向いている場合のステンシル・テストの設定 DepthStencil.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; // 維持 DepthStencil.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; // 維持 DepthStencil.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; // 維持 DepthStencil.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; // 常に成功 hr = g_pD3DDevice->CreateDepthStencilState(&DepthStencil, &g_pDepthStencilState); if (FAILED(hr)) return DXTRACE_ERR(L"InitDirect3D g_pD3DDevice->CreateDepthStencilState", hr); // ********************************************************** // Waveform OBJファイルの読み込み char mtlFileName[80]; if (g_wfObjKuma.Load(g_pD3DDevice, g_pImmediateContext, "..\\misc\\kuma.obj", mtlFileName, sizeof(mtlFileName)) == false) return DXTRACE_ERR(L"InitDirect3D g_wfObjKuma.Load", E_FAIL); // MTLファイルの読み込み if (g_wfMtl.Load(g_pD3DDevice, mtlFileName, "..\\misc\\default.bmp") == false) return DXTRACE_ERR(L"InitDirect3D g_wfMtl.Load", E_FAIL); // ********************************************************** // サンプラーの作成 D3D11_SAMPLER_DESC descSampler; descSampler.Filter = D3D11_FILTER_ANISOTROPIC; descSampler.AddressU = D3D11_TEXTURE_ADDRESS_WRAP; descSampler.AddressV = D3D11_TEXTURE_ADDRESS_WRAP; descSampler.AddressW = D3D11_TEXTURE_ADDRESS_WRAP; descSampler.MipLODBias = 0.0f; descSampler.MaxAnisotropy = 2; descSampler.ComparisonFunc = D3D11_COMPARISON_NEVER; descSampler.BorderColor[0] = 0.0f; descSampler.BorderColor[1] = 0.0f; descSampler.BorderColor[2] = 0.0f; descSampler.BorderColor[3] = 0.0f; descSampler.MinLOD = -FLT_MAX; descSampler.MaxLOD = FLT_MAX; hr = g_pD3DDevice->CreateSamplerState(&descSampler, &g_pTextureSampler[0]); if (FAILED(hr)) return DXTRACE_ERR(L"InitDirect3D g_pD3DDevice->CreateSamplerState", hr); descSampler.AddressU = D3D11_TEXTURE_ADDRESS_BORDER; descSampler.AddressV = D3D11_TEXTURE_ADDRESS_BORDER; descSampler.AddressW = D3D11_TEXTURE_ADDRESS_BORDER; descSampler.BorderColor[0] = 1.0f; descSampler.BorderColor[1] = 1.0f; descSampler.BorderColor[2] = 1.0f; descSampler.BorderColor[3] = 1.0f; hr = g_pD3DDevice->CreateSamplerState(&descSampler, &g_pTextureSampler[1]); if (FAILED(hr)) return DXTRACE_ERR(L"InitDirect3D g_pD3DDevice->CreateSamplerState", hr); // ********************************************************** // バック バッファの初期化 hr = InitBackBuffer(); if (FAILED(hr)) return DXTRACE_ERR(L"InitDirect3D InitBackBuffer", hr); // ********************************************************** // シャドウ・マップの作成 hr = InitShadowMap(); if (FAILED(hr)) return DXTRACE_ERR(L"InitDirect3D InitShadowMap", hr); return hr; }
//DirectX initialization bool Game::InitApp(HINSTANCE hInstance, HWND hwnd) { hwndRef = hwnd; ZeroMemory(&bufferDesc, sizeof(DXGI_MODE_DESC)); //Back buffer properties bufferDesc.Width = WIDTH; bufferDesc.Height = HEIGHT; bufferDesc.RefreshRate.Numerator = 60; //60 frames... bufferDesc.RefreshRate.Denominator = 1; //per second bufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; //display format bufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; //how the rasterizer will render onto a surface bufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; //how images are stretched to fit resolution of monitor ZeroMemory(&scd, sizeof(DXGI_SWAP_CHAIN_DESC)); //Describe our SwapChain scd.BufferDesc = bufferDesc; scd.SampleDesc.Count = 1; //multisampling, makes objects less pixelated scd.SampleDesc.Quality = 0; scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; scd.BufferCount = 1; //number of back buffers in use scd.OutputWindow = hwndRef; //handle to window scd.Windowed = true; //windowed or full screen scd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; //how back buffer swaps with front buffer hr = D3D11CreateDeviceAndSwapChain(NULL, //video adapter to use (NULL is default) D3D_DRIVER_TYPE_HARDWARE, //how Direct3D will be implemented (video card or software) NULL, //software rasterizing NULL, NULL, NULL, D3D11_SDK_VERSION, //version of Direct3D to use &scd, &swapChain, &device, NULL, //feature levels for backwards compatibility &deviceContext); if (FAILED(hr)) { MessageBox(NULL, DXGetErrorDescription(hr), TEXT("D3D11CreateDeviceAndSwapChain"), MB_OK); return 0; } //Creating back buffer ID3D11Texture2D* backBuffer; hr = swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&backBuffer); //Create the render target hr = device->CreateRenderTargetView(backBuffer, NULL, &renderTargetView); backBuffer->Release(); if (FAILED(hr)) { MessageBox(NULL, DXGetErrorDescription(hr), TEXT("d3d11Device->CreateRenderTargetView"), MB_OK); return 0; } //Defining depth/stencil buffer depthStencilDesc.Width = WIDTH; depthStencilDesc.Height = HEIGHT; depthStencilDesc.MipLevels = 1; depthStencilDesc.ArraySize = 1; depthStencilDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; depthStencilDesc.SampleDesc.Count = 1; depthStencilDesc.SampleDesc.Quality = 0; depthStencilDesc.Usage = D3D11_USAGE_DEFAULT; depthStencilDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL; depthStencilDesc.CPUAccessFlags = 0; depthStencilDesc.MiscFlags = 0; //Creating depth/stencil buffer device->CreateTexture2D(&depthStencilDesc, NULL, &depthStencilBuffer); device->CreateDepthStencilView(depthStencilBuffer, NULL, &depthStencilView); //bind buffer to OM stage in pipeline return true; }
D3D::D3D(int screenWidth, int screenHeight, bool vsync, HWND hwnd, bool fullscreen, float screenDepth, float screenNear) : wireframe_enabled_(false) { IDXGIFactory* factory; IDXGIAdapter* adapter; IDXGIOutput* adapterOutput; unsigned int numModes, i, numerator, denominator, stringLength; DXGI_MODE_DESC* displayModeList; DXGI_ADAPTER_DESC adapterDesc; DXGI_SWAP_CHAIN_DESC swapChainDesc; D3D_FEATURE_LEVEL featureLevel; ID3D11Texture2D* backBufferPtr; D3D11_TEXTURE2D_DESC depthBufferDesc; D3D11_DEPTH_STENCIL_DESC depthStencilDesc; D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc; D3D11_RASTERIZER_DESC rasterDesc; float fieldOfView, screenAspect; D3D11_DEPTH_STENCIL_DESC depthDisabledStencilDesc; D3D11_BLEND_DESC blendStateDescription; // Store the vsync setting. m_vsync_enabled = vsync; // Create a DirectX graphics interface factory. CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&factory); // Use the factory to create an adapter for the primary graphics interface (video card). factory->EnumAdapters(0, &adapter); // Enumerate the primary adapter output (monitor). adapter->EnumOutputs(0, &adapterOutput); // Get the number of modes that fit the DXGI_FORMAT_R8G8B8A8_UNORM display format for the adapter output (monitor). adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, NULL); // Create a list to hold all the possible display modes for this monitor/video card combination. displayModeList = new DXGI_MODE_DESC[numModes]; // Now fill the display mode list structures. adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, displayModeList); // Now go through all the display modes and find the one that matches the screen width and height. // When a match is found store the numerator and denominator of the refresh rate for that monitor. for (i = 0; i<numModes; i++) { if (displayModeList[i].Width == (unsigned int)screenWidth) { if (displayModeList[i].Height == (unsigned int)screenHeight) { numerator = displayModeList[i].RefreshRate.Numerator; denominator = displayModeList[i].RefreshRate.Denominator; } } } // Get the adapter (video card) description. adapter->GetDesc(&adapterDesc); // Store the dedicated video card memory in megabytes. m_videoCardMemory = (int)(adapterDesc.DedicatedVideoMemory / 1024 / 1024); // Convert the name of the video card to a character array and store it. wcstombs_s(&stringLength, m_videoCardDescription, 128, adapterDesc.Description, 128); // Release the display mode list. delete[] displayModeList; displayModeList = 0; // Release the adapter output. adapterOutput->Release(); adapterOutput = 0; // Release the adapter. adapter->Release(); adapter = 0; // Release the factory. factory->Release(); factory = 0; // Initialize the swap chain description. ZeroMemory(&swapChainDesc, sizeof(swapChainDesc)); // Set to a single back buffer. swapChainDesc.BufferCount = 1; // Set the width and height of the back buffer. swapChainDesc.BufferDesc.Width = screenWidth; swapChainDesc.BufferDesc.Height = screenHeight; // Set regular 32-bit surface for the back buffer. swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; // Set the refresh rate of the back buffer. if (m_vsync_enabled) { swapChainDesc.BufferDesc.RefreshRate.Numerator = numerator; swapChainDesc.BufferDesc.RefreshRate.Denominator = denominator; } else { swapChainDesc.BufferDesc.RefreshRate.Numerator = 0; swapChainDesc.BufferDesc.RefreshRate.Denominator = 1; } // Set the usage of the back buffer. swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; // Set the handle for the window to render to. swapChainDesc.OutputWindow = hwnd; // Turn multisampling off. swapChainDesc.SampleDesc.Count = 1; swapChainDesc.SampleDesc.Quality = 0; // Set to full screen or windowed mode. if (fullscreen) { swapChainDesc.Windowed = false; } else { swapChainDesc.Windowed = true; } // Set the scan line ordering and scaling to unspecified. swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; // Discard the back buffer contents after presenting. swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; // Don't set the advanced flags. swapChainDesc.Flags = 0; // Set the feature level to DirectX 11. featureLevel = D3D_FEATURE_LEVEL_11_0; // Create the swap chain, Direct3D device, and Direct3D device context. D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, D3D11_CREATE_DEVICE_DEBUG, &featureLevel, 1, D3D11_SDK_VERSION, &swapChainDesc, &m_swapChain, &m_device, NULL, &m_deviceContext); // Get the pointer to the back buffer. m_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&backBufferPtr); // Create the render target view with the back buffer pointer. m_device->CreateRenderTargetView(backBufferPtr, NULL, &m_renderTargetView); // Release pointer to the back buffer as we no longer need it. backBufferPtr->Release(); backBufferPtr = 0; // Initialize the description of the depth buffer. ZeroMemory(&depthBufferDesc, sizeof(depthBufferDesc)); // Set up the description of the depth buffer. 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; // Create the texture for the depth buffer using the filled out description. 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; // Create the depth stencil state. m_device->CreateDepthStencilState(&depthStencilDesc, &m_depthStencilState); // Set the depth stencil state. m_deviceContext->OMSetDepthStencilState(m_depthStencilState, 1); // Initialize 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; // Create the depth stencil view. m_device->CreateDepthStencilView(m_depthStencilBuffer, &depthStencilViewDesc, &m_depthStencilView); // Bind the render target view and depth stencil buffer to the output render pipeline. m_deviceContext->OMSetRenderTargets(1, &m_renderTargetView, m_depthStencilView); // Setup the raster description which will determine how and what polygons will be drawn. 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 = true; rasterDesc.MultisampleEnable = false; rasterDesc.ScissorEnable = false; rasterDesc.SlopeScaledDepthBias = 0.0f; // Create the rasterizer state from the description we just filled out. m_device->CreateRasterizerState(&rasterDesc, &m_rasterState); // Now set the rasterizer state. m_deviceContext->RSSetState(m_rasterState); //create raster state with wireframe enabled rasterDesc.FillMode = D3D11_FILL_WIREFRAME; m_device->CreateRasterizerState(&rasterDesc, &m_rasterStateWF); // Setup the viewport for rendering. viewport.Width = (float)screenWidth; viewport.Height = (float)screenHeight; viewport.MinDepth = 0.0f; viewport.MaxDepth = 1.0f; viewport.TopLeftX = 0.0f; viewport.TopLeftY = 0.0f; // Create the viewport. m_deviceContext->RSSetViewports(1, &viewport); // Setup the projection matrix. fieldOfView = (float)XM_PI / 4.0f; screenAspect = (float)screenWidth / (float)screenHeight; // Create the projection matrix for 3D rendering. m_projectionMatrix = XMMatrixPerspectiveFovLH(fieldOfView, screenAspect, screenNear, screenDepth); // Initialize the world matrix to the identity matrix. m_worldMatrix = XMMatrixIdentity(); // Create an orthographic projection matrix for 2D rendering. m_orthoMatrix = XMMatrixOrthographicLH((float)screenWidth, (float)screenHeight, screenNear, screenDepth); // Clear the second depth stencil state before setting the parameters. ZeroMemory(&depthDisabledStencilDesc, sizeof(depthDisabledStencilDesc)); // Now create a second depth stencil state which turns off the Z buffer for 2D rendering. The only difference is // that DepthEnable is set to false, all other parameters are the same as the other depth stencil state. 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; // Create the state using the device. m_device->CreateDepthStencilState(&depthDisabledStencilDesc, &m_depthDisabledStencilState); // Clear the blend state description. ZeroMemory(&blendStateDescription, sizeof(D3D11_BLEND_DESC)); // Create an alpha enabled blend state description. blendStateDescription.RenderTarget[0].BlendEnable = TRUE; 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_ONE; blendStateDescription.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; blendStateDescription.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; blendStateDescription.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; // Ste's pre multiply //blendStateDescription.RenderTarget[0].BlendEnable = TRUE; //blendStateDescription.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE; //blendStateDescription.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; //blendStateDescription.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; //blendStateDescription.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; //blendStateDescription.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; //blendStateDescription.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; //blendStateDescription.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; // Create the blend state using the description. m_device->CreateBlendState(&blendStateDescription, &m_alphaEnableBlendingState); // Modify the description to create an alpha disabled blend state description. blendStateDescription.RenderTarget[0].BlendEnable = FALSE; // Create the second blend state using the description. m_device->CreateBlendState(&blendStateDescription, &m_alphaDisableBlendingState); }
bool D3DManager::Initialize(int screenWidth, int screenHeight, bool vsync, HWND hwnd, bool fullscreen, float screenDepth, float screenNear) { HRESULT result; IDXGIFactory* factory; IDXGIAdapter* adapter; IDXGIOutput* adapterOutput; unsigned int numModes, i, numerator, denominator, stringLength; DXGI_MODE_DESC* displayModeList; DXGI_ADAPTER_DESC adapterDesc; int error; DXGI_SWAP_CHAIN_DESC swapChainDesc; D3D_FEATURE_LEVEL featureLevel; ID3D11Texture2D* backBufferPtr; D3D11_TEXTURE2D_DESC depthBufferDesc; D3D11_DEPTH_STENCIL_DESC depthStencilDesc; D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc; D3D11_RASTERIZER_DESC rasterDesc; D3D11_VIEWPORT viewport; float fieldOfView, screenAspect; D3D11_DEPTH_STENCIL_DESC depthDisabledStencilDesc; D3D11_BLEND_DESC blendStateDescription; std::vector<IDXGIAdapter*> vAdapters; int largestAdapter = 0; int videoCardMemory; // Store our screen width and height m_ScreenWidth = screenWidth; m_ScreenHeight = screenHeight; // Store the vsync setting. m_vsync_enabled = vsync; // Create a DirectX graphics interface factory. result = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&factory); if(FAILED(result)) { log_sxerror("D3DManager", "Failed to create a DXGI factory."); return false; } // Loop through each adapter on the computer for(UINT i = 0; factory->EnumAdapters(i, &adapter) != DXGI_ERROR_NOT_FOUND; ++i) { // Store the adapter vAdapters.push_back(adapter); // Get the adapter (video card) description. result = adapter->GetDesc(&adapterDesc); if(FAILED(result)) { log_sxerror("D3DManager", "Failed to get the video card description."); return false; } // Store the dedicated video card memory in megabytes. videoCardMemory = (int)(adapterDesc.DedicatedVideoMemory / 1024 / 1024); // If the memory is larger than our current memory, save this index if(videoCardMemory > m_videoCardMemory) { m_videoCardMemory = videoCardMemory; largestAdapter = i; // Convert the name of the video card to a character array and store it. error = wcstombs_s(&stringLength, m_videoCardDescription, 128, adapterDesc.Description, 128); if(error != 0) { log_sxerror("D3DManager", "Failed to get the name of the graphics card."); return false; } } } // Enumerate the primary adapter output (monitor). result = vAdapters.at(0)->EnumOutputs(0, &adapterOutput); if(FAILED(result)) { log_sxerror("D3DManager", "Failed to grab the monitor."); return false; } // Get the number of modes that fit the DXGI_FORMAT_R8G8B8A8_UNORM display format for the adapter output (monitor). result = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, NULL); if(FAILED(result)) { log_sxerror("D3DManager", "Failed to get a list of display modes."); return false; } // Create a list to hold all the possible display modes for this monitor/video card combination. displayModeList = new DXGI_MODE_DESC[numModes]; if(!displayModeList) { log_sxerror("D3DManager", "Failed to create a display mode list for the monitor/gfx card combo."); return false; } // Now fill the display mode list structures. result = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, displayModeList); if(FAILED(result)) { log_sxerror("D3DManager", "Failed to fill the display mode list structures."); return false; } // Now go through all the display modes and find the one that matches the screen width and height. // When a match is found store the numerator and denominator of the refresh rate for that monitor. for(i=0; i<numModes; i++) { if(displayModeList[i].Width == (unsigned int)screenWidth) { if(displayModeList[i].Height == (unsigned int)screenHeight) { numerator = displayModeList[i].RefreshRate.Numerator; denominator = displayModeList[i].RefreshRate.Denominator; } } } // Release the display mode list. delete [] displayModeList; displayModeList = 0; // Release the adapter output. adapterOutput->Release(); adapterOutput = 0; // Release the factory. factory->Release(); factory = 0; // Initialize the swap chain description. ZeroMemory(&swapChainDesc, sizeof(swapChainDesc)); // Set to a single back buffer. swapChainDesc.BufferCount = 1; // Set the width and height of the back buffer. swapChainDesc.BufferDesc.Width = screenWidth; swapChainDesc.BufferDesc.Height = screenHeight; // Set regular 32-bit surface for the back buffer. swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; // Set the refresh rate of the back buffer. if(m_vsync_enabled) { swapChainDesc.BufferDesc.RefreshRate.Numerator = 60;//numerator; swapChainDesc.BufferDesc.RefreshRate.Denominator = 1;//denominator; } else { swapChainDesc.BufferDesc.RefreshRate.Numerator = 0; swapChainDesc.BufferDesc.RefreshRate.Denominator = 1; } // Set the usage of the back buffer. swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; // Set the handle for the window to render to. swapChainDesc.OutputWindow = hwnd; // Turn multisampling off. swapChainDesc.SampleDesc.Count = 1; swapChainDesc.SampleDesc.Quality = 0; // Set to full screen or windowed mode. if(fullscreen) { swapChainDesc.Windowed = false; } else { swapChainDesc.Windowed = true; } // Set the scan line ordering and scaling to unspecified. swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; // Discard the back buffer contents after presenting. swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; //swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_SEQUENTIAL; // Don't set the advanced flags. swapChainDesc.Flags = 0; // Grab the highest feature level result = D3D11CreateDevice(vAdapters.at(largestAdapter), D3D_DRIVER_TYPE_UNKNOWN, NULL, 0, NULL, 0, D3D11_SDK_VERSION, NULL, &featureLevel, NULL ); if(FAILED(result)) { log_sxerror("D3DManager", "Failed to retrieve the featurelevel."); ErrorDescription(result); // Try to use the default adapter largestAdapter = 0; result = D3D11CreateDevice(vAdapters.at(largestAdapter), D3D_DRIVER_TYPE_UNKNOWN, NULL, 0, NULL, 0, D3D11_SDK_VERSION, NULL, &featureLevel, NULL ); if(FAILED(result)) { log_sxerror("D3DManager", "Failed to retrieve the featurelevel the second time."); ErrorDescription(result); return false; } } #ifdef _DEBUG // Create the swap chain, Direct3D device, and Direct3D device context. result = D3D11CreateDeviceAndSwapChain(vAdapters.at(largestAdapter), D3D_DRIVER_TYPE_UNKNOWN, NULL, D3D11_CREATE_DEVICE_DEBUG | D3D11_CREATE_DEVICE_BGRA_SUPPORT , &featureLevel, 1, D3D11_SDK_VERSION, &swapChainDesc, &m_swapChain, &m_device, NULL, &m_deviceContext); if(FAILED(result)) { log_sxerror("D3DManager", "Failed to create the Direct3D device, context, and swap chain."); return false; } result = m_device->QueryInterface((IID)IID_ID3D11Debug, (void**)&m_Debug); if(FAILED(result)) { log_sxerror("D3DManager", "Failed to create a debugging interface for the device. Debugging may not work"); } else { result = m_Debug->ReportLiveDeviceObjects(D3D11_RLDO_DETAIL); if(FAILED(result)) { log_sxerror("D3DManager", "Failed to enable detailed object reporting."); } } #else // Create the swap chain, Direct3D device, and Direct3D device context. result = D3D11CreateDeviceAndSwapChain(vAdapters.at(largestAdapter), D3D_DRIVER_TYPE_UNKNOWN, NULL, D3D11_CREATE_DEVICE_BGRA_SUPPORT , &featureLevel, 1, D3D11_SDK_VERSION, &swapChainDesc, &m_swapChain, &m_device, NULL, &m_deviceContext); if(FAILED(result)) { log_sxerror("D3DManager", "Failed to create the Direct3D device, context, and swap chain."); return false; } #endif // Release each adapter. for(auto it = vAdapters.begin(); it != vAdapters.end(); ++it) { (*it)->Release(); (*it) = 0; } // Get the pointer to the back buffer. result = m_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&backBufferPtr); if(FAILED(result)) { log_sxerror("D3DManager", "Failed to get a pointer to the back buffer."); return false; } // Create the render target view with the back buffer pointer. result = m_device->CreateRenderTargetView(backBufferPtr, NULL, &m_renderTargetView); if(FAILED(result)) { log_sxerror("D3DManager", "Failed to create the render target view."); return false; } // Release pointer to the back buffer as we no longer need it. backBufferPtr->Release(); backBufferPtr = 0; // Initialize the description of the depth buffer. ZeroMemory(&depthBufferDesc, sizeof(depthBufferDesc)); // Set up the description of the depth buffer. 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; // Create the texture for the depth buffer using the filled out description. result = m_device->CreateTexture2D(&depthBufferDesc, NULL, &m_depthStencilBuffer); if(FAILED(result)) { log_sxerror("D3DManager", "Failed to create the depth buffer."); return false; } // 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; // Create the depth stencil state. result = m_device->CreateDepthStencilState(&depthStencilDesc, &m_depthStencilState); if(FAILED(result)) { log_sxerror("D3DManager", "Failed to create the depth stencil state."); return false; } // Set the depth stencil state. m_deviceContext->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; // Create the depth stencil view. result = m_device->CreateDepthStencilView(m_depthStencilBuffer, &depthStencilViewDesc, &m_depthStencilView); if(FAILED(result)) { log_sxerror("D3DManager", "Failed to create the depth stencil view."); return false; } // Bind the render target view and depth stencil buffer to the output render pipeline. m_deviceContext->OMSetRenderTargets(1, &m_renderTargetView, m_depthStencilView); // Setup the raster description which will determine how and what polygons will be drawn. 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; // Create the rasterizer state from the description we just filled out. result = m_device->CreateRasterizerState(&rasterDesc, &m_rasterState); if(FAILED(result)) { log_sxerror("D3DManager", "Failed to create the rasterizer state."); return false; } // Now set the rasterizer state. m_deviceContext->RSSetState(m_rasterState); // Setup the viewport for rendering. viewport.Width = (float)screenWidth; viewport.Height = (float)screenHeight; viewport.MinDepth = 0.0f; viewport.MaxDepth = 1.0f; viewport.TopLeftX = 0.0f; viewport.TopLeftY = 0.0f; // Create the viewport. m_deviceContext->RSSetViewports(1, &viewport); // Setup the projection matrix. fieldOfView = (float)XM_PI / 4.0f; assert(screenWidth != 0); assert(screenHeight != 0); screenAspect = (float)screenWidth / (float)screenHeight; // Create the projection matrix for 3D rendering. XMStoreFloat4x4(&m_projectionMatrix, XMMatrixPerspectiveFovLH(fieldOfView, screenAspect, screenNear, screenDepth)); // Initialize the world and view matrix to the identity matrix. XMStoreFloat4x4(&m_worldMatrix, XMMatrixIdentity()); XMStoreFloat4x4(&m_viewMatrix, XMMatrixIdentity()); // Create an orthographic projection matrix for 2D rendering. XMStoreFloat4x4(&m_orthoMatrix, XMMatrixOrthographicLH((float)screenWidth, (float)screenHeight, screenNear, screenDepth)); // Clear the second depth stencil state before setting the parameters. ZeroMemory(&depthDisabledStencilDesc, sizeof(depthDisabledStencilDesc)); // Now create a second depth stencil state which turns off the Z buffer for 2D rendering. The only difference is // that DepthEnable is set to false, all other parameters are the same as the other depth stencil state. 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; // Create the state using the device. result = m_device->CreateDepthStencilState(&depthDisabledStencilDesc, &m_depthDisabledStencilState); if(FAILED(result)) { log_sxerror("D3DManager", "Failed to create the depth disabled stencil state."); return false; } // Clear the blend state description. ZeroMemory(&blendStateDescription, sizeof(D3D11_BLEND_DESC)); // Create an alpha enabled blend state description. blendStateDescription.RenderTarget[0].BlendEnable = TRUE; 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_ZERO; blendStateDescription.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; blendStateDescription.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; blendStateDescription.RenderTarget[0].RenderTargetWriteMask = 0x0f; //blendStateDescription.RenderTarget[0].BlendEnable = true; //blendStateDescription.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_COLOR; // This one f***s by adding white //blendStateDescription.RenderTarget[0].DestBlend = D3D11_BLEND_DEST_COLOR; // This one produces fail whale, dusky background, lite trees //blendStateDescription.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; //blendStateDescription.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_SRC_ALPHA; //blendStateDescription.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_DEST_ALPHA; //blendStateDescription.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; //blendStateDescription.RenderTarget[0].RenderTargetWriteMask = 7; // Create the blend state using the description. result = m_device->CreateBlendState(&blendStateDescription, &m_alphaEnableBlendingState); if(FAILED(result)) { log_sxerror("D3DManager", "Failed to create the alpha blending state."); return false; } // Modify the description to create an alpha disabled blend state description. blendStateDescription.RenderTarget[0].BlendEnable = FALSE; // Create the blend state using the description. result = m_device->CreateBlendState(&blendStateDescription, &m_alphaDisableBlendingState); if(FAILED(result)) { log_sxerror("D3DManager", "Failed to create the alpha disabled blending state."); return false; } return true; }
bool H3DRenderer::Initialize(int screen_width, int screen_height, bool vsync, HWND hwnd, bool full_screen, float screen_depth, float screen_near) { HRESULT result = S_OK; IDXGIFactory* factory = NULL; IDXGIAdapter* adapter = NULL; IDXGIOutput* adapter_output = NULL; unsigned int num_modes, i, numerator, denominator; DXGI_MODE_DESC* display_mode_list; DXGI_SWAP_CHAIN_DESC swap_chain_desc; D3D_FEATURE_LEVEL feature_level; ID3D11Texture2D* back_buffer; D3D11_TEXTURE2D_DESC depth_buffer_desc; D3D11_DEPTH_STENCIL_DESC depth_stencil_desc; // 用来设置ds缓冲区state的desc结构体 D3D11_DEPTH_STENCIL_VIEW_DESC depth_stencil_view_desc; D3D11_RASTERIZER_DESC rasterDesc; D3D11_VIEWPORT viewport; D3D11_DEPTH_STENCIL_DESC depth_disable_stencil_desc; D3D11_BLEND_DESC blend_state_desc; // 垂直同步是否开启 vsync_enabled_ = vsync; sync_interval_ = vsync_enabled_ ? 1 : 0; // Create a DirectX graphics interface factory. result = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&factory); if(FAILED(result)) { return false; } // Use the factory to create an adapter for the primary graphics interface (video card). result = factory->EnumAdapters(0, &adapter); if(FAILED(result)) { return false; } // Enumerate the primary adapter output (monitor). result = adapter->EnumOutputs(0, &adapter_output); if(FAILED(result)) { return false; } // directx11时代,只枚举RGBA32位颜色模式,不需要搞其他了 result = adapter_output->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &num_modes, NULL); if(FAILED(result)) { return false; } // Create a list to hold all the possible display modes for this monitor/video card combination. display_mode_list = new DXGI_MODE_DESC[num_modes]; if(!display_mode_list) { return false; } // Now fill the display mode list structures. result = adapter_output->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &num_modes, display_mode_list); if(FAILED(result)) { return false; } // Now go through all the display modes and find the one that matches the screen width and height. // When a match is found store the numerator and denominator of the refresh rate for that monitor. for(i=0; i<num_modes; i++) { if(display_mode_list[i].Width == (unsigned int)screen_width) { if(display_mode_list[i].Height == (unsigned int)screen_height) { numerator = display_mode_list[i].RefreshRate.Numerator; denominator = display_mode_list[i].RefreshRate.Denominator; } } } // Release the display mode list. delete [] display_mode_list; display_mode_list = 0; // Release the adapter output. adapter_output->Release(); adapter_output = 0; // Release the adapter. adapter->Release(); adapter = 0; // Release the factory. factory->Release(); factory = 0; // 填充swap chain结构,这个swap chain将和main backbuffer关联 ZeroMemory(&swap_chain_desc, sizeof(swap_chain_desc)); // 仅设置本swap chain的backbuffer为1个,如果想在多窗口使用 // 同一个renderer的话,这里就要指定多个bufferCount了 swap_chain_desc.BufferCount = 1; swap_chain_desc.BufferDesc.Width = screen_width; swap_chain_desc.BufferDesc.Height = screen_height; swap_chain_desc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; // Set the refresh rate of the back buffer. if(vsync_enabled_) { swap_chain_desc.BufferDesc.RefreshRate.Numerator = numerator; swap_chain_desc.BufferDesc.RefreshRate.Denominator = denominator; } else { swap_chain_desc.BufferDesc.RefreshRate.Numerator = 0; swap_chain_desc.BufferDesc.RefreshRate.Denominator = 1; } // 指定这个render target是用来output用的 swap_chain_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swap_chain_desc.OutputWindow = hwnd; swap_chain_desc.SampleDesc.Count = 1; // 关闭多重采样 swap_chain_desc.SampleDesc.Quality = 0; swap_chain_desc.Windowed = (full_screen) ? false : true; swap_chain_desc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; // Set the scan line ordering and scaling to unspecified. swap_chain_desc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; swap_chain_desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; // Discard the back buffer contents after presenting. swap_chain_desc.Flags = 0; // Don't set the advanced flags. // Set the feature level to DirectX 11. // 设置 feature_level = D3D_FEATURE_LEVEL_11_0; // 一口气创建main swap chain,d3d device d3d device context result = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, &feature_level, 1, D3D11_SDK_VERSION, &swap_chain_desc, &swap_chain_, &d3d_device_, NULL, &d3d_device_context_); if(FAILED(result)) { return false; } // 获取到backbuffer的指针 result = swap_chain_->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&back_buffer); if(FAILED(result)) { return false; } // 通过backbuffer的指针创建到back buffer的render target. result = d3d_device_->CreateRenderTargetView(back_buffer, NULL, &back_buffer_view_); if(FAILED(result)) { return false; } // 这个指针不用了要记得释放 back_buffer->Release(); back_buffer = 0; // ---------------------- // 填充深度缓冲区结构 ZeroMemory(&depth_buffer_desc, sizeof(depth_buffer_desc)); depth_buffer_desc.Width = screen_width; depth_buffer_desc.Height = screen_height; depth_buffer_desc.MipLevels = 1; depth_buffer_desc.ArraySize = 1; depth_buffer_desc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; depth_buffer_desc.SampleDesc.Count = 1; depth_buffer_desc.SampleDesc.Quality = 0; depth_buffer_desc.Usage = D3D11_USAGE_DEFAULT; depth_buffer_desc.BindFlags = D3D11_BIND_DEPTH_STENCIL; // 指定所使用的buffer为深度和模板缓冲区 depth_buffer_desc.CPUAccessFlags = 0; depth_buffer_desc.MiscFlags = 0; // 初始化深度和模板缓冲区view ZeroMemory(&depth_stencil_view_desc, sizeof(depth_stencil_view_desc)); depth_stencil_view_desc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; depth_stencil_view_desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; depth_stencil_view_desc.Texture2D.MipSlice = 0; bool ret = depth_stencil_zone_.Create(&depth_buffer_desc,&depth_stencil_view_desc); if(!ret) { return false; } // 把作为backbuffer的render target view和depth_stenci view进行 depth_stencil_zone_.AttachToRenderTarget( &back_buffer_view_,1); // ---------------------- // 初始化模板缓冲区渲染状态描述结构体 ZeroMemory(&depth_stencil_desc, sizeof(depth_stencil_desc)); depth_stencil_desc.DepthEnable = true; depth_stencil_desc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; depth_stencil_desc.DepthFunc = D3D11_COMPARISON_LESS; // 比较函数为“小于” depth_stencil_desc.StencilEnable = true; depth_stencil_desc.StencilReadMask = 0xFF; depth_stencil_desc.StencilWriteMask = 0xFF; // 当像素是front-facing的时候执行的模板操作 depth_stencil_desc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; depth_stencil_desc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR; depth_stencil_desc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; depth_stencil_desc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; // 当像素是back-facing的时候执行的模板操作 depth_stencil_desc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; depth_stencil_desc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR; depth_stencil_desc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; depth_stencil_desc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; result = d3d_device_->CreateDepthStencilState(&depth_stencil_desc, &depth_stencil_state_); if(FAILED(result)) { return false; } d3d_device_context_->OMSetDepthStencilState(depth_stencil_state_, 1); // ---------------------- // 描述光栅化状态 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; // 创建光栅化状态对象 result = d3d_device_->CreateRasterizerState(&rasterDesc, &rasterizer_state_); if(FAILED(result)) { return false; } // 把刚才创建的状态对象设置 d3d_device_context_->RSSetState(rasterizer_state_); // 创建并设置主视口 viewport.Width = (float)screen_width; viewport.Height = (float)screen_height; viewport.MinDepth = 0.0f; viewport.MaxDepth = 1.0f; viewport.TopLeftX = 0.0f; viewport.TopLeftY = 0.0f; d3d_device_context_->RSSetViewports(1, &viewport); //// Clear the second depth stencil state before setting the parameters. //ZeroMemory(&depth_disable_stencil_desc, sizeof(depth_disable_stencil_desc)); //// Now create a second depth stencil state which turns off the Z buffer for 2D rendering. The only difference is //// that DepthEnable is set to false, all other parameters are the same as the other depth stencil state. //depth_disable_stencil_desc.DepthEnable = false; //depth_disable_stencil_desc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; //depth_disable_stencil_desc.DepthFunc = D3D11_COMPARISON_LESS; //depth_disable_stencil_desc.StencilEnable = true; //depth_disable_stencil_desc.StencilReadMask = 0xFF; //depth_disable_stencil_desc.StencilWriteMask = 0xFF; //depth_disable_stencil_desc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; //depth_disable_stencil_desc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR; //depth_disable_stencil_desc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; //depth_disable_stencil_desc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; //depth_disable_stencil_desc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; //depth_disable_stencil_desc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR; //depth_disable_stencil_desc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; //depth_disable_stencil_desc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; //// Create the state using the device. //result = d3d_device_->CreateDepthStencilState(&depth_disable_stencil_desc, &depth_disable_stencil_state_); //if(FAILED(result)) //{ // return false; //} // 创建alpha blend状态对象,并且指定这个对象所作用的0号render target的相关混合操作属性 ZeroMemory(&blend_state_desc, sizeof(D3D11_BLEND_DESC)); blend_state_desc.RenderTarget[0].BlendEnable = TRUE; blend_state_desc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; blend_state_desc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; blend_state_desc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; blend_state_desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; blend_state_desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; blend_state_desc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; blend_state_desc.RenderTarget[0].RenderTargetWriteMask = 0x0f; result = d3d_device_->CreateBlendState(&blend_state_desc, &alpha_enable_blending_state_); if(FAILED(result)) { return false; } // 创建一个关闭alpha blend的状态对象 blend_state_desc.RenderTarget[0].BlendEnable = FALSE; result = d3d_device_->CreateBlendState(&blend_state_desc, &alpha_disable_blending_state_); if(FAILED(result)) { return false; } return true; }
// Create a DX11 context //----------------------------------------------------------------------------- CPUTResult CPUT_DX11::CreateDXContext(CPUTContextCreation ContextParams ) { HRESULT hr = S_OK; CPUTResult result = CPUT_SUCCESS; // window params RECT rc; HWND hWnd = mpWindow->GetHWnd(); GetClientRect( hWnd, &rc ); UINT width = rc.right - rc.left; UINT height = rc.bottom - rc.top; // set up DirectX creation parameters mdriverType = D3D_DRIVER_TYPE_NULL; mfeatureLevel = D3D_FEATURE_LEVEL_11_0; mpD3dDevice = NULL; mpContext = NULL; mpSwapChain = NULL; mSwapChainBufferCount = ContextParams.swapChainBufferCount; mpBackBufferRTV = NULL; 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 ); // SRV's (shader resource views) require Structured Buffer // usage (D3D11_RESOURCE_MISC_BUFFER_STRUCTURED) which was // introduced in shader model 5 (directx 11.0) // D3D_FEATURE_LEVEL featureLevels[] = { D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0 }; UINT numFeatureLevels = ARRAYSIZE( featureLevels ); // swap chain information DXGI_SWAP_CHAIN_DESC sd; ZeroMemory( &sd, sizeof( sd ) ); sd.BufferCount = mSwapChainBufferCount; sd.BufferDesc.Width = width; sd.BufferDesc.Height = height; mSwapChainFormat = ContextParams.swapChainFormat; sd.BufferDesc.Format = ContextParams.swapChainFormat; sd.BufferDesc.RefreshRate.Numerator = ContextParams.refreshRate; sd.BufferDesc.RefreshRate.Denominator = 1; sd.BufferUsage = ContextParams.swapChainUsage; sd.OutputWindow = hWnd; sd.SampleDesc.Count = 1; // Number of MSAA samples sd.SampleDesc.Quality = 0; sd.Windowed = TRUE; sd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; // set the vsync parameter if(0 != ContextParams.refreshRate) { mSyncInterval = 1; } // walk devices and create device and swap chain on best matching piece of hardware bool functionalityTestPassed = false; for( UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++ ) { mdriverType = driverTypes[driverTypeIndex]; hr = D3D11CreateDeviceAndSwapChain( NULL, mdriverType, NULL, createDeviceFlags, featureLevels, numFeatureLevels, D3D11_SDK_VERSION, &sd, &mpSwapChain, &mpD3dDevice, &mfeatureLevel, &mpContext ); if( SUCCEEDED( hr ) ) { functionalityTestPassed = TestContextForRequiredFeatures(); if(true == functionalityTestPassed) { break; } else { // context was created, but failed to have required features // release and destroy this context and created resources SAFE_RELEASE(mpSwapChain); SAFE_RELEASE(mpContext); SAFE_RELEASE(mpD3dDevice); } } } ASSERT( (SUCCEEDED(hr) && (true==functionalityTestPassed)), _L("Failed creating device and swap chain.") ); if(!SUCCEEDED(hr) || !functionalityTestPassed) { CPUTOSServices::GetOSServices()->OpenMessageBox(_L("Required DirectX hardware support not present"), _L("Your system does not support the DirectX feature levels required for this sample.")); exit(1); // exit app directly } // If the WARP or Reference rasterizer is being used, the performance is probably terrible. // we throw up a dialog right after drawing the loading screen in CPUTCreateWindowAndContext // warning about that perf problem // call the DeviceCreated callback/backbuffer/etc creation result = CreateContext(); CPUTRenderStateBlock *pBlock = new CPUTRenderStateBlockDX11(); pBlock->CreateNativeResources(); CPUTRenderStateBlock::SetDefaultRenderStateBlock( pBlock ); // Create the per-frame constant buffer. D3D11_BUFFER_DESC bd = {0}; bd.ByteWidth = sizeof(CPUTFrameConstantBuffer); bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER; bd.Usage = D3D11_USAGE_DYNAMIC; bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; ID3D11Buffer *pPerFrameConstantBuffer; hr = (CPUT_DX11::GetDevice())->CreateBuffer( &bd, NULL, &pPerFrameConstantBuffer ); ASSERT( !FAILED( hr ), _L("Error creating constant buffer.") ); CPUTSetDebugName( pPerFrameConstantBuffer, _L("Per-Frame Constant buffer") ); cString name = _L("$cbPerFrameValues"); mpPerFrameConstantBuffer = new CPUTBufferDX11( name, pPerFrameConstantBuffer ); CPUTAssetLibrary::GetAssetLibrary()->AddConstantBuffer( name, mpPerFrameConstantBuffer ); SAFE_RELEASE(pPerFrameConstantBuffer); // We're done with it. The CPUTBuffer now owns it. return result; }
EGDevice egCreateDevice(HWND windowHandle) { if (pBoundDevice) { if (pBoundDevice->bIsInBatch) return 0; } EGDevice ret = 0; DXGI_SWAP_CHAIN_DESC swapChainDesc; HRESULT result; ID3D11Texture2D *pBackBuffer; ID3D11Resource *pBackBufferRes; ID3D11Texture2D *pDepthStencilBuffer; // Set as currently bound device devices = realloc(devices, sizeof(SEGDevice) * (deviceCount + 1)); memset(devices + deviceCount, 0, sizeof(SEGDevice)); pBoundDevice = devices + deviceCount; ++deviceCount; ret = deviceCount; // Define our swap chain memset(&swapChainDesc, 0, sizeof(swapChainDesc)); swapChainDesc.BufferCount = 1; swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChainDesc.OutputWindow = windowHandle; swapChainDesc.SampleDesc.Count = 1; swapChainDesc.Windowed = TRUE; // Create the swap chain, device and device context result = D3D11CreateDeviceAndSwapChain( NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, #if _DEBUG D3D11_CREATE_DEVICE_DEBUG, #else /* _DEBUG */ 0, #endif /* _DEBUG */ NULL, 0, D3D11_SDK_VERSION, &swapChainDesc, &pBoundDevice->pSwapChain, &pBoundDevice->pDevice, NULL, &pBoundDevice->pDeviceContext); if (result != S_OK) { setError("Failed D3D11CreateDeviceAndSwapChain"); egDestroyDevice(&ret); return 0; } // Create render target result = pBoundDevice->pSwapChain->lpVtbl->GetBuffer(pBoundDevice->pSwapChain, 0, &IID_ID3D11Texture2D, (void**)&pBackBuffer); if (result != S_OK) { setError("Failed IDXGISwapChain GetBuffer IID_ID3D11Texture2D"); egDestroyDevice(&ret); return 0; } result = pBoundDevice->pSwapChain->lpVtbl->GetBuffer(pBoundDevice->pSwapChain, 0, &IID_ID3D11Resource, (void**)&pBackBufferRes); if (result != S_OK) { setError("Failed IDXGISwapChain GetBuffer IID_ID3D11Resource"); egDestroyDevice(&ret); return 0; } result = pBoundDevice->pDevice->lpVtbl->CreateRenderTargetView(pBoundDevice->pDevice, pBackBufferRes, NULL, &pBoundDevice->pRenderTargetView); if (result != S_OK) { setError("Failed CreateRenderTargetView"); egDestroyDevice(&ret); return 0; } pBackBuffer->lpVtbl->GetDesc(pBackBuffer, &pBoundDevice->backBufferDesc); pBackBufferRes->lpVtbl->Release(pBackBufferRes); pBackBuffer->lpVtbl->Release(pBackBuffer); // Set up the description of the depth buffer. D3D11_TEXTURE2D_DESC depthBufferDesc = {0}; depthBufferDesc.Width = pBoundDevice->backBufferDesc.Width; depthBufferDesc.Height = pBoundDevice->backBufferDesc.Height; 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; // Create the texture for the depth buffer using the filled out description. result = pBoundDevice->pDevice->lpVtbl->CreateTexture2D(pBoundDevice->pDevice, &depthBufferDesc, NULL, &pDepthStencilBuffer); if (result != S_OK) { setError("Failed DepthStencil CreateTexture2D"); egDestroyDevice(&ret); return 0; } // Initailze the depth stencil view. D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc = {0}; depthStencilViewDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; depthStencilViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; depthStencilViewDesc.Texture2D.MipSlice = 0; // Create the depth stencil view. result = pDepthStencilBuffer->lpVtbl->QueryInterface(pDepthStencilBuffer, &IID_ID3D11Resource, (void**)&pBackBufferRes); if (result != S_OK) { setError("Failed DepthStencil ID3D11Texture2D QueryInterface IID_ID3D11Resource"); egDestroyDevice(&ret); return 0; } result = pBoundDevice->pDevice->lpVtbl->CreateDepthStencilView(pBoundDevice->pDevice, pBackBufferRes, &depthStencilViewDesc, &pBoundDevice->pDepthStencilView); if (result != S_OK) { setError("Failed CreateDepthStencilView"); egDestroyDevice(&ret); return 0; } pBackBufferRes->lpVtbl->Release(pBackBufferRes); pDepthStencilBuffer->lpVtbl->Release(pDepthStencilBuffer); // Compile vertex shaders and related input layouts { ID3DBlob *pCompiled; CREATE_VS(g_vs, &pBoundDevice->pVS, pCompiled); D3D11_INPUT_ELEMENT_DESC layout[6] = { {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}, {"NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0}, {"TANGENT", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 24, D3D11_INPUT_PER_VERTEX_DATA, 0}, {"BINORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 36, D3D11_INPUT_PER_VERTEX_DATA, 0}, {"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 48, D3D11_INPUT_PER_VERTEX_DATA, 0}, {"COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 56, D3D11_INPUT_PER_VERTEX_DATA, 0} }; result = pBoundDevice->pDevice->lpVtbl->CreateInputLayout(pBoundDevice->pDevice, layout, 6, pCompiled->lpVtbl->GetBufferPointer(pCompiled), pCompiled->lpVtbl->GetBufferSize(pCompiled), &pBoundDevice->pInputLayout); if (result != S_OK) { setError("Failed CreateInputLayout"); egDestroyDevice(&ret); return 0; } pCompiled->lpVtbl->Release(pCompiled); } { ID3DBlob *pCompiled; CREATE_VS(g_vsPassThrough, &pBoundDevice->pVSPassThrough, pCompiled); D3D11_INPUT_ELEMENT_DESC layout[3] = { {"POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}, {"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 48, D3D11_INPUT_PER_VERTEX_DATA, 0}, {"COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 56, D3D11_INPUT_PER_VERTEX_DATA, 0} }; result = pBoundDevice->pDevice->lpVtbl->CreateInputLayout(pBoundDevice->pDevice, layout, 3, pCompiled->lpVtbl->GetBufferPointer(pCompiled), pCompiled->lpVtbl->GetBufferSize(pCompiled), &pBoundDevice->pInputLayoutPassThrough); if (result != S_OK) { setError("Failed CreateInputLayout PassThrough"); egDestroyDevice(&ret); return 0; } pCompiled->lpVtbl->Release(pCompiled); } // Pixel shaders for (int i = 0; i < 18; ++i) { CREATE_PS(g_pses[i], &(pBoundDevice->pPSes[i])); } pBoundDevice->pActivePS = pBoundDevice->pPSes[0]; CREATE_PS(g_psPassThrough, &pBoundDevice->pPSPassThrough); CREATE_PS(g_psLDR, &pBoundDevice->pPSLDR); CREATE_PS(g_psAmbient, &pBoundDevice->pPSAmbient); CREATE_PS(g_psOmni, &pBoundDevice->pPSOmni); CREATE_PS(g_psBlurH, &pBoundDevice->pPSBlurH); CREATE_PS(g_psBlurV, &pBoundDevice->pPSBlurV); for (int i = 0; i < 2; ++i) { CREATE_PS(g_psPostProcess[i], &(pBoundDevice->pPSPostProcess[i])); } // Create uniforms { D3D11_BUFFER_DESC cbDesc = {64, D3D11_USAGE_DYNAMIC, D3D11_BIND_CONSTANT_BUFFER, D3D11_CPU_ACCESS_WRITE, 0, 0}; result = pBoundDevice->pDevice->lpVtbl->CreateBuffer(pBoundDevice->pDevice, &cbDesc, NULL, &pBoundDevice->pCBViewProj); if (result != S_OK) { setError("Failed CreateBuffer CBViewProj"); egDestroyDevice(&ret); return 0; } result = pBoundDevice->pDevice->lpVtbl->CreateBuffer(pBoundDevice->pDevice, &cbDesc, NULL, &pBoundDevice->pCBModel); if (result != S_OK) { setError("Failed CreateBuffer CBModel"); egDestroyDevice(&ret); return 0; } result = pBoundDevice->pDevice->lpVtbl->CreateBuffer(pBoundDevice->pDevice, &cbDesc, NULL, &pBoundDevice->pCBInvViewProj); if (result != S_OK) { setError("Failed CreateBuffer CBInvViewProj"); egDestroyDevice(&ret); return 0; } } { D3D11_BUFFER_DESC cbDesc = {sizeof(SEGOmni), D3D11_USAGE_DYNAMIC, D3D11_BIND_CONSTANT_BUFFER, D3D11_CPU_ACCESS_WRITE, 0, 0}; result = pBoundDevice->pDevice->lpVtbl->CreateBuffer(pBoundDevice->pDevice, &cbDesc, NULL, &pBoundDevice->pCBOmni); if (result != S_OK) { setError("Failed CreateBuffer CBInvViewProj"); egDestroyDevice(&ret); return 0; } } { D3D11_BUFFER_DESC cbDesc = {sizeof(float) * 4, D3D11_USAGE_DYNAMIC, D3D11_BIND_CONSTANT_BUFFER, D3D11_CPU_ACCESS_WRITE, 0, 0}; float initialRef[4] = {.5f, 4.f, 0, 0}; D3D11_SUBRESOURCE_DATA initialData = {initialRef, 0, 0}; result = pBoundDevice->pDevice->lpVtbl->CreateBuffer(pBoundDevice->pDevice, &cbDesc, &initialData, &pBoundDevice->pCBAlphaTestRef); if (result != S_OK) { setError("Failed CreateBuffer CBAlphaTestRef"); egDestroyDevice(&ret); return 0; } pBoundDevice->pDeviceContext->lpVtbl->PSSetConstantBuffers(pBoundDevice->pDeviceContext, 2, 1, &pBoundDevice->pCBAlphaTestRef); } { D3D11_BUFFER_DESC cbDesc = {sizeof(float) * 4, D3D11_USAGE_DYNAMIC, D3D11_BIND_CONSTANT_BUFFER, D3D11_CPU_ACCESS_WRITE, 0, 0}; result = pBoundDevice->pDevice->lpVtbl->CreateBuffer(pBoundDevice->pDevice, &cbDesc, NULL, &pBoundDevice->pCBBlurSpread); if (result != S_OK) { setError("Failed CreateBuffer CBBlurSpread"); egDestroyDevice(&ret); return 0; } } // Create our geometry batch vertex buffer that will be used to batch everything D3D11_BUFFER_DESC vertexBufferDesc; vertexBufferDesc.Usage = D3D11_USAGE_DYNAMIC; vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; vertexBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; vertexBufferDesc.MiscFlags = 0; vertexBufferDesc.StructureByteStride = 0; pBoundDevice->pCurrentBatchVertices = (SEGVertex *)malloc(sizeof(SEGVertex) * MAX_VERTEX_COUNT); for (UINT i = 0; i < VERTEX_BUFFER_COUNT; ++i) { UINT vertCount = (UINT)pow(2, 8 + (double)i); vertexBufferDesc.ByteWidth = vertCount * sizeof(SEGVertex); result = pBoundDevice->pDevice->lpVtbl->CreateBuffer(pBoundDevice->pDevice, &vertexBufferDesc, NULL, &pBoundDevice->pVertexBuffers[i]); if (result != S_OK) { setError("Failed CreateBuffer VertexBuffer"); egDestroyDevice(&ret); return 0; } result = pBoundDevice->pVertexBuffers[i]->lpVtbl->QueryInterface(pBoundDevice->pVertexBuffers[i], &IID_ID3D11Resource, &pBoundDevice->pVertexBufferResources[i]); if (result != S_OK) { setError("Failed VertexBuffer ID3D11Buffer QueryInterface -> IID_ID3D11Resource"); egDestroyDevice(&ret); return 0; } } // Create default textures { uint8_t pixel[4] = {255, 255, 255, 255}; texture2DFromData(pBoundDevice->pDefaultTextureMaps + DIFFUSE_MAP, pixel, 1, 1, FALSE); if (!pBoundDevice->pDefaultTextureMaps[DIFFUSE_MAP].pTexture) { egDestroyDevice(&ret); return 0; } } { uint8_t pixel[4] = {128, 128, 255, 255}; texture2DFromData(pBoundDevice->pDefaultTextureMaps + NORMAL_MAP, pixel, 1, 1, FALSE); if (!pBoundDevice->pDefaultTextureMaps[NORMAL_MAP].pTexture) { egDestroyDevice(&ret); return 0; } } { uint8_t pixel[4] = {0, 1, 0, 0}; texture2DFromData(pBoundDevice->pDefaultTextureMaps + MATERIAL_MAP, pixel, 1, 1, FALSE); if (!pBoundDevice->pDefaultTextureMaps[MATERIAL_MAP].pTexture) { egDestroyDevice(&ret); return 0; } } { uint8_t pixel[4] = {0, 0, 0, 0}; texture2DFromData(&pBoundDevice->transparentBlackTexture, pixel, 1, 1, FALSE); if (!pBoundDevice->transparentBlackTexture.pTexture) { egDestroyDevice(&ret); return 0; } } // Create our G-Buffer result = createRenderTarget(pBoundDevice->gBuffer + G_DIFFUSE, pBoundDevice->backBufferDesc.Width, pBoundDevice->backBufferDesc.Height, DXGI_FORMAT_R8G8B8A8_UNORM); if (result != S_OK) { egDestroyDevice(&ret); return 0; } result = createRenderTarget(pBoundDevice->gBuffer + G_DEPTH, pBoundDevice->backBufferDesc.Width, pBoundDevice->backBufferDesc.Height, DXGI_FORMAT_R32_FLOAT); if (result != S_OK) { egDestroyDevice(&ret); return 0; } result = createRenderTarget(pBoundDevice->gBuffer + G_NORMAL, pBoundDevice->backBufferDesc.Width, pBoundDevice->backBufferDesc.Height, DXGI_FORMAT_R8G8B8A8_UNORM); if (result != S_OK) { egDestroyDevice(&ret); return 0; } result = createRenderTarget(pBoundDevice->gBuffer + G_MATERIAL, pBoundDevice->backBufferDesc.Width, pBoundDevice->backBufferDesc.Height, DXGI_FORMAT_R8G8B8A8_UNORM); if (result != S_OK) { egDestroyDevice(&ret); return 0; } // Accumulation buffer. This is an HDR texture result = createRenderTarget(&pBoundDevice->accumulationBuffer, pBoundDevice->backBufferDesc.Width, pBoundDevice->backBufferDesc.Height, DXGI_FORMAT_R16G16B16A16_FLOAT); // DXGI_FORMAT_R11G11B10_FLOAT if (result != S_OK) { egDestroyDevice(&ret); return 0; } // Create blur buffers for (int i = 0; i < 8; ++i) { UINT divider = (UINT)pow(2, (double)i); for (int k = 0; k < 2; ++k) { UINT w = pBoundDevice->backBufferDesc.Width / divider; UINT h = pBoundDevice->backBufferDesc.Height / divider; result = createRenderTarget(&pBoundDevice->blurBuffers[i][k], w, h, DXGI_FORMAT_R8G8B8A8_UNORM); if (result != S_OK) { egDestroyDevice(&ret); return 0; } } } resetState(); // Create some internal states { egDisable(EG_ALL); egEnable(EG_BLEND); egBlendFunc(EG_ONE, EG_ONE); pBoundDevice->passStates[EG_AMBIENT_PASS] = egCreateState(); pBoundDevice->passStates[EG_OMNI_PASS] = egCreateState(); SEGState *pState = pBoundDevice->states + (pBoundDevice->passStates[EG_AMBIENT_PASS] - 1); pState->ignoreBits = STATE_ALPHA_TEST | STATE_VIGNETTE; pState = pBoundDevice->states + (pBoundDevice->passStates[EG_OMNI_PASS] - 1); pState->ignoreBits = STATE_ALPHA_TEST | STATE_VIGNETTE; } { egDisable(EG_ALL); egFilter(EG_FILTER_MIN_MAG_LINEAR_MIP_POINT); SEGState *pState = pBoundDevice->stateStack + pBoundDevice->statesStackCount; pState->samplerState.desc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP; pState->samplerState.desc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP; pState->samplerState.desc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; pState->samplerState.desc.ComparisonFunc = D3D11_COMPARISON_ALWAYS; pState->samplerState.desc.MaxLOD = D3D11_FLOAT32_MAX; pBoundDevice->passStates[EG_POST_PROCESS_PASS] = egCreateState(); pState = pBoundDevice->states + (pBoundDevice->passStates[EG_POST_PROCESS_PASS] - 1); pState->ignoreBits = STATE_ALPHA_TEST | STATE_VIGNETTE; } resetState(); return ret; }
bool DXManager::InitializeSwapChain(HWND hwnd, bool fullscreen, int screenWidth, int screenHeight, unsigned int numerator, unsigned int denominator) { DXGI_SWAP_CHAIN_DESC swapChainDesc; D3D_FEATURE_LEVEL featureLevel; HRESULT result; //initialize swap chain ZeroMemory(&swapChainDesc, sizeof(swapChainDesc)); //set to a single back buffer swapChainDesc.BufferCount = 1; //set the width and height of the back buffer swapChainDesc.BufferDesc.Width = screenWidth; swapChainDesc.BufferDesc.Height = screenHeight; //set regular 32-bit back buffer swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; //Set the refresh rate of the back buffer if(m_vsync_enabled) { swapChainDesc.BufferDesc.RefreshRate.Numerator = numerator; swapChainDesc.BufferDesc.RefreshRate.Denominator = denominator; } else { swapChainDesc.BufferDesc.RefreshRate.Numerator = 0; swapChainDesc.BufferDesc.RefreshRate.Denominator = 1; } // set the usage of the back buffer swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; //set the handle for the window swapChainDesc.OutputWindow = hwnd; //turn multisampling off swapChainDesc.SampleDesc.Count = 1; swapChainDesc.SampleDesc.Quality = 0; //set to full screen or windowed mode swapChainDesc.Windowed = !fullscreen; //set the scan line ordering and scaling to unspecified swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; //Discard the back buffer contents after presenting swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; swapChainDesc.Flags = 0; //Set the feature level to DirectX11 featureLevel = D3D_FEATURE_LEVEL_11_0; //create swap chain, device, and device context result = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, &featureLevel, 1, D3D11_SDK_VERSION, &swapChainDesc, &m_swapChain, &m_device, NULL, &m_deviceContext); if(FAILED(result)) { return false; } return true; }
bool D3DClass::Initialize(int screenWidth, int screenHeight, bool vsync, HWND hwnd, bool fullscreen, float screenDepth, float screenNear) { HRESULT result; IDXGIFactory* factory; IDXGIAdapter* adapter; IDXGIOutput* adapterOutput; unsigned int numModes, i, numerator, denominator, stringLength; DXGI_MODE_DESC* displayModeList; DXGI_ADAPTER_DESC adapterDesc; int error; DXGI_SWAP_CHAIN_DESC swapChainDesc; D3D_FEATURE_LEVEL featureLevel; ID3D11Texture2D* backBufferPtr; D3D11_TEXTURE2D_DESC depthBufferDesc; D3D11_DEPTH_STENCIL_DESC depthStencilDesc; D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc; D3D11_RASTERIZER_DESC rasterDesc; D3D11_VIEWPORT viewport; float fieldOfView, screenAspect; D3D11_DEPTH_STENCIL_DESC depthDisabledStencilDesc; D3D11_BLEND_DESC blendStateDesc; m_vsync_enabled = vsync; result = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&factory); if(FAILED(result)) { return false; } result = factory->EnumAdapters(0, &adapter); if(FAILED(result)) { return false; } result = adapter->EnumOutputs(0, &adapterOutput); if(FAILED(result)) { return false; } result = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, NULL); if(FAILED(result)) { return false; } displayModeList = new DXGI_MODE_DESC[numModes]; if(!displayModeList) { return false; } result = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, displayModeList); if(FAILED(result)) { return false; } for(i=0; i<numModes; i++) { if(displayModeList[i].Width == (unsigned int) screenWidth) { if(displayModeList[i].Height == (unsigned int) screenHeight) { numerator = displayModeList[i].RefreshRate.Numerator; denominator = displayModeList[i].RefreshRate.Denominator; } } } result = adapter->GetDesc(&adapterDesc); if(FAILED(result)) { return false; } m_videoCardMemory = (int)(adapterDesc.DedicatedVideoMemory / 1024 / 1024); error = wcstombs_s(&stringLength, m_videoCardDescription, 128, adapterDesc.Description, 128); if(error != 0) { return false; } delete [] displayModeList; displayModeList = 0; adapterOutput->Release(); adapterOutput = 0; adapter->Release(); adapter = 0; factory->Release(); factory = 0; ZeroMemory(&swapChainDesc, sizeof(swapChainDesc)); swapChainDesc.BufferCount = 1; swapChainDesc.BufferDesc.Width = screenWidth; swapChainDesc.BufferDesc.Height = screenHeight; swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; if(m_vsync_enabled) { swapChainDesc.BufferDesc.RefreshRate.Numerator = numerator; swapChainDesc.BufferDesc.RefreshRate.Denominator = denominator; } else { swapChainDesc.BufferDesc.RefreshRate.Numerator = 0; swapChainDesc.BufferDesc.RefreshRate.Denominator = 1; } swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChainDesc.OutputWindow = hwnd; swapChainDesc.SampleDesc.Count = 1; swapChainDesc.SampleDesc.Quality = 0; if(fullscreen) { swapChainDesc.Windowed = false; } else { swapChainDesc.Windowed = true; } swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; swapChainDesc.Flags = 0; featureLevel = D3D_FEATURE_LEVEL_11_0; result = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, &featureLevel, 1, D3D11_SDK_VERSION, &swapChainDesc, &m_swapChain, &m_device, NULL, &m_deviceContext); if(FAILED(result)) { return false; } result = m_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&backBufferPtr); if(FAILED(result)) { return false; } result = m_device->CreateRenderTargetView(backBufferPtr, NULL, &m_renderTargetView); if(FAILED(result)) { return false; } backBufferPtr->Release(); backBufferPtr = 0; 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; result = m_device->CreateTexture2D(&depthBufferDesc, NULL, &m_depthStencilBuffer); if(FAILED(result)) { return false; } 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; result = m_device->CreateDepthStencilState(&depthStencilDesc, &m_depthStencilState); if(FAILED(result)) { return false; } m_deviceContext->OMSetDepthStencilState(m_depthStencilState, 1); ZeroMemory(&depthStencilViewDesc, sizeof(depthStencilViewDesc)); depthStencilViewDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; depthStencilViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; depthStencilViewDesc.Texture2D.MipSlice = 0; result = m_device->CreateDepthStencilView(m_depthStencilBuffer, &depthStencilViewDesc, &m_depthStencilView); if(FAILED(result)) { return false; } m_deviceContext->OMSetRenderTargets(1, &m_renderTargetView, m_depthStencilView); rasterDesc.AntialiasedLineEnable = false; rasterDesc.CullMode = D3D11_CULL_BACK; rasterDesc.DepthBias = 0; rasterDesc.DepthBiasClamp = 0.0f; rasterDesc.DepthClipEnable = false; rasterDesc.FillMode = D3D11_FILL_SOLID; rasterDesc.FrontCounterClockwise = false; rasterDesc.MultisampleEnable = false; rasterDesc.ScissorEnable = false; rasterDesc.SlopeScaledDepthBias = 0.0f; result = m_device->CreateRasterizerState(&rasterDesc, &m_rasterState); if(FAILED(result)) { return false; } m_deviceContext->RSSetState(m_rasterState); 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); fieldOfView = (float)DirectX::XM_PI / 4.0f; screenAspect = (float)screenWidth / (float)screenHeight; m_projectionMatrix = DirectX::XMMatrixPerspectiveFovLH(fieldOfView, screenAspect, screenNear, screenDepth); m_worldMatrix = DirectX::XMMatrixIdentity(); m_orthoMatrix = DirectX::XMMatrixOrthographicLH((float)screenWidth, (float)screenHeight, screenNear, screenDepth); 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; result = m_device->CreateDepthStencilState(&depthDisabledStencilDesc, &m_depthDisabledStencilState); if(FAILED(result)) { return false; } ZeroMemory(&blendStateDesc, sizeof(D3D11_BLEND_DESC)); blendStateDesc.RenderTarget[0].BlendEnable = TRUE; blendStateDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE; 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 = 0x0f; result = m_device->CreateBlendState(&blendStateDesc, &m_alphaEnableBlendingState); if(FAILED(result)) { return false; } blendStateDesc.RenderTarget[0].BlendEnable = FALSE; result = m_device->CreateBlendState(&blendStateDesc, &m_alphaDisableBlendingState); if(FAILED(result)) { return false; } return true; }
bool D3DClass::Initialize(int screenWidth, int screenHeight, bool vsync, HWND hwnd, bool fullscreen, float screenDepth, float screenNear) { HRESULT result; IDXGIFactory* factory; IDXGIAdapter* adapter; IDXGIOutput* adapterOutput; unsigned int numModes, i, numerator, denominator, stringLength; DXGI_MODE_DESC* displayModeList; DXGI_ADAPTER_DESC adapterDesc; int error; DXGI_SWAP_CHAIN_DESC swapChainDesc; D3D_FEATURE_LEVEL featureLevel; ID3D11Texture2D* backBufferPtr; D3D11_TEXTURE2D_DESC depthBufferDesc; D3D11_DEPTH_STENCIL_DESC depthStencilDesc; D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc; D3D11_RASTERIZER_DESC rasterDesc; D3D11_VIEWPORT viewport; float fieldOfView, screenAspect; // Store the vsync setting. m_vsync_enabled = vsync; // Create a DX graphics interface factory result = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&factory); if (FAILED(result)) { return false; } // Adapter for the primary graphics interface (video card) result = factory->EnumAdapters(0, &adapter); if (FAILED(result)) { return false; } // primary adapter output = monitor result = adapter->EnumOutputs(0, &adapterOutput); if (FAILED(result)) { return false; } // Get the number of modes that fit the DXGI_FORMAT_R8G8B8A8_UNORM display format result = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, NULL); if (FAILED(result)) { return false; } // Create a list to hold all the possible display modes for this monitor/video card combination. displayModeList = new DXGI_MODE_DESC[numModes]; if(!displayModeList) { return false; } // Now fill the display mode list structures. result = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, displayModeList); if(FAILED(result)) { return false; } // Now go through all the display modes and find the one that matches the screen width and height. // When a match is found store the numerator and denominator of the refresh rate for that monitor. for(i=0; i<numModes; i++) { if(displayModeList[i].Width == (unsigned int)screenWidth) { if(displayModeList[i].Height == (unsigned int)screenHeight) { numerator = displayModeList[i].RefreshRate.Numerator; denominator = displayModeList[i].RefreshRate.Denominator; } } } // Get the adapter (video card) description. result = adapter->GetDesc(&adapterDesc); if(FAILED(result)) { return false; } m_videoCardMemory = (int)(adapterDesc.DedicatedVideoMemory / 1024 / 1024); error = wcstombs_s(&stringLength, m_videoCardDescription, 128, adapterDesc.Description, 128); if (error != 0) { return false; } // Release the display mode list. delete[] displayModeList; displayModeList = 0; adapterOutput->Release(); adapterOutput = 0; adapter->Release(); adapter = 0; factory->Release(); factory = 0; ZeroMemory(&swapChainDesc, sizeof(swapChainDesc)); swapChainDesc.BufferCount = 1; swapChainDesc.BufferDesc.Width = screenWidth; swapChainDesc.BufferDesc.Height = screenHeight; swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; if (m_vsync_enabled) { swapChainDesc.BufferDesc.RefreshRate.Numerator = numerator; swapChainDesc.BufferDesc.RefreshRate.Denominator = denominator; } else { swapChainDesc.BufferDesc.RefreshRate.Numerator = 0; swapChainDesc.BufferDesc.RefreshRate.Denominator = 1; } swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChainDesc.OutputWindow = hwnd; //multisampling off swapChainDesc.SampleDesc.Count = 1; swapChainDesc.SampleDesc.Quality = 0; if (fullscreen) { swapChainDesc.Windowed = false; } else { swapChainDesc.Windowed = true; } //set scan line ordering and scaling to unspecified swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; // discard back buffer contents after presenting swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; swapChainDesc.Flags = 0; featureLevel = D3D_FEATURE_LEVEL_11_0; result = D3D11CreateDeviceAndSwapChain( NULL, D3D_DRIVER_TYPE_REFERENCE, NULL, 0, &featureLevel, 1, D3D11_SDK_VERSION, &swapChainDesc, &m_swapChain, &m_device, NULL, &m_deviceContext); if (FAILED(result)) { return false; } // Get the pointer to the back buffer result = m_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&backBufferPtr); if (FAILED(result)) { return false; } result = m_device->CreateRenderTargetView(backBufferPtr, NULL, &m_renderTargetView); if (FAILED(result)) { return false; } //Release pointer to the back buffer as we no longer need it backBufferPtr->Release(); backBufferPtr = 0; 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; result = m_device->CreateTexture2D(&depthBufferDesc, NULL, &m_depthStencilBuffer); if (FAILED(result)) { return false; } 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; // 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; // Create the depth stencil state. result = m_device->CreateDepthStencilState(&depthStencilDesc, &m_depthStencilState); if(FAILED(result)) { return false; } // Set the depth stencil state. m_deviceContext->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; // Create the depth stencil view. result = m_device->CreateDepthStencilView(m_depthStencilBuffer, &depthStencilViewDesc, &m_depthStencilView); if(FAILED(result)) { return false; } // Bind the render target view and depth stencil buffer to the output render pipeline. m_deviceContext->OMSetRenderTargets(1, &m_renderTargetView, m_depthStencilView); // Setup the raster description which will determine how and what polygons will be drawn. 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; // Create the rasterizer state from the description we just filled out. result = m_device->CreateRasterizerState(&rasterDesc, &m_rasterState); if(FAILED(result)) { return false; } // Now set the rasterizer state. m_deviceContext->RSSetState(m_rasterState); 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); fieldOfView = (float)D3DX_PI / 4.0f; screenAspect = (float)screenWidth / (float)screenHeight; D3DXMatrixPerspectiveFovLH(&m_projectionMatrix, fieldOfView, screenAspect, screenNear, screenDepth); // Initialize the world matrix to the identity matrix. D3DXMatrixIdentity(&m_worldMatrix); // Create an orthographic projection matrix for 2D rendering. D3DXMatrixOrthoLH(&m_orthoMatrix, (float)screenWidth, (float)screenHeight, screenNear, screenDepth); return true; }
bool GSDevice11::Create(GSWnd* wnd) { if(!__super::Create(wnd)) { return false; } HRESULT hr = E_FAIL; DXGI_SWAP_CHAIN_DESC scd; D3D11_BUFFER_DESC bd; D3D11_SAMPLER_DESC sd; D3D11_DEPTH_STENCIL_DESC dsd; D3D11_RASTERIZER_DESC rd; D3D11_BLEND_DESC bsd; CComPtr<IDXGIAdapter1> adapter; D3D_DRIVER_TYPE driver_type = D3D_DRIVER_TYPE_HARDWARE; std::string adapter_id = theApp.GetConfig("Adapter", "default"); if (adapter_id == "default") ; else if (adapter_id == "ref") { driver_type = D3D_DRIVER_TYPE_REFERENCE; } else { CComPtr<IDXGIFactory1> dxgi_factory; CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)&dxgi_factory); if (dxgi_factory) for (int i = 0;; i++) { CComPtr<IDXGIAdapter1> enum_adapter; if (S_OK != dxgi_factory->EnumAdapters1(i, &enum_adapter)) break; DXGI_ADAPTER_DESC1 desc; hr = enum_adapter->GetDesc1(&desc); if (S_OK == hr && GSAdapter(desc) == adapter_id) { adapter = enum_adapter; driver_type = D3D_DRIVER_TYPE_UNKNOWN; break; } } } memset(&scd, 0, sizeof(scd)); scd.BufferCount = 2; scd.BufferDesc.Width = 1; scd.BufferDesc.Height = 1; scd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; //scd.BufferDesc.RefreshRate.Numerator = 60; //scd.BufferDesc.RefreshRate.Denominator = 1; scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; scd.OutputWindow = (HWND)m_wnd->GetHandle(); scd.SampleDesc.Count = 1; scd.SampleDesc.Quality = 0; // Always start in Windowed mode. According to MS, DXGI just "prefers" this, and it's more or less // required if we want to add support for dual displays later on. The fullscreen/exclusive flip // will be issued after all other initializations are complete. scd.Windowed = TRUE; spritehack = !!theApp.GetConfig("UserHacks", 0) ? theApp.GetConfig("UserHacks_SpriteHack", 0) : 0; // NOTE : D3D11_CREATE_DEVICE_SINGLETHREADED // This flag is safe as long as the DXGI's internal message pump is disabled or is on the // same thread as the GS window (which the emulator makes sure of, if it utilizes a // multithreaded GS). Setting the flag is a nice and easy 5% speedup on GS-intensive scenes. uint32 flags = D3D11_CREATE_DEVICE_SINGLETHREADED; #ifdef DEBUG flags |= D3D11_CREATE_DEVICE_DEBUG; #endif D3D_FEATURE_LEVEL level; const D3D_FEATURE_LEVEL levels[] = { D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0, }; hr = D3D11CreateDeviceAndSwapChain(adapter, driver_type, NULL, flags, levels, countof(levels), D3D11_SDK_VERSION, &scd, &m_swapchain, &m_dev, &level, &m_ctx); if(FAILED(hr)) return false; if(!SetFeatureLevel(level, true)) { return false; } D3D11_FEATURE_DATA_D3D10_X_HARDWARE_OPTIONS options; hr = m_dev->CheckFeatureSupport(D3D11_FEATURE_D3D10_X_HARDWARE_OPTIONS, &options, sizeof(D3D11_FEATURE_D3D10_X_HARDWARE_OPTIONS)); // msaa for(uint32 i = 2; i <= D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; i++) { uint32 quality[2] = {0, 0}; if(SUCCEEDED(m_dev->CheckMultisampleQualityLevels(DXGI_FORMAT_R8G8B8A8_UNORM, i, &quality[0])) && quality[0] > 0 && SUCCEEDED(m_dev->CheckMultisampleQualityLevels(DXGI_FORMAT_D32_FLOAT_S8X24_UINT, i, &quality[1])) && quality[1] > 0) { m_msaa_desc.Count = i; m_msaa_desc.Quality = std::min<uint32>(quality[0] - 1, quality[1] - 1); if(i >= m_msaa) break; } } if(m_msaa_desc.Count == 1) { m_msaa = 0; } // convert D3D11_INPUT_ELEMENT_DESC il_convert[] = { {"POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}, {"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 16, D3D11_INPUT_PER_VERTEX_DATA, 0}, }; vector<unsigned char> shader; theApp.LoadResource(IDR_CONVERT_FX, shader); CompileShader((const char *)shader.data(), shader.size(), "convert.fx", nullptr, "vs_main", nullptr, &m_convert.vs, il_convert, countof(il_convert), &m_convert.il); for(size_t i = 0; i < countof(m_convert.ps); i++) { CompileShader((const char *)shader.data(), shader.size(), "convert.fx", nullptr, format("ps_main%d", i).c_str(), nullptr, &m_convert.ps[i]); } memset(&dsd, 0, sizeof(dsd)); dsd.DepthEnable = false; dsd.StencilEnable = false; hr = m_dev->CreateDepthStencilState(&dsd, &m_convert.dss); memset(&bsd, 0, sizeof(bsd)); bsd.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; hr = m_dev->CreateBlendState(&bsd, &m_convert.bs); // merge memset(&bd, 0, sizeof(bd)); bd.ByteWidth = sizeof(MergeConstantBuffer); bd.Usage = D3D11_USAGE_DEFAULT; bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER; hr = m_dev->CreateBuffer(&bd, NULL, &m_merge.cb); theApp.LoadResource(IDR_MERGE_FX, shader); for(size_t i = 0; i < countof(m_merge.ps); i++) { CompileShader((const char *)shader.data(), shader.size(), "merge.fx", nullptr, format("ps_main%d", i).c_str(), nullptr, &m_merge.ps[i]); } memset(&bsd, 0, sizeof(bsd)); bsd.RenderTarget[0].BlendEnable = true; bsd.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; bsd.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; bsd.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; bsd.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; bsd.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; bsd.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; bsd.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; hr = m_dev->CreateBlendState(&bsd, &m_merge.bs); // interlace memset(&bd, 0, sizeof(bd)); bd.ByteWidth = sizeof(InterlaceConstantBuffer); bd.Usage = D3D11_USAGE_DEFAULT; bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER; hr = m_dev->CreateBuffer(&bd, NULL, &m_interlace.cb); theApp.LoadResource(IDR_INTERLACE_FX, shader); for(size_t i = 0; i < countof(m_interlace.ps); i++) { CompileShader((const char *)shader.data(), shader.size(), "interlace.fx", nullptr, format("ps_main%d", i).c_str(), nullptr, &m_interlace.ps[i]); } // Shade Boost int ShadeBoost_Contrast = theApp.GetConfig("ShadeBoost_Contrast", 50); int ShadeBoost_Brightness = theApp.GetConfig("ShadeBoost_Brightness", 50); int ShadeBoost_Saturation = theApp.GetConfig("ShadeBoost_Saturation", 50); string str[3]; str[0] = format("%d", ShadeBoost_Saturation); str[1] = format("%d", ShadeBoost_Brightness); str[2] = format("%d", ShadeBoost_Contrast); D3D_SHADER_MACRO macro[] = { {"SB_SATURATION", str[0].c_str()}, {"SB_BRIGHTNESS", str[1].c_str()}, {"SB_CONTRAST", str[2].c_str()}, {NULL, NULL}, }; memset(&bd, 0, sizeof(bd)); bd.ByteWidth = sizeof(ShadeBoostConstantBuffer); bd.Usage = D3D11_USAGE_DEFAULT; bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER; hr = m_dev->CreateBuffer(&bd, NULL, &m_shadeboost.cb); theApp.LoadResource(IDR_SHADEBOOST_FX, shader); CompileShader((const char *)shader.data(), shader.size(), "shadeboost.fx", nullptr, "ps_main", macro, &m_shadeboost.ps); // External fx shader memset(&bd, 0, sizeof(bd)); bd.ByteWidth = sizeof(ExternalFXConstantBuffer); bd.Usage = D3D11_USAGE_DEFAULT; bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER; hr = m_dev->CreateBuffer(&bd, NULL, &m_shaderfx.cb); // Fxaa memset(&bd, 0, sizeof(bd)); bd.ByteWidth = sizeof(FXAAConstantBuffer); bd.Usage = D3D11_USAGE_DEFAULT; bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER; hr = m_dev->CreateBuffer(&bd, NULL, &m_fxaa.cb); // memset(&rd, 0, sizeof(rd)); rd.FillMode = D3D11_FILL_SOLID; rd.CullMode = D3D11_CULL_NONE; rd.FrontCounterClockwise = false; rd.DepthBias = false; rd.DepthBiasClamp = 0; rd.SlopeScaledDepthBias = 0; rd.DepthClipEnable = false; // ??? rd.ScissorEnable = true; rd.MultisampleEnable = true; rd.AntialiasedLineEnable = false; hr = m_dev->CreateRasterizerState(&rd, &m_rs); m_ctx->RSSetState(m_rs); // memset(&sd, 0, sizeof(sd)); sd.Filter = theApp.GetConfig("MaxAnisotropy", 0) && !theApp.GetConfig("paltex", 0) ? D3D11_FILTER_ANISOTROPIC : D3D11_FILTER_MIN_MAG_MIP_LINEAR; sd.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP; sd.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP; sd.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; sd.MinLOD = -FLT_MAX; sd.MaxLOD = FLT_MAX; sd.MaxAnisotropy = theApp.GetConfig("MaxAnisotropy", 0); sd.ComparisonFunc = D3D11_COMPARISON_NEVER; hr = m_dev->CreateSamplerState(&sd, &m_convert.ln); sd.Filter = theApp.GetConfig("MaxAnisotropy", 0) && !theApp.GetConfig("paltex", 0) ? D3D11_FILTER_ANISOTROPIC : D3D11_FILTER_MIN_MAG_MIP_POINT; hr = m_dev->CreateSamplerState(&sd, &m_convert.pt); // Reset(1, 1); // CreateTextureFX(); // memset(&dsd, 0, sizeof(dsd)); dsd.DepthEnable = false; dsd.StencilEnable = true; dsd.StencilReadMask = 1; dsd.StencilWriteMask = 1; dsd.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; dsd.FrontFace.StencilPassOp = D3D11_STENCIL_OP_REPLACE; dsd.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; dsd.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; dsd.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; dsd.BackFace.StencilPassOp = D3D11_STENCIL_OP_REPLACE; dsd.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; dsd.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; m_dev->CreateDepthStencilState(&dsd, &m_date.dss); D3D11_BLEND_DESC blend; memset(&blend, 0, sizeof(blend)); m_dev->CreateBlendState(&blend, &m_date.bs); // Exclusive/Fullscreen flip, issued for legacy (managed) windows only. GSopen2 style // emulators will issue the flip themselves later on. if(m_wnd->IsManaged()) { SetExclusive(!theApp.GetConfig("windowed", 1)); } return true; }
bool D3DClass::Initialize(int screenWidth, int screenHeight, bool vsync, HWND hwnd, bool fullscreen, float screenDepth, float screenNear) { //set vsync enabled variable m_vsync_enabled = vsync; //----- get refresh rate from monitor / video card //create DirectX graphics interface factory HRESULT result; IDXGIFactory* factory; result = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&factory); if(FAILED(result)) return false; //use factory to create adapter for primary graphics interface (video card) IDXGIAdapter* adapter; result = factory->EnumAdapters(0, &adapter); if(FAILED(result)) return false; //enumerate primary adapter output IDXGIOutput* adapterOutput; result = adapter->EnumOutputs(0, &adapterOutput); if(FAILED(result)) return false; //get amount of modes that fit in the DXGI_FORMAT_R8G8B8A8_UNORM display format for adapter output (monitor) unsigned int numModes; result = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, & numModes, NULL); if(FAILED(result)) return false; //create list to hold all possible display modes for this monitor/video card combination DXGI_MODE_DESC* displayModeList; displayModeList = new DXGI_MODE_DESC[numModes]; if(!displayModeList) return false; //fill the display mode list structures result = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, & numModes, displayModeList); if(FAILED(result)) return false; //go through all display modes and find one that matches the screen width and height //when finding a match, store the enumaerator and denominator of the refresh rate for this monitor unsigned int numerator, denominator; for(unsigned int i = 0; i < numModes; i++) { if(displayModeList[i].Width == (unsigned int)screenWidth) if(displayModeList[i].Height == (unsigned int)screenHeight) { numerator = displayModeList[i].RefreshRate.Numerator; denominator = displayModeList[i].RefreshRate.Denominator; } } //----- release the structures delete [] displayModeList; displayModeList = 0; adapterOutput->Release(); adapterOutput = 0; adapter->Release(); adapter = 0; factory->Release(); factory = 0; //----- //----- start DirectX initialization //init swap chain (front and back buffer) - first graphics will be drawn in back buffer, then swapped with front buffer to display results DXGI_SWAP_CHAIN_DESC swapChainDesc; ZeroMemory(&swapChainDesc, sizeof(swapChainDesc)); //set to single back buffer swapChainDesc.BufferCount = 1; //set width and height of back buffer swapChainDesc.BufferDesc.Width = screenWidth; swapChainDesc.BufferDesc.Height = screenHeight; //set back buffer to 32bit surface swapChainDesc.BufferDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; //----- //set frame rate of back buffer if(m_vsync_enabled) { swapChainDesc.BufferDesc.RefreshRate.Numerator = numerator; swapChainDesc.BufferDesc.RefreshRate.Denominator = denominator; } else { swapChainDesc.BufferDesc.RefreshRate.Numerator = 0; swapChainDesc.BufferDesc.RefreshRate.Denominator = 1; } //set usage of back buffer swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; //set handle for window to render to swapChainDesc.OutputWindow = hwnd; //turn multisampling off swapChainDesc.SampleDesc.Count = 1; swapChainDesc.SampleDesc.Quality = 0; //set full screen mode accordingly if(fullscreen) swapChainDesc.Windowed = false; else swapChainDesc.Windowed = true; //set scan line ordering and scaling to unspecified swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; //discard back buffer contents after presenting swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; //unset advanced flags swapChainDesc.Flags = 0; //set up feature level D3D_FEATURE_LEVEL featureLevel; featureLevel = D3D_FEATURE_LEVEL_11_0; //create swap chain, Direct3D device and device context result = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, &featureLevel, 1, D3D11_SDK_VERSION, &swapChainDesc, &m_swapChain, &m_device, NULL, &m_deviceContext); if(FAILED(result)) return false; //get pointer to back buffer ID3D11Texture2D* backBufferPtr; result = m_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&backBufferPtr); if(FAILED(result)) return false; //create render target view result = m_device->CreateRenderTargetView(backBufferPtr, NULL, &m_renderTargetView); if(FAILED(result)) return false; //release pointer to back buffer backBufferPtr->Release(); backBufferPtr = 0; //----- set up depth buffer desc - for rendering polygons in 3D space // + depth/stencil buffer to achieve effects like motion blur D3D11_TEXTURE2D_DESC depthBufferDesc; ZeroMemory(&depthBufferDesc, sizeof(depthBufferDesc)); //set up description values 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; //create depth/stencil buffer result = m_device->CreateTexture2D(&depthBufferDesc, NULL, &m_depthStencilBuffer); if(FAILED(result)) return false; //set up stencil buffer values D3D11_DEPTH_STENCIL_DESC depthStencilDesc; 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; //create depth stencil state result = m_device->CreateDepthStencilState(&depthStencilDesc, &m_depthStencilState); if(FAILED(result)) return false; //set the state to take its effect m_deviceContext->OMSetDepthStencilState(m_depthStencilState, 1); //init depth stencil view desc D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc; ZeroMemory(&depthStencilViewDesc, sizeof(depthStencilViewDesc)); //set up desc depthStencilViewDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; depthStencilViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; depthStencilViewDesc.Texture2D.MipSlice = 0; //create the depth stencil view result = m_device->CreateDepthStencilView(m_depthStencilBuffer, &depthStencilViewDesc, &m_depthStencilView); if(FAILED(result)) return false; //bind render target view and depth stencil buffer to output render pipeline m_deviceContext->OMSetRenderTargets(1, &m_renderTargetView, m_depthStencilView); // Setup the viewport for rendering. m_viewport.Width = (float)screenWidth; m_viewport.Height = (float)screenHeight; m_viewport.MinDepth = 0.0f; m_viewport.MaxDepth = 1.0f; m_viewport.TopLeftX = 0.0f; m_viewport.TopLeftY = 0.0f; // Create the viewport. m_deviceContext->RSSetViewports(1, &m_viewport); //create rasterize state - controls how polygons are rendered (e.g. wireframe mode or drawing both front and back faces) 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; // Create the rasterizer state from the description we just filled out. result = m_device->CreateRasterizerState(&rasterDesc, &m_rasterState); if(FAILED(result)) return false; //set rasterizer state m_deviceContext->RSSetState(m_rasterState); //set up viewport to clip space coordinates to render target space //in this case, the entire window 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; // Create the viewport. m_deviceContext->RSSetViewports(1, &viewport); //create projection matrix --> translates 3D scene into 2D viewport space; necessary for shaders float fieldOfView, screenAspect; fieldOfView = (float)D3DX_PI * 0.25f; screenAspect = (float)screenWidth / (float)screenHeight; D3DXMatrixPerspectiveFovLH(&m_projectionMatrix, fieldOfView, screenAspect, screenNear, screenDepth); //create world matrix --> convert vertices of objects into vertices for 3D scene --> necessary to manipulate objects in 3D //necessary for shader rendering too D3DXMatrixIdentity(&m_worldMatrix); //create orthographic projection matrix --> rendering 2D elements like UI elements on the screen and skipping 3D rendering on those places //e.g. UI elements and text D3DXMatrixOrthoLH(&m_orthoMatrix, (float)screenWidth, (float)screenHeight, screenNear, screenDepth); // Clear the second depth stencil state before setting the parameters. D3D11_DEPTH_STENCIL_DESC depthDisabledStencilDesc; ZeroMemory(&depthDisabledStencilDesc, sizeof(depthDisabledStencilDesc)); // Now create a second depth stencil state which turns off the Z buffer for 2D rendering. The only difference is // that DepthEnable is set to false, all other parameters are the same as the other depth stencil state. 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; // Create the state using the device result = m_device->CreateDepthStencilState(&depthDisabledStencilDesc, &m_depthDisabledStencilState); if(FAILED(result)) return false; // Clear the blend state description D3D11_BLEND_DESC blendStateDescription; ZeroMemory(&blendStateDescription, sizeof(D3D11_BLEND_DESC)); // Create an alpha enabled blend state description. blendStateDescription.RenderTarget[0].BlendEnable = TRUE; blendStateDescription.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE; blendStateDescription.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; blendStateDescription.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; blendStateDescription.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; blendStateDescription.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; blendStateDescription.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; blendStateDescription.RenderTarget[0].RenderTargetWriteMask = 0x0f; // Create the blend state using the description. result = m_device->CreateBlendState(&blendStateDescription, &m_alphaEnableBlendingState); if(FAILED(result)) return false; // Modify the description to create an alpha disabled blend state description. blendStateDescription.RenderTarget[0].BlendEnable = FALSE; // Create the second blend state using the description. result = m_device->CreateBlendState(&blendStateDescription, &m_alphaDisableBlendingState); if(FAILED(result)) return false; return true; }
int main(void) { struct nk_context *ctx; struct nk_color background; WNDCLASSW wc; RECT rect = { 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT }; DWORD style = WS_OVERLAPPEDWINDOW; DWORD exstyle = WS_EX_APPWINDOW; HWND wnd; int running = 1; HRESULT hr; D3D_FEATURE_LEVEL feature_level; DXGI_SWAP_CHAIN_DESC swap_chain_desc; /* Win32 */ memset(&wc, 0, sizeof(wc)); wc.lpfnWndProc = WindowProc; wc.hInstance = GetModuleHandleW(0); wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.lpszClassName = L"NuklearWindowClass"; RegisterClassW(&wc); AdjustWindowRectEx(&rect, style, FALSE, exstyle); wnd = CreateWindowExW(exstyle, wc.lpszClassName, L"Nuklear Demo", style | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, rect.right - rect.left, rect.bottom - rect.top, NULL, NULL, wc.hInstance, NULL); /* D3D11 setup */ memset(&swap_chain_desc, 0, sizeof(swap_chain_desc)); swap_chain_desc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; swap_chain_desc.BufferDesc.RefreshRate.Numerator = 60; swap_chain_desc.BufferDesc.RefreshRate.Denominator = 1; 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 = 1; swap_chain_desc.OutputWindow = wnd; swap_chain_desc.Windowed = TRUE; swap_chain_desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; swap_chain_desc.Flags = 0; if (FAILED(D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, NULL, 0, D3D11_SDK_VERSION, &swap_chain_desc, &swap_chain, &device, &feature_level, &context))) { /* if hardware device fails, then try WARP high-performance software rasterizer, this is useful for RDP sessions */ hr = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_WARP, NULL, 0, NULL, 0, D3D11_SDK_VERSION, &swap_chain_desc, &swap_chain, &device, &feature_level, &context); assert(SUCCEEDED(hr)); } set_swap_chain_size(WINDOW_WIDTH, WINDOW_HEIGHT); /* GUI */ ctx = nk_d3d11_init(device, WINDOW_WIDTH, WINDOW_HEIGHT, MAX_VERTEX_BUFFER, MAX_INDEX_BUFFER); /* Load Fonts: if none of these are loaded a default font will be used */ {struct nk_font_atlas *atlas; nk_d3d11_font_stash_begin(&atlas); /*struct nk_font *droid = nk_font_atlas_add_from_file(atlas, "../../../extra_font/DroidSans.ttf", 14, 0);*/ /*struct nk_font *robot = nk_font_atlas_add_from_file(atlas, "../../../extra_font/Robot-Regular.ttf", 14, 0);*/ /*struct nk_font *future = nk_font_atlas_add_from_file(atlas, "../../../extra_font/kenvector_future_thin.ttf", 13, 0);*/ /*struct nk_font *clean = nk_font_atlas_add_from_file(atlas, "../../../extra_font/ProggyClean.ttf", 12, 0);*/ /*struct nk_font *tiny = nk_font_atlas_add_from_file(atlas, "../../../extra_font/ProggyTiny.ttf", 10, 0);*/ /*struct nk_font *cousine = nk_font_atlas_add_from_file(atlas, "../../../extra_font/Cousine-Regular.ttf", 13, 0);*/ nk_d3d11_font_stash_end(); /*nk_style_set_font(ctx, &droid->handle)*/;} background = nk_rgb(28,48,62); while (running) { MSG msg; /* Input */ nk_input_begin(ctx); while (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE)) { if (msg.message == WM_QUIT) running = 0; TranslateMessage(&msg); DispatchMessageW(&msg); } nk_input_end(ctx); /* GUI */ {struct nk_panel layout; if (nk_begin(ctx, &layout, "Demo", nk_rect(50, 50, 230, 250), NK_WINDOW_BORDER|NK_WINDOW_MOVABLE|NK_WINDOW_SCALABLE| NK_WINDOW_MINIMIZABLE|NK_WINDOW_TITLE)) { enum {EASY, HARD}; static int op = EASY; static int property = 20; nk_layout_row_static(ctx, 30, 80, 1); if (nk_button_label(ctx, "button", NK_BUTTON_DEFAULT)) fprintf(stdout, "button pressed\n"); nk_layout_row_dynamic(ctx, 30, 2); if (nk_option_label(ctx, "easy", op == EASY)) op = EASY; if (nk_option_label(ctx, "hard", op == HARD)) op = HARD; nk_layout_row_dynamic(ctx, 22, 1); nk_property_int(ctx, "Compression:", 0, &property, 100, 10, 1); {struct nk_panel combo; nk_layout_row_dynamic(ctx, 20, 1); nk_label(ctx, "background:", NK_TEXT_LEFT); nk_layout_row_dynamic(ctx, 25, 1); if (nk_combo_begin_color(ctx, &combo, background, 400)) { nk_layout_row_dynamic(ctx, 120, 1); background = nk_color_picker(ctx, background, NK_RGBA); nk_layout_row_dynamic(ctx, 25, 1); background.r = (nk_byte)nk_propertyi(ctx, "#R:", 0, background.r, 255, 1,1); background.g = (nk_byte)nk_propertyi(ctx, "#G:", 0, background.g, 255, 1,1); background.b = (nk_byte)nk_propertyi(ctx, "#B:", 0, background.b, 255, 1,1); background.a = (nk_byte)nk_propertyi(ctx, "#A:", 0, background.a, 255, 1,1); nk_combo_end(ctx); }} } nk_end(ctx);} if (nk_window_is_closed(ctx, "Demo")) break; /* Draw */ { float bg[4]; nk_color_fv(bg, background); ID3D11DeviceContext_ClearRenderTargetView(context, rt_view, bg); ID3D11DeviceContext_OMSetRenderTargets(context, 1, &rt_view, NULL); nk_d3d11_render(context, NK_ANTI_ALIASING_ON); hr = IDXGISwapChain_Present(swap_chain, 1, 0); if (hr == DXGI_ERROR_DEVICE_RESET || hr == DXGI_ERROR_DEVICE_REMOVED) { /* to recover from this, you'll need to recreate device and all the resources */ MessageBoxW(NULL, L"D3D11 device is lost or removed!", L"Error", 0); break; } else if (hr == DXGI_STATUS_OCCLUDED) { /* window is not visible, so vsync won't work. Let's sleep a bit to reduce CPU usage */ Sleep(10); } assert(SUCCEEDED(hr)); } } ID3D11DeviceContext_ClearState(context); nk_d3d11_shutdown(); ID3D11ShaderResourceView_Release(rt_view); ID3D11DeviceContext_Release(context); ID3D11Device_Release(device); IDXGISwapChain_Release(swap_chain); UnregisterClassW(wc.lpszClassName, wc.hInstance); return 0; }
bool InitDirect3D(RENDERER_SETTINGS * pSetup) { DXGI_FORMAT format = DXGI_FORMAT_R8G8B8A8_UNORM; DXGI_SWAP_CHAIN_DESC desc; ZeroMemory(&desc, sizeof(DXGI_SWAP_CHAIN_DESC)); desc.BufferCount = 1; desc.BufferDesc.Width = pSetup->nWidth; desc.BufferDesc.Height = pSetup->nHeight; desc.BufferDesc.Format = format; if (pSetup->bVsync) { bVsync = true; IDXGIFactory1 * pFactory = NULL; HRESULT hr = CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)&pFactory); if (pFactory) { IDXGIAdapter1 * pAdapter = NULL; pFactory->EnumAdapters1( 0, &pAdapter ); if (pAdapter) { IDXGIOutput * pOutput = NULL; pAdapter->EnumOutputs( 0, &pOutput ); if (pOutput) { unsigned int nModeCount = 0; pOutput->GetDisplayModeList( format, DXGI_ENUM_MODES_INTERLACED | DXGI_ENUM_MODES_SCALING, &nModeCount, NULL); DXGI_MODE_DESC * pModes = new DXGI_MODE_DESC[ nModeCount ]; pOutput->GetDisplayModeList( format, DXGI_ENUM_MODES_INTERLACED | DXGI_ENUM_MODES_SCALING, &nModeCount, pModes); for (int i=0; i<nModeCount; i++) { if (pModes[i].Width == pSetup->nWidth && pModes[i].Height == pSetup->nHeight) { desc.BufferDesc = pModes[i]; break; } } delete[] pModes; pOutput->Release(); } pAdapter->Release(); } pFactory->Release(); } } desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; desc.OutputWindow = hWnd; desc.SampleDesc.Count = 1; desc.Windowed = pSetup->windowMode != RENDERER_WINDOWMODE_FULLSCREEN; DWORD deviceCreationFlags = 0; #ifdef _DEBUG //deviceCreationFlags |= D3D11_CREATE_DEVICE_DEBUG; #endif if (D3D11CreateDeviceAndSwapChain( NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, deviceCreationFlags, NULL, NULL, D3D11_SDK_VERSION, &desc, &pSwapChain, &pDevice, NULL, &pContext) != S_OK) { printf("[Renderer] D3D11CreateDeviceAndSwapChain failed\n"); return false; } pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&pBackBuffer); pDevice->CreateRenderTargetView(pBackBuffer, NULL, &pRenderTarget); pBackBuffer->Release(); pContext->OMSetRenderTargets(1, &pRenderTarget, NULL); // create staging texture for frame grabbing D3D11_TEXTURE2D_DESC description; pBackBuffer->GetDesc( &description ); description.BindFlags = 0; description.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; description.Usage = D3D11_USAGE_STAGING; HRESULT hr = pDevice->CreateTexture2D( &description, NULL, &pFrameGrabTexture ); return true; }
bool D3D::InitializeD3D(int screenWidth, int screenHeight, bool vsync, HWND hwnd, bool fullscreen) { HRESULT result; //used to test things are created ok. vsync; //---------------------------------------------------------------------------------------------- // Fetch the numerator and denominator for refresh rate and video card description. // Create DirectX Graphics Interface factory. IDXGIFactory* factory; result = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&factory); if(FAILED(result)) return false; // Create adapter. IDXGIAdapter* adapter; result = factory->EnumAdapters(0, &adapter); if(FAILED(result)) return false; // Enumerate primary adapter output (monitor). IDXGIOutput* adapterOutput; result = adapter->EnumOutputs(0, &adapterOutput); if(FAILED(result)) return false; // Get the number of modes that fit the DXGI_R8G8B8A8_UNORM display format for adpater output. unsigned int numModes; result = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, NULL); if(FAILED(result)) return false; // Create a list to hold all possible display modes. DXGI_MODE_DESC* displayModeList; displayModeList = new DXGI_MODE_DESC[numModes]; if(!displayModeList) return false; // Fill list. result = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, displayModeList); if(FAILED(result)) return false; // Loop through modes and find one that matches screen width and height, store numerator and // denominator for corresponding refresh rate. unsigned int numerator, denominator; for(unsigned int i = 0; i < numModes; ++i) { if(displayModeList[i].Width == (unsigned int)screenWidth && displayModeList[i].Height == (unsigned int)screenHeight) { numerator = displayModeList[i].RefreshRate.Numerator; denominator = displayModeList[i].RefreshRate.Denominator; } } // Get adapter description. DXGI_ADAPTER_DESC adapterDesc; result = adapter->GetDesc(&adapterDesc); if(FAILED(result)) return false; // Store dedicated video card memory (in mb). m_videoCardMemory = (int)(adapterDesc.DedicatedVideoMemory / 1024 / 1024); // Convert the name of the video card to char array and store. unsigned int stringLength; int error = wcstombs_s(&stringLength, m_videoCardDesc, 128, adapterDesc.Description, 128); if(error != 0) return false; // Release unneeded memory. delete[] displayModeList; displayModeList = 0; adapterOutput->Release(); adapterOutput = 0; adapter->Release(); adapter = 0; factory->Release(); factory = 0; //---------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------- // Set up SwapChain description and create swap chain. DXGI_SWAP_CHAIN_DESC swapChainDesc; ZeroMemory(&swapChainDesc, sizeof(swapChainDesc)); // Setup back buffer. swapChainDesc.BufferCount = 1; swapChainDesc.BufferDesc.Width = screenWidth; swapChainDesc.BufferDesc.Height = screenHeight; swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; // Refresh Rate. if(m_vsyncEnabled) { swapChainDesc.BufferDesc.RefreshRate.Numerator = numerator; swapChainDesc.BufferDesc.RefreshRate.Denominator = denominator; } else { // Draw as soon as possible. swapChainDesc.BufferDesc.RefreshRate.Numerator = 0; swapChainDesc.BufferDesc.RefreshRate.Denominator = 1; } swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChainDesc.OutputWindow = hwnd; // Turn off multisampling. swapChainDesc.SampleDesc.Count = 1; swapChainDesc.SampleDesc.Quality = 0; swapChainDesc.Windowed = !fullscreen; swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; swapChainDesc.Flags = 0; // Create the swap chain. D3D_FEATURE_LEVEL featureLevel = D3D_FEATURE_LEVEL_11_0; result = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, &featureLevel, 1, D3D11_SDK_VERSION, &swapChainDesc, &m_swapChain, &m_device, NULL, &m_deviceContext); if(FAILED(result)) return false; //---------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------- // Set up render target view. ID3D11Texture2D* backBufferPtr; result = m_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&backBufferPtr); if(FAILED(result)) return false; // Create render target view with back buffer ptr. result = m_device->CreateRenderTargetView(backBufferPtr, NULL, &m_renderTargetView); if(FAILED(result)) return false; backBufferPtr->Release(); backBufferPtr = 0; //---------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------- // Set up depthStencilBuffer. D3D11_TEXTURE2D_DESC depthBufferDesc; ZeroMemory(&depthBufferDesc, sizeof(depthBufferDesc)); // Set up description. 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; // Create depth/stencil buffer. result = m_device->CreateTexture2D(&depthBufferDesc, NULL, &m_depthStencilBuffer); if(FAILED(result)) return false; // Setup depth stencil description. 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; // Create depth stencil state. result = m_device->CreateDepthStencilState(&depthStencilDesc, &m_depthStencilState); if(FAILED(result)) return false; // Set depth stencil state. m_deviceContext->OMSetDepthStencilState(m_depthStencilState, 1); //---------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------- // Create second depth stencil state with depth disabled. (for 2D rendering) 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_DECR; 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; result = m_device->CreateDepthStencilState(&depthDisabledStencilDesc, &m_depthDisabledStencilState); if(FAILED(result)) return false; //---------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------- // Create description of the view of the depth stencil buffer. // Do this so D3D knows to use the depth buffer as a depth stencil texture. 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; result = m_device->CreateDepthStencilView(m_depthStencilBuffer, &depthStencilViewDesc, &m_depthStencilView); if(FAILED(result)) return false; // Bind render target view and depth stencil buffer to output render pipeline. m_deviceContext->OMSetRenderTargets(1, &m_renderTargetView, m_depthStencilView); //---------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------- // Create rasterizer state and viewport. 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.0; result = m_device->CreateRasterizerState(&rasterDesc, &m_rasterState); if(FAILED(result)) return false; m_deviceContext->RSSetState(m_rasterState); // Set up viewport. 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); //---------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------- // Create blend states. D3D11_BLEND_DESC blendStateDesc; ZeroMemory(&blendStateDesc, sizeof(D3D11_BLEND_DESC)); blendStateDesc.RenderTarget[0].BlendEnable = TRUE; blendStateDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE; blendStateDesc.RenderTarget[0].DestBlend = D3D11_BLEND_ONE; 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 = 0x0f; result = m_device->CreateBlendState(&blendStateDesc, &m_alphaEnableBlendingState); if(FAILED(result)) { return false; } blendStateDesc.RenderTarget[0].BlendEnable = FALSE; result = m_device->CreateBlendState(&blendStateDesc, &m_alphaDisableBlendingState); if(FAILED(result)) { return false; } //---------------------------------------------------------------------------------------------- return true; }