Creating DirectX device fails in remote desktop - c++

I have an application that uses DirectX to capture the screen. The application works fine locally, however when I run it through a remote desktop session the IDirect3D9::CreateDevice function fails:
d3dpp.Windowed=WINDOW_MODE;
d3dpp.Flags=D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
d3dpp.BackBufferFormat=ddm.Format;
d3dpp.BackBufferHeight=nDisplayHeight=gScreenRect.bottom =ddm.Height;
d3dpp.BackBufferWidth=nDisplayWidth=gScreenRect.right =ddm.Width;
d3dpp.MultiSampleType=D3DMULTISAMPLE_NONE;
d3dpp.SwapEffect=D3DSWAPEFFECT_DISCARD;
d3dpp.hDeviceWindow=hWnd;
d3dpp.PresentationInterval=D3DPRESENT_INTERVAL_DEFAULT;
d3dpp.FullScreen_RefreshRateInHz=D3DPRESENT_RATE_DEFAULT;
if(FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_REF,hWnd,D3DCREATE_SOFTWARE_VERTEXPROCESSING ,&d3dpp,&g_pd3dDevice)))
{
ErrorMessage("Unable to Create Device");
return E_FAIL;
}
I am using Windows 7 to access Windows Server 2008 R2 with RDP.
What exactly is wrong here? I read that its possible to do use Direct3D through RDP.

I don't know the exact reason for failure, but I can give you a direction.
When you connect through the RDP the Windows doesn't load your native video driver at all, and nothing is actually displayed on the monitor. Instead the system loads the RDPDD virtual video driver, which draws everything in the system memory, and sends it to RDP client over the network. This is how remote desktop works.
So that your native video card/driver is not involved at all. RDPDD is a very minimalistic "frame buffer" driver, it does not support Direct3D/DirectDraw at all.
OTOH you call CreateDevice with D3DDEVTYPE_REF parameter, which should work even if you don't have D3D-compatible video card, the D3D should be emulated in software. Hence - I don't know why this happens. I can guess that the problem may be within the D3DPRESENT_PARAMETERS parameters. Perhaps some of them may not be emulated.
Try to check the error code, play with D3DPRESENT_PARAMETERS .

Haha, the problem was I had not the DirectX drivers installed. After it works!

Related

Current state and solutions for OpenGL over Windows Remote [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 2 years ago.
The community reviewed whether to reopen this question 5 months ago and left it closed:
Original close reason(s) were not resolved
Improve this question
OpenGL and Windows Remote don't play along nicely.
Solutions for this are dependent on the use case and answers are fragmented across the vast depths of the net.
This is a write-up I wish existed when I started researching this, both for coders and non-coders.
Problem:
A RDP session of Windows does not expose the graphics card, at least not directly. For instance you cannot change the desktop resolution and GraphicsCard drivers usually just disable their setting menus. Starting a OpenGL context higher than v1.1 fails because of this. The, especially in support IRCs, often suggested "Don't use WindowsRemote" is unfortunately not an option for many. In many corporate environments Windows Remote is a constantly used tool and an app has to work there as well.
Non-Coder workarounds
You can start the OpenGL program, allowing it to see the graphics card, create an opengl context and then connect via WindowsRemote. This always works, as Windows remote just transfers the window content. This can be accomplished by:
A batch script, that closes the session and starts the program, allowing you to connect to the program already running. (Source)
Using VNC or other to remote into the machine, start the program and then switch to Windows Remote. (Simple VNC programm, also with a portable client)
Coder workarounds
(Only for OpenGL ES)Translate OpenGL to DirectX. DirectX works under Windows Remote flawselly and even has a Software rendering fallback built into DX11 if something fails.
Use the ANGLE Project to do this at run-time. This is what QT officially suggests you do and how Chrome and Firefox implement WebGL. (Source)
Switch to software rendering as a fall back. Some CAD software like 3dsMax does this for instance:
Under SDL2 you can use SDL_CreateSoftwareRenderer (Source)
Under GLFW version 3.3 will release OSMesa (Mesa's off screen rendering), in the mean time you can build the Github version with -DGLFW_USE_OSMESA=TRUE, but I personally still struggle to get that running (Source)
Directly use Mesa's LLVM pipe for a fast OpenGL implementation. (Source)
Misc:
Use OpenGL 1.1: Windows has a built in implementation of OpenGL 1.1 and
earlier. Some game engines have a built in fall back to this and thus
work under Windows Remote.
Apparently there is a middle-ware, that allows for even OpenGL 4 over Windows Remote, but it's part of a bigger package and is a commercial solution. (Source)
Any other solutions or corrections are greatly appreciated.
[10] Nvidia -> https://www.khronos.org/news/permalink/nvidia-provides-opengl-accelerated-remote-desktop-for-geforce-5e88fc2035e342.98417181
According to this article it seems that now RDP handles newer versions of Direct3D and OpenGL on Windows 10 and Windows Server 2016, but by default it is disabled by Group Policy.
I suppose that for performance reasons, using a hardware graphics card is disabled, and RDP uses a software-emulated graphics card driver that provides only some baseline features.
I stumbled upon this problem when trying to run Ultimaker CURA over standard Remote Desktop from a Windows 10 client to a Windows 10 host. Cura shouted "cannot initialize OpenGL 2.0 context". I also noticed that Repetier Host's "preview" window runs terribly slow, and Repetier detects only an OpenGL 1.1 card. Pretty much fits the "only baseline features" description.
By running gpedit.msc then navigating to
Local Computer Policy\Computer Configuration\Administrative Templates\Windows Components\Remote Desktop Services\Remote Desktop Session Host\Remote Session Environment
and changing the value of
Use hardware graphics adapters for all Remote Desktop Services sessions
I was able to successfully run Ultimaker CURA via with no issues, and Repetier-Host now displays OpenGL 4.6, and everything finally runs fast as it should.
Note from genpfault:
As usual, this Policy is kept in the HKLM registry group in
HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services
Set REG_DWORD:bEnumerateHWBeforeSW to 1 to turn ON using GPUs in RDP.
OpenGL works great by RDP with professional Nvidia cards without anything like virtual machines and RemoteFX. For Quadro (Quadro 4000 tested) you need driver 377.xx. For M60 you can use the same driver. If you want to use last driver with M60, you have to change the driver mode to WDDM mode (see c:\Program Files\NVIDIA Corporation\NVSMI\nvidia-smi.1.pdf). It is possible that there are some problems with licensing in this last case.
Some people recommend using "tscon.exe" if you can: https://stackoverflow.com/a/45723167/32453 or using a scheduler to do it on native hardware: https://stackoverflow.com/a/41839102/32453 or creating a group policy:
https://community.esri.com/thread/225251-enabling-gpu-rendering-on-windows-server-2016-windows-10-rdp
maybe copy opengl32.dll (or opengl64.dll) to your executable's dir: https://blender.stackexchange.com/a/73014 and newer version of the dll: https://fdossena.com/?p=mesa/index.frag
Remote Desktop and OpenGL does not play very well. When you connect to a Windows box the OpenGL Driver is unloaded and you end up with software emulation of OpenGL.
When you disconnect from the Windows box the OpenGL driver is not reloaded. This causes issues when you are running tests on the machine as you have to physically login to the machine to reset the drivers.
The solution I ended up using was to:
Disable Remote Desktop.
Delete all other software for remote desktop access. Because if it's used for logging in remotely the current set of drivers loaded may be messed up.
Install NoMachine
NoMachine is my personal favourite (when it does not play up) for a number of reasons:
Hardware acceleration of compression (video of desktop).
Works on Windows and Linux.
Works well on low-bandwidth connections especially if the client and server have the necessary hardware for compression of the data stream.
On Linux you get your desktop as you last left it when you were sitting in front of the machine.
On Windows it does not affect OpenGL.
currently free for personal and commercial use. Do check the licence in case it's changed.
When NoMachine plays up it hogs the CPU but this happens rarely. It is however in active development
Others to consider:
TurboVNC
TightVNC
TeamViewer - only free for personal use.

How to program a virtual sound output device on windows 7+?

I want to add a new sound device on windows 7+ so that I can redirect the computer sound on the network (using a protocol of my own or PulseAudio for example).
Basically, I think I want to write a kernel driver that expose a new sound output device to the OS. If there's a way to write the driver so that I only have to deal with a simple sample buffer input to process it would be great (the simpler the better). I don't care too much about latency, I just want it to be as transparent as possible for the system and the applications running so that everything goes through this virtual device out of the box.
I have some experience in Linux kernel development but I know next to nothing about Windows driver development. I have a genuine Visual Studio 2013 ultimate and I want to target Windows 7 (above would be nice but it has to work on W7).
I would like to know which API/framework/system should I use to achieve my goal and possibly link to dev ressources to get me started.

Can't access USB device inside Windows Store App

OK, first I shall point that I am completely new to Windows Apps Development, which is good, since I am trying to develop a Windows Store App for PC to use a PrimeSense Scanner connected via USB. I have asked a more specific question about this here.
This time I have a more generic question, which is more related to Windows Store app development. I am using VS2013 Express and compiling for Win32.
When I compile my application for VS2012 and run it as an execcutable file, I can connect to the scanner perfectly. But I can't do the same with VS2013 and running it as a Store app.
I know the device is connected and the drivers are updated and all dlls file placed in the Widnows System 32 directory.
I have also added all Capabilities to the App Manifest and also added the following Device Capability
<m2:DeviceCapability Name="usb">
<!--OSRFX2 Device-->
<m2:Device Id="vidpid:1d27 0609">
<m2:Function Type="classId:ff * *" />
<m2:Function Type="name:vendorSpecific" />
</m2:Device>
</m2:DeviceCapability>
The vid and pid, obviously match the corresponding codes of the device.
One of the errors I recieve when trying to conenct to the scanner using OpenNI is:
Could not open to "\\?\usb#vid_1d27&pid_0609&mi_00#7&1601586a&0&0000#{c3b5f022-5a42-1980-1909-ea72095601b1}" USB Device not found
This error is quite frustrating since I know the device is connected. So I tend to think that there is some level os specificity on the Windows Store App side of the game that is not enabling my to connect to the device. As I said, I am compiling for Win32.
Is there a chance that the drivers will not work for a Windows Store App. Is there some extra stuff I should do inside the Windows Store App logic that I am not doing and that is necessary to connect the USB device? I am sorry, but I am completely new to Windows Store App development.
Thank you.
You can't do that from metro apps.
You typically create a handle to that usb device by calling CreateFile with that object mananger path as the file to 'create'. CreateFile is not allowed in metro apps - "desktop apps only" - and its 'replacement', CreateFile2, specifically doesn't allow opening object manager objects.
Furthermore, the documentation for CreateFile2 states that in metro apps this function can only open files and directories (and not things like pipes, mailslots, consoles, etc.).
See also this post on social.msdn
Unless I missed something, I don't think this is possible.

Accessing device via existing device driver

I'm looking to write an application that will allow me to control music, etc with a remote control. The infrared receiver I have is built into my MacBook Pro which is running Windows.
What I want to know is how can I go about this? Most of the information I can find online is specific to writing Windows device drivers and I'm having trouble finding out how to use drivers that already exist for a device.
Is it absolutely necessary for me to write my own drivers or is there a way to use the drivers provided by Apple?
On Windows you communicate with a driver by first opening it using CreateFile and subsequently sending commands to it using DeviceIoControl. You need documentation for the driver's API though to understand what functionality is available through which control codes and what parameters they expect. Digging up that information is probably the hard part.

How to fallback to software rendering in Java3D?

We are having some weird problems using Java3D over a Windows' remote desktop. The remote machine is a virtualized server, which can't use the (physical) server's graphic card. When I run the app, the following error pops:
Unable to create DirectX D3D context.
Neither Hardware and Software Renderer are available.
Please update your video card drivers
and get the latest DirectX available at http://microsoft.com/directx
After switching to OpenGL (starting the JVM with -Dj3d.rend=ogl) the same error appears! What is possibly happening? How can I fallback to software rendering, either with OpenGL or DirectX, when the error appears?
EDIT: I've already tried using another OpenGL vendor, using Mesa3D's DLLs instead of the native ones, but it did nothing different. I also installed DirectX SDK and tried to start Java3D with the reference driver (-Dj3d.d3ddevice=reference), but it didn't work either.
The same error appears because if OpenGL fails, Java3D tries to use DirectX. If that fails, too, then the pop is shown.
I didn't manage to solve it because, instead of trying to change things at the remote server, I tried to emulate the problem at my own machine by disabling the video driver. I still don't know why both problems aren't equivalent, but after I returned to work on the server and put DirectX's d3dref9.dll at Java's \bin, it worked.
Now I have an entire new problem, as the JVM can't find the DLL if I place it at java.library.path or Tomcat's \bin :) Problems just can't not exist.
Try the following:
Under Windows:
First, open the Display Properties pane by right clicking on desktop screen and choosing Properties item in menu. In that pane, display the Settings tab, and click on the Advanced button. Then in the Troubleshoot tab of the pane that opened, check the Hardware acceleration cursor is at its maximum on Full, confirm your choice and try to run your program again.
If the previous operation didn't resolve your problem, update the OpenGL and DirectX drivers of your graphic card with the latest available ones, and try to run Sweet Home 3D again.