23

Вопрос по c# – Захватывать визуальный вывод приложения DirectX - даже в фоновом режиме?

Мне нужно захватить визуальный вывод (например, скриншот) окна DirectX. В настоящее время я используюэтот подход.
Но когда окно находится в фоновом режиме, оно захватывает все, что находится перед ним.

Я вижу, что окна DirectX отображаются даже в свернутом или в фоновом режиме, поэтому это должно быть возможно.
Но как? (Он также должен быть быстрым и работать на Windows XP, к сожалению ...)

EditЯ очень занят в эти дни ... Не волнуйтесь, я верну вознаграждение, если оно истечет.

  • Error: User Rate Limit Exceeded

    от
  • Error: User Rate Limit Exceeded

    от
  • Error: User Rate Limit Exceededgithub.com/spazzarama/Direct3DHook)

    от
  • Error: User Rate Limit Exceededmsdn.microsoft.com/en-us/library/windows/desktop/…Error: User Rate Limit Exceeded

    от
  • Error: User Rate Limit Exceeded

    от Vercas
  • Error: User Rate Limit ExceededSetForegroundWindowError: User Rate Limit Exceeded

    от Vercas
  • Error: User Rate Limit Exceeded

    от
  • Error: User Rate Limit Exceeded

    от Vercas
  • Error: User Rate Limit Exceeded

    от Vercas
  • Error: User Rate Limit Exceeded

    от Vercas
  • Error: User Rate Limit Exceeded

    от Vercas
  • Нету. Мне просто нужно захватить вывод окна DirectX и обработать растровое изображение.

    от Vercas
  • Я не понимаю, что вы имеете в виду ...

    от Vercas
  • Я не знаю, применимо ли это к вашему проекту, но одно теоретическое решение, о котором я знаю, состоит в том, чтобы встроить задержку в функцию захвата визуального вывода, чтобы вы могли переключиться обратно в окно DirectX, прежде чем оно начнет запись.

    от GeorgePotter
  • Вы говорите, что хотите захватить то, что визуализируется окном DirectX, даже если это окно находится в фоновом режиме. Если причина, по которой вы хотите это сделать, заключается в том, что, например, существует задержка между запуском программы записи и переключением в окно DirectX, тогда вы можете попробовать встроить задержку в программу, чтобы позволить вам переключиться в окно DirectX. Это, вероятно, не ваша ситуация, но, если это так, этот метод может помочь.

    от GeorgePotter
  • 5

    Быстрый Google

    и я нашел этот проект кода, который относится к Windows XP. Я не знаю, можно ли применить эти знания в Windows Vista и 7 ??

    http://www.codeproject.com/Articles/5051/Various-methods-for-capturing-the-screen

    EDIT:

    Я также нашел эту статью:

    http://www.codeproject.com/Articles/20651/Capturing-Minimized-Window-A-Kid-s-Trick

    Это ссылки с поста блога Джастинса здесь из комментариев. Кажется, он работал над этим с кем-то (я вижу, вот ваша ссылка).

    http://spazzarama.com/2009/02/07/screencapture-with-direct3d/

  • 1

    Код

    с которым вы связались (из spazzarama), который, как вы сказали, использовали в своем проекте, захватывает передний буфер вашего устройства DirectX. Вы пытались захватить задний буфер вместо этого? Исходя из кода на вашем сайте, вы измените строку 90 с

    device.GetFrontBufferData(0, surface);
    

    в

    Surface backbuffer = device.GetBackBuffer(0, 0, BackBufferType.Mono);
    SurfaceLoader.Save("Screens,hot.bmp", ImageFileFormat.Bmp, backbuffer);
    

    Это также может привести к удалению строк 96-98 в вашем связанном примере. Backbuffer может быть создан без блокирующего окна.

    EDIT

    Не обращай внимания на все это. Я только что понял, что ваш связанный пример кода использует дескриптор окна для определения области экрана, и фактически ничего не делает с окном DirectX. Ваш пример кода не обойдет препятствие, потому что ваш регион уже нарисован с другим окном перед ним, когда вы к нему обращаетесь.

    Лучше всего спасти приложение, вероятно, перед тем, как запустить код для захвата изображения, чтобы окно DirectX переместилось в верхнюю часть экрана. Вы можете использоватьWind32API BringWindowToTop функция для этого (http://msdn.microsoft.com/en-us/library/ms632673%28VS.85%29.aspx).

  • 19

    Я думаю

    что для захвата окон Direct3D, которые находятся в фоновом режиме (или перемещены за пределы экрана), у вас есть следующие варианты:

    Inject and hook Direct3D within the target application via the link you have already posted or this more up-to-date example (EasyHook can be difficult to get setup but it does work really well) - you can always ask for help about getting it working. I have used that technique for capturing in a number of games without issues (most recently for an ambilight-clone project). The problem with this approach is your concern about game protection causing bans, however FRAPs also uses hooking to achieve this, so perhaps your concerns are exaggerated? I guess gamers being banned for a screen shot is an expensive way of finding out.

    For windowed applications on Vista/Win 7 - you could inject and hook the DWM and make your capture requests through its shared surface. I have had this working on Vista, but have not finished getting it working on Windows 7, here is an example of it working for Windows 7 http://www.youtube.com/watch?v=G75WKeXqXkc. The main problem with this approach is the use of undocumented API's which could mean your application breaks without any warning upon a windows patch release - also you would have to redo the technique for each new major Windows flavour. This also does not address your need to capture in Windows XP.

    Also within the DWM, there is a thumbnail API. This has limitations depending on what your trying to do. There is some information on this API along with other DWM API's here http://blogs.msdn.com/b/greg_schechter/archive/2006/09/14/753605.aspx

    There are other techniques for intercepting the Direct3D calls without using EasyHook, such as substituting the various DLL's with wrappers. You will find various other game hooking/interception techniques here: http://www.gamedeception.net/

    Simply bring the Direct3D application to the foreground (which I guess is undesirable in your situation) - this wouldn't work for off-screen windows unless you also move the window.

    Unfortunately the only solution for Windows XP that I can think of is intercepting the Direct3D API in some form.

    Просто разъяснение по рендерингу Direct3D, пока оно минимизировано. Во время моего довольно ограниченного тестирования по этому вопросу я обнаружил, что это зависит от приложения; это вообщене рекомендуется что рендеринг происходит, пока приложение свернутоссылка), он продолжает отображаться в фоновом режиме.

    UPDATED: предоставлена дополнительная ссылка на более современный пример внедрения для пункта 1.