void D3D9Device::copyContentsToMemory(const D3D9RenderWindowCore* renderWindow, PixelData &dst, RenderTargetCore::FrameBuffer buffer) { const RenderWindowProperties& props = renderWindow->getProperties(); RenderWindowToResorucesIterator it = getRenderWindowIterator(renderWindow); RenderWindowResources* resources = it->second; bool swapChain = isSwapChainWindow(renderWindow); if ((dst.getLeft() < 0) || (dst.getRight() > props.getWidth()) || (dst.getTop() < 0) || (dst.getBottom() > props.getHeight()) || (dst.getFront() != 0) || (dst.getBack() != 1)) { BS_EXCEPT(InvalidParametersException, "Invalid box."); } HRESULT hr; IDirect3DSurface9* pSurf = NULL; IDirect3DSurface9* pTempSurf = NULL; D3DSURFACE_DESC desc; D3DLOCKED_RECT lockedRect; if (buffer == RenderTargetCore::FB_AUTO) { buffer = RenderTargetCore::FB_FRONT; } if (buffer == RenderTargetCore::FB_FRONT) { D3DDISPLAYMODE dm; if (FAILED(hr = mpDevice->GetDisplayMode(0, &dm))) { BS_EXCEPT(RenderingAPIException, "Can't get display mode: TODO PORT NO ERROR"); // TODO PORT - Translate HR to error } desc.Width = dm.Width; desc.Height = dm.Height; desc.Format = D3DFMT_A8R8G8B8; if (FAILED(hr = mpDevice->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &pTempSurf, 0))) { BS_EXCEPT(RenderingAPIException, "Can't create offscreen buffer: TODO PORT NO ERROR"); // TODO PORT - Translate HR to error } if (FAILED(hr = swapChain ? resources->swapChain->GetFrontBufferData(pTempSurf) : mpDevice->GetFrontBufferData(0, pTempSurf))) { SAFE_RELEASE(pTempSurf); BS_EXCEPT(RenderingAPIException, "Can't get front buffer: TODO PORT NO ERROR"); // TODO PORT - Translate HR to error } if (props.isFullScreen()) { if ((dst.getLeft() == 0) && (dst.getRight() == props.getWidth()) && (dst.getTop() == 0) && (dst.getBottom() == props.getHeight())) { hr = pTempSurf->LockRect(&lockedRect, 0, D3DLOCK_READONLY | D3DLOCK_NOSYSLOCK); } else { RECT rect; rect.left = static_cast<LONG>(dst.getLeft()); rect.right = static_cast<LONG>(dst.getRight()); rect.top = static_cast<LONG>(dst.getTop()); rect.bottom = static_cast<LONG>(dst.getBottom()); hr = pTempSurf->LockRect(&lockedRect, &rect, D3DLOCK_READONLY | D3DLOCK_NOSYSLOCK); } if (FAILED(hr)) { SAFE_RELEASE(pTempSurf); BS_EXCEPT(RenderingAPIException, "Can't lock rect: TODO PORT NO ERROR"); // TODO PORT - Translate HR to error } } else { RECT srcRect; //GetClientRect(mHWnd, &srcRect); srcRect.left = static_cast<LONG>(dst.getLeft()); srcRect.top = static_cast<LONG>(dst.getTop()); srcRect.right = static_cast<LONG>(dst.getRight()); srcRect.bottom = static_cast<LONG>(dst.getBottom()); POINT point; point.x = srcRect.left; point.y = srcRect.top; ClientToScreen(renderWindow->_getWindowHandle(), &point); srcRect.top = point.y; srcRect.left = point.x; srcRect.bottom += point.y; srcRect.right += point.x; desc.Width = srcRect.right - srcRect.left; desc.Height = srcRect.bottom - srcRect.top; if (FAILED(hr = pTempSurf->LockRect(&lockedRect, &srcRect, D3DLOCK_READONLY | D3DLOCK_NOSYSLOCK))) { SAFE_RELEASE(pTempSurf); BS_EXCEPT(RenderingAPIException, "Can't lock rect: TODO PORT NO ERROR"); // TODO PORT - Translate HR to error } } } else { SAFE_RELEASE(pSurf); if(FAILED(hr = swapChain? resources->swapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &pSurf) : mpDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &pSurf))) { BS_EXCEPT(RenderingAPIException, "Can't get back buffer: TODO PORT NO ERROR"); // TODO PORT - Translate HR to error } if(FAILED(hr = pSurf->GetDesc(&desc))) { BS_EXCEPT(RenderingAPIException, "Can't get description: TODO PORT NO ERROR"); // TODO PORT - Translate HR to error } if (FAILED(hr = mpDevice->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &pTempSurf, 0))) { BS_EXCEPT(RenderingAPIException, "Can't create offscreen surface: TODO PORT NO ERROR"); // TODO PORT - Translate HR to error } if (desc.MultiSampleType == D3DMULTISAMPLE_NONE) { if (FAILED(hr = mpDevice->GetRenderTargetData(pSurf, pTempSurf))) { SAFE_RELEASE(pTempSurf); BS_EXCEPT(RenderingAPIException, "Can't get render target data: TODO PORT NO ERROR"); // TODO PORT - Translate HR to error } } else { IDirect3DSurface9* pStretchSurf = 0; if (FAILED(hr = mpDevice->CreateRenderTarget(desc.Width, desc.Height, desc.Format, D3DMULTISAMPLE_NONE, 0, false, &pStretchSurf, 0))) { SAFE_RELEASE(pTempSurf); BS_EXCEPT(RenderingAPIException, "Can't create render target: TODO PORT NO ERROR"); // TODO PORT - Translate HR to error } if (FAILED(hr = mpDevice->StretchRect(pSurf, 0, pStretchSurf, 0, D3DTEXF_NONE))) { SAFE_RELEASE(pTempSurf); SAFE_RELEASE(pStretchSurf); BS_EXCEPT(RenderingAPIException, "Can't stretch rect: TODO PORT NO ERROR"); // TODO PORT - Translate HR to error } if (FAILED(hr = mpDevice->GetRenderTargetData(pStretchSurf, pTempSurf))) { SAFE_RELEASE(pTempSurf); SAFE_RELEASE(pStretchSurf); BS_EXCEPT(RenderingAPIException, "Can't get render target data: TODO PORT NO ERROR"); // TODO PORT - Translate HR to error } SAFE_RELEASE(pStretchSurf); } if ((dst.getLeft() == 0) && (dst.getRight() == props.getWidth()) && (dst.getTop() == 0) && (dst.getBottom() == props.getHeight())) { hr = pTempSurf->LockRect(&lockedRect, 0, D3DLOCK_READONLY | D3DLOCK_NOSYSLOCK); } else { RECT rect; rect.left = static_cast<LONG>(dst.getLeft()); rect.right = static_cast<LONG>(dst.getRight()); rect.top = static_cast<LONG>(dst.getTop()); rect.bottom = static_cast<LONG>(dst.getBottom()); hr = pTempSurf->LockRect(&lockedRect, &rect, D3DLOCK_READONLY | D3DLOCK_NOSYSLOCK); } if (FAILED(hr)) { SAFE_RELEASE(pTempSurf); BS_EXCEPT(RenderingAPIException, "Can't lock rect: TODO PORT NO ERROR"); // TODO PORT - Translate HR to error } } PixelFormat format = BansheeEngine::D3D9Mappings::_getPF(desc.Format); if (format == PF_UNKNOWN) { SAFE_RELEASE(pTempSurf); BS_EXCEPT(RenderingAPIException, "Unsupported format"); } PixelData src(dst.getWidth(), dst.getHeight(), 1, format); src.setExternalBuffer((UINT8*)lockedRect.pBits); src.setRowPitch(lockedRect.Pitch / PixelUtil::getNumElemBytes(format)); src.setSlicePitch(desc.Height * src.getRowPitch()); PixelUtil::bulkPixelConversion(src, dst); SAFE_RELEASE(pTempSurf); SAFE_RELEASE(pSurf); }