In window mode.
I have my computer set on 1024/768 and i create a irrlicht window size 1024/768.
(window size >= screen resolution )
When i use createScreenShot() an illegal memory ... is thrown.
The problem is in:
// d3d pads the image, so we need to copy the correct number of bytes
u32* pPixels = (u32*)newImage->lock();
if (pPixels)
{
u8 * sP = (u8 *)lockedRect.pBits;
u32* dP = (u32*)pPixels;
s32 y;
for (y = 0; y < ScreenSize.Height; ++y)
{
memcpy(dP, sP, ScreenSize.Width * 4);
sP += lockedRect.Pitch;
dP += ScreenSize.Width;
}
newImage->unlock();
}
When y = screen resolution - clientPoint.x the error is generated.
I think the problem is that somehow the screen surface is createad at a size of screen resolution.height - bar height - ? (window size >= screen resolution )
Screen shoot crush
Screen shoot crush
Last edited by Pr3t3nd3r on Sat Sep 23, 2006 11:55 pm, edited 2 times in total.
Galactic Dream Best RTS game
http://www.rageofwar.net
Engage in epic galactic warfare, guide your people through the galaxy! in the real time strategy game made with Irrlicht
http://www.evolutionvault.com
http://www.rageofwar.net
Engage in epic galactic warfare, guide your people through the galaxy! in the real time strategy game made with Irrlicht
http://www.evolutionvault.com
it seems that even with window smaller than the screen resolution is happening if clientRect.bottom > ScreenSize.Height
... the solution is somethink like:
//for (y = 0; y < ScreenSize.Height - clientRect.top ; ++y)
//bad
Edit:
That code is not working well (bad screenshot no more crush) with smaller windows than the resolution...
The correct code should be something like this:
s32 maxHeight = ScreenSize.Height;
if (clientRect.bottom > desktopHeight)
maxHeight -= clientRect.bottom - desktopHeight;
But i don't know how to find out the desktopHeight.
... the solution is somethink like:
//for (y = 0; y < ScreenSize.Height - clientRect.top ; ++y)
//bad
Edit:
That code is not working well (bad screenshot no more crush) with smaller windows than the resolution...
The correct code should be something like this:
s32 maxHeight = ScreenSize.Height;
if (clientRect.bottom > desktopHeight)
maxHeight -= clientRect.bottom - desktopHeight;
But i don't know how to find out the desktopHeight.
Galactic Dream Best RTS game
http://www.rageofwar.net
Engage in epic galactic warfare, guide your people through the galaxy! in the real time strategy game made with Irrlicht
http://www.evolutionvault.com
http://www.rageofwar.net
Engage in epic galactic warfare, guide your people through the galaxy! in the real time strategy game made with Irrlicht
http://www.evolutionvault.com
Two things.
- It is called a crash not a crush.
- There will be an incompatibility between all of the other drivers and the D3D drivers. The D3D drivers can only capture the part of the image that is on screen. The other drivers capture the whole image.
This code works for the D3D9 driver. The D3D8 driver is similar, just replace all occurances of 9 with 8 and change the GetFrontBufferData call to GetFrontBuffer and lose the first parameter.
As mentioned above the D3D drivers will give different results if the window is partially off screen. The screenshot that is captured is exactly what you see on the screen in the area occupied by the application window. If the task manager is sitting on top then you will see the task manager in the screenshot. This is not true for the OGL and software drivers.
As mentioned above the D3D drivers will give different results if the window is partially off screen. The screenshot that is captured is exactly what you see on the screen in the area occupied by the application window. If the task manager is sitting on top then you will see the task manager in the screenshot. This is not true for the OGL and software drivers.
Code: Select all
//! Returns an image created from the last rendered frame.
IImage* CD3D9Driver::createScreenShot()
{
HRESULT hr;
// query the screen dimensions of the current adapter
D3DDISPLAYMODE displayMode;
pID3DDevice->GetDisplayMode(0, &displayMode);
// create the image surface to store the front buffer image [always A8R8G8B8]
LPDIRECT3DSURFACE9 lpSurface;
if (FAILED(hr = pID3DDevice->CreateOffscreenPlainSurface(displayMode.Width, displayMode.Height, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &lpSurface, 0)))
return 0;
// read the front buffer into the image surface
if (FAILED(hr = pID3DDevice->GetFrontBufferData(0, lpSurface)))
{
lpSurface->Release();
return 0;
}
// find the size of the surface
D3DSURFACE_DESC surfaceDesc;
if (FAILED(lpSurface->GetDesc(&surfaceDesc)))
{
lpSurface->Release();
return 0;
}
RECT clientRect;
clientRect.top = 0;
clientRect.left = 0;
clientRect.bottom = clientRect.top + surfaceDesc.Height;
clientRect.right = clientRect.left + surfaceDesc.Width;
//if (!Fullscreen)
{
HWND hDriverWnd = (HWND)getExposedVideoData().D3D9.HWnd;
RECT frameRect;
GetClientRect(hDriverWnd, &frameRect);
POINT topLeftCorner;
topLeftCorner.x = 0;
topLeftCorner.y = 0;
ClientToScreen(hDriverWnd, &topLeftCorner);
// move the frame rect into screen coordinates
OffsetRect(&frameRect, topLeftCorner.x, topLeftCorner.y);
// clip the client rect to the window size
IntersectRect(&clientRect, &clientRect, &frameRect);
}
// lock the entire surface
D3DLOCKED_RECT lockedRect;
if (FAILED(lpSurface->LockRect(&lockedRect, &clientRect, D3DLOCK_READONLY)))
{
lpSurface->Release();
return 0;
}
// this is the size of the image that we will generate
core::dimension2d<s32> newImageSize(clientRect.right - clientRect.left,
clientRect.bottom - clientRect.top);
// this could throw, but we aren't going to worry about that case very much
IImage* newImage = new CImage(ECF_A8R8G8B8, newImageSize);
// d3d pads the image, so we need to copy the correct number of bytes
u32* pPixels = (u32*)newImage->lock();
if (pPixels)
{
u8 * sP = (u8 *)lockedRect.pBits;
u32* dP = (u32*)pPixels;
s32 y;
for (y = 0; y < newImageSize.Height; ++y)
{
memcpy(dP, sP, newImageSize.Width * 4);
sP += lockedRect.Pitch;
dP += newImageSize.Width;
}
newImage->unlock();
}
// we can unlock and release the surface
lpSurface->UnlockRect();
// release the image surface
lpSurface->Release();
// return status of save operation to caller
return newImage;
}