• Advertisement
Sign in to follow this  

Fullscreen capture to surface

This topic is 2137 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

[font=arial,helvetica,sans-serif]Greetings,[/font]

[font=arial,helvetica,sans-serif]I'm new to DirectX and l am trying to modify an existing project ([url="http://spazzarama.com/2011/03/14/c-screen-capture-and-overlays-for-direct3d-9-10-and-11-using-api-hooks/"]http://spazzarama.co...sing-api-hooks/[/url]) so that it will properly take screenshots from fullscreen directx9 applications from a third party application written in c#, hence the SlimDX. This app also hooks with easy hook.[/font]

[font=arial,helvetica,sans-serif]The comments on the author's post above indicate that to get fullscreen working for dx9, one must set [color=#111111] DeviceType.NullReference when initializing the device:[/color][/font]

[font=arial,helvetica,sans-serif][color=#111111][code] using (device = new Device(d3d, 0, DeviceType.NullReference, IntPtr.Zero, CreateFlags.HardwareVertexProcessing, new PresentParameters() { BackBufferWidth = 1, BackBufferHeight = 1 }))
{
id3dDeviceFunctionAddresses.AddRange(GetVTblAddresses(device.ComPointer, D3D9_DEVICE_METHOD_COUNT));
}[/code][/color][/font]

[font=arial,helvetica,sans-serif]This, however, is not working for me in various DX9 games running fullscreen. It does seem to work fine for games running Windowed mode.[/font]

[font=arial, helvetica, sans-serif]Here is the exception:[/font]
[b]SlimDX.Direct3D9.Direct3D9Exception: D3DERR_INVALIDCALL: Invalid call (-2005530516)[/b]

Similar to this thread:
[url="http://www.gamedev.net/topic/543847-slimdx-handling-lost-devices-solved/"]http://www.gamedev.n...devices-solved/[/url]

I've tried the solution offered in that thread, but I am having the same result. Here is the screenshot producing function, can anybody point me in the right direction to overcome this exception?

Thank you,
Dan

[code] int EndSceneHook(IntPtr devicePtr)
{
Configuration.AddResultWatch(ResultCode.DeviceLost, ResultWatchFlags.AlwaysIgnore);
using (Device device = Device.FromPointer(devicePtr))
{
// If you need to capture at a particular frame rate, add logic here decide whether or not to skip the frame
try
{
#region Screenshot Request
// Is there a screenshot request? If so lets grab the backbuffer
//this.DebugMessage("Locking");
lock (_lockRenderTarget)
{

if (Request != null)
{
this.DebugMessage("Locked");
_lastRequestTime = DateTime.Now;
DateTime start = DateTime.Now;
try
{
// First ensure we have a Surface to the render target data into
if (_renderTarget == null)
{
this.DebugMessage("Render Target is Null");
// Create offscreen surface to use as copy of render target data
using (SwapChain sc = device.GetSwapChain(0))
{
this.DebugMessage("Create a New Target to Render on");
_renderTarget = Surface.CreateOffscreenPlain(device, sc.PresentParameters.BackBufferWidth, sc.PresentParameters.BackBufferHeight, sc.PresentParameters.BackBufferFormat, Pool.SystemMemory);
}
}
#region Prepare lines for overlay
if (this.Request.RegionToCapture.Width == 0)
{
_lineVectors = new SlimDX.Vector2[] {
new SlimDX.Vector2(0, 0),
new SlimDX.Vector2(_renderTarget.Description.Width - 1, _renderTarget.Description.Height - 1),
new SlimDX.Vector2(0, _renderTarget.Description.Height - 1),
new SlimDX.Vector2(_renderTarget.Description.Width - 1, 0),
new SlimDX.Vector2(0, 0),
new SlimDX.Vector2(0, _renderTarget.Description.Height - 1),
new SlimDX.Vector2(_renderTarget.Description.Width - 1, _renderTarget.Description.Height - 1),
new SlimDX.Vector2(_renderTarget.Description.Width - 1, 0),
};
}
else
{
_lineVectors = new SlimDX.Vector2[] {
new SlimDX.Vector2(this.Request.RegionToCapture.X, this.Request.RegionToCapture.Y),
new SlimDX.Vector2(this.Request.RegionToCapture.Right, this.Request.RegionToCapture.Bottom),
new SlimDX.Vector2(this.Request.RegionToCapture.X, this.Request.RegionToCapture.Bottom),
new SlimDX.Vector2(this.Request.RegionToCapture.Right, this.Request.RegionToCapture.Y),
new SlimDX.Vector2(this.Request.RegionToCapture.X, this.Request.RegionToCapture.Y),
new SlimDX.Vector2(this.Request.RegionToCapture.X, this.Request.RegionToCapture.Bottom),
new SlimDX.Vector2(this.Request.RegionToCapture.Right, this.Request.RegionToCapture.Bottom),
new SlimDX.Vector2(this.Request.RegionToCapture.Right, this.Request.RegionToCapture.Y),
};
}
#endregion
using (Surface backBuffer = device.GetBackBuffer(0, 0))
{
// Create a super fast copy of the back buffer on our Surface
device.GetRenderTargetData(backBuffer, _renderTarget);

this.DebugMessage("We have the frame in memory");
// We have the back buffer data and can now work on copying it to a bitmap
ProcessRequest();
}
}
finally
{
// We have completed the request - mark it as null so we do not continue to try to capture the same request
// Note: If you are after high frame rates, consider implementing buffers here to capture more frequently
// and send back to the host application as needed. The IPC overhead significantly slows down
// the whole process if sending frame by frame.
Request = null;
}
DateTime end = DateTime.Now;
this.DebugMessage("EndSceneHook: Capture time: " + (end - start).ToString());
_lastScreenshotTime = (end - start);
}
}
#endregion
#region Example: Draw Overlay (after screenshot so we don't capture overlay as well)
#region Draw fading lines based on last screencapture request
if (_lastRequestTime != null && _lineVectors != null)
{
TimeSpan timeSinceRequest = DateTime.Now - _lastRequestTime.Value;
if (timeSinceRequest.TotalMilliseconds < 1000.0)
{
using (Line line = new Line(device))
{
_lineAlpha = (float)((1000.0 - timeSinceRequest.TotalMilliseconds) / 1000.0); // This is our fade out
line.Antialias = true;
line.Width = 1.0f;
line.Begin();
line.Draw(_lineVectors, new SlimDX.Color4(_lineAlpha, 0.5f, 0.5f, 1.0f));
line.End();
}
}
else
{
_lineVectors = null;
}
}
#endregion
#region Draw frame rate
using (SlimDX.Direct3D9.Font font = new SlimDX.Direct3D9.Font(device, new System.Drawing.Font("Times New Roman", 16.0f)))
{
if (_lastFrame != null)
{
font.DrawString(null, String.Format("{0:N1} fps", (1000.0 / (DateTime.Now - _lastFrame.Value).TotalMilliseconds)), 100, 100, System.Drawing.Color.Red);
}
_lastFrame = DateTime.Now;
}
#endregion
#endregion
}
catch(Exception e)
{
// If there is an error we do not want to crash the hooked application, so swallow the exception
this.DebugMessage("EndSceneHook: Exeception: " + e.GetType().FullName + ": " + e.Message);
}
// EasyHook has already repatched the original EndScene - so calling EndScene against the SlimDX device will call the original
// EndScene and bypass this hook. EasyHook will automatically reinstall the hook after this hook function exits.
return device.EndScene().Code;
}
}[/code]

Share this post


Link to post
Share on other sites
Advertisement
Sign in to follow this  

  • Advertisement