| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778 |
- #include "CmD3D11RenderWindow.h"
- #include "CmWindowEventUtilities.h"
- #include "CmD3D11RenderSystem.h"
- #include "CmD3D11Device.h"
- #include "CmDepthStencilBuffer.h"
- #include "CmTextureManager.h"
- #include "CmException.h"
- namespace CamelotEngine
- {
- D3D11RenderWindow::D3D11RenderWindow(D3D11Device& device, IDXGIFactory* DXGIFactory)
- : RenderWindow()
- , mDevice(device)
- , mDXGIFactory(DXGIFactory)
- , mIsExternal(false)
- , mSizing(false)
- , mClosed(false)
- , mHidden(false)
- , mSwitchingFullscreen(false)
- , mDisplayFrequency(0)
- , mRenderTargetView(nullptr)
- , mDepthStencilView(nullptr)
- , mBackBuffer(nullptr)
- , mSwapChain(nullptr)
- , mHWnd(0)
- {
- ZeroMemory(&mSwapChainDesc, sizeof(DXGI_SWAP_CHAIN_DESC));
- }
- D3D11RenderWindow::~D3D11RenderWindow()
- {
- destroy();
- }
- void D3D11RenderWindow::initialize(const String& name, unsigned int width, unsigned int height,
- bool fullScreen, const NameValuePairList *miscParams)
- {
- mFSAAType.Count = 1;
- mFSAAType.Quality = 0;
- mFSAA = 0;
- mFSAAHint = "";
- mVSync = false;
- mVSyncInterval = 1;
- HWND parentHWnd = 0;
- HWND externalHandle = 0;
- String title = name;
- int left = -1; // Defaults to screen center
- int top = -1; // Defaults to screen center
- String border = "";
- bool outerSize = false;
- bool enableDoubleClick = false;
- unsigned int colourDepth = 32;
- bool depthBuffer = true;
- if(miscParams)
- {
- // Get variable-length params
- NameValuePairList::const_iterator opt;
- // vsync [parseBool]
- opt = miscParams->find("vsync");
- if(opt != miscParams->end())
- mVSync = parseBool(opt->second);
- // vsyncInterval [parseUnsignedInt]
- opt = miscParams->find("vsyncInterval");
- if(opt != miscParams->end())
- mVSyncInterval = parseUnsignedInt(opt->second);
- // hidden [parseBool]
- opt = miscParams->find("hidden");
- if(opt != miscParams->end())
- mHidden = parseBool(opt->second);
- // displayFrequency
- opt = miscParams->find("displayFrequency");
- if(opt != miscParams->end())
- mDisplayFrequency = parseUnsignedInt(opt->second);
- // colourDepth
- opt = miscParams->find("colourDepth");
- if(opt != miscParams->end())
- colourDepth = parseUnsignedInt(opt->second);
- // depthBuffer [parseBool]
- opt = miscParams->find("depthBuffer");
- if(opt != miscParams->end())
- depthBuffer = parseBool(opt->second);
- // FSAA type
- opt = miscParams->find("FSAA");
- if(opt != miscParams->end())
- mFSAA = parseUnsignedInt(opt->second);
- // FSAA quality
- opt = miscParams->find("FSAAHint");
- if(opt != miscParams->end())
- mFSAAHint = opt->second;
- // sRGB?
- opt = miscParams->find("gamma");
- if(opt != miscParams->end())
- mHwGamma = parseBool(opt->second);
- // left (x)
- opt = miscParams->find("left");
- if(opt != miscParams->end())
- left = parseInt(opt->second);
- // top (y)
- opt = miscParams->find("top");
- if(opt != miscParams->end())
- top = parseInt(opt->second);
- // Window title
- opt = miscParams->find("title");
- if(opt != miscParams->end())
- title = opt->second;
- // parentWindowHandle -> parentHWnd
- opt = miscParams->find("parentWindowHandle");
- if(opt != miscParams->end())
- parentHWnd = (HWND)parseUnsignedInt(opt->second);
- // externalWindowHandle -> externalHandle
- opt = miscParams->find("externalWindowHandle");
- if(opt != miscParams->end())
- externalHandle = (HWND)parseUnsignedInt(opt->second);
- // window border style
- opt = miscParams->find("border");
- if(opt != miscParams->end())
- border = opt->second;
- // set outer dimensions?
- opt = miscParams->find("outerDimensions");
- if(opt != miscParams->end())
- outerSize = parseBool(opt->second);
- // enable double click messages
- opt = miscParams->find("enableDoubleClick");
- if(opt != miscParams->end())
- enableDoubleClick = parseBool(opt->second);
- }
- mName = name;
- mIsFullScreen = fullScreen;
- mColourDepth = colourDepth;
- mWidth = mHeight = mLeft = mTop = 0;
- mActive = true;
- mClosed = false;
- // Destroy current window if any
- if(mHWnd)
- destroy();
- if (!externalHandle)
- {
- DWORD dwStyle = (mHidden ? 0 : WS_VISIBLE) | WS_CLIPCHILDREN;
- RECT rc;
- mWidth = width;
- mHeight = height;
- mTop = top;
- mLeft = left;
- if (!fullScreen)
- {
- if (parentHWnd)
- {
- dwStyle |= WS_CHILD;
- }
- else
- {
- if (border == "none")
- dwStyle |= WS_POPUP;
- else if (border == "fixed")
- dwStyle |= WS_OVERLAPPED | WS_BORDER | WS_CAPTION |
- WS_SYSMENU | WS_MINIMIZEBOX;
- else
- dwStyle |= WS_OVERLAPPEDWINDOW;
- }
- if (!outerSize)
- {
- // Calculate window dimensions required
- // to get the requested client area
- SetRect(&rc, 0, 0, mWidth, mHeight);
- AdjustWindowRect(&rc, dwStyle, false);
- mWidth = rc.right - rc.left;
- mHeight = rc.bottom - rc.top;
- // Clamp width and height to the desktop dimensions
- int screenw = GetSystemMetrics(SM_CXSCREEN);
- int screenh = GetSystemMetrics(SM_CYSCREEN);
- if ((int)mWidth > screenw)
- mWidth = screenw;
- if ((int)mHeight > screenh)
- mHeight = screenh;
- if (mLeft < 0)
- mLeft = (screenw - mWidth) / 2;
- if (mTop < 0)
- mTop = (screenh - mHeight) / 2;
- }
- }
- else
- {
- dwStyle |= WS_POPUP;
- mTop = mLeft = 0;
- }
- UINT classStyle = 0;
- if (enableDoubleClick)
- classStyle |= CS_DBLCLKS;
- HINSTANCE hInst = NULL;
- // Register the window class
- // Allow 4 bytes of window data for D3D11RenderWindow pointer
- WNDCLASS wc = { classStyle, WindowEventUtilities::_WndProc, 0, 0, hInst,
- LoadIcon(0, IDI_APPLICATION), LoadCursor(NULL, IDC_ARROW),
- (HBRUSH)GetStockObject(BLACK_BRUSH), 0, "D3D11Wnd" };
- RegisterClass(&wc);
- // Create our main window
- // Pass pointer to self
- mIsExternal = false;
- mHWnd = CreateWindow("D3D11Wnd", title.c_str(), dwStyle,
- mLeft, mTop, mWidth, mHeight, parentHWnd, 0, hInst, this);
- WindowEventUtilities::_addRenderWindow(this);
- }
- else
- {
- mHWnd = externalHandle;
- mIsExternal = true;
- }
- RECT rc;
- // top and left represent outer window coordinates
- GetWindowRect(mHWnd, &rc);
- mTop = rc.top;
- mLeft = rc.left;
- // width and height represent interior drawable area
- GetClientRect(mHWnd, &rc);
- mWidth = rc.right;
- mHeight = rc.bottom;
- _createSwapChain();
- _createSizeDependedD3DResources();
- mDXGIFactory->MakeWindowAssociation(mHWnd, NULL);
- setHidden(mHidden);
- }
- void D3D11RenderWindow::destroy()
- {
- _destroySizeDependedD3DResources();
- mActive = false;
- mClosed = true;
- SAFE_RELEASE(mSwapChain);
- if (mHWnd && !mIsExternal)
- {
- WindowEventUtilities::_removeRenderWindow(this);
- DestroyWindow(mHWnd);
- }
- mHWnd = nullptr;
- }
- void D3D11RenderWindow::swapBuffers(bool waitForVSync)
- {
- if(mDevice.getD3D11Device() != nullptr)
- {
- HRESULT hr = mSwapChain->Present(waitForVSync ? mVSyncInterval : 0, 0);
- if( FAILED(hr) )
- CM_EXCEPT(RenderingAPIException, "Error Presenting surfaces");
- }
- }
- void D3D11RenderWindow::reposition(int top, int left)
- {
- if (mHWnd && !mIsFullScreen)
- {
- SetWindowPos(mHWnd, 0, top, left, 0, 0,
- SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
- }
- }
- void D3D11RenderWindow::resize(unsigned int width, unsigned int height)
- {
- if (mHWnd && !mIsFullScreen)
- {
- RECT rc = { 0, 0, width, height };
- AdjustWindowRect(&rc, GetWindowLong(mHWnd, GWL_STYLE), false);
- width = rc.right - rc.left;
- height = rc.bottom - rc.top;
- SetWindowPos(mHWnd, 0, 0, 0, width, height,
- SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
- }
- }
- void D3D11RenderWindow::windowMovedOrResized()
- {
- if (!mHWnd || IsIconic(mHWnd))
- return;
- RECT rc;
- // top and left represent outer window position
- GetWindowRect(mHWnd, &rc);
- mTop = rc.top;
- mLeft = rc.left;
- // width and height represent drawable area only
- GetClientRect(mHWnd, &rc);
- unsigned int width = rc.right - rc.left;
- unsigned int height = rc.bottom - rc.top;
- if (width == 0)
- width = 1;
- if (height == 0)
- height = 1;
- if (mWidth == width && mHeight == height)
- return;
- _resizeSwapChainBuffers(width, height);
- }
- void D3D11RenderWindow::setActive(bool state)
- {
- if (mHWnd && mSwapChain)
- {
- if (state)
- {
- ShowWindow(mHWnd, SW_RESTORE);
- mSwapChain->SetFullscreenState(mIsFullScreen, nullptr);
- }
- else
- {
- ShowWindow(mHWnd, SW_SHOWMINIMIZED);
- mSwapChain->SetFullscreenState(FALSE, nullptr);
- }
- }
- RenderWindow::setActive(state);
- }
- void D3D11RenderWindow::setHidden(bool hidden)
- {
- mHidden = hidden;
- if (!mIsExternal)
- {
- if (hidden)
- ShowWindow(mHWnd, SW_HIDE);
- else
- ShowWindow(mHWnd, SW_SHOWNORMAL);
- }
- }
- void D3D11RenderWindow::setFullscreen(bool fullScreen, unsigned int width, unsigned int height)
- {
- if (fullScreen != mIsFullScreen || width != mWidth || height != mHeight)
- {
- if (fullScreen != mIsFullScreen)
- mSwitchingFullscreen = true;
- DWORD dwStyle = WS_VISIBLE | WS_CLIPCHILDREN;
- bool oldFullscreen = mIsFullScreen;
- mIsFullScreen = fullScreen;
- if (fullScreen)
- {
- dwStyle |= WS_POPUP;
- mTop = mLeft = 0;
- mWidth = width;
- mHeight = height;
- // need different ordering here
- if (oldFullscreen)
- {
- // was previously fullscreen, just changing the resolution
- SetWindowPos(mHWnd, HWND_TOPMOST, 0, 0, width, height, SWP_NOACTIVATE);
- }
- else
- {
- SetWindowPos(mHWnd, HWND_TOPMOST, 0, 0, width, height, SWP_NOACTIVATE);
- //MoveWindow(mHWnd, mLeft, mTop, mWidth, mHeight, FALSE);
- SetWindowLong(mHWnd, GWL_STYLE, dwStyle);
- SetWindowPos(mHWnd, 0, 0,0, 0,0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER);
- }
- }
- else
- {
- dwStyle |= WS_OVERLAPPEDWINDOW;
- // Calculate window dimensions required
- // to get the requested client area
- RECT rc;
- SetRect(&rc, 0, 0, width, height);
- AdjustWindowRect(&rc, dwStyle, false);
- unsigned int winWidth = rc.right - rc.left;
- unsigned int winHeight = rc.bottom - rc.top;
- SetWindowLong(mHWnd, GWL_STYLE, dwStyle);
- SetWindowPos(mHWnd, HWND_NOTOPMOST, 0, 0, winWidth, winHeight,
- SWP_DRAWFRAME | SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOACTIVATE);
- // Note that we also set the position in the restoreLostDevice method
- // via _finishSwitchingFullScreen
- }
- mSwapChainDesc.Windowed = !fullScreen;
- mSwapChainDesc.BufferDesc.RefreshRate.Numerator = 0;
- mSwapChainDesc.BufferDesc.RefreshRate.Denominator=0;
- mSwapChainDesc.BufferDesc.Height = height;
- mSwapChainDesc.BufferDesc.Width = width;
- }
- }
- void D3D11RenderWindow::getCustomAttribute( const String& name, void* pData )
- {
- // Valid attributes and their equvalent native functions:
- // D3DDEVICE : getD3DDevice
- // WINDOW : getWindowHandle
- if(name == "WINDOW")
- {
- HWND *pWnd = (HWND*)pData;
- *pWnd = mHWnd;
- return;
- }
- if(name == "D3DDEVICE")
- {
- ID3D11Device **device = (ID3D11Device **)pData;
- *device = mDevice.getD3D11Device();
- return;
- }
- else if(name == "isTexture")
- {
- bool *b = reinterpret_cast< bool * >( pData );
- *b = false;
- return;
- }
- else if(name == "ID3D11RenderTargetView")
- {
- *static_cast<ID3D11RenderTargetView**>(pData) = mRenderTargetView;
- return;
- }
- else if(name == "ID3D11Texture2D")
- {
- ID3D11Texture2D **pBackBuffer = (ID3D11Texture2D**)pData;
- *pBackBuffer = mBackBuffer;
- return;
- }
- else if(name == "numberOfViews")
- {
- unsigned int* n = reinterpret_cast<unsigned int*>(pData);
- *n = 1;
- return;
- }
- else if(name == "DDBACKBUFFER")
- {
- ID3D11Texture2D **ppBackBuffer = (ID3D11Texture2D**) pData;
- ppBackBuffer[0] = NULL;
- return;
- }
- RenderWindow::getCustomAttribute_internal(name, pData);
- }
- void D3D11RenderWindow::copyContentsToMemory(const PixelData &dst, FrameBuffer buffer)
- {
- if(mBackBuffer == nullptr)
- return;
- // get the backbuffer desc
- D3D11_TEXTURE2D_DESC BBDesc;
- mBackBuffer->GetDesc(&BBDesc);
- ID3D11Texture2D *backbuffer = nullptr;
- if(BBDesc.SampleDesc.Quality > 0)
- {
- D3D11_TEXTURE2D_DESC desc = BBDesc;
- desc.Usage = D3D11_USAGE_DEFAULT;
- desc.CPUAccessFlags = 0;
- desc.BindFlags = 0;
- desc.SampleDesc.Quality = 0;
- desc.SampleDesc.Count = 1;
- HRESULT hr = mDevice.getD3D11Device()->CreateTexture2D(
- &desc,
- NULL,
- &backbuffer);
- if (FAILED(hr) || mDevice.hasError())
- {
- String errorDescription = mDevice.getErrorDescription();
- CM_EXCEPT(RenderingAPIException,
- "Error creating texture\nError Description:" + errorDescription);
- }
- mDevice.getImmediateContext()->ResolveSubresource(backbuffer, D3D11CalcSubresource(0, 0, 1), mBackBuffer, D3D11CalcSubresource(0, 0, 1), desc.Format);
- }
- // change the parameters of the texture so we can read it
- BBDesc.Usage = D3D11_USAGE_STAGING;
- BBDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
- BBDesc.BindFlags = 0;
- BBDesc.SampleDesc.Quality = 0;
- BBDesc.SampleDesc.Count = 1;
- // create a temp buffer to copy to
- ID3D11Texture2D * pTempTexture2D;
- HRESULT hr = mDevice.getD3D11Device()->CreateTexture2D(
- &BBDesc,
- NULL,
- &pTempTexture2D);
- if (FAILED(hr) || mDevice.hasError())
- {
- String errorDescription = mDevice.getErrorDescription();
- CM_EXCEPT(RenderingAPIException,
- "Error creating texture\nError Description:" + errorDescription);
- }
- // copy the back buffer
- mDevice.getImmediateContext()->CopyResource(pTempTexture2D, backbuffer != NULL ? backbuffer : mBackBuffer);
- // map the copied texture
- D3D11_MAPPED_SUBRESOURCE mappedTex2D;
- mDevice.getImmediateContext()->Map(pTempTexture2D, 0,D3D11_MAP_READ, 0, &mappedTex2D);
- // copy the the texture to the dest
- PixelUtil::bulkPixelConversion(PixelData(mWidth, mHeight, 1, PF_A8B8G8R8, mappedTex2D.pData), dst);
- // unmap the temp buffer
- mDevice.getImmediateContext()->Unmap(pTempTexture2D, 0);
- // Release the temp buffer
- SAFE_RELEASE(pTempTexture2D);
- SAFE_RELEASE(backbuffer);
- }
- void D3D11RenderWindow::_createSwapChain()
- {
- ZeroMemory(&mSwapChainDesc, sizeof(DXGI_SWAP_CHAIN_DESC));
- // get the dxgi device
- IDXGIDevice* pDXGIDevice = _queryDxgiDevice();
- ZeroMemory(&mSwapChainDesc, sizeof(DXGI_SWAP_CHAIN_DESC));
- DXGI_FORMAT format = DXGI_FORMAT_R8G8B8A8_UNORM;
- mSwapChainDesc.OutputWindow = mHWnd;
- mSwapChainDesc.BufferDesc.Width = mWidth;
- mSwapChainDesc.BufferDesc.Height = mHeight;
- mSwapChainDesc.BufferDesc.Format = format;
- mSwapChainDesc.BufferDesc.RefreshRate.Numerator=0;
- mSwapChainDesc.BufferDesc.RefreshRate.Denominator = 0;
- mSwapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
- mSwapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
- mSwapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH ;
- // triple buffer if VSync is on
- mSwapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
- mSwapChainDesc.BufferCount = mVSync ? 2 : 1;
- mSwapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD ;
- mSwapChainDesc.OutputWindow = mHWnd;
- mSwapChainDesc.Windowed = !mIsFullScreen;
- D3D11RenderSystem* rs = static_cast<D3D11RenderSystem*>(RenderSystem::instancePtr());
- rs->determineFSAASettings(mFSAA, mFSAAHint, format, &mFSAAType);
- mSwapChainDesc.SampleDesc.Count = mFSAAType.Count;
- mSwapChainDesc.SampleDesc.Quality = mFSAAType.Quality;
- HRESULT hr;
- // Create swap chain
- hr = mDXGIFactory->CreateSwapChain(pDXGIDevice, &mSwapChainDesc, &mSwapChain);
- if (FAILED(hr))
- {
- // Try a second time, may fail the first time due to back buffer count,
- // which will be corrected by the runtime
- hr = mDXGIFactory->CreateSwapChain(pDXGIDevice, &mSwapChainDesc, &mSwapChain);
- }
- SAFE_RELEASE(pDXGIDevice);
- if (FAILED(hr))
- CM_EXCEPT(RenderingAPIException, "Unable to create swap chain");
- }
- void D3D11RenderWindow::_createSizeDependedD3DResources()
- {
- // obtain back buffer
- SAFE_RELEASE(mBackBuffer);
- HRESULT hr = mSwapChain->GetBuffer(0, __uuidof( ID3D11Texture2D ), (LPVOID*)&mBackBuffer);
- if( FAILED(hr) )
- CM_EXCEPT(RenderingAPIException, "Unable to Get Back Buffer for swap chain");
- // create all other size depended resources
- assert(mBackBuffer && !mRenderTargetView && !mDepthStencilView);
- // get the backbuffer desc
- D3D11_TEXTURE2D_DESC BBDesc;
- mBackBuffer->GetDesc(&BBDesc);
- // create the render target view
- D3D11_RENDER_TARGET_VIEW_DESC RTVDesc;
- ZeroMemory( &RTVDesc, sizeof(RTVDesc) );
- RTVDesc.Format = BBDesc.Format;
- RTVDesc.ViewDimension = mFSAA ? D3D11_RTV_DIMENSION_TEXTURE2DMS : D3D11_RTV_DIMENSION_TEXTURE2D;
- RTVDesc.Texture2D.MipSlice = 0;
- hr = mDevice.getD3D11Device()->CreateRenderTargetView(mBackBuffer, &RTVDesc, &mRenderTargetView);
- if( FAILED(hr) )
- {
- String errorDescription = mDevice.getErrorDescription();
- CM_EXCEPT(RenderingAPIException, "Unable to create rendertagert view\nError Description:" + errorDescription);
- }
- mDepthStencilBuffer = TextureManager::instance().createDepthStencilBuffer(32, BBDesc.Width, BBDesc.Height, mFSAA, mFSAAHint);
- //if(mDepthBufferPoolId != DepthStencilBuffer::POOL_NO_DEPTH)
- //{
- // // Create depth stencil texture
- // ID3D11Texture2D* pDepthStencil = NULL;
- // D3D11_TEXTURE2D_DESC descDepth;
- // descDepth.Width = BBDesc.Width;
- // descDepth.Height = BBDesc.Height;
- // descDepth.MipLevels = 1;
- // descDepth.ArraySize = 1;
- // descDepth.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
- // descDepth.SampleDesc.Count = mFSAAType.Count;
- // descDepth.SampleDesc.Quality = mFSAAType.Quality;
- // descDepth.Usage = D3D11_USAGE_DEFAULT;
- // descDepth.BindFlags = D3D11_BIND_DEPTH_STENCIL;
- // descDepth.CPUAccessFlags = 0;
- // descDepth.MiscFlags = 0;
- // hr = mDevice.getD3D11Device()->CreateTexture2D(&descDepth, NULL, &pDepthStencil);
- // if( FAILED(hr) || mDevice.hasError())
- // {
- // String errorDescription = mDevice.getErrorDescription(hr);
- // CM_EXCEPT(RenderingAPIException, "Unable to create depth texture\nError Description:" + errorDescription);
- // }
- // // Create the depth stencil view
- // D3D11_DEPTH_STENCIL_VIEW_DESC descDSV;
- // ZeroMemory( &descDSV, sizeof(D3D11_DEPTH_STENCIL_VIEW_DESC) );
- // descDSV.Format = descDepth.Format;
- // descDSV.ViewDimension = mFSAA ? D3D11_DSV_DIMENSION_TEXTURE2DMS : D3D11_DSV_DIMENSION_TEXTURE2D;
- // descDSV.Texture2D.MipSlice = 0;
- // hr = mDevice.getD3D11Device()->CreateDepthStencilView(pDepthStencil, &descDSV, &mDepthStencilView);
- // SAFE_RELEASE(pDepthStencil);
- // if( FAILED(hr) )
- // {
- // String errorDescription = mDevice.getErrorDescription();
- // CM_EXCEPT(RenderingAPIException,
- // "Unable to create depth stencil view\nError Description:" + errorDescription);
- // }
- // D3D11RenderSystem* rsys = static_cast<D3D11RenderSystem*>(RenderSystem::instancePtr());
- // DepthStencilBuffer *depthBuf = rsys->_addManualDepthBuffer(mDepthStencilView, mWidth, mHeight, mFSAAType.Count, mFSAAType.Quality);
- // //Don't forget we want this window to use _this_ depth buffer
- // this->attachDepthBuffer(depthBuf);
- //}
- }
- void D3D11RenderWindow::_destroySizeDependedD3DResources()
- {
- SAFE_RELEASE(mBackBuffer);
- SAFE_RELEASE(mRenderTargetView);
- mDepthStencilBuffer = nullptr;
- SAFE_RELEASE(mDepthStencilView);
- }
- void D3D11RenderWindow::_resizeSwapChainBuffers(unsigned width, unsigned height)
- {
- _destroySizeDependedD3DResources();
- // width and height can be zero to autodetect size, therefore do not rely on them
- UINT Flags = mIsFullScreen ? DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH : 0;
- mSwapChain->ResizeBuffers(mSwapChainDesc.BufferCount, width, height, mSwapChainDesc.BufferDesc.Format, Flags);
- mSwapChain->GetDesc(&mSwapChainDesc);
- mWidth = mSwapChainDesc.BufferDesc.Width;
- mHeight = mSwapChainDesc.BufferDesc.Height;
- mIsFullScreen = (0 == mSwapChainDesc.Windowed); // Alt-Enter together with SetWindowAssociation() can change this state
- _createSizeDependedD3DResources();
- mDevice.getImmediateContext()->OMSetRenderTargets(0, 0, 0);
- // Additional swap chains need their own depth buffer
- // to support resizing them
- HRESULT hr = mSwapChain->GetBuffer( 0, __uuidof( ID3D11Texture2D ), (LPVOID*)&mBackBuffer );
- if( FAILED(hr) )
- {
- CM_EXCEPT(RenderingAPIException,
- "Unable to Get Back Buffer for swap chain");
- }
- // get the backbuffer desc
- D3D11_TEXTURE2D_DESC BBDesc;
- mBackBuffer->GetDesc(&BBDesc);
- // create the render target view
- D3D11_RENDER_TARGET_VIEW_DESC RTVDesc;
- ZeroMemory( &RTVDesc, sizeof(RTVDesc) );
- RTVDesc.Format = BBDesc.Format;
- RTVDesc.ViewDimension = mFSAA ? D3D11_RTV_DIMENSION_TEXTURE2DMS : D3D11_RTV_DIMENSION_TEXTURE2D;
- RTVDesc.Texture2D.MipSlice = 0;
- hr = mDevice.getD3D11Device()->CreateRenderTargetView(mBackBuffer, &RTVDesc, &mRenderTargetView);
- if(FAILED(hr))
- {
- String errorDescription = mDevice.getErrorDescription();
- CM_EXCEPT(RenderingAPIException,
- "Unable to create rendertagert view\nError Description:" + errorDescription);
- }
- }
- IDXGIDevice* D3D11RenderWindow::_queryDxgiDevice()
- {
- if (mDevice.getD3D11Device() == nullptr)
- {
- CM_EXCEPT(RenderingAPIException, "D3D11Device is NULL!");
- }
- IDXGIDevice* pDXGIDevice = nullptr;
- HRESULT hr = mDevice.getD3D11Device()->QueryInterface(__uuidof(IDXGIDevice), (void**)&pDXGIDevice);
- if(FAILED(hr))
- CM_EXCEPT(RenderingAPIException, "Unable to query a DXGIDevice");
- return pDXGIDevice;
- }
- void D3D11RenderWindow::_finishSwitchingFullscreen()
- {
- if(mIsFullScreen)
- {
- // Need to reset the region on the window sometimes, when the
- // windowed mode was constrained by desktop
- HRGN hRgn = CreateRectRgn(0, 0, mSwapChainDesc.BufferDesc.Width, mSwapChainDesc.BufferDesc.Height);
- SetWindowRgn(mHWnd, hRgn, FALSE);
- }
- else
- {
- // When switching back to windowed mode, need to reset window size
- // after device has been restored
- RECT rc;
- SetRect(&rc, 0, 0, mSwapChainDesc.BufferDesc.Width, mSwapChainDesc.BufferDesc.Height);
- AdjustWindowRect(&rc, GetWindowLong(mHWnd, GWL_STYLE), false);
- unsigned int winWidth = rc.right - rc.left;
- unsigned int winHeight = rc.bottom - rc.top;
- int screenw = GetSystemMetrics(SM_CXSCREEN);
- int screenh = GetSystemMetrics(SM_CYSCREEN);
- int left = (screenw - winWidth) / 2;
- int top = (screenh - winHeight) / 2;
- SetWindowPos(mHWnd, HWND_NOTOPMOST, left, top, winWidth, winHeight,
- SWP_DRAWFRAME | SWP_FRAMECHANGED | SWP_NOACTIVATE);
- }
- mSwapChain->SetFullscreenState(mIsFullScreen, NULL);
- mSwitchingFullscreen = false;
- }
- bool D3D11RenderWindow::_checkMultiSampleQuality(UINT SampleCount, UINT *outQuality, DXGI_FORMAT format)
- {
- if (SUCCEEDED(mDevice.getD3D11Device()->CheckMultisampleQualityLevels(format, SampleCount, outQuality)))
- return true;
- else
- return false;
- }
- }
|