Рендеринг 3D сцены на заблокированной системе - PullRequest
5 голосов
/ 16 мая 2011

Я написал движок рендеринга на основе Direct3D 9 в c #, используя SlimDX. В новом проекте мне теперь нужно распространять изображения загруженной 3d-сцены с помощью веб-сервиса. Проблема в том, что для того, чтобы что-то сделать вообще, мне нужно устройство Direct3d. Есть ли способ создать устройство direct3d без входа пользователя в систему и блокировки рабочего стола?

Если это невозможно, кто-нибудь знает об обходном пути? В конце мне нужен либо исполняемый файл, который можно запустить из планировщика задач с использованием некоторой локальной учетной записи пользователя, либо службы, которая периодически отображает изображения сцены с определенных точек зрения.

Двигатель разделен на две части: сам двигатель и средство визуализации. Поэтому, если нет другого пути, я мог бы также реализовать новый рендер, используя opengl или любую другую технологию, которая позволяет выполнять рендеринг без видимой формы.

Edit:

То, что я имею до сих пор, таково:

protected override void OnContinue() {
        base.OnContinue();

        NativeFunctions.SafeWindowStationHandle hwinsta = NativeFunctions.WindowStation.OpenWindowStation(
            "WinSta0", 
            true, 
            NativeFunctions.AccessMask.WINSTA_ALL_ACCESS);

        if(hwinsta == null || hwinsta.IsClosed || hwinsta.IsInvalid)
            Marshal.ThrowExceptionForHR(Marshal.GetLastWin32Error());

        if(NativeFunctions.WindowStation.SetProcessWindowStation(hwinsta.DangerousGetHandle())) {
            NativeFunctions.SafeDesktopHandle ptrDesktop = NativeFunctions.WindowStation.OpenInputDesktop(
                0, 
                true, 
                NativeFunctions.AccessMask.DESKTOP_CREATEWINDOW);

            if(ptrDesktop.IsClosed || ptrDesktop.IsInvalid)
                return;

            if(!NativeFunctions.WindowStation.SetThreadDesktop(ptrDesktop.DangerousGetHandle()))
                return;

            Log log = Logger.Instance.CreateLog("DXService", true, true, false);

            log.LogMessage("Desktop set, creating D3D-Object.", LOGMESSAGELEVEL.CRITICAL, true);

            Direct3D direct3D = new Direct3D();
            log.LogMessage("Direct3D object created,  creating device.", LOGMESSAGELEVEL.CRITICAL, true);

            if(direct3D.AdapterCount == 0) {
                log.LogMessage("FATAL: direct3D.AdapterCount == 0");
            }
        }
    }

Это часть минимальной службы Windows. Я поместил важный код в функцию OnContinue, потому что его легче отлаживать, чем код запуска. Я дал этим сервисам право взаимодействовать с активным рабочим столом. когда я запускаю службу как локальную системную учетную запись, получая рабочий стол и windowstation, но число GraphicsAdapters по-прежнему равно 0, когда я запускаю службу с использованием выделенной учетной записи пользователя, я даже не могу открыть WindowStation. Есть ли что-то еще, что я могу попробовать или что я делаю не так? Я тестирую это на компьютере с Windows 7, в то время как я вошел в систему, так как в противном случае отладка становится очень сложной. Может ли это быть проблемой?

Спасибо

Ответы [ 2 ]

0 голосов
/ 17 мая 2011

Еще во времена XP я работал над проектом, который успешно вызывал аппаратную визуализацию Direct3D из службы на машине, когда никто не вошел в консоль. Я полностью забыл (гениальные) подробности, но потребовалось некоторое использование API Window Station and Desktop Functions , чтобы каким-то образом получить пригодный для использования HWND. Однако все новые и серверные ОС, скорее всего, будут совершенно другими со всеми новыми средствами безопасности.

Я был бы удивлен, если бы OpenGL работал лучше, чем Direct3D в этой области, хотя, возможно, стоит попробовать. Другие вещи, которые вы могли бы рассмотреть:

  • NVidia, похоже, очень активно разрабатывает свои GPGPU / CUDA-компоненты с учетом безголовых серверов. Это просто работает. Тем не менее, это означает полное воплощение ваших вещей в неграфическом API.
  • Microsoft RemoteFX (Server2008R2 и Win7) облегчает виртуальным машинам доступ к серверным графическим процессорам. (Наоборот, самый простой вариант - запустить рендерер на виртуальной машине.)
0 голосов
/ 16 мая 2011

В случае OpenGL использование контекста PBuffer может работать для ускорения GPU даже на заблокированном рабочем столе; однако это сильно зависит от драйвера, который может установить PBuffer на постоянное повреждение при блокировке, поэтому YMMV. Я бы дал ему шанс.

...