sensics / OSVR-RenderManager

Apache License 2.0
64 stars 45 forks source link

Mirror window #170

Open rpavlik opened 8 years ago

rpavlik commented 8 years ago

I'm surprised this isn't in here - I know it's been talked about, maybe I just missed seeing it.

Feature request: a (cheaply-rendered) window on a desktop display showing (presumably, a non-distorted) view of what the user in the HMD is seeing.

russell-taylor commented 8 years ago

We've talked about it a lot, but it has not risen to the top of the list. We've not yet decided which viewpoint it should show (one of the eyes, both eyes, the head view) or what set of features it should include (distortion, time warp). For different purposes, different ones are desirable. We could make this all configurable as a second display in the config file.

We did talk about that fact that to keep this display from interfering with the rendering of the primary display (since it may have different video refresh rates and such) we'll want a separate rendering thread to show it. This makes it look a lot like the ATW thread, but rendering to a window rather than DirectMode.

For now, an app could open multiple RenderManager windows and do it themselves except that there is no way to pass a different config file than the one that comes from the server.

russell-taylor commented 7 years ago

There will need to be a separate one of these for OpenGL and for D3D11, since they receive different buffers. I'll describe the D3D11 path here because we have the ATW example to pull from, but the same approach should work for an OpenGL one.

I would probably implement this as a pass-through RenderManagerD3D11-derived object that both sends the info on to a harnessed RenderManagerD3D11 and (after doing that) makes a copy for use by its own rendering thread that would display into that window.

The RenderManagerConfig parser, which lives in Core at https://github.com/OSVR/OSVR-Core/blob/master/inc/osvr/Client/RenderManagerConfig.h will need to be augmented to add a new section describing the preview window, including: window size, window placement, any flags telling whether or not to perform distortion correction and time warp on the window, a flag if needed telling whether to show one or both eyes.

The createRenderManager function at https://github.com/sensics/OSVR-RenderManager/blob/master/osvr/RenderKit/RenderManagerBase.cpp#L1979 would be modified to respond to this new config info by generating the passthrough RenderManager in much the way it wraps a RenderManagerD1D11ATW around the existing renderer (after modifying the config file entries to configure the window size and position and fullscreenness) at https://github.com/sensics/OSVR-RenderManager/blob/master/osvr/RenderKit/RenderManagerBase.cpp#L1979. This will construct the new RenderManager, passing it arguments describing its preview window.

The new pass-through RenderManagerD3D11-derived object (not just RenderManagerD3D11Base) would be similar to the ATW one at https://github.com/sensics/OSVR-RenderManager/blob/master/osvr/RenderKit/RenderManagerD3D11ATW.h. It does not need to be header-only, but if it includes a .cpp file, it should also be linked into the library in the CMakeLists.txt file. The creation code would have adjusted its window information, distortion correction, and time warp to match that in the new section of the config file before starting it. It would use its harnessed RenderManager to do a lot of the work (as the ATW does), but it would also create separate copy buffers, one per eye, to cache the most-recent info from the client for use by its new rendering thread. The info would first be passed down to the harnessed RenderManager and then copied into the eye buffers. It would construct a new rendering thread, which would run at some rate, to read from the copied buffers and render into its window. That rendering thread would re-use much of the code from the existing RenderManagerD3D11 it is derived from, just reading from the copy buffers rather than from the presented buffers.