Just want to take fullscreen capture.. somthing missing - please help

Started by
14 comments, last by Barina 13 years, 7 months ago
when should i call device.EndScene() and device.Present() ?
i tried somthing but i get invalidCall on device.EndScene()...
and when i removed it i get DeviceLostException
Advertisement
What did you try ? Your render loop should look like this:
device.BeginScene();// ... clear and draw your scene ...device.EndScene();if(takeScreenShot)    SaveScreenShot();device.Present();
Hmmm, never had a problem so far, I can even take a screenshot every frame and my debug runtimes are fine. What do the debug runtimes say exactly about that InvalidCall in your case ?

Oh, I just realized my presentation parameters use SwapEffect.Flip in fullscreen (and Discard in windowed). Can't even switch to fullscreen (dynamically) when using Discard. Maybe that's it.

Nope, it wasn't, sorry for the confusion: Just had "break on exception" enabled in the Visual Studio debugger which disturbed the switching. So the rendering and screenshooting should work either way.

[Edited by - unbird on September 8, 2010 12:59:42 PM]
exception when i tried:
device.GetFrontBufferData(0, surface);


D3DERR_DEVICELOST: Device lost (-2005530520)

at SlimDX.Result.Throw[T](Object dataKey, Object dataValue)
at SlimDX.Result.Record[T](Int32 hr, Boolean failed, Object dataKey, Object dataValue)
at SlimDX.Direct3D9.Device..ctor(Direct3D direct3D, Int32 adapter, DeviceType deviceType, IntPtr controlHandle, CreateFlags createFlags, PresentParameters[] presentParameters)
at ScreenGrabber.Program.grabDX() in D:\Documents\Visual Studio 2008\Projects\ScreenGrabber\ScreenGrabber\Program.cs:line 286

and when i tried:
surface = device.GetBackBuffer(0, 0);



D3DERR_DEVICELOST: Device lost (-2005530520)

at SlimDX.Result.Throw[T](Object dataKey, Object dataValue)
at SlimDX.Result.Record[T](Int32 hr, Boolean failed, Object dataKey, Object dataValue)
at SlimDX.Direct3D9.Device..ctor(Direct3D direct3D, Int32 adapter, DeviceType deviceType, IntPtr controlHandle, CreateFlags createFlags, PresentParameters[] presentParameters)
at ScreenGrabber.Program.grabDX() in D:\Documents\Visual Studio 2008\Projects\ScreenGrabber\ScreenGrabber\Program.cs:line 286



the code is:

                        D3D9.Direct3D direct3d = new SlimDX.Direct3D9.Direct3D();                        D3D9.AdapterInformation adapter = direct3d.Adapters.DefaultAdapter;                        D3D9.PresentParameters parameters = new SlimDX.Direct3D9.PresentParameters();                        parameters.BackBufferFormat = adapter.CurrentDisplayMode.Format;                        parameters.BackBufferHeight = adapter.CurrentDisplayMode.Height;                        parameters.BackBufferWidth = adapter.CurrentDisplayMode.Width;                        parameters.Multisample = SlimDX.Direct3D9.MultisampleType.None;                        parameters.SwapEffect = SlimDX.Direct3D9.SwapEffect.Discard;                        parameters.PresentationInterval = SlimDX.Direct3D9.PresentInterval.Default;                        parameters.FullScreenRefreshRateInHertz = 0;                        D3D9.Device device = new D3D9.Device(direct3d, adapter.Adapter, D3D9.DeviceType.Hardware,                            parameters.DeviceWindowHandle, D3D9.CreateFlags.SoftwareVertexProcessing, parameters); // this is line 286.                        D3D9.Surface surface = D3D9.Surface.CreateOffscreenPlain(device, adapter.CurrentDisplayMode.Width,                            adapter.CurrentDisplayMode.Height, D3D9.Format.A8R8G8B8, D3D9.Pool.SystemMemory);                        device.BeginScene(); // do i really need this?                        device.EndScene();                        //device.GetFrontBufferData(0, surface);                        surface = device.GetBackBuffer(0, 0);                        D3D9.Surface.ToFile(surface, Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\screenshot.bmp", D3D9.ImageFileFormat.Bmp);                                                Rectangle region = new Rectangle(0, 0, adapter.CurrentDisplayMode.Width, adapter.CurrentDisplayMode.Height);                        bmp = new Bitmap(D3D9.Surface.ToStream(surface, D3D9.ImageFileFormat.Bmp, new Rectangle(region.Left, region.Top, region.Width, region.Height)));                        surface.Dispose();                        device.Present();

line 286:
D3D9.Device device = new D3D9.Device(direct3d, adapter.Adapter, D3D9.DeviceType.Hardware, parameters.DeviceWindowHandle, D3D9.CreateFlags.SoftwareVertexProcessing, parameters);

i just want to take a screenshot from a fullscreen game
from the desktop it works great.. i can see the desktop and a windowed game running inside :)


BTW i have the source code on github at
https://Barina@github.com/Barina/ScreenGrabber.git
Sorry, I fatally misread. You want to grab from another game, not your's. Ok, not much help from me then, never tried.

Anyway: What I meant with debug runtimes is enabling the DirectX Debug runtimes, not just the call stack of the exception. This will give you more detailed information than just InvalidCall. See here.

Edit: I think you will have to resort to hooking DirectX calls. Be warned: hooking from a managed language has its quirks. Also, there have been threads about overlay rendering (like steam does) which might point you in the right direction.

[Edited by - unbird on September 9, 2010 2:52:21 PM]
Thank you both unbird and standby01!
its too complicated for my project.. ill ask my teacher to give up.. :(
i bet opengl has a single function to do this(apart from GDI+)......
so thanks again guys you helped me a lot here and i really appreciate it!
Thank you very much
Roy
maybe this would help me...?
http://spazzarama.wordpress.com/2010/03/29/screen-capture-with-direct3d-api-hooks/

This topic is closed to new replies.

Advertisement