/************************************************************************ * desc: Create the DirectX device for rendering * * return: bool - true on success or false on fail ************************************************************************/ void CXDevice::CreateXDevice( HWND hwnd ) { hWnd = hwnd; D3DDISPLAYMODE dxdm; HRESULT hresult; D3DFORMAT depthFormat[] = {D3DFMT_D32, D3DFMT_D24X8, D3DFMT_D16, (D3DFORMAT)0}; D3DFORMAT selectedDepthFormat; int counter = 0; // Set the initial buffer clear mask if( CSettings::Instance().GetClearTargetBuffer() ) bufferClearMask = D3DCLEAR_TARGET; // Recored the max and min z distances maximumZDist = CSettings::Instance().GetMaxZdist(); minimumZDist = CSettings::Instance().GetMinZdist(); viewAngle = D3DXToRadian( CSettings::Instance().GetViewAngle() ); // Calc the aspect ratio float aspectRatio = CSettings::Instance().GetSize().w / CSettings::Instance().GetSize().h; // Calc the square percentage squarePercentage = CSettings::Instance().GetSize().h / CSettings::Instance().GetSize().w; // calc the y ratio to the frustrum frustrumYRatio = squarePercentage / aspectRatio; // Create the DirectX 9 instance spDXInstance.Attach( Direct3DCreate9( D3D_SDK_VERSION ) ); if( spDXInstance == NULL ) throw NExcept::CCriticalException("DirectX Init Error", boost::str( boost::format("Error creating an instance of DirectX9.\n\n%s\nLine: %s") % __FUNCTION__ % __LINE__ )); // Get the caps to see if we can do hardware vertex processing if( FAILED( spDXInstance->GetDeviceCaps( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &d3dCaps ) ) ) throw NExcept::CCriticalException("DirectX Init Error", boost::str( boost::format("Error getting device capabilities of video card.\n\n%s\nLine: %s") % __FUNCTION__ % __LINE__ )); // Get info about the video card if( FAILED( spDXInstance->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &dxdm ) ) ) throw NExcept::CCriticalException("DirectX Init Error", boost::str( boost::format("Error getting adapter display mode of video card.\n\n%s\nLine: %s") % __FUNCTION__ % __LINE__ )); // Check for the best z buffer format do { selectedDepthFormat = depthFormat[counter]; hresult = spDXInstance->CheckDeviceFormat( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, dxdm.Format, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, depthFormat[counter++] ); } while( hresult != D3D_OK && depthFormat[counter] ); // Tell them we couldn't secure a depth buffer if( hresult != D3D_OK ) throw NExcept::CCriticalException("DirectX Init Error", boost::str( boost::format("Video card does not support depth buffering.\n\n%s\nLine: %s") % __FUNCTION__ % __LINE__ )); // clear out the structure memset( &dxpp, 0, sizeof(dxpp) ); // Full screen or windowed mode dxpp.Windowed = !CSettings::Instance().GetFullScreen(); // Fill out the remaining items of the structure dxpp.SwapEffect = D3DSWAPEFFECT_DISCARD; dxpp.BackBufferFormat = dxdm.Format; dxpp.BackBufferWidth = (int)CSettings::Instance().GetSize().w; dxpp.BackBufferHeight = (int)CSettings::Instance().GetSize().h; dxpp.hDeviceWindow = hWnd; dxpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; dxpp.BackBufferCount = 1; if( CSettings::Instance().GetTripleBuffering() ) dxpp.BackBufferCount = 2; if( CSettings::Instance().GetVSync() ) dxpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE; // Do we need the depth stencil? Z buffer and stencil are both created at the same time in hardware if( CSettings::Instance().GetCreateDepthStencilBuffer() ) { dxpp.EnableAutoDepthStencil = true; dxpp.AutoDepthStencilFormat = selectedDepthFormat; depthStencilBufferClearMask = D3DCLEAR_ZBUFFER; if( CSettings::Instance().GetClearStencilBuffer() ) depthStencilBufferClearMask |= D3DCLEAR_STENCIL; // check for stencil buffer support if( spDXInstance->CheckDepthStencilMatch( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, dxpp.BackBufferFormat, dxpp.BackBufferFormat, D3DFMT_D24FS8 ) != D3D_OK ) { if( spDXInstance->CheckDepthStencilMatch( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, dxpp.BackBufferFormat, dxpp.BackBufferFormat, D3DFMT_D24S8 ) != D3D_OK ) { if( spDXInstance->CheckDepthStencilMatch( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, dxpp.BackBufferFormat, dxpp.BackBufferFormat, D3DFMT_D24X4S4 ) != D3D_OK ) { if( spDXInstance->CheckDepthStencilMatch( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, dxpp.BackBufferFormat, dxpp.BackBufferFormat, D3DFMT_D24FS8 ) != D3D_OK ) { throw NExcept::CCriticalException("DirectX Init Error", boost::str( boost::format("Video card does not support hardware stencil buffer.\n\n%s\nLine: %s") % __FUNCTION__ % __LINE__ )); } else // support for a d15s1 buffer { dxpp.AutoDepthStencilFormat = D3DFMT_D15S1; } } else // support for a d24x4s4 buffer { dxpp.AutoDepthStencilFormat = D3DFMT_D24X4S4; } } else // support for a d24s8 buffer { dxpp.AutoDepthStencilFormat = D3DFMT_D24S8; } } else //support for a d24fs8 buffer { dxpp.AutoDepthStencilFormat = D3DFMT_D24FS8; } } DWORD dwBehaviorFlags = D3DCREATE_SOFTWARE_VERTEXPROCESSING; if( d3dCaps.VertexProcessingCaps != 0 ) dwBehaviorFlags = D3DCREATE_HARDWARE_VERTEXPROCESSING; // Create the device if( FAILED( hresult = spDXInstance->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, dwBehaviorFlags | D3DCREATE_MULTITHREADED, &dxpp, &spDXDevice ) ) ) { DisplayError( hresult ); } // Calculate the projection matrixes CalcProjMatrix( CSettings::Instance().GetSize(), CSettings::Instance().GetDefaultSize() ); // Get the initial texture memory amount initialVideoMemory = GetAvailableTextureMem(); // Buffers and render states that need to be reset/recreated after a device rest ResetXDevice(); } // CreateXDevice
bool DX10_Renderer::onResize() { // Release the old render target view before creating again ReleaseCOM(m_pRenderTargetView); ReleaseCOM(m_pDepthStencilView); ReleaseCOM(m_pDepthStencilBuffer); // Resize the buffers of the Swap Chain and create the new render target view VALIDATEHR(m_pDX10SwapChain->ResizeBuffers(1, m_clientWidth, m_clientHeight, DXGI_FORMAT_R8G8B8A8_UNORM, 0)); // Create a temporary Back buffer ID3D10Texture2D* pBackBuffer; // Retrieve the Back Buffer of the Swap Chain and create a Render Target View using the Back Buffer VALIDATEHR(m_pDX10SwapChain->GetBuffer(0, __uuidof(ID3D10Texture2D), reinterpret_cast<void**>(&pBackBuffer))); VALIDATEHR(m_pDX10Device->CreateRenderTargetView(pBackBuffer, 0, &m_pRenderTargetView)); // Release the memory from the temporary Back Buffer ReleaseCOM(pBackBuffer); // Create the depth buffer. D3D10_TEXTURE2D_DESC depthBufferDesc; depthBufferDesc.Width = m_clientWidth; depthBufferDesc.Height = m_clientHeight; depthBufferDesc.MipLevels = 1; depthBufferDesc.ArraySize = 1; depthBufferDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; depthBufferDesc.SampleDesc.Count = 1; // multi sampling must match depthBufferDesc.SampleDesc.Quality = 0; // swap chain values. depthBufferDesc.Usage = D3D10_USAGE_DEFAULT; depthBufferDesc.BindFlags = D3D10_BIND_DEPTH_STENCIL; depthBufferDesc.CPUAccessFlags = 0; depthBufferDesc.MiscFlags = 0; VALIDATEHR(m_pDX10Device->CreateTexture2D(&depthBufferDesc, NULL, &m_pDepthStencilBuffer)); //-------------------------------------------------------------------------------------- // Normal Depth Stencil //-------------------------------------------------------------------------------------- D3D10_DEPTH_STENCIL_DESC depthStencilDesc; // Initialize the description of the stencil state. ZeroMemory(&depthStencilDesc, sizeof(depthStencilDesc)); // Set up the description of the stencil state. depthStencilDesc.DepthEnable = true; depthStencilDesc.DepthWriteMask = D3D10_DEPTH_WRITE_MASK_ALL; depthStencilDesc.DepthFunc = D3D10_COMPARISON_LESS; depthStencilDesc.StencilEnable = true; depthStencilDesc.StencilReadMask = 0xFF; depthStencilDesc.StencilWriteMask = 0xFF; // Stencil operations if pixel is front-facing. depthStencilDesc.FrontFace.StencilFailOp = D3D10_STENCIL_OP_KEEP; depthStencilDesc.FrontFace.StencilDepthFailOp = D3D10_STENCIL_OP_INCR; depthStencilDesc.FrontFace.StencilPassOp = D3D10_STENCIL_OP_KEEP; depthStencilDesc.FrontFace.StencilFunc = D3D10_COMPARISON_ALWAYS; // Stencil operations if pixel is back-facing. depthStencilDesc.BackFace.StencilFailOp = D3D10_STENCIL_OP_KEEP; depthStencilDesc.BackFace.StencilDepthFailOp = D3D10_STENCIL_OP_DECR; depthStencilDesc.BackFace.StencilPassOp = D3D10_STENCIL_OP_KEEP; depthStencilDesc.BackFace.StencilFunc = D3D10_COMPARISON_ALWAYS; // Create the depth stencil state. VALIDATEHR(m_pDX10Device->CreateDepthStencilState(&depthStencilDesc, &m_pDepthStencilStateNormal)); // Set the depth stencil state on the D3D device. m_pDX10Device->OMSetDepthStencilState(m_pDepthStencilStateNormal, 1); D3D10_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc; // 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 = D3D10_DSV_DIMENSION_TEXTURE2D; depthStencilViewDesc.Texture2D.MipSlice = 0; // Create the depth stencil view. VALIDATEHR(m_pDX10Device->CreateDepthStencilView(m_pDepthStencilBuffer, &depthStencilViewDesc, &m_pDepthStencilView)); // Bind the render target view and depth stencil buffer to the output render pipeline. m_pDX10Device->OMSetRenderTargets(1, &m_pRenderTargetView, m_pDepthStencilView); //-------------------------------------------------------------------------------------- // Disabled Depth Stencil //-------------------------------------------------------------------------------------- D3D10_DEPTH_STENCIL_DESC depthDisabledStencilDesc; // 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. depthDisabledStencilDesc.DepthEnable = false; depthDisabledStencilDesc.DepthWriteMask = D3D10_DEPTH_WRITE_MASK_ALL; depthDisabledStencilDesc.DepthFunc = D3D10_COMPARISON_LESS; depthDisabledStencilDesc.StencilEnable = true; depthDisabledStencilDesc.StencilReadMask = 0xFF; depthDisabledStencilDesc.StencilWriteMask = 0xFF; depthDisabledStencilDesc.FrontFace.StencilFailOp = D3D10_STENCIL_OP_KEEP; depthDisabledStencilDesc.FrontFace.StencilDepthFailOp = D3D10_STENCIL_OP_INCR; depthDisabledStencilDesc.FrontFace.StencilPassOp = D3D10_STENCIL_OP_KEEP; depthDisabledStencilDesc.FrontFace.StencilFunc = D3D10_COMPARISON_ALWAYS; depthDisabledStencilDesc.BackFace.StencilFailOp = D3D10_STENCIL_OP_KEEP; depthDisabledStencilDesc.BackFace.StencilDepthFailOp = D3D10_STENCIL_OP_DECR; depthDisabledStencilDesc.BackFace.StencilPassOp = D3D10_STENCIL_OP_KEEP; depthDisabledStencilDesc.BackFace.StencilFunc = D3D10_COMPARISON_ALWAYS; // Create the state using the device. VALIDATEHR(m_pDX10Device->CreateDepthStencilState(&depthDisabledStencilDesc, &m_pDepthStencilStateZDisabled)); // Set the View Port for the Device D3D10_VIEWPORT viewPort; viewPort.TopLeftX = 0; viewPort.TopLeftY = 0; viewPort.Width = m_clientWidth; viewPort.Height = m_clientHeight; viewPort.MinDepth = 0.0f; viewPort.MaxDepth = 1.0f; // Binds the View port to the Rasterizer stage of the pipeline m_pDX10Device->RSSetViewports(1, &viewPort); // Calculate the new Projection Matrix CalcProjMatrix(); // Create an orthographic projection matrix for 2D rendering. D3DXMatrixOrthoLH(&m_matOrtho, static_cast<float>(m_clientWidth), static_cast<float>(m_clientHeight), 0.1f, 100.0f); return true; }