void
D3D9RenderWindow::copyContentsToMemory(
const
PixelBox
&
dst, FrameBuffer buffer)
{
if
((dst.left
<
0
)
||
(dst.right
>
mWidth)
||
(dst.top
<
0
)
||
(dst.bottom
>
mHeight)
||
(dst.front
!=
0
)
||
(dst.back
!=
1
))
{
OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
"
Invalid box.
"
,
"
D3D9RenderWindow::copyContentsToMemory
"
);
}
HRESULT hr;
LPDIRECT3DSURFACE9 pSurf
=
0
, pTempSurf
=
0
;
D3DSURFACE_DESC desc;
D3DLOCKED_RECT lockedRect;
LPDIRECT3DDEVICE9 mpD3DDevice
=
mDriver
->
getD3DDevice();
if
(buffer
==
FB_AUTO)
{
//
buffer = mIsFullScreen? FB_FRONT : FB_BACK;
buffer
=
FB_FRONT;
}
if
(buffer
==
FB_FRONT)
{
D3DDISPLAYMODE dm;
LPDIRECT3DDEVICE9 mpD3DDevice
=
mDriver
->
getD3DDevice();
if
(FAILED(hr
=
mpD3DDevice
->
GetDisplayMode(
0
,
&
dm)))
{
OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
"
Can't get display mode:
"
+
Root::getSingleton().getErrorDescription(hr),
"
D3D9RenderWindow::copyContentsToMemory
"
);
}
desc.Width
=
dm.Width;
desc.Height
=
dm.Height;
desc.Format
=
D3DFMT_A8R8G8B8;
if
(FAILED(hr
=
mpD3DDevice
->
CreateOffscreenPlainSurface(desc.Width, desc.Height,
desc.Format,
D3DPOOL_SYSTEMMEM,
&
pTempSurf,
0
)))
{
OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
"
Can't create offscreen buffer:
"
+
Root::getSingleton().getErrorDescription(hr),
"
D3D9RenderWindow::copyContentsToMemory
"
);
}
if
(FAILED(hr
=
mIsSwapChain
?
mpSwapChain
->
GetFrontBufferData(pTempSurf) :
mpD3DDevice
->
GetFrontBufferData(
0
, pTempSurf)))
{
SAFE_RELEASE(pTempSurf);
OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
"
Can't get front buffer:
"
+
Root::getSingleton().getErrorDescription(hr),
"
D3D9RenderWindow::copyContentsToMemory
"
);
}
if
(mIsFullScreen)
{
if
((dst.left
==
0
)
&&
(dst.right
==
mWidth)
&&
(dst.top
==
0
)
&&
(dst.bottom
==
mHeight))
{
hr
=
pTempSurf
->
LockRect(
&
lockedRect,
0
, D3DLOCK_READONLY
|
D3DLOCK_NOSYSLOCK);
}
else
{
RECT rect;
rect.left
=
(LONG)dst.left;
rect.right
=
(LONG)dst.right;
rect.top
=
(LONG)dst.top;
rect.bottom
=
(LONG)dst.bottom;
hr
=
pTempSurf
->
LockRect(
&
lockedRect,
&
rect, D3DLOCK_READONLY
|
D3DLOCK_NOSYSLOCK);
}
if
(FAILED(hr))
{
SAFE_RELEASE(pTempSurf);
OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
"
Can't lock rect:
"
+
Root::getSingleton().getErrorDescription(hr),
"
D3D9RenderWindow::copyContentsToMemory
"
);
}
}
else
{
RECT srcRect;
//
GetClientRect(mHWnd, &srcRect);
srcRect.left
=
(LONG)dst.left;
srcRect.top
=
(LONG)dst.top;
srcRect.right
=
(LONG)dst.right;
srcRect.bottom
=
(LONG)dst.bottom;
POINT point;
point.x
=
srcRect.left;
point.y
=
srcRect.top;
ClientToScreen(mHWnd,
&
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);
OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
"
Can't lock rect:
"
+
Root::getSingleton().getErrorDescription(hr),
"
D3D9RenderWindow::copyContentsToMemory
"
);
}
}
}
else
{
SAFE_RELEASE(pSurf);
if
(FAILED(hr
=
mIsSwapChain
?
mpSwapChain
->
GetBackBuffer(
0
, D3DBACKBUFFER_TYPE_MONO,
&
pSurf) :
mpD3DDevice
->
GetBackBuffer(
0
,
0
, D3DBACKBUFFER_TYPE_MONO,
&
pSurf)))
{
OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
"
Can't get back buffer:
"
+
Root::getSingleton().getErrorDescription(hr),
"
D3D9RenderWindow::copyContentsToMemory
"
);
}
if
(FAILED(hr
=
pSurf
->
GetDesc(
&
desc)))
{
OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
"
Can't get description:
"
+
Root::getSingleton().getErrorDescription(hr),
"
D3D9RenderWindow::copyContentsToMemory
"
);
}
if
(FAILED(hr
=
mpD3DDevice
->
CreateOffscreenPlainSurface(desc.Width, desc.Height,
desc.Format,
D3DPOOL_SYSTEMMEM,
&
pTempSurf,
0
)))
{
OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
"
Can't create offscreen surface:
"
+
Root::getSingleton().getErrorDescription(hr),
"
D3D9RenderWindow::copyContentsToMemory
"
);
}
if
(desc.MultiSampleType
==
D3DMULTISAMPLE_NONE)
{
if
(FAILED(hr
=
mpD3DDevice
->
GetRenderTargetData(pSurf, pTempSurf)))
{
SAFE_RELEASE(pTempSurf);
OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
"
Can't get render target data:
"
+
Root::getSingleton().getErrorDescription(hr),
"
D3D9RenderWindow::copyContentsToMemory
"
);
}
}
else
{
LPDIRECT3DSURFACE9 pStretchSurf
=
0
;
if
(FAILED(hr
=
mpD3DDevice
->
CreateRenderTarget(desc.Width, desc.Height,
desc.Format,
D3DMULTISAMPLE_NONE,
0
,
false
,
&
pStretchSurf,
0
)))
{
SAFE_RELEASE(pTempSurf);
OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
"
Can't create render target:
"
+
Root::getSingleton().getErrorDescription(hr),
"
D3D9RenderWindow::copyContentsToMemory
"
);
}
if
(FAILED(hr
=
mpD3DDevice
->
StretchRect(pSurf,
0
, pStretchSurf,
0
, D3DTEXF_NONE)))
{
SAFE_RELEASE(pTempSurf);
SAFE_RELEASE(pStretchSurf);
OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
"
Can't stretch rect:
"
+
Root::getSingleton().getErrorDescription(hr),
"
D3D9RenderWindow::copyContentsToMemory
"
);
}
if
(FAILED(hr
=
mpD3DDevice
->
GetRenderTargetData(pStretchSurf, pTempSurf)))
{
SAFE_RELEASE(pTempSurf);
SAFE_RELEASE(pStretchSurf);
OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
"
Can't get render target data:
"
+
Root::getSingleton().getErrorDescription(hr),
"
D3D9RenderWindow::copyContentsToMemory
"
);
}
SAFE_RELEASE(pStretchSurf);
}
if
((dst.left
==
0
)
&&
(dst.right
==
mWidth)
&&
(dst.top
==
0
)
&&
(dst.bottom
==
mHeight))
{
hr
=
pTempSurf
->
LockRect(
&
lockedRect,
0
, D3DLOCK_READONLY
|
D3DLOCK_NOSYSLOCK);
}
else
{
RECT rect;
rect.left
=
(LONG)dst.left;
rect.right
=
(LONG)dst.right;
rect.top
=
(LONG)dst.top;
rect.bottom
=
(LONG)dst.bottom;
hr
=
pTempSurf
->
LockRect(
&
lockedRect,
&
rect, D3DLOCK_READONLY
|
D3DLOCK_NOSYSLOCK);
}
if
(FAILED(hr))
{
SAFE_RELEASE(pTempSurf);
OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
"
Can't lock rect:
"
+
Root::getSingleton().getErrorDescription(hr),
"
D3D9RenderWindow::copyContentsToMemory
"
);
}
}
PixelFormat format
=
Ogre::D3D9Mappings::_getPF(desc.Format);
if
(format
==
PF_UNKNOWN)
{
SAFE_RELEASE(pTempSurf);
OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
"
Unsupported format
"
,
"
D3D9RenderWindow::copyContentsToMemory
"
);
}
PixelBox src(dst.getWidth(), dst.getHeight(),
1
, format, lockedRect.pBits);
src.rowPitch
=
lockedRect.Pitch
/
PixelUtil::getNumElemBytes(format);
src.slicePitch
=
desc.Height
*
src.rowPitch;
PixelUtil::bulkPixelConversion(src, dst);
SAFE_RELEASE(pTempSurf);
SAFE_RELEASE(pSurf);
}