steamworks-vr-api
steamworks-vr-api copied to clipboard
IHmd objects representing Oculus devices do not react to display mode changes under Win32
Under Win32, IHmd
objects that represent Oculus devices initialize the display geometry at initialization time only, causing the information to be stale if you change the display mode unless you do a full VR_Shutdown()
/ VR_Init()
cycle.
As it stands, this actually means the workflow has to be something like:
- Call
VR_Init()
to getIHmd
object - Identify target display and change video mode
- Call
VR_Shutdown()
to destroyIHmd
Object - Call
VR_Init()
again to get anIHmd
object that (hopefully) represents the same HMD and is valid for the current display settings - Query render target size / view bounds
- Do stuff.
Looking at oculushmdlatest.cpp it looks like it should be possible to correct this behavior without any API changes by inserting a call to DetermineActualDisplaySize()
inside GetWindowBounds()
, GetRecommendedRenderTargetSize()
, and GetEyeOutputViewport()
- although that would cause it to re-enumerate all displays every time one of those functions is called.
In my opinion, though, it would probably be better if the IHmd
API could be extended so that you tell it your target resolution instead of it attempting to infer this information on it's own. This might actually be better in the long run as it would make the behavior more consistent across a wider variety of situations (off screen render targets, different OS's, etc.). It would simplify the API interaction to something like this:
- Call
VR_Init()
to getIHmd
object - Change display mode for target display (or set up a window that covers the target rect)
- Tell your
IHmd
object your target resolution - Query render target size / view bounds
- Do stuff
After sleeping on it a bit, I think it's also worth bringing up that the API (or at least with the Oculus driver under Windows) is conflating the window boundaries necessary to be visible on the HMD and the desired render resolution.
Right now the Oculus driver under Windows is implicitly assuming that we want to render at the resolution of the window, and deriving the recommended render target size from that. So far I've been deriving the ratio of the recommended render target size to the window size and making a new render target size relative to the desired resolution, but given the API is intentionally obscuring that information (for good reason - the two resolutions might not actually be related at all) that strikes me as a dangerous workaround.
Which gets back to my original point - it would probably be smarter if we could provide a recommended render resolution to the API and get appropriate render target sizes back out of it.
In what scenario would you want the window to be a different size than the desired render resolution? Isn't this just a question of stale cached values?
I get that the window bounds aren't updating when you change the resolution to something else (or plug in/unplug a monitor). I can fix that by listening for WM_DISPLAYCHANGE and updating the cached values when that happens. (Or whatever the OSX and LInux equivalents are on those platforms.)
Alrighty, that would work. The issue reported is just a question of stale cached values - I got side tracked thinking about it (sorry). I can move the discussion about different resolutions to a separate bug or over onto the Steam discussion forums if that would be better.
The biggest thing I can think of re: different resolutions would be if you cannot (or do not want to) do a mode change to achieve a desired resolution. I know a lot of people who prefer (especially under Linux) to fake full screen modes by doing a borderless window matched to the display boundaries, and then rendering at a different resolution in an offscreen render target. While it wouldn't be an issue of stale cached values, the behavior would be similar as the VR API will be reporting information based on the desktop resolution and not the desired offscreen resolution.