D3DContext::D3DContext(ApplicationWindow* targetWindow, const Description& description) : mTargetWindow(targetWindow) { if (!CreateDeviceAndSwapChain(description)) throw std::runtime_error("Failed to create device and swap chain"); if (!CreateBackBufferView()) throw std::runtime_error("Failed to create a back buffer view"); if (!CreateDepthStencilBuffer(description.DepthBuffer)) throw std::runtime_error("Failed to create a depth/stencil buffer"); mDevice->OMSetRenderTargets(1, &mBackBufferView, mDepthStencilView); SetViewports(description.Viewports); SetActiveViewport(0); }
HRESULT ACD3D::AddViewport(HWND hWnd, BOOL enableVSync) { HRESULT hr; VSyncEnable = enableVSync; Log("Add viewport"); //cria o retangulo para renderizacao RECT rc; GetClientRect( hWnd, &rc ); UINT width = rc.right - rc.left; UINT height = rc.bottom - rc.top; //adiciona os objetos necessarios para cada vp ACD3DVpComponents* vpComponent = new ACD3DVpComponents(); //pega o factory IDXGIFactory* pDXGIFactory = ACD3DTools::GetDXGIFactory(); #pragma region CREATE SWAP CHAIN IDXGISwapChain* pSwapChain; //define o rendertargetview, define o buffer e coloca como backbuffer em cada swapchain //cria os swpachains para cada janela DXGI_SWAP_CHAIN_DESC scd; SecureZeroMemory(&scd, sizeof(scd)); if (VSyncEnable) scd = ACD3DConfigurations::DefineSwapShain(hWnd, width, height, ACD3DGlobals::G_Numerator, ACD3DGlobals::G_Denomerator); //ser form o vsync enable ele sincroniza a renderizacao com o refreshrate da tela else scd = ACD3DConfigurations::DefineSwapShain(hWnd, width, height, 60, 1); //senao ele usa direto os valores padroes isso pode gerar alguns artefatos MF hr = pDXGIFactory->CreateSwapChain(ACD3DGlobals::G_pD3dDevice, &scd, &pSwapChain); if( FAILED( hr ) ) { MessageBoxA(nullptr, "[ERROR] Creating SwapChain. AddViewport()", "Error", MB_OK | MB_ICONERROR); return hr; } // Release the factory. pDXGIFactory->Release(); pDXGIFactory = nullptr; vpComponent->pSwapChain = pSwapChain; #pragma endregion #pragma region CREATE RENDERTARGETVIEW //array de backbuffers, um pra cada janela ID3D11Texture2D* pBackBuffer; ID3D11RenderTargetView* pRenderTargetView; hr = pSwapChain->GetBuffer( 0, __uuidof( ID3D11Texture2D ), ( LPVOID* )&pBackBuffer ); if( FAILED( hr ) ) { MessageBoxA(nullptr, "[ERROR] Create buffer. AddViewport()", "Error", MB_OK | MB_ICONERROR); return hr; } hr = ACD3DGlobals::G_pD3dDevice->CreateRenderTargetView( pBackBuffer, nullptr, &pRenderTargetView ); if( FAILED( hr ) ) { MessageBoxA(nullptr, "[ERROR] Create render target. AddViewport()", "Error", MB_OK | MB_ICONERROR); return hr; } vpComponent->pRenderTargetView = pRenderTargetView; pBackBuffer->Release(); #pragma endregion #pragma region CREATE DEPTHSTENCILVIEW ID3D11Texture2D* pDepthStencil; ID3D11DepthStencilView* pDepthStencilView; //define o stencil view hr = ACD3DConfigurations::DefineDepthStencilView(ACD3DGlobals::G_pD3dDevice, &pDepthStencil, &pDepthStencilView, width, height); if( FAILED( hr ) ) { MessageBoxA(nullptr, "[ERROR] Create depth stencil view. AddViewport()", "Error", MB_OK | MB_ICONERROR); return hr; } vpComponent->pDepthStencilView = pDepthStencilView; pDepthStencil->Release(); #pragma endregion #pragma region CREATE VIEWPORT D3D11_VIEWPORT vp; ACD3DConfigurations::DefineViewPort(width, height, 0, 1, rc.left, rc.top, &vp); vpComponent->Viewport = vp; #pragma endregion //inser o objeto no map mpVpComponents.insert(std::pair<HWND, ACD3DVpComponents*>(hWnd, vpComponent)); //seta a viewport ACD3DGlobals::G_pContext->RSSetViewports( 1, &vp ); //seta o render target e o depthstencil ACD3DGlobals::G_pContext->OMSetRenderTargets( 1, &pRenderTargetView, pDepthStencilView ); SetActiveViewport(hWnd); SetActiveRenderingViewport(hWnd); return AC_OK; };