void Scene::onInit() { this->mpZBufferDSV.Reset(); this->mpZBuffer.Reset(); this->mpBackBufferRTV.Reset(); this->mpBackBuffer.Reset(); this->mpImmediateContext.Reset(); this->mpDevice.Reset(); this->mpSwapChain.Reset(); //デバイスなどを作り直す //DXGIを使う上で必要となるIDXGIFactory1を作成 HRESULT hr; Microsoft::WRL::ComPtr<IDXGIFactory1> pFactory; hr = CreateDXGIFactory1(IID_PPV_ARGS(pFactory.GetAddressOf())); if (FAILED(hr)) { throw std::runtime_error("IDXGIFactoryクラスの作成に失敗しました。"); } //GPUアダプターを列挙して一番最初に見つかった使えるものを選ぶ Microsoft::WRL::ComPtr<IDXGIAdapter1> pAdapterIt; for (UINT adapterIndex = 0; S_OK == pFactory->EnumAdapters1(adapterIndex, pAdapterIt.GetAddressOf()); ++adapterIndex) { DXGI_ADAPTER_DESC1 desc; pAdapterIt->GetDesc1(&desc); OutputDebugStringA( std::string("adapter " + std::to_string(adapterIndex) + "\n").c_str()); OutputDebugStringW((std::wstring(L" decription = ") + desc.Description + L"\n").c_str()); OutputDebugStringA( std::string(" VemdorId = " + std::to_string(desc.VendorId) + "\n").c_str()); OutputDebugStringA( std::string(" DeviceId = " + std::to_string(desc.DeviceId) + "\n").c_str()); OutputDebugStringA( std::string(" SubSysId = " + std::to_string(desc.SubSysId) + "\n").c_str()); OutputDebugStringA( std::string(" Revision = " + std::to_string(desc.Revision) + "\n").c_str()); OutputDebugStringA( std::string(" DedicatedVideoMemory = " + std::to_string(desc.DedicatedVideoMemory) + "\n").c_str()); OutputDebugStringA( std::string(" DedicatedSystemMemory = " + std::to_string(desc.DedicatedSystemMemory) + "\n").c_str()); OutputDebugStringA( std::string(" SharedSystemMemory = " + std::to_string(desc.SharedSystemMemory) + "\n").c_str()); OutputDebugStringA( std::string(" AdapterLuid = high:" + std::to_string(desc.AdapterLuid.HighPart) + " low:" + std::to_string(desc.AdapterLuid.LowPart) + "\n").c_str()); OutputDebugStringA( std::string(" Flag = " + std::to_string(desc.Flags) + "\n").c_str()); if (nullptr == this->mpAdapter) { if (desc.Flags ^= DXGI_ADAPTER_FLAG_SOFTWARE) { this->mpAdapter = pAdapterIt; OutputDebugStringA(std::string("このアダプターを使用します。 adapterIndex = " + std::to_string(adapterIndex) + "\n").c_str()); } //期待通りに動作してくれなかった //LARGE_INTEGER version; //hr = pAdapterIt->CheckInterfaceSupport(__uuidof(ID3D11Device), &version); //DXGI_ERROR_UNSUPPORTED; //if (S_OK == hr) { // pAdapter = pAdapterIt; // OutputDebugStringA(std::string("このアダプターを使用します。 adapterIndex = " + std::to_string(adapterIndex) + "\n").c_str()); //} } //使い終わったら必ずReleaseすること pAdapterIt.Reset(); } //ID3D11DeviceとID3D11DeviceContextの作成 std::array<D3D_FEATURE_LEVEL, 3> featureLevels = { { D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0 } }; UINT flags = 0; #ifdef _DEBUG flags |= D3D11_CREATE_DEVICE_DEBUG; #endif D3D_FEATURE_LEVEL usedLevel; hr = D3D11CreateDevice( this->mpAdapter.Get(), D3D_DRIVER_TYPE_UNKNOWN, nullptr, flags, featureLevels.data(), static_cast<UINT>(featureLevels.size()), D3D11_SDK_VERSION, this->mpDevice.GetAddressOf(), &usedLevel, this->mpImmediateContext.GetAddressOf() ); if (FAILED(hr)) { throw std::runtime_error("ID3D11Deviceの作成に失敗。"); } //IDXGISwapChainの作成 DXGI_SWAP_CHAIN_DESC swapChainDesc = { 0 }; swapChainDesc.OutputWindow = Win32Application::hwnd(); swapChainDesc.BufferCount = 2; swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_SEQUENTIAL; swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; //swapChainDesc.Flags = 0; swapChainDesc.SampleDesc.Count = 1; swapChainDesc.SampleDesc.Quality = 0; //フルスクリーンとウィンドモードの切り替えがしたい場合は、まずウィンドウモードとして生成することを推奨しているみたい //https://msdn.microsoft.com/en-us/library/bb174579(v=vs.85).aspx swapChainDesc.Windowed = true; //希望する画面設定 swapChainDesc.BufferDesc.Width = this->width(); swapChainDesc.BufferDesc.Height = this->height(); swapChainDesc.BufferDesc.RefreshRate.Numerator = 60; swapChainDesc.BufferDesc.RefreshRate.Denominator = 1; swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; //上の画面設定に一番近いものを調べる Microsoft::WRL::ComPtr<IDXGIOutput> pOutput; if (DXGI_ERROR_NOT_FOUND == this->mpAdapter->EnumOutputs(0, pOutput.GetAddressOf())) { throw std::runtime_error("アダプターの出力先が見つかりません。"); } DXGI_MODE_DESC modeDesc; hr = pOutput->FindClosestMatchingMode(&swapChainDesc.BufferDesc, &modeDesc, this->mpDevice.Get()); if (FAILED(hr)) { throw std::runtime_error("表示モードの取得に失敗"); } //IDXGISwapChainの作成 swapChainDesc.BufferDesc = modeDesc; hr = pFactory->CreateSwapChain(this->mpDevice.Get(), &swapChainDesc, this->mpSwapChain.GetAddressOf()); if (FAILED(hr)) { throw std::runtime_error("IDXGISwapChainの作成に失敗"); } //ディスプレイの画面モードの一覧を取得する //IDXGIOutput* pOutput; //this->mpSwapChain->GetContainingOutput(&pOutput); //UINT num; //UINT flag = DXGI_ENUM_MODES_INTERLACED; //pOutput->GetDisplayModeList(swapChainDesc.BufferDesc.Format, flag, &num, nullptr); //std::vector<DXGI_MODE_DESC> modeDesces; //modeDesces.resize(num); //pOutput->GetDisplayModeList(swapChainDesc.BufferDesc.Format, flag, &num, &modeDesces[0]); //pOutput->Release(); // // 後はバックバッファのレンダーターゲットビューの作成、必要ならZバッファの作成とビューポートの設定を行う // initRenderTargetAndDepthStencil(swapChainDesc.BufferDesc.Width, swapChainDesc.BufferDesc.Height); }
//----------------------------------------------------------------------- GraphicsContextDirect3D11::GraphicsContextDirect3D11( HWND windowHandle, Microsoft::WRL::ComPtr<IDXGIFactory1> const& dxgiFactory, Microsoft::WRL::ComPtr<ID3D11Device> const& device, Microsoft::WRL::ComPtr<ID3D11DeviceContext> const& deviceContextIn, PresentationParameters const& presentationParameters) : deviceContext(deviceContextIn) , blendFactor({1.0f, 1.0f, 1.0f, 1.0f}) , preferredBackBufferWidth(1) , preferredBackBufferHeight(1) , backBufferCount(2) , backBufferFormat(DXGIFormatHelper::ToDXGIFormat(presentationParameters.BackBufferFormat)) , backBufferDepthFormat(presentationParameters.DepthStencilFormat) , needToApplyPipelineState(true) { using Microsoft::WRL::ComPtr; POMDOG_ASSERT(device); POMDOG_ASSERT(deviceContext); DXGI_SAMPLE_DESC sampleDesc; sampleDesc.Count = 1; sampleDesc.Quality = 0; if (presentationParameters.MultiSampleCount > 1) { ChooseMultiSampleSetting( device.Get(), backBufferFormat, presentationParameters.MultiSampleCount, sampleDesc); } #if defined(DEBUG) && !defined(NDEBUG) Log::Internal(StringHelper::Format( "DXGI_SAMPLE_DESC.Count : %d\n" "DXGI_SAMPLE_DESC.Quality: %d", sampleDesc.Count, sampleDesc.Quality)); #endif { RECT rect; ::GetClientRect(windowHandle, &rect); auto const windowWidth = rect.right - rect.left; auto const windowHeight = rect.bottom - rect.top; preferredBackBufferWidth = std::max<int>(preferredBackBufferWidth, windowWidth); preferredBackBufferHeight = std::max<int>(preferredBackBufferHeight, windowHeight); } { DXGI_SWAP_CHAIN_DESC swapChainDesc; ZeroMemory(&swapChainDesc, sizeof(swapChainDesc)); swapChainDesc.BufferCount = backBufferCount; swapChainDesc.BufferDesc.Width = preferredBackBufferWidth; swapChainDesc.BufferDesc.Height = preferredBackBufferHeight; swapChainDesc.BufferDesc.Format = backBufferFormat; swapChainDesc.BufferDesc.RefreshRate.Numerator = 60; swapChainDesc.BufferDesc.RefreshRate.Denominator = 1; swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChainDesc.OutputWindow = windowHandle; swapChainDesc.Windowed = (!presentationParameters.IsFullScreen ? TRUE : FALSE); swapChainDesc.SampleDesc.Count = sampleDesc.Count; swapChainDesc.SampleDesc.Quality = sampleDesc.Quality; POMDOG_ASSERT(dxgiFactory); HRESULT hr = dxgiFactory->CreateSwapChain(device.Get(), &swapChainDesc, &swapChain); if (FAILED(hr)) { // FUS RO DAH! POMDOG_THROW_EXCEPTION(std::runtime_error, "Failed to create SwapChain"); } } { ///@todo MSAA is not implemented yet constexpr int multiSampleCount = 1; backBuffer = std::make_shared<RenderTarget2DDirect3D11>( device.Get(), swapChain.Get(), preferredBackBufferWidth, preferredBackBufferHeight, backBufferDepthFormat, multiSampleCount); renderTargets.reserve(D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT); renderTargets.push_back(backBuffer); } SetRenderTarget(); textureResourceViews.fill(nullptr); }